All things - Low Power

It's true that the unsuspecting could ruin a board applying >6 V, but I designed all of these to run from LiPo batteries so <6 V max should be OK. The great thing about Teensy 3.2 is you can run it from a standard 9 V battery!

And I finally learned to use diodes to prevent reverse polarity problems; I have destroyed more boards this way than with too high voltage!
 
Unfortunately, the LP38691 does consume some static power. It shouldn't be anything like 0.33 mA, so perhaps something else is going on here? Maybe I need to dig into this?
Oh that was my mistake, I had it compile for VLPW instead of LLS low power mode with the USB regulator off when I wrote that, sorry for the confusion. One thing that I did notice is if you power it directly through the 3.3V power pin it doesn't always boot up. I see now that the LP38691 doesn't have an enable pin so there is note in the data sheet about having a higher potential on the output than the input that could be causing this no boot issue.
 
I tried out your new (to me) snooze library and ran the deepSleep_all_wakeup sketch. It looks like this resets the Teensy on wakeup (by RTC alarm in the case I chose). I switched to sleep rather than deepSleep and it does the same thing. That is, I get the thunk-kthunk from Windows i usually get on reset. I have a couple of questions then:

1) Is there a sleep mode that just suspends the loop and upon wake resumes where it left off? Maybe this is exactly what is happening and i am misinterpreting the sound as a reset?

2) If I add stuff to the loop like sensor reads and serial output that might take several hundred milliseconds to accomplish will all of the stuff get executed and then, at the top of the loop, where I have the Snooze.sleep(config); statement the Teensy will go to sleep and start the cycle all over again?

3) in this case, when the Teensy wakes, would I2C and Serial configurations that were set up in the setup section remain activated? I mean does sleep or deepSleep merely interrupt the loop, shut things down to a low power state, wakeup and then resume as though nothing has happened or does it restart the sketch from scratch and require all the peripherals to be reinstantiated?

I suppose I could just try it and see but i thought I would ask first...
 
1) Is there a sleep mode that just suspends the loop and upon wake resumes where it left off? Maybe this is exactly what is happening and i am misinterpreting the sound as a reset?

2) If I add stuff to the loop like sensor reads and serial output that might take several hundred milliseconds to accomplish will all of the stuff get executed and then, at the top of the loop, where I have the Snooze.sleep(config); statement the Teensy will go to sleep and start the cycle all over again?

3) in this case, when the Teensy wakes, would I2C and Serial configurations that were set up in the setup section remain activated? I mean does sleep or deepSleep merely interrupt the loop, shut things down to a low power state, wakeup and then resume as though nothing has happened or does it restart the sketch from scratch and require all the peripherals to be reinstantiated?

I suppose I could just try it and see but i thought I would ask first...

  1. all sleep modes disable the USB and its clock, thats why you are hearing that sound on your win box. USB and sleep modes don't like each other currently. I'm working on trying to make them play nice together.
  2. No, you have to make sure any Serial, SPI, etc., transactions finishes before you call any of the sleep functions or they will get cut off.
  3. Currently it does not save the state of anything so if you configure to use pin wakeup on the same pin as your I2C or Serial you will have to re configure it after it wakes up. The new version I'm working on will save the state and return it after it wakes for all wakeups used.
 
Since this thread is "all things" low power, I thought I would mention a couple of recent finds:

First up is a very low Iq LDO, the NCP8170 150 mA LDO voltage regulator with a quiescent current of just 500 nAmps. It's only rated to 150 mA but this is fine for many low power applications. I note the Teensy 3.1 was limited to 100 mA and this worked well for many people.

Next is a very low-power SPI NOR flash memory, the 128 Mbit of Macronix MX25L12835F NOR flash memory. It has an Iq of 10 microAmp, which is already very low but it also has a deepPowerDown mode where the Iq drops to 2 microAmp. These large memories tend to be power hogs when running so the best way to operate is to power them up, read and/or write, then power down until the next memory operation. This chip allows this mode of operation and provides significant power savings over others available.

I am using both on the ultra-low-power STM32L4 breakout I'm developing. For remote sensing/logging and wearable applications, I expect to get thousands of hours of operation with a small 110 mAH LiPo battery using this device.
 
Since this thread is "all things" low power, I thought I would mention a couple of recent finds:

First up is a very low Iq LDO, the NCP8170 150 mA LDO voltage regulator with a quiescent current of just 500 nAmps. It's only rated to 150 mA but this is fine for many low power applications. I note the Teensy 3.1 was limited to 100 mA and this worked well for many people.

