Skip to content
George edited this page Jun 10, 2019 · 28 revisions

Introduction

Battery-powered devices usually need to be put in sleep mode to save current. This is a crucial technique when you want your devices to last for years from simple battery packs. panStamp provides multiple commands to make the nodes come in sleep mode. The MSP430 core found in NRG/CC430 supports 5 low-power modes (LPM0/AM to LPM4) with LPM4 being the lowest power consumption but also with most limitations (features, clocks and CPU will be disabled and may take up to 100ms to wake back to the main loop).

Low power nodes usually follow this workflow:

  1. Read sensors and transmit values
  2. Enter sleep mode
  3. Stay in sleep mode until an event (external pin or RTC) occurs
  4. Leave sleep mode
  5. Back to 1

The above workflow can be implemented in the arduino loop so that the process is repeated forever.

Notes:

  • Avoid using the delay() function within the ISR as this will render the workflow stuck. To fix this you can add panstamp.wakeUp() and detachInterrupt() at the start of your ISR or use delayMicroseconds() instead. This happens because the delay() function pushes the module in Active Mode and re-enables interrupts.
  • Avoid using the Serial Monitor and its functions if you are going to use attachInterrupt() and sleep modes. Use your LED for debugging instead or use Serial.end() right after finishing with serial communication.
  • Remember that everything in the ISR function runs at 1Mhz instead of 12Mhz so any delayed timing must be divided by 12, except for ACLK dependent features like timers.
  • Always try using RISING, FALLING and CHANGE within the attachInterrupt() function.
  • Try using volatile variables for ISR related flags.
  • pinMode() changes and interrupts don't get on well together. detachInterrupt() before you swap a pin from input to output or vice-versa.

Available commands

There are different ways to enter sleep mode from a panStamp:

sleep with external pin interrupt (LPM4)

This command belongs to the global panstamp object and puts the module in sleep mode until a pin change interruption is detected. If no interrupt is enabled or detected, the module could stay in sleep mode forever. The module can't be woken up from radio but other interrupts are enabled.

Example:

void myIsr()
{
  // This function is called whenever digital pin changes
}

void setup()
{
  swap.init();
  attachInterrupt(1, myIsr, CHANGE);  // Attach interrupt on digital pin 1 to custom ISR
}

void loop()
{
  // Read sensor and transmit SWAP status packet
  swap.getRegister(REGI_MYSENSOR)->getData();
  // Enter sleep mode
  panstamp.sleep();
  // The panStamp is now sleeping. It will wake up when pin 1 changes
  // ZZZZZZZZ....
}

sleep with RTC calendar (LPM3)

This option is only available for panStamp NRG. The CC430 SoC from NRG has a hardware RTC module which can be put in calendar mode. In order to wake-up from sleep, the appilcation needs to initialize the RTC clock and program an alarm before calling panstamp.sleep()

Example:

void setup()
{
  // Set current time : Thursday 8-Apr 2015 12:15:00 (PM)
  rtcData.year = 2015;
  rtcData.mon = 4;
  rtcData.day = 9;
  rtcData.wday = 4;
  rtcData.hour = 13;
  rtcData.min = 48;
  rtcData.sec = 0;
  
  panstamp.rtc.startCalendar(&rtcData);
  
  // Trigger alarm at every day at 10h00 AM
  panstamp.rtc.setAlarmHour(10);
}

void loop()
{
  // Read sensor and transmit SWAP status packet
  swap.getRegister(REGI_MYSENSOR)->getData();
  // Enter sleep mode
  panstamp.sleep();
  // The panStamp is now sleeping. It will wake up when the RTC alarm occurs
  // ZZZZZZZZ....
}

sleepSec (LPM3)

This command belongs to the global panstamp object as well and puts the module in sleep mode for the amount of seconds passed as argument. Even in the absence of a pin interrupt the module comes out from sleep once the sleeping interval has elapsed. Interrupts are (re)enabled with this function.

Example:

void loop()
{
  // Read sensor and transmit SWAP status packet
  swap.getRegister(REGI_MYSENSOR)->getData();
  // Enter sleep mode for 30 seconds
  panstamp.sleepSec(30);
  // The panStamp is now sleeping. It will wake up after 30 seconds
  // ZZZZZZZZ....
}

goToSleep

This command is part of the global swap object, as far as the SWAP library is being used of course. It also puts the panStamp in sleep mode for a fixed period of time but, unlike panstamp.sleep(), the interval is taken from the global SWAP register txInterval, making the sleeping interval dynamically modifiable wirelessly via SWAP commands or from the application itself.

Example:

void loop()
{
  // Read sensor and transmit SWAP status packet
  swap.getRegister(REGI_MYSENSOR)->getData();
  // Enter sleep mode for txInterval seconds
  swap.goToSleep();
  // The panStamp is now sleeping. It will wake up after txInterval seconds
  // ZZZZZZZZ....
}

setPowerDownState

This mode completely disables the CC1101 radio module, thus leveraging more power saving for the main MCU. Any radio signals coming will not be received and transmission may be delayed by a few milliseconds in order for the radio module to power on again. Disabling the CC1101 saves approx. 16mA which is the majority of the power consumed by the CC430. To wake the radio module back simply use "panstamp.radio.wakeUp()".

Example:

void setup()
{
panstamp.radio.setPowerDownState();
}

setRxOffState

While "panstamp.rxOff()" disables the receiving signals, it does not power down the receiving part of the CC1101. This mode accomplishes just that, powering down the reception. You may use this mode to enable better transmission latency instead of turning off all the radio module. This mode saves approx. 14.4mA. You can restore from this mode using "panstamp.radio.setRxOnState()".

Example:

void setup()
{
panstamp.radio.setRxOffState();
}

setWorState (LPM3)

Puts the CC430 into Wake-on-radio state where the Rx polls a specified interval and wakes up the module to packets received. Particularly useful as it puts the CPU in a permanent sleep state (LPM3) while the RF module (CC1101) listens to packets then wakes the module only when required, thus saving more power.

millis: Sleeping interval in milliseconds. It must be between 12ms and 2000ms.

Example:

void loop()
{
panstamp.radio.setWorState(200);
}

Anti Swap

API for Anti Swap

Clone this wiki locally