170 likes | 437 Views
Ultra-low Power Motion Detection using the MSP430F2013. PIR Sensor Output & Signal Conditioning. Motion Detection Software Flowchart. //****************************************************************************** #include <msp430x20x3.h>
E N D
//******************************************************************************//****************************************************************************** #include <msp430x20x3.h> #define LED_OUT BIT0 // Bit location for LED #define SENSOR_PWR BIT7 // Bit location for power to sensor #define THRESHOLD 50 // Threshold for motion static unsigned int result_old = 0; // Storage for last conversion void main(void) { WDTCTL = WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL; // ACLK/32768, int timer: ~10s BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; BCSCTL1 |= DIVA_2; // ACLK = VLO/4 BCSCTL3 |= LFXT1S_2; P1OUT = 0x10; // P1OUTs P1SEL = 0x08; // Select VREF function P1DIR = 0xEF; // Unused pins as outputs P2OUT = 0x00 + SENSOR_PWR; // P2OUTs P2SEL &= ~SENSOR_PWR; // P2.7 = GPIO P2DIR = 0xff; // Unused pins as outputs SD16CTL = SD16VMIDON + SD16REFON + SD16SSEL_1;// 1.2V ref, SMCLK SD16INCTL0 = SD16GAIN_4 + SD16INCH_4; // PGA = 4x, Diff inputs A4- & A4+ SD16CCTL0 = SD16SNGL + SD16IE; // Single conversion, 256OSR, Int enable SD16CTL &= ~SD16VMIDON; // VMID off: used to settle ref cap SD16AE = SD16AE1 + SD16AE2; // P1.1 & P1.2: A4+/- SD16_A inputs // Wait for PIR sensor to settle: 1st WDT+ interval P1SEL |= LED_OUT; // Turn LED on with ACLK (for low Icc) while(!(IFG1 & WDTIFG)); // ~5.4s delay: PIR sensor settling P1SEL &= ~LED_OUT; // Turn LED off with ACLK (for low Icc) // Reconfig WDT+ for normal operation: interval of ~341msec WDTCTL = WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1;// ACLK/512, int timer: 341msec BCSCTL1 |= DIVA_3; // ACLK = VLO/8 IE1 |= WDTIE; // Enable WDT interrupt _BIS_SR(LPM3_bits + GIE); // Enter LPM3 with interrupts }
/****************************************************** // SD16_A interrupt service routine ******************************************************/ #pragma vector = SD16_VECTOR __interrupt void SD16ISR(void) { unsigned int result_new; SD16CTL &= ~SD16REFON; // Turn off SD16_A ref result_new = SD16MEM0; // Save result (clears IFG) if (result_new > result_old) // Get difference between samples result_old = result_new - result_old; else result_old = result_old - result_new; if (result_old > THRESHOLD) // If motion detected... P1OUT |= LED_OUT; // Turn LED on result_old = SD16MEM0; // Save last conversion __bis_SR_register_on_exit(SCG1+SCG0); // Return to LPM3 after reti } /****************************************************** // Watchdog Timer interrupt service routine ******************************************************/ #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) { if (!(P1OUT & LED_OUT)) // Has motion already been detected? { SD16CTL |= SD16REFON; // If no, turn on SD16_A ref SD16CCTL0 |= SD16SC; // Set bit to start new conversion __bic_SR_register_on_exit(SCG1+SCG0); // Keep DCO & SMCLK on after reti } else P1OUT &= ~LED_OUT; // If yes, turn off LED, measure on next loop }
Sampling frequency • The idea is that the variable resistor mimics a thermistor and the LED should be illuminated if the temperature falls too low, when R2 > 10kΩ.Overall, the two resistances are in series to give Rin = Rs+RI.We now have the classic RC circuit and found in the section “Practical Issues with SARs” on page 405 that we need to allow 7.6 time-constants for charging in a 10-bit ADC. The worst case is when the resistance and capacitance take theirmaximum values.We should therefore assume that the variable resistor R2 = 20k Ω, in which case Rs = R1// R2 ≈ 7k Ω. The data sheet gives RI ≤ 2k Ω so we should take Rin = 9k Ω. The data sheet also gives CI ≤ 27pF and again we take this maximum value as the most pessimistic estimate. Then τ = RinCI = 0.24μs and 7.6τ = 1.85μs. • The sampling time is configured in terms of cycles of ADC10CLK. I use the internal oscillator ADC10OSC and we should take its maximum frequency of 6.3MHz for safety. • The number of cycles is therefore 1.85μs×6.3MHz = 12.
Application notes/projects with ADCs • Temperature recorder • A Simple Glass Breakage Detector Using the MSP430 (slaa351) • Implementing a Smoke Detector with the MSP430F2012 (slaa335) • Low-Power Tilt Sensor Using the MSP430F2012 (slaa309). A two-axis accelerometer is interfaced directly to a F2012, which illuminates six LEDs to show the direction in which the PCB is tilted.
Application notes/projects with ADCs • Li-Ion Battery Charger Solution Using the MSP430 (slaa287). An ADC10 is used to monitor the voltage across the battery, the charging current, and the temperature of the battery, sensed by a thermistor. Charging goes through two stages, one at constant current followed by one at constant voltage, before the battery is fully charged. The temperature sensor is needed to detect overheating, in which case the battery might catch fire. • Solid State Voice Recorder Using Flash MSP430 (slaa123). The sound is digitized by an ADC12 triggered by Timer_B to avoid jitter in the sampling clock. The sound is recorded in flash memory. Several external components are needed to complete the system but could be eliminated by selecting a newer device such as the FG4618.