I just realized I have a 1307 RTC module which doesn't have alarms like later models.
Does this mean I cant use it to wake up my Arduino project 2 or 3 times a day?
I just realized I have a 1307 RTC module which doesn't have alarms like later models.
Does this mean I cant use it to wake up my Arduino project 2 or 3 times a day?
How would I go about doing that?
I mean, if I can wake it up once a second, I could wake it up once a (second x any number), right?
You can, but you can also just use the 8 second sleep of the Arduino itself. Waking up less often is less power... But the RTC is going to be more accurate. But you can try to make a hybrid...
How often do you plan on doing something?
And how time critical is this task?
Can wake up each second, get a time read from DS1307, compare to alarmed time in Arduino, if no match go back to sleep. Not hard.
If the time is action times are far apart I would just put the uC asleep ith the 8 seconds watchdog for most of the time and just read the RTC like once an hour to see how much we are off. And some time before I would switch to the 1 sec square for the exact moment. (Or leaf it out as the exact moment isn't really critical...)
I mean, if I can wake it up once a second, I could wake it up once a (second x any number), right?
The method was explained to you in reply #4 here but you don't pay attention.
My intent:
Have the Arduino plus CO sensor take a reading at say, 8:00-8:02, sleep to consume less power, wake up at 16:00-16:02, sleep again and wake up to take a last measurement at 24:00-01:02 and back to sleep.
So basically I need it awake 3 times a day for 2 minutes each time.
Jremington, thanks. It's not that I didn't pay attention but I'm just looking at different options.
One is the watchdog which I understand can put the Arduino to sleep for 8 seconds maximum. But I understand that i can somehow play with that 8 second interval and make it as long as I want. But it seems kinda "inefficient" to take 8 second intervals and convert a day into 10,800 8-second intervals. I haven't tried it but it seemed like having an external signal wake up the Arduino would be more efficient. Now that I think about it, this would mean the Arduino would go to sleep for x seconds in which case it would consume less power and wake itself up to carry out a task and go back to sleep.
What I'm still trying to understand is how the rtc ds-1307 would work. From what I understand the rtc can keep time itself. The problem with the ds1307 is that it doesn't have an ic itself to run code such as the TimeAlarms code? Which is why TimeAlarms would not be useful because the TimeAlarms code would have to run on the Arduino which would be asleep so it would be no good.
So I asked about this square wave pulse feature that the ds1307 does have because i see the pinhole for it.
Delta_G proposes to make the Rtc wake up the Arduino via this square wave every second. But how would this work, I CAN make the Rtc send a pulse every second? Why is it not possible to program the rtc to send it every hour?
Crossroads suggests I sleep the Arduino with watchdog, wake Arduino every second and have it read the rtc and check the time. If it's time to read then read and sleep, else just sleep. Ok I guess I understand this.
Septillion proposes a hybrid...This one I don't understand. Could you elaborate? You're telling me to put the Arduino to sleep using watchdog for 8 seconds and use try rtc to wake up the Arduino once an hour. How? Have the Arduino sleep via watchdog and have Arduino read the rtc once an hour? So this would be again using (3,600/8)-second intervals created programmatically?
Why is it not possible to program the rtc to send it every hour?
With a DS3231, it is possible.
With a DS1307, it is not possible.
Explained in the data sheets.
Use your RTC to send a signal every second, put this signal in a counter, CD 4020, CD 4040 or any other adapted to your project, then choose the output, or place some logic to decode the output you want, deliver this signal to Arduino in order to be waked-up
Thanks Escrich, but I dont have a counter. I only have a DS1307 RTC.
I would use the watchdog timer but then I read that its very problematic and can soft brick my Arduino?
Yikes, that doesnt sound like something I want. Ill just plug my Arduino into a wall socket until I get a DS3231.
Thanks
I would use the watchdog timer but then I read that its very problematic and can soft brick my Arduino?
Nonsense. See this thread.
You can also use the DS1307 1 Hz square wave to wake up the Arduino every second. Count 3600 of those and do something every hour. Much more accurate than the watchdog timer.
So you're saying I can wake up the arduino every second from the RTC module. This means I need to:
Marciokoko:
But waking it every second will not save much will it?
If all you do is increment a variable, check it and then go back to sleep the processor will only be awake for something like 0.01% of the time.
It takes just a couple of microseconds to wake up, increment a variable, check for total elapsed time, and go back to sleep. So, roughly 0.001% duty cycle.
Since he never said what Arduino he has my estimate is for a stock Uno. It has a 16MHz resonator with the fuses set for low power oscillator and BOD enabled. According to the data sheet, from power down mode it takes 1024 clock cycles to start up, or about 63us. Add in another 5-10 us to service the interrupt, increment and check his variable and then go back to sleep and it's going to be the better part of 100us. I rounded up.
It's all theory to me though as I haven't measured it on an oscilloscope. I tried to indirectly measure the wakeup time of a 328p (configured differently) by using the analog comparator of another board to detect when the current rose. It didn't match what I calculated from the datasheet though. I wish I had a scope to see a little more clearly.
Here is a program that demonstrates use of the watchdog timer in interrupt mode only. It also implements close to maximum power savings. The WDT interrupts at (roughly) 1 second intervals, causes a counter to be incremented and the program then prints a message every 10 of those interrupts. Modified from Nick Gammon's examples.
This works on an ATMega328 Pro Mini (16 MHz).
#include <avr/sleep.h>
#include <avr/wdt.h>
// This program sleeps, wakes up about every second using the watchdog timer,
// counts ten of those intervals and then does something useful.
// see http://www.gammon.com.au/power
// watchdog timer interrupt, wake from sleep each second (approx)
ISR (WDT_vect) {
}
void setup() {
Serial.begin(9600); //initialize serial
Serial.println("sleep for ten...");
Serial.flush(); //wait till done printing.
// implement maximum possible power reduction
// disable ADC
ADCSRA = 0;
//set PRR Power Reduction Register (set PRADC after ADCSRA=0)
//Bit 7 - PRTWI: Power Reduction TWI
//Bit 6 - PRTIM2: Power Reduction Timer/Counter2
//Bit 5 - PRTIM0: Power Reduction Timer/Counter0
//Bit 4 - Res: Reserved bit
//Bit 3 - PRTIM1: Power Reduction Timer/Counter1
//Bit 2 - PRSPI: Power Reduction Serial Peripheral Interface
//Bit 1 - PRUSART0: Power Reduction USART0
//Bit 0 - PRADC: Power Reduction ADC
PRR |= (1<<PRTWI)|(1<<PRTIM0)|(1<<PRTIM1)|(1<<PRTIM2)|(1<<PRSPI)|(1<<PRADC)|(1<<PRUSART0);
/* sleep modes on ATmega328p
SLEEP_MODE_IDLE
SLEEP_MODE_ADC
SLEEP_MODE_PWR_DOWN
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_EXT_STANDBY
*/
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
// clear various "reset" flags
MCUSR = 0;
// allow changes, disable reset
WDTCSR = (1<<WDCE) | (1<<WDE);
// set interrupt mode and an interval
WDTCSR = (1<<WDIE) | (1<<WDP2)| (1<<WDP1); // set WDIE, and ~1 second delay
wdt_reset(); // reset it
int count=0; //sleep loop counter
// main loop. Sleep, wake up on watchdog, check time and do something
while(1) {
sleep_enable();
cli(); //time critical steps follow
MCUCR = (1<<BODS) | (1<<BODSE); // turn on brown-out enable select
MCUCR = (1<<BODS); //Brown out off. This must be done within 4 clock cycles of above
sei();
sleep_cpu();
// wake up here on WDT interrupt
count++;
if (count > 9) { //ten intervals have passed
count=0; //reset counter
PRR &= ~(1<<PRUSART0); //turn USART
Serial.println("about 10 seconds");
Serial.flush(); //wait till done printing, and snooze
PRR |= (1<<PRUSART0); //turn off USART
} //end if count
} //end while(1)
} // end setup()
void loop(){
} //nothing to do
In power down mode the 328p uses about 6.5uA (at 5V) with the watchdog enabled. With the watchdog disabled it uses less than 0.2uA. The DS1307, running on it's battery and outputting a 1Hz square wave, consumes about 0.5uA. So it's actually less current to use the RTC as an interrupt source. And since the watchdog isn't very accurate you'd have to occasionally wake the RTC up and read it, during which time you'd be pulling milliamps. Whereas if you use the 1Hz square wave you could leave the RTC powered off the whole time until your alarm interval was over.
The difference is pretty minor though.
Ok, so i put the Arduino to sleep for how long, 10,800-8second intervals?
As long as you want.
Ok I guess I need to understand wdt better. From jremington's Reply 16, I see:
ADCSRA = 0; // sleeps as most as possible including the ADC which I understand is one of the main power connsumers
Sets some power reduction registers...
Calls set_sleep_mode(SLEEP_MODE_PWR_SAVE); which puts the arduino to sleep?
Starts a sleep counter and a while(1) loop
Actually sleep_enable(); puts the Arduino to sleep, the previous line simply set the power mode into which it would sleep when called, right?
Then it starts counting to ...9 and prints "about 10 seconds" when its reached!
A few questions:
What does while(1) do? I know its a while loop, but how does that loop condition ever change? Im used to simple while loops which say while some variable is greater than x do this...
So I put the Arduino to sleep and the wdt interrupt wakes it up every second, but i put it back to sleep until it has woken Arduino up 10 times?
Ive seen other code using sleep_enable() and then sleep_mode() to trigger the sleep instead of sleep_cpu(). Whats the difference? (http://citizen-sensing.org/2013/07/arduino-watchdog/)
Ive seen code use sleep_disable(); because otherwise your Arduino might fall into a deep eternal slumber (bricking it). I dont see that used in jremington/gammon's code above, why?
Ive seen code that explains WDT somewhat differently, such as this case:
// Example of sleeping and saving power
//
// Author: Nick Gammon
// Date: 25 May 2011
#include <avr/sleep.h>
#include <avr/wdt.h>
#define LED 13
// watchdog interrupt
ISR(WDT_vect)
{
wdt_disable(); // disable watchdog
}
void myWatchdogEnable(const byte interval)
{
MCUSR = 0; // reset various flags
WDTCSR |= 0b00011000; // see docs, set WDCE, WDE
WDTCSR = 0b01000000 | interval; // set WDIE, and appropriate delay
wdt_reset();
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_mode(); // now goes to Sleep and waits for the interrupt
}
void setup()
{
pinMode (LED, OUTPUT);
} // end of setup
void loop()
{
digitalWrite (LED, HIGH); // awake
delay (2000); // ie. do stuff here
digitalWrite (LED, LOW); // asleep
// sleep for a total of 20 seconds
myWatchdogEnable (0b100001); // 8 seconds
myWatchdogEnable (0b100001); // 8 seconds
myWatchdogEnable (0b100000); // 4 seconds
} // end ofloop
// sleep bit patterns:
// 1 second: 0b000110
// 2 seconds: 0b000111
// 4 seconds: 0b100000
// 8 seconds: 0b100001
or even
#include <avr/wdt.h>
#define RESETWATCHDOG
void setup(){
Serial.begin(57600);
Serial.println("");
Serial.println ("------->Arduino Rebooted");
Serial.println("");
wdt_enable(WDTO_8S);
}
void loop(){
#ifdef RESETWATCHDOG
wdt_reset();
#endif
Serial.println("Arduino Running");
delay(1000);
}
found here at Reliable Projects 3: Using the Internal WatchDog Timer for the Arduino - SwitchDoc Labs Blog