duff2013 / Snooze

Teensy Low Power Library
MIT License
134 stars 37 forks source link

Can't get LC to deepsleep more than 60 seconds #75

Closed jnevinsiv closed 4 years ago

jnevinsiv commented 4 years ago

Hi!

I want my teensy LC to wake up from deepsleep every 6 hours via timer. However the longest it seems to sleep is 1 minute 5 seconds.

I just mod your example deepsleep script for 2 minutes - timer.setTimer(120000);// milliseconds but it starts again after a minute I tried timer.setTimer(21600000) and no luck.

However it doesn't seem to be able to handle large millis given the period is defined as uint16_t.

I also tried hibernate and sleep example script with no luck - 1min max sleep is all I can get.

/*** This shows all the wakeups for deepSleep Expect IDD of around 230uA (Teensy 3.x) and IDD of around 150uA for (Teensy LC). Teensy 3.5/3.6 are yet to be determined. ****/

include

// Load drivers SnoozeDigital digital; SnoozeCompare compare; SnoozeTimer timer; SnoozeTouch touch; SnoozeAlarm alarm; // configures the lc's 5v data buffer (OUTPUT, LOW) for low power Snoozelc5vBuffer lc5vBuffer; /*** Teensy 3.6/LC can't use Timer Driver with either Touch or Compare Drivers and Touch can't be used with Compare.

Teensy 3.5 does not touch interface.

Teensy LC does not have a rtc so Alarm driver can't be used as of yet.

Teensy 3.2 can use any Core Drivers together. ***/

if defined(MK66FX1M0)

SnoozeBlock config_teensy36(touch, digital, alarm);

elif defined(MK64FX512)

SnoozeBlock config_teensy35(digital, timer, compare);

elif defined(MK20DX256)

SnoozeBlock config_teensy32(touch, digital, timer, compare);

elif defined(MK20DX128)

SnoozeBlock config_teensy30(touch, digital, timer, compare);

elif defined(MKL26Z64)

SnoozeBlock config_teensyLC(digital, timer, lc5vBuffer);

endif

void setup() { pinMode(LED_BUILTIN, OUTPUT); /**** Define digital pins for waking the teensy up. This combines pinMode and attachInterrupt in one function.

 Teensy 3.x
 Digtal pins: 2,4,6,7,9,10,11,13,16,21,22,26,30,33

 Teensy LC
 Digtal pins: 2,6,7,9,10,11,16,21,22
 ********************************************************/
digital.pinMode(21, INPUT_PULLUP, RISING);//pin, mode, type
digital.pinMode(22, INPUT_PULLUP, RISING);//pin, mode, type

/********************************************************
 Teensy 3.x only currently.

 Set RTC alarm wake up in (hours, minutes, seconds).
 ********************************************************/
alarm.setRtcTimer(0, 0, 10);// hour, min, sec

/********************************************************
 Set Low Power Timer wake up in milliseconds.
 ********************************************************/
timer.setTimer(120000);// milliseconds

/********************************************************
 In deepSleep the Compare module works by setting the
 internal 6 bit DAC to a volatge threshold and monitors
 the pin volatge for a voltage crossing. The internal
 DAC uses a 64 tap resistor ladder network supplied by
 VOUT33 at 0.0515625v per tap (VOUT33/64). Thus the
 possible threshold voltages are 0.0515625*(0-64).

 parameter "type": LOW & FALLING are the same and have no effect.
 parameter "type": HIGH & RISING are the same and have no effect.

 Teensy 3.x
 Compare pins: 11,9,4

 Teensy LC
 Compare pins: 11
 ********************************************************/
// trigger at threshold values greater than 1.65v
//compare.pinMode(11, HIGH, 1.65);//pin, type, threshold(v)
// trigger at threshold values less than 1.65v
compare.pinMode(11, LOW, 1.65);//pin, type, threshold(v)

/********************************************************
 Values greater than threshold will trigger TSI wakeup.
 Threshold value is in capacitance. Only one pin can be
 used while sleeping.

 Teensy 3.x
 Touch Sense pins: 0,1,15,16,17,18,19,22,23,25,32,33

 Teensy LC
 Touch Sense pins: 0,1,3,4,15,16,17,18,19,22,23
 ********************************************************/
touch.pinMode(0, touchRead(0) + 250); // pin, threshold

}

void loop() { int who; /**** feed the sleep function its wakeup parameters. Then go to deepSleep. ****/

if defined(MK66FX1M0)

who = Snooze.deepSleep( config_teensy36 );// return module that woke processor

elif defined(MK64FX512)

who = Snooze.deepSleep( config_teensy35 );// return module that woke processor

elif defined(MK20DX256)

who = Snooze.deepSleep( config_teensy32 );// return module that woke processor

elif defined(MK20DX128)

who = Snooze.deepSleep( config_teensy30 );// return module that woke processor

elif defined(MKL26Z64)

who = Snooze.deepSleep( config_teensyLC );// return module that woke processor

endif

if (who == 21) { // pin wakeup source is its pin value
    for (int i = 0; i < 1; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(200);
        digitalWrite(LED_BUILTIN, LOW);
        delay(200);
    }
}

if (who == 22) { // pin wakeup source is its pin value
    for (int i = 0; i < 2; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(200);
        digitalWrite(LED_BUILTIN, LOW);
        delay(200);
    }
}

if (who == 34) { // compare wakeup value
    for (int i = 0; i < 3; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(200);
        digitalWrite(LED_BUILTIN, LOW);
        delay(200);
    }
}

if (who == 35) { // rtc wakeup value
    for (int i = 0; i < 4; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(200);
        digitalWrite(LED_BUILTIN, LOW);
        delay(200);
    }
}

if (who == 36) { // lptmr wakeup value
    for (int i = 0; i < 5; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(200);
        digitalWrite(LED_BUILTIN, LOW);
        delay(200);
    }
}

if (who == 37) { // tsi wakeup value
    for (int i = 0; i < 6; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(200);
        digitalWrite(LED_BUILTIN, LOW);
        delay(200);
    }
}

}

duff2013 commented 4 years ago

right the timer driver has 16bit max value and uses a 1kHz clock gives you around one minute and five seconds. Unfortunately the LC does not a usable RTC so thats what you got. The only way to change this would be to do some low level driver work to change the prescaler of the clock that runs the timer. Currently changing the clock prescaler is not supported in Snooze and most likely won't be for some time. You might want to look at a external way to wakeup you Teensy like a RTC module or something and use the pin wakeup (Digital Driver).

jnevinsiv commented 4 years ago

Got it. Thanks for the quick reply!

cabintech commented 3 years ago

I know this is closed, but I have been looking and cannot find any doc about the prescaler being disabled in low power modes. The 1 minute interval is a bit limiting... it would be really cool to add another signature:

setTimer(newPeriod, scaleFactor)

where scaleFactor is one of 1,2,4,...65536. I think it would change only one line in the driver where the prescaler is currently disabled:

LPTMR0_PSR = LPTMR_PSR_PBYP | LPTMR_PSR_PCS( LPTMR_LPO );//LPO Clock

Is the prescaler disabled in sleep for all Teensy versions?

cabintech commented 3 years ago

I tried this on Teensy 3.2, changing the line above to:

LPTMR0_PSR = LPTMR_PSR_PCS( LPTMR_LPO );//LPO Clock

enabling the prescaler for 2X. But it did not work, the timer never went off (at least for hibernate mode). Drat.