I want to build a small Arduino project where I'm using the following components.
DHT11 Sensor - to measure the temperature and humidity
IR Sensor - to receive IR Signals
Double relay module - to switch on and off electrical components
The Arduino will follow like this, the DHT11 will be watched using the Watch Dog Timer every 24 seconds and based on the value, the relay will be switched on and off. The IR sensor is used to switch the other relay module based on the signal received.
I'm having an error with the DHT11 sensor when using the Watch Dog Timer together with the IR Sensor. When I do monitor console, I'm getting 'Error' for the DHT11 Sensor.
#include <SimpleDHT.h> // library for DHT11 sensor
#include <avr/wdt.h> // library for default watchdog functions
#include <avr/interrupt.h> // library for interrupts handling
#include <avr/sleep.h> // library for sleep
#include <avr/power.h> // library for power control
#include <IRremote.h> // library for IR Sensor
SimpleDHT11 dht11;
int pin_relay1 = 8;
int pin_relay2 = 9;
int pin_dht11 = 10;
int pin_irSensor = 2;
int pin_led = 11;
IRrecv irrecv(pin_irSensor);
decode_results results;
//ON relay == LOW
//OFF relay == HIGH
// how many times remain to sleep before wake up
// volatile to be modified in interrupt function
volatile int nbr_remaining;
volatile byte state = LOW;
void setup() {
Serial.begin(9600);
pinMode(pin_relay1, OUTPUT);
pinMode(pin_relay2, OUTPUT);
pinMode(pin_dht11, INPUT);
pinMode(pin_irSensor, INPUT);
pinMode(pin_led, OUTPUT);
irrecv.enableIRIn(); // Start the receiver
// configure the watchdog
configure_wdt();
attachInterrupt(0, wakeUpNow, FALLING); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW
}
void loop() {
getDHTReading();
}
void wakeUpNow() // here the interrupt is handled after wakeup
{
//execute code here after wake-up before returning to the loop() function
// timers and code using timers (serial.print and more...) will not work here.
if (irrecv.decode(&results)) {
if (results.value == 0xff629d) {
state = !state;
digitalWrite(pin_led, state);
}
irrecv.resume(); // Receive the next value
}
}
void getDHTReading() {
byte temperature = 0.0;
byte humidity = 0.0;
int err = SimpleDHTErrSuccess;
if ((err = dht11.read(pin_dht11, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.println("Error");
return;
}
Serial.print((double)temperature); Serial.print(" *C, ");
Serial.print((double)humidity); Serial.println(" H");
delay(5000);
// sleep for a given number of cycles (here, 5 * 8 seconds) in lowest power mode
sleep(3);
}
// interrupt raised by the watchdog firing
// when the watchdog fires, this function will be executed
// remember that interrupts are disabled in ISR functions
// now we must check if the board is sleeping or if this is a genuine
// interrupt (hanging)
ISR(WDT_vect) {
// Check if we are in sleep mode or it is a genuine WDR.
if (nbr_remaining > 0)
{
// not hang out, just waiting
// decrease the number of remaining avail loops
nbr_remaining = nbr_remaining - 1;
wdt_reset();
}
else
{
// must be rebooted
// configure
MCUSR = 0; // reset flags
// Put timer in reset-only mode:
WDTCSR |= 0b00011000; // Enter config mode.
WDTCSR = 0b00001000 | 0b000000; // clr WDIE (interrupt enable...7th from left)
// set WDE (reset enable...4th from left), and set delay interval
// reset system in 16 ms...
// unless wdt_disable() in loop() is reached first
// reboot
while (1);
}
}
// function to configure the watchdog: let it sleep 8 seconds before firing
// when firing, configure it for resuming program execution by default
// hangs will correspond to watchdog fired when nbr_remaining <= 0 and will
// be determined in the ISR function
void configure_wdt(void)
{
cli(); // disable interrupts for changing the registers
MCUSR = 0; // reset status register flags
// Put timer in interrupt-only mode:
WDTCSR |= 0b00011000; // Set WDCE (5th from left) and WDE (4th from left) to enter config mode,
// using bitwise OR assignment (leaves other bits unchanged).
WDTCSR = 0b01000000 | 0b100001; // set WDIE: interrupt enabled
// clr WDE: reset disabled
// and set delay interval (right side of bar) to 8 seconds
sei(); // re-enable interrupts
}
// Put the Arduino to deep sleep. Only an interrupt can wake it up.
void sleep(int ncycles)
{
nbr_remaining = ncycles; // defines how many cycles should sleep
// Set sleep to full power down. Only external interrupts or
// the watchdog timer can wake the CPU!
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// Turn off the ADC while asleep.
power_adc_disable();
while (nbr_remaining > 0) { // while some cycles left, sleep!
// Enable sleep and enter sleep mode.
sleep_mode();
// CPU is now asleep and program execution completely halts!
// Once awake, execution will resume at this point if the
// watchdog is configured for resume rather than restart
// When awake, disable sleep mode
sleep_disable();
}
// put everything on again
power_all_enable();
}