p2baron 11 Posted December 13, 2013 Share Posted December 13, 2013 I am currently working on a battery operated wireless doorsensor. A message is sent whenever a magnetic switch causes an interrupt. I have read some topics on this forum and changed some lines in Winterrupts file and created the following sketch: #include <x10rf.h> #define intpin1 P1_5 #define txpin P1_7 #define txvcc P1_0 #define reps 4 x10rf myx10 = x10rf(txpin,0,reps); void setup() { myx10.begin(); pinMode(intpin1,INPUT_PULLUP); pinMode(txvcc,OUTPUT); digitalWrite(intpin1, HIGH); digitalWrite(txvcc, LOW); attachInterrupt(intpin1, Wake, CHANGE); } void loop() { LPM4; } void Wake() { int state = digitalRead(intpin1); digitalWrite(txvcc, HIGH); switch(state) { case 0: myx10.x10Security(3,0x84); break; case 1: myx10.x10Security(3,0x04); break; } delay(10); digitalWrite(txvcc, LOW); } This is working great but I have some questions. How can I check that MCU is running in LPM4? Do I need CCS to check (debug) this or are there other ways? At some point I want to add sensors to periodically report temperature and light conditions. What is a power efficient way to do this? I know timers don't work in LPM4. Should I switch to LPM3 or use an external circuit to wake the MCU every x minutes? Quote Link to post Share on other sites
roadrunner84 466 Posted December 13, 2013 Share Posted December 13, 2013 Whenever the CPU is running you're not in any LPM. If you want to, you can set up a specific pin to output ACLK, if this clock signal dies you know you're in LPM4. Depending on your sensor type and frequencies, timer power consumption etc. you could either switch to LPM3 or feed either a timer or a digital input with a signal to wake up. Your question is too vague to answer directly. Best is to try different approaches and connect a sensitive current sensor (the uCurrent or something like that). Note that if you want a stable period to wake when running in LPM3, you need to set ACLK to run from a crystal. MSP430 do not support CHANGE for an interrupt, only FALLING and RISING. In your case I should use FALLING, since your pin is pull-up. Or flip the interrupting edge in the Wake() routine, make sure the state of the pin is indeed opposed when changing to RISING, or you'll miss the interrupt. Also, keep in mind that any mechanical contact (like a reed sensor) bounces, causing a train of high/low signals for a brief moment before settling on a stable high or low. p2baron 1 Quote Link to post Share on other sites
energia 484 Posted December 14, 2013 Share Posted December 14, 2013 The Watchdog timer is being abused to keep millis/micros counter. Eventhough you go to LPM, when the Watchdog timer triggers it will wake you up again. Since you have nothing in loop other than LPM4 you will go back to LPM immediatly though. So to stay in LPM you have to disable the Watchdog timer using disableWatchdog(). Note that once you do so any delay function will stop working since it depends on the Watchdog running. You can reenable the watchdog with enableWatchDogIntervalMode(). While the Watchdog is disabled millis() and micros() will not be updated. As for the CHANGE interrupt, @@roadrunner84 is right, this was not supported until Energia 10. We have added code to emulate the CHANGE interrupt by flipping the edge bit in the interrupt register when the interrupt triggers if the type of interrupt is CHANGE. roadrunner84 1 Quote Link to post Share on other sites
spirilis 1,265 Posted December 14, 2013 Share Posted December 14, 2013 Watchdog will halt in LPM4 since its clock source is disabled (actually it will in LPM3 too bc Energia uses SMCLK for the WDT)... The WDT clock fail-safe mechanism (where it forces its clock system back on if the app tries to shut it off) only functions with WDT in true "watchdog" mode according to the user's guide... Sent from my Galaxy Note II with Tapatalk 4 roadrunner84 1 Quote Link to post Share on other sites
grahamf72 169 Posted December 15, 2013 Share Posted December 15, 2013 What @spirilis says about the WDT clocking is correct. I might also add though that when another interrupt does occur (eg a pin interrupt while in LPM4) the clock starts up again, and hence the internal counter of the WDT. The WDT triggers every 512 clock cycles, so once 512 clocks have elapsed, the WDT interrupt will trigger, and the interrupt routine will run when the current interrupt has finished. This can cause what appears to be strange behaviour. For example if your pin interrupt takes 128 clock cycles to run, the WDT will run every 4th interrupt, and leave the processor at full power when it finishes. Sent from my iPad using Tapatalk spirilis 1 Quote Link to post Share on other sites
spirilis 1,265 Posted December 15, 2013 Share Posted December 15, 2013 Ahh, so that can explain how wakeups can inadvertently occur. Sent from my Galaxy Note II with Tapatalk 4 Quote Link to post Share on other sites
p2baron 11 Posted December 16, 2013 Author Share Posted December 16, 2013 Whenever the CPU is running you're not in any LPM. If you want to, you can set up a specific pin to output ACLK, if this clock signal dies you know you're in LPM4. Depending on your sensor type and frequencies, timer power consumption etc. you could either switch to LPM3 or feed either a timer or a digital input with a signal to wake up. Your question is too vague to answer directly. Best is to try different approaches and connect a sensitive current sensor (the uCurrent or something like that). Note that if you want a stable period to wake when running in LPM3, you need to set ACLK to run from a crystal. MSP430 do not support CHANGE for an interrupt, only FALLING and RISING. In your case I should use FALLING, since your pin is pull-up. Or flip the interrupting edge in the Wake() routine, make sure the state of the pin is indeed opposed when changing to RISING, or you'll miss the interrupt. Also, keep in mind that any mechanical contact (like a reed sensor) bounces, causing a train of high/low signals for a brief moment before settling on a stable high or low. Thanks, I will try LPM3. Timing isn't critical since I need to send temperature (dallas 1-wire) and brightness (LDR?) every 30-60 minutes. The Watchdog timer is being abused to keep millis/micros counter. Eventhough you go to LPM, when the Watchdog timer triggers it will wake you up again. Since you have nothing in loop other than LPM4 you will go back to LPM immediatly though. So to stay in LPM you have to disable the Watchdog timer using disableWatchdog(). Note that once you do so any delay function will stop working since it depends on the Watchdog running. You can reenable the watchdog with enableWatchDogIntervalMode(). While the Watchdog is disabled millis() and micros() will not be updated. As for the CHANGE interrupt, @@roadrunner84 is right, this was not supported until Energia 10. We have added code to emulate the CHANGE interrupt by flipping the edge bit in the interrupt register when the interrupt triggers if the type of interrupt is CHANGE. I've used the latest Energia version so that should explain why my sketch is working. Watchdog will halt in LPM4 since its clock source is disabled (actually it will in LPM3 too bc Energia uses SMCLK for the WDT)... The WDT clock fail-safe mechanism (where it forces its clock system back on if the app tries to shut it off) only functions with WDT in true "watchdog" mode according to the user's guide... Sent from my Galaxy Note II with Tapatalk 4 Not sure what this means for my code. It has been running for over a week on a coin cell battery. (cr2032) Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.