Put arduino into sleep witch watchdog timer for longer time

Hi all,

I hope i’m on the right forum section for this question.

First of all this is what i have running,

A water tank, that needs to be filled. Note this can only be done manually.

I have the ultrasonic sensor measure the distance to the water. If the distance is more then 75 cm a LED will light and i know i’ll have to fill my tank. When filling the distance will become less then 75 cm and the LED will turn off. At the point the distance will be less then 25 cm the led will blink twice. I know i have to shut down my pump.

So the problem with this code is:
When i’m done filling my tank, the led will keep on blinking after the 5 seconds delay i have at the end, since water level will only drop down below 25 cm after i start using water off course. This is a waste of power and can become annoying after a while.

So my idea is, after reading distance less then 25cm and blink 2 times, put the arduino in sleep mode. Keep the arduino asleep for at least 36 hours since my water level will never get below 75cm distance in this time. Now i read that the watchdog timer can only put your arduino into sleep for 8 seconds but that it it possible to “count” how many times the arduino went into sleep mode until the 36 hours has passed.

As you can see still a big noob and trying to get my arduino to do something functional for me.

Here the code u use for what’s happening, i used a photo-resistor instead of the ultrasound at this point for prototyping , reading the analog data and use that for triggering the LED.

int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the sensor divider
int LEDROOD = 11;          // connect Red LED to pin 11 (PWM pin)

void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);   
}
 
void loop(void) {
  photocellReading = analogRead(photocellPin);  
 
  Serial.print("Analog reading = ");
  Serial.println(photocellReading);     // the raw analog reading
 
  if (photocellReading >= 400) {

  Serial.println("afstand groot");  // distance greater than 75 cm
  Serial.println(photocellReading);
  digitalWrite(LEDROOD, HIGH); 
 }
 
  else {
 
  Serial.println("afstand ok");
  Serial.println(photocellReading);
  digitalWrite(LEDROOD, LOW); 
 }
 
  if (photocellReading <= 100) {   // distance less then 25 cm
  Serial.println("afstand klein");
  Serial.println(photocellReading);
  digitalWrite(LEDROOD, HIGH);
  delay(500);                 
  digitalWrite(LEDROOD, LOW);    
  delay(500);                  
  digitalWrite(LEDROOD, HIGH);
  delay(500);                 
  digitalWrite(LEDROOD, LOW);    
  delay(500);                
}
 
//delay before next reading
  delay(5000);
}

If you got so far that you read this i thank you for your time allready!

I figured the lowest powerconsuming mode is (SLEEP_MODE_PWR_DOWN) so was thinking about using that. But now we get to the part of actually putting the arduino into sleep mode.

I found a tutorial online giving me this:

void enterSleep(void)
{
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);   /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
  sleep_enable();
  
  /* Now enter sleep mode. */
  sleep_mode();
  
  /* The program will continue from here after the WDT timeout*/
  sleep_disable(); /* First thing to do is disable sleep. */
  
  /* Re-enable the peripherals. */
  power_all_enable();
}

How do i integrate this into my own little bit of code?

I hope some of you can help me out here! Thanks in advance!

[ps, English is not my native English sorry for grammar errors]

Or maybe someone has a link for me taking me true the whole watchdog thing?

So this is what i got now:

retrieve output: pipe: The handle is invalid

After i played around a bit with the sleep code… exactly the reason i hoped somebody could help me out here before this would happen :open_mouth:

/* Photocell simple testing sketch. 
 
Connect one end of the photocell to 5V, the other end to Analog 0.
Then connect one end of a 10K resistor from Analog 0 to ground 
Connect LED from pin 11 through a resistor to ground 
For more information see http://learn.adafruit.com/photocells */


// dit deel voor de sleep

#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

volatile int f_wdt=1;

int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the sensor divider
int LEDROOD = 11;          // connect Red LED to pin 11 (PWM pin)
int LEDGEEL = 10;          // connect Red LED to pin 10 (PWM pin)

//slaapcode
ISR(WDT_vect)
{
  if(f_wdt == 0)
  {
    f_wdt=1;
  }
}

void enterSleep(void)
{
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);   //EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. 
  sleep_enable();
  
  // Now enter sleep mode. 
  sleep_mode();
  
  // The program will continue from here after the WDT timeout
  sleep_disable(); // First thing to do is disable sleep. 
  
  // Re-enable the peripherals. 
  power_all_enable();
}


void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600); 
  /* Clear the reset flag. */
  MCUSR &= ~(1<<WDRF);
    /* In order to change WDE or the prescaler, we need to
   * set WDCE (This will allow updates for 4 clock cycles).
   */
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  /* set new watchdog timeout prescaler value */
  WDTCSR = 1<<WDP0 | 1<<WDP3; /* 8.0 seconds */
  /* Enable the WD interrupt (note no reset). */
  WDTCSR |= _BV(WDIE);
}
 
void loop(void) {
  photocellReading = analogRead(photocellPin);  
 
  Serial.print("Analog reading = ");
  Serial.println(photocellReading);     // the raw analog reading
 
  if (photocellReading >= 400) {

  Serial.println("afstand groot");  // distance greater than 75 cm
  Serial.println(photocellReading);
  digitalWrite(LEDROOD, HIGH); 
 }
 
  else {
 
  Serial.println("afstand ok");
  Serial.println(photocellReading);
  digitalWrite(LEDROOD, LOW); 
 }
 
  if (photocellReading <= 100) {   // distance less then 25 cm
  Serial.println("afstand klein");
  Serial.println(photocellReading);
  digitalWrite(LEDROOD, HIGH);
  delay(500);                 
  digitalWrite(LEDROOD, LOW);    
  delay(500);                  
  digitalWrite(LEDROOD, HIGH);
  delay(500);                 
  digitalWrite(LEDROOD, LOW);    
  delay(500);  
  enterSleep();
}  
  
  else {
  digitalWrite(LEDGEEL, HIGH);
 
}

//delay before next reading
  delay(5000);
}

anyone please help, not able to write anything on the arduino now