Next is a very low-power SPI NOR flash memory, the 128 Mbit of Macronix MX25L12835F NOR flash memory. It has an Iq of 10 microAmp, which is already very low but it also has a deepPowerDown mode where the Iq drops to 2 microAmp. These large memories tend to be power hogs when running so the best way to operate is to power them up, read and/or write, then power down until the next memory operation. This chip allows this mode of operation and provides significant power savings over others available.

I am using both on the ultra-low-power STM32L4 breakout I'm developing. For remote sensing/logging and wearable applications, I expect to get thousands of hours of operation with a small 110 mAH LiPo battery using this device.
All good info!

Have you looked at any of the high side load switch ic's also? These can be used for electronics that don't have a low power option or just analog circuits that you don't need powered all the time. Here is one that I just found TPS27081A: One application I saw is using this for a 'True Shutdown' for your boost regualtors because of the leakage current throught he inductor and the feedback resistor.
 
The other application is to power VUSB for USB Host mode. I use a load switch as an RF power switcher in the electronic Imp and might need one for USB host mode for the STM32L4. But the 5 V booster on the flight controllers don't need to be ultra-low power when the motors draw 4 Amps!
 
Hi Duff,

yes that is correct micros will not reflect the sleep duration. If your using the timer to wake up then you can update the "systick_millis_count" variable by the timer amount.

but what if we wake up by interrupt ? How can we know the sleep duration ?

Thank you.
 
but what if we wake up by interrupt ? How can we know the sleep duration ?
If you have rtc crystal installed you can use the rtc for 1 sec resolution. Just read before you go to sleep and after. I'm assuming you have T3.x
 
If you have rtc crystal installed you can use the rtc for 1 sec resolution. Just read before you go to sleep and after. I'm assuming you have T3.x

Understood, thanks!

The documentation says that idle() will be interrupted by systick, but in smc.h systick is disabled before entering wait mode. After some measure (using RTC ticks), my teensy3 never stay idle for more than ~1000 microseconds. I'm wondering what is waking-up the CPU in idle() ?

If I use a modified idle(), with systick enabled, the average idle duration is 500 microseconds (with a big stddev).

I also measure sleep() and deepSleep(). With only a LPTimer of 1 ms (smallest possible) and no interrupt. The average duration of sleep (~4000 microseconds) is bigger than deepSleep() (~3000 microseconds). Is that normal ?

Thanks again, pretty useful library :)
 
The documentation says that idle() will be interrupted by systick, but in smc.h systick is disabled before entering wait mode. After some measure (using RTC ticks), my teensy3 never stay idle for more than ~1000 microseconds. I'm wondering what is waking-up the CPU in idle() ?
You are right, but since any interrupt can wake the cpu from "wait" mode something else is waking it probably USB stuff but it could be problem if you run the cpu below 24 MHz with no USB. My new version has separate 'wait' function for idle so the systick is not disabled. I got side tracked recently with some new Audio library stuff but I hope to have preview of Snooze V6 up soon so people can try it out see if they like it. I'm trying to solve a bunch of issues and shortcoming that various people have pointed out. The new version tries to bridge the gap between performance and flexibility but its been a hard marriage of the two :cool:.
I also measure sleep() and deepSleep(). With only a LPTimer of 1 ms (smallest possible) and no interrupt. The average duration of sleep (~4000 microseconds) is bigger than deepSleep() (~3000 microseconds). Is that normal ?
Yes, that is normal, that is one of the performance issues I'm struggling with in the new version is how to handle the setup code for before and after sleeping the Teensy. The current version has to setup the Low Power Timer and then disable it again with a bunch of other register stuff that takes time. I don't want to make the configurations of the different wakeup methods static which would probably solve the performance but then you can't have multiple wakeup method configurations.
 
Are there any Snooze power consumption measurements for the Teensy LC?

(Haven't found any.)

Since the LC features the MKL26Z64VFT4 supposedly a "ultra-low-power MCU" this should be interesting.

Thanks for all info.

-Markk
I see with standard 'hibernate' sleep a current of around 4uA. Can't remeber the other sleep currents off hand.
 
I tried just "{asm("wfi");}" while polling for keyboard input. Simple without a large library. It doesn't disconnect USB, but I didn't notice any power drop until I did:
Code:
for (int i = 0; i < 100; ++i)
    {asm("wfi");}

The STM32L4 sounds impressive in terms of power draw.
 
Last edited:
I measured 9 μA on a mk20dx256 in hibernate mode. About 200 μA in deep sleep.

Question: when hibernating, what state do the pins go to? High impedance?
 
Say some random pin, unrelated to wakeup that was configured as an output and set high.
That pin would stay in static state of what it was before sleeping, you can verify it for yourself, set the LED high before going to sleep and you will see that it stays high, same goes for any other digital configured pin.
 
Thanks (and thanks for your library). So for the lowest power draw, one may want to (depends on the circuit and application) set some pins to high impedance, sleep, then restore their state.

If you have some 3.3V external chips that are fairly low draw (say < 9ma) and aren't needed all the time, it might be best to power them from a teensy output pin, not VOUT33 (which remains on during sleep). This makes them easy to shut off
 
Last edited:
Just got an ad from DigiKey touting a new IoT Wifi module with these specs. No prices yet
- Shutdown 12.33uA
- Idle & Wi-Fi Associated (DTIM:3) 1.8mA
- Active (RX/TX) 40mA/220mA
Product brief PDF at : http://www.econais.com/wp-content/uploads/2014/12/Econais_EC19W01_WiSmart_Modules_ProdBrief.pdf

I've not delved into WiFi on Teensy yet, though I've purchased some parts.
When I do delve in... I'd love it if there was "one best path" to learn about.

Seems like, to date, the best choice for low power and small size is the ESP8266,
though this newcomer might offer advantages in both
 
Hello, hoping to get some guidance on an issue I'm having with the snooze library?

Sample programs all work fine for me but when I go to implement in a larger project I'm getting mixed results. Sometimes the Teensy does not wake up? I've tried to strip the code down to a minimum example that I will insert below. I am using pin 2 as the pin in snooze.config and I'm also reading the state of that pin in the code to determine when to go into sleep mode. Also, prior to calling sleep, I'm disabling some simple timers and then upon wakeup, want to enable them. So I have assumed that placing the routine that runs the "wakeup" code is the next to run upon the interrupt when coming out of sleep? So that function is called right after the call to sleep.

Pin 2 is attached to a physical latching push button switch.

The code below is intermittent with waking up. For the most part it does but sometimes I cannot get it to wakeup? I also had to add the call to standby (which calls the snooze.sleep) at the bottom of setup or it will never wakeup? Seems like I'm missing something or doing something wrong. Hopefully you can help.

Code:
void setup()
{
    Serial.begin(115200);

    pinMode(SYSTEMPWR, INPUT);
    pinMode(LED_BUILTIN, OUTPUT);

    // Setup a timer for teensy led visual indicator
    ledOnTimerID = timer.setInterval(4000, ledOn);
    ledOffTimerID = timer.setInterval(500, ledOff);

    config.pinMode(SYSTEMPWR, INPUT, HIGH); //REMOVED FOR PROTOTYPE

    standby();
}

void loop()
{

     switchState = digitalRead(SYSTEMPWR);
     if (switchState == HIGH)
     {
         //Updates whatever timers have been defined
         timer.run();
         processDebug();

         functionOne();
         ...............
         functionThree();
    }
    else
    {
        standby();
    }

}
........
void wakeUp(void)
{
    Serial.println("Wake Up from Sleep Called");

    // when you come out of sleep power on the
    // the display and reset the timers
    digitalWrite(DISPLAYPWR, HIGH);
    displayOnPwrState = displayOnPwrState + 1;
    displayPwrState = 1;
    // enable the timers that were disabled in standby
    timer.enable(ledOnTimerID);
    timer.enable(ledOffTimerID);

    awake = true;
    sleeping = false;
}

void standby(void)
{
    digitalWrite(DISPLAYPWR, LOW);
    displayOffPwrState = displayOffPwrState + 1;
    displayPwrState = 0;
    //Serial.println("Sleeping ");
    // disable the active timers

    if(timer.isEnabled(ledOnTimerID))
    {
        timer.disable(ledOnTimerID);
    }
    if(timer.isEnabled(ledOffTimerID))
    {
        timer.disable(ledOffTimerID);
    }

    sleeping = true;
    awake = false;
    Snooze.sleep(config);
    wakeUp();
}

any help would be most appreciated.
 
Last edited:
can you post something that compiles and does not rely on other non posted code or libraries that shows this problem?
 
can you post something that compiles and does not rely on other non posted code or libraries that shows this problem?

Thanks for looking at this. Sorry about the posting. Here is some code that should compile with no other libraries:

Code:
#define SYSTEMPWR 2
#define DISPLAYPWR 12

//#include <SimpleTimer.h>
#include <Snooze.h>


uint8_t rx_byte = 0x00;
boolean badIn = false;

boolean sleeping = false;
boolean awake = false;

//SimpleTimer timer;
//int ledOnTimerID = 0;
//int ledOffTimerID = 0;

elapsedMillis ledOnTimerID = 0;
elapsedMillis ledOffTimerID = 0;

int ledOnLimit = 4000;
int ledOffLimit = 4000;

int displayOffPwrState = 0;
int displayOnPwrState = 0;
int displayPwrState = 0;
int count = 0;

SnoozeBlock config;
bool switchState; //variable that holds the system power state



void processDebug()
{

    // capture any serial input to support debug printouts
    if (Serial.available() > 0)  // is a character available?
    {
       rx_byte = Serial.read(); // get a character from the Serial port
       //Serial.print("Number received: ");
       //Serial.println(rx_byte);
       switch(rx_byte)
       {
             case 'z':
                Serial.println(" ");
                Serial.print("Display Power Off Count is: ");
                Serial.println(displayOffPwrState);
                Serial.print("Display Power On Count is: ");
                Serial.println(displayOnPwrState);
                Serial.print("Current Display Power State: ");
                Serial.println(displayPwrState);
                break;
            default :
                badIn = true;
                break;
        }

        if (badIn)
        {
            Serial.println("Bad Input Try Again:");
            Serial.println("z - Prints the power on power off counts");
            badIn = false;
        }
    }
}

void wakeUp(void)
{
    Serial.println("Wake Up from Sleep Called");

    // when you come out of sleep power on the
    // the display and reset the timers
    digitalWrite(DISPLAYPWR, HIGH);
    displayOnPwrState = displayOnPwrState + 1;
    displayPwrState = 1;
    // enable the timers that were disabled in standby
    //timer.enable(ledOnTimerID);
    //timer.enable(ledOffTimerID);

    // reset the timers to flash the LED every 4 seconds when running
    ledOffTimerID = 0;
    ledOnTimerID = 300; // set led on 300 ms ahead of off so led stays on for 300 ms

    awake = true;
    sleeping = false;
}

void standby(void)
{
    digitalWrite(DISPLAYPWR, LOW);
    displayOffPwrState = displayOffPwrState + 1;
    displayPwrState = 0;
    //Serial.println("Sleeping ");
    // disable the active timers

    sleeping = true;
    awake = false;
    Snooze.sleep(config);
}

void functionOne()
{
    count++;

}

void functionTwo()
{
    count--;

}

void functionThree()
{
    count++;

}

void checkTimer()
{
    if(ledOnTimerID > ledOnLimit)
    {
        ledOn();
        // reset the timer
        ledOnTimerID = 0;
    }

    if(ledOffTimerID >= ledOffLimit)
    {
        ledOff();
        // reset the timer
        ledOffTimerID = 0;
    }
}

//Teensy Light OFF (to verify Teensy is "Up")
void ledOff()
{
    digitalWriteFast(LED_BUILTIN, LOW);
}

//Teensy Light ON (to verify Teensy is "Up")
void ledOn()
{
    digitalWriteFast(LED_BUILTIN, HIGH);
}

void setup()
{
    Serial.begin(115200);

    pinMode(SYSTEMPWR, INPUT);
    pinMode(DISPLAYPWR, OUTPUT);
    pinMode(LED_BUILTIN, OUTPUT);

    //config.pinMode(SYSTEMPWR, INPUT_PULLUP, RISING);
    config.pinMode(SYSTEMPWR, INPUT, HIGH);

    ledOffTimerID = 0;
    ledOnTimerID = 300; // set led on 300 ms ahead of off so led stays on for 300 ms

    // there is always power to the board so sleep or not based on external switch position
    if(digitalRead(SYSTEMPWR))
    {
        displayPwrState = 1;
        digitalWrite(DISPLAYPWR, HIGH);
    }
    else
    {
        standby();
    }
}

void loop()
{
     switchState = digitalRead(SYSTEMPWR);
     if (switchState == HIGH)
     {
         if(sleeping)
         {
             wakeUp();
         }
         //Updates whatever timers have been defined
         checkTimer();
         //timer.run();
         processDebug();

         functionOne();
         functionTwo();
         functionThree();
    }
    else
    {
        standby();
    }
}

I do not "wake up" using this code.

Thank you
 
can you post something that compiles and does not rely on other non posted code or libraries that shows this problem?

Duff, I was using version 5 and have just tried your version 6 from github. initial testing seems to work well for me. I'm currently looking at usb serial port not printing for me after initial sleep. I think you had some notes on that so I will read through that.

Thank you
 
Duff, I was using version 5 and have just tried your version 6 from github. initial testing seems to work well for me. I'm currently looking at usb serial port not printing for me after initial sleep. I think you had some notes on that so I will read through that.

Thank you
Ok good, i was going to suggest that first, I also had to use a pulldown resistor to make your sketch work as expected when power is not present on pin 2. Yes, the USB gets disconnected when sleeping so you have to reopen the Serial monitor and even then it could take awhile for the usb to stabilize. What I found works best is to use usb for debug and use a delay of 1000 ms after sleeping to let the usb reconnect with your pc and it still can be a little flakey.
 
Back
Top