Is my program compatible with using idle mode?

Status
Not open for further replies.

THX1138

Member
I don't know how to program but I've managed to cobble something together from code copied from other people's work. I was wondering whether my program was compatible with the idle function and if so, do I put it between the setup and the loop? I read that it may stop the first analogue read from working after waking from idle so my solution is to just code the read to happen twice in a row. Does that make sense?

I figured I could make it sleep in the time between alarm deactivation (by push-button) and alarm activation (at 2100 hrs each day). Can it also sleep during the delays or does that make no sense?

Incidentally, I'm running at 2 Mhz with the consequence that USB won't work; does that mean that disabling the USB to save power is unnecessary?

Teensy 3.2

Code:
  //This sketch triggers daily alarms at 2100 hrs.
  
  #include <Time.h>
  #include <TimeAlarms.h>
  
  int buttonPin = 1; // assign pin to alarm silence button
  int ledPin = 12; // assign pin to alarm signal output
  int sensorPin = A2; // assign input pin for ldr
  
  int sensorValue = 0; // variable to store the value coming from the sensor
  int buttonState = 0; // variable to store the value of the push button
  volatile int alarmState = 0; // variable to store the status of the alarm
  
  // the setup function runs once when you press reset or power the board
  void setup()
  {
   setTime(20,59,59,0,0,0); // set time to 20:59:59
   // create the alarms 
   Alarm.alarmRepeat(21,0,0, LithiumAlarm);  // set alarm for 2100 hrs every day
    // initialize ledPin as an output and buttonPin as an input
    pinMode(ledPin, OUTPUT);
    pinMode(buttonPin, INPUT_PULLUP);
    pinMode(sensorPin, INPUT);
    Serial.begin(9600);      // open the serial port at 9600 bps:   
  }
  
  // functions to be called when an alarm triggers:
  void LithiumAlarm(){
    alarmState = 1;
  }
    
  // the loop function runs over and over again forever
  void loop() {
    sensorValue = analogRead(sensorPin); // read the value from the sensor
    Serial.println(sensorValue); //prints the values coming from the sensor on the screen
    Alarm.delay(1000);
    if (alarmState==1 && sensorValue<200) {
    digitalWrite(ledPin, HIGH);   // turn the LED on (HIGH is the voltage level)
    Alarm.delay(50);                       // wait for a second
    digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
    Alarm.delay(1000);                       // wait for a second
    }
    if (digitalRead(buttonPin) == 0) {
      alarmState = 0;
    }
  }
 
What flavour Teensy is this? For 3.x where you want to get power savings you'd normally use the snooze library
https://github.com/duff2013/Snooze


I'm using Teensy 3.2. Thanks for the link. Can you tell me that the bold additions to my code below are correct? The readme seems a little incomplete and I can find discussions of the library but no reasonably simple examples to steal code from.

Am I right in thinking I can tell the Teensy to hibernate when the alarm silence button is correct and then awake from hibernation when the alarm triggers? Is it possible for the timer to continue in hibernation? There is no RTC or crystal connected.

Code:
  //This sketch triggers daily alarms at 2100 hrs.
  
  #include <Time.h>
  #include <TimeAlarms.h>
  [B]#include <Snooze.h>
  // Load drivers
  SnoozeAlarm alarm;

  // install drivers to a SnoozeBlock
  SnoozeBlock config(alarm);[/B]
  
  int buttonPin = 8;
  int ledPin = 7;
  int sensorPin = A18; // select the input pin for ldr
  
  int sensorValue = 0; // variable to store the value coming from the sensor
  int buttonState = 0; // variable to store the value of the push button
  volatile int alarmState = 0; // variable to store the status of the alarm
  
  // the setup function runs once when you press reset or power the board
  void setup()
  {
   setTime(20,59,59,0,0,0); // set time to 20:59:59
   // create the alarms 
   Alarm.alarmRepeat(21,0,0, LithiumAlarm);  // 2100 hrs every day
    // initialize ledPin as an output and buttonPin as an input
    pinMode(ledPin, OUTPUT);
    pinMode(buttonPin, INPUT_PULLUP);
    pinMode(sensorPin, INPUT);
    Serial.begin(9600);      // open the serial port at 9600 bps:   
  }
  
  // functions to be called when an alarm triggers:
  void LithiumAlarm(){
    alarmState = 1;
  }
    
  // the loop function runs over and over again forever
  void loop() {
    sensorValue = analogRead(sensorPin); // read the value from the sensor
    Serial.println(sensorValue); //prints the values coming from the sensor on the screen
    Alarm.delay(1000);
    if (alarmState==1 && sensorValue>123) {
    digitalWrite(ledPin, HIGH);   // turn the LED on (HIGH is the voltage level)
    Alarm.delay(50);                       // wait for a second
    digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
    Alarm.delay(1000);                       // wait for a second
    }
    if (digitalRead(buttonPin) == 0) {
      alarmState = 0;
    }
  }
 
The best way to achieve what you want would be RTC, but will need a crystal connected so it can keep time while everything else is asleep. That would probably also allow you to run the main CPU at normal speeds (ie sleep, quickly execute instructions and then sleep again). If you want the crystal you can probably pull one from any random time keeping appliance around the house, especially one a couple of years old. Otherwise you'd look to timer, as per the example on that page that sleeps for 5 second bursts. Do note that sleep will do terrible things to the time keeping since the counters that it relys on will be changing rate, and there will most likely be gaps where it's waking and sleeping where they don't run at all. Unsure if this is supposed to be just 'wait 24 hours ish from startup and execute' or 'run for years triggering the same time each day'.

Another option if you want a point and shoot solution is to buy an RTC module, possibly with an alarm function internal and then just worry about sleeping and waking your Teensy to manage battery and buttons and just check the time when it needs to.
https://www.adafruit.com/products/3013
https://www.adafruit.com/product/3295
 
Thanks; I guess I'll order some crystals at some point if I can't find any to salvage but I don't need this to be very accurate; I'd like it to not deviate more than 20-30 minutes between battery changes. I think 20 ppm gives 60 seconds deviation per month which is already more accurate than I need but I don't know how much that will change with sleeping.

My project currently draws 1.7 mA when not flashing which is literally (the old definition) >99.9% of the time.
 
Status
Not open for further replies.
Back
Top