Jump to content
p2baron

Check if I am in LPM4

Recommended Posts

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?

 

 

 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

 

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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) 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×