0

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

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);
  }
}

Source: http://arduino.cc/en/Tutorial/BlinkWithoutDelay

  • 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). – Gerben Oct 14 '14 at 14:48
0

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.

  • 1
    Thank you for sharing your knowledge. I am going to make tries. – pascal007 Oct 13 '14 at 6:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy