I'm an amateur and I wish to use timers in my project. I'm using an Arduino Mega 2560 with a touch-sensitive screen with six DS18B20 temperature sensors and a DS1307 RTC (real time clock). I would like to query my sensors every 1 or 2 minutes to refresh the screen for temperature acquisition. I do not how to program timers to schedule the readings and which timers to use?
2 Answers
You can use the function millis()
, that returns the number of milliseconds since the Arduino board began running the current program (unsigned long). This number will overflow (go back to zero), after approximately 50 days.
The code below uses the millis()
function, a command that returns the number of milliseconds since the Arduino board started running its current program, to blink an LED.
/* Blink without Delay
Turns on and off a light emitting diode(LED) connected to a digital
pin, without using the delay() function. This means that other code
can run at the same time without being interrupted by the LED code.
The circuit:
* LED attached from pin 13 to ground.
* Note: on most Arduinos, there is already an LED on the board
that's attached to pin 13, so no hardware is needed for this example.
created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/
// constants won't change. Used here to
// set pin numbers:
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop()
{
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
-
This solution is the way to go. Timers aren't really useful in this case. Also don't worry about the 50 day overflow. Since you are calculating the time difference, this will never become a problem (unless you want to check the temperature every 60days or so).– GerbenCommented Oct 14, 2014 at 14:48
You can use the watchdog timer for that. Below is part of the code that I use to make temperature readings every 8 seconds using the watchdog timer. It compiles on Arduino IDE 1.0.5 for Arduino Uno R3 board, but be warned that I didn't run it as it is below (so it's untested). You can change variables COUNTER_TRIGGER
and WATCHDOG_PARAM
to adjust its timing it to your liking. Note also that I'm using ATmega328P, so map it accordingly to your MCU.
#include <avr/sleep.h>
#include <avr/power.h>
#define WDTCR_REG WDTCSR
#define SERIAL_DEBUG
int COUNTER_TRIGGER = 1; // 1 * 8 sec = 8 seconds
int WATCHDOG_PARAM = 9; // 9 = 8 sec
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
volatile long watchdog_counter = 0;
int counter_trigger = COUNTER_TRIGGER;
const byte TEMP_PIN = A5;
void setup() {
#ifdef SERIAL_DEBUG
Serial.begin(9600);
#endif
pinMode(TEMP_PIN, INPUT);
//Power down various bits of hardware to lower power usage
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
// ADCSRA &= ~(1<<ADEN); //Disable ADC
ACSR = (1<<ACD); //Disable the analog comparator
DIDR0 = 0x3F; //Disable digital input buffers on all ADC0-ADC5 pins
sei();
setup_watchdog(WATCHDOG_PARAM);
}
void loop() {
#ifdef SERIAL_DEBUG
Serial.print("Sleeping...");
Serial.flush();
delay(20);
#endif
sleep_mode();
#ifdef SERIAL_DEBUG
Serial.println("awake");
#endif
// Zzzz...
#ifdef SERIAL_DEBUG
Serial.print("watchdog_counter = ");
Serial.println(watchdog_counter);
Serial.print("counter_trigger = ");
Serial.println(counter_trigger);
#endif
if (watchdog_counter >= counter_trigger) {
watchdog_counter = 0;
doSomething();
}
}
void doSomething() {
// do your thing here
}
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
byte bb;
int ww;
if (ii > 9 ) ii=9;
bb=ii & 7;
if (ii > 7) bb|= (1<<5);
bb|= (1<<WDCE);
ww=bb;
MCUSR &= ~(1<<WDRF);
// start timed sequence
WDTCR_REG |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCR_REG = bb;
WDTCR_REG |= _BV(WDIE);
}
// executed when watchdog timer expires
ISR(WDT_vect) {
watchdog_counter++; // increment volatile
}
I don't remember where I got it. I'll add proper attribution when I find out who provided the code... soon.
I hope this helps.
-
1Thank you for sharing your knowledge. I am going to make tries.– pascal007Commented Oct 13, 2014 at 6:06