Public Lab Research note


One way of using the RTC Alarms to schedule logging on the Riffle

by kinasmith | June 07, 2016 04:51 07 Jun 04:51 | #13171 | #13171

OK!

This is my first research note. I'll get used to the formatting in a minute. I finally got to dig into my Riffle a little bit and was super excited to figure out how to use the Alarms in the DS3231 Real Time Clock to schedule sensor reading events...or any other events for that matter.

Why this matters?

Power Consumption!!!

The ATmega328 consumes power, obviously. When it's just churning through code, or stuck in a delay() it just sits there drawing something around 20mA. That's not good if you want to have a battery powered device that lasts a long time. Putting the MCU to sleep saves lots of power. There have been projects dedicated to exactly that which have reduced consumption to around 1µA. I'm pretty sure you generate more energy than that when petting a cat on a dry day. But that's another project.

The issue with putting the ATmega to sleep is that you have to wake it up, which isn't really that much of a problem, because there are libraries for it. Low Power Lab and Jeelib have excellent and easy to use libraries. BUT...we can save MORE power if we disable the things that allow it to wake up and completely rely on an external device to do the waking. Plus wouldn't it be nice just to say...

"Hay, you..thing. Just do another thing in 23 minutes and 17 seconds"

instead of having to worry about logging at times divisible by 8 seconds.

The Real Time Clock

There is this real time clock on the Riffle, the DS3231. It tells time. But it also has alarms that you can set. At intervals....or for a specific time. When the alarm triggers, it pulls its INT pin low, which is conveniently attached to Pin 5 on the ATmega. We can use that connection and behavior to cause the action to wake the ATmega from a DEEP sleep. Make it do something, then go back to sleep again. This can happen once per second, or once per month, or once per year, and while it's waiting it consumes a very VERY small amount of power.

This is the code. Try it out!

It uses three libraries:

Be aware too, that there are a wide array of confusing libraries for the DS3231 which are all named the same thing, so make sure you keep them organized and differentiated in your Arduino Libraries folder.

Simple Code Here

Datalogger using the SHT21 sensor here


10 Comments

Wow, thanks for this note!

Reply to this comment...


Wow, so that might be a bug in the post writing front end. I used a standard markdown formatting for code input, which worked in preview, but broke spectacularly in actual post layout.

I just put the code on Github, feel free to fork, clone, and change. https://github.com/kinasmith/publicLab/tree/master/Riffle

Reply to this comment...


Wow, I'm going to have to try this. I tested some markdown below to see if it could display your code. The editor won't let me preview this comment, so I will post it and see how it looks.

#include Wire.h
#include EnableInterrupt.h
#include DS3231.h
#include LowPower.h

DS3231 rtc; //initialize the Real Time Clock

const int RTC_INT = 5; //This is the interrupt pin
int interval_min = 1; //this is the interval which the RTC will wake the MCU (microcontroller)

//This function is called by the interrupt when it is triggered by the RTC
void pin5_interrupt()
{
disableInterrupt(RTC_INT); //first it Disables the interrupt so it doesn't get retriggered
}

//Puts the MCU into power saving sleep mode and sets the wake time
void enterSleep(int h, int m, int s)
{
//we give it an argument for when we want it to wake up in Hour, Minute, Second rtc.clearINTStatus(); //resets the alarm interrupt status on the RTC
enableInterrupt(RTC_INT, pin5_interrupt, FALLING); //Sets the interrupt on Pin5

rtc.enableInterrupts(h, m, s); //Sets the alarm on the RTC to the specified time
delay(100); //wait for a moment for everything to complete
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); //power down everything until the alarm fires
}

void setup()
{
Serial.begin(9600);
pinMode(RTC_INT, INPUT_PULLUP);
Wire.begin();
rtc.begin();
rtc.adjust(DateTime((DATE), (TIME))); //this sets the RTC to the computer time. More documentation in other examples
}

void loop()
{
DateTime now = rtc.now(); //get the current time
if (now.second() == 0)
{
//at the top of the minute....
//calculate the next alarm time
int nextHour = now.hour();
int nextMinute = now.minute() + interval_min;
if (nextMinute >= 60)
{
nextMinute -= 60;

//this bit of code assumes an interval time of less than 60 min. There is a more elegant way of doing this, I'm sure.

nextHour += 1;
}
Serial.print("The Current Time is: ");
Serial.print(now.hour());
Serial.print(":");
Serial.print(now.minute());
Serial.println();
Serial.print("Sleeping until: ");
Serial.print(nextHour);
Serial.print(":");
Serial.print(nextMinute);
Serial.println();
enterSleep(nextHour, nextMinute, 0); //enter Sleep until alarm fires
}
}

Reply to this comment...


The lead image reveals your profound research strategy and rigorous philosophy of open science.

Reply to this comment...


Well. I just used <pre and <code tags to wrap the code in, and that worked. would also be super cool to be able to embed Gists i n a post.

There is a bug in the code that I'm going to fix now where it doesn't roll over past midnight. I'll update the github repo. @liz: Thank for noticing!

Reply to this comment...


The names of the libraries which are in < > brackets don't display. I deleted the brackets in my comment above so the libraries would display.

I'm glad you are working on this because I can't get the code in Don's riffle_basic_logging sketch to log at any interval longer than 18 seconds.

Reply to this comment...


I forked the seed Studio DS3231 library and made a little more straightforward and easy to use.

Library is here.

Example Code is here.

Reply to this comment...


Holy cow, it works. I modified your SHT21_Logger.ino sketch to log data from two MCP9808 sensors and one DHT22 sensor and it seems to work great. It was logging fine every ten seconds, so I changed it to every 5 minutes, but I was too eager to get the probes back into the compost pile so I didn't wait around for five minutes to confirm. I might check on it tomorrow to make sure it is working.

Thanks for the new sketch,
Chris

Reply to this comment...


Awesome, I'm glad it worked for you. I did an afternoon/overnight test and it seems reliable. This is the plot of the time difference between logging events. All stable except the one anomoly where the sensor got detached on the bike ride home.

time_dif.png

And the Temp/Humidity/Battery Voltage....I am concerned about how much power the Riffle draws. I could only get the it down to about 1.5-2mA even when asleep...which isn't good at all.

Temp.png

Humidity.png

Battery.png

Reply to this comment...


I am so excited to try this out. 8 seconds is a ridiculous interval! (Sorry Don.)

Reply to this comment...


Login to comment.