Arduino Uno Sleep (LowPower.h) and no ADC readings after wakeup

Hello,

I am builing a water sensor that is battery driven and therefore needs to save energy by
watchdog sleeping.

the code works as long as there is no wakeup after sleep. after wakeup i get these
readings: þ“I‚j

I tried to save and restore adcsra, with no success:

Here is my (a beginners) code:

float SpannungR2;
int AnalogPin=5; //ATMEGA Pin 28
float Quellspannung=5.0; //5 Volt Betriebspannung;
long Messwert;
int anzahlSMS=0;
byte keep_ADCSRA;

#include <RCSwitch.h>
#include "LowPower.h"

RCSwitch mySwitch = RCSwitch();

void setup() {

// initialize digital pin 13 as an output.
pinMode(13, OUTPUT); //ATMEGA Pin 19
pinMode(12, OUTPUT); //ATMEGA Pin 18
Serial.begin(9600);

// Transmitter is connected to Arduino Pin #7 ATMEGA PIN 13
mySwitch.enableTransmit(7);

}

void loop() {

for(int i=0;i<5;i++)
{Messwert+=analogRead(AnalogPin);}
Messwert=trunc(Messwert/5);
SpannungR2=(Quellspannung/1023.0)*Messwert;

Serial.println(SpannungR2);
Serial.print("ADCSRA ");Serial.println(ADCSRA);

while (SpannungR2<3.5)
{
digitalWrite(13, HIGH); //LED an auf Arduino nano Board
delay(300);
digitalWrite(13, LOW);
delay(300);
for(int i=0;i<5;i++){
Messwert+=analogRead(AnalogPin);
}
Messwert=trunc(Messwert/5);
SpannungR2=(Quellspannung/1023.0)*Messwert;
digitalWrite(12, HIGH); //433 Modul an
mySwitch.send(1305, 24);
digitalWrite(12, LOW); //433 Modul aus
delay(100);
Serial.println("Whileschleife");
Serial.println( SpannungR2 );
}
keep_ADCSRA = ADCSRA;
// for (int i = 0; i < 2; i++) {

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
// ADCSRA = 1;
//}
ADCSRA = keep_ADCSRA;
Serial.print("ADCSRA WakeUp ");
Serial.println(ADCSRA);
delay(1500);
}

Regards
Timo

Please read the forum guidance, in particular point 6, before posting questions in future. And please post all program output (in code tags), not just ridiculously small snippets like that.

I don't recommend that you directly manipulate registers like ADCSRA unless you really know what you're doing. In this case it is not necessary because the LowPower library restores the register state upon wakeup.

int AnalogPin = 5; //ATMEGA Pin 28

I think you mean A5

okay, second try.

I am builing a water sensor that is battery driven and therefore needs to save energy by
watchdog sleeping.
The A5 is pulled up (circiut diagramm attached) and does a reading of a wire that is connected to ground (V<3,5 volts) when
its wet or high voltage (pull up resistor) when its dry. this works perfectly when there is no sleep involved.
there is also code for a 433 tx, but this works fine.

there are some serialprint commands for debugging in the code.
with sleep and after wakeup i get these readings from serial monitor:
ý“ ‚j
ADCSRA 151
ADCSRA WakeUp 135
þ“ ‚j
ADCSRA 151
ADCSRA WakeUp 135
þ“I‚j
ADCSRA 151
ADCSRA WakeUp 135
þ
and so on....

Without sleep I get normal numbers for voltage, not these crappy signs...

float SpannungR2; 
int AnalogPin=5; //ATMEGA Pin 28
float Quellspannung=5.0; //5 Volt Betriebspannung;
long Messwert;
int anzahlSMS=0;
byte keep_ADCSRA; 

#include <RCSwitch.h>
#include "LowPower.h"

RCSwitch mySwitch = RCSwitch();

void setup() {

  // initialize digital pin 13 as an output.
 pinMode(13, OUTPUT); //ATMEGA Pin 19
 pinMode(12, OUTPUT); //ATMEGA Pin 18
 Serial.begin(9600);
    
  // Transmitter is connected to Arduino Pin #7 ATMEGA PIN 13
  mySwitch.enableTransmit(7);

  
}

void loop() {

for(int i=0;i<5;i++)
   {Messwert+=analogRead(AnalogPin);}
    Messwert=trunc(Messwert/5);
  SpannungR2=(Quellspannung/1023.0)*Messwert;
 
   Serial.println(SpannungR2);
   Serial.print("ADCSRA ");Serial.println(ADCSRA);
   
while (SpannungR2<3.5)
  {
    digitalWrite(13, HIGH); //LED on
    delay(300);
    digitalWrite(13, LOW);
    delay(300);
    for(int i=0;i<5;i++){
    Messwert+=analogRead(AnalogPin);
    }
    Messwert=trunc(Messwert/5); 
    SpannungR2=(Quellspannung/1023.0)*Messwert;
    digitalWrite(12, HIGH); //433 TX on
    mySwitch.send(1305, 24);
    digitalWrite(12, LOW); //433 Tx off
  delay(100); 
  Serial.println("Whileschleife");
  Serial.println( SpannungR2 );
  }
  keep_ADCSRA = ADCSRA;
// for (int i = 0; i < 2; i++) { 
 
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
 // ADCSRA = 1;
 //}   
ADCSRA = keep_ADCSRA;
Serial.print("ADCSRA WakeUp ");
Serial.println(ADCSRA);
  delay(1500);
}

at the moment, the code runs just on an arduino uno board (with pullup - 5k- on A5), not on my board, foto attached.
but this makes no difference, just more current. I want to get down the µA...
What works fine with Bareduino and sleep.

A very odd problem indeed. It doesn't have anything to do with the ADC; that just reads a value into memory. The Serial.println(SpannungR2) is where the action is at; it just has to print the contents of the 4 bytes of float. Whatever the 4 bytes contain, the println() should be able to print out something sensible and not garbage. So what's happening?

I'm speculating that the serial output is somehow (timing dependent) getting corrupted. It seems unlikely, but, unless I have missed something obvious, the other possibilities seem equally unlikely.

Try some additional debugging:

Remove the keep_ADCSRA = ADCSRA;, ADCSRA = keep_ADCSRA; lines, and remove anything relating to the RCSwitch. Check if the behaviour is the same.

Now, change this Serial.println(SpannungR2); to:

  Serial.println(SpannungR2);
  Serial.println(1.2345);
  Serial.println(SpannungR2);
  delay(20);
  Serial.println(SpannungR2);
  Serial.println(3.4567);
  Serial.println(Messwert);
  Serial.println(98765);
  Serial.println(SpannungR2);

And see what is output.

Okay, I tried the following code and it seems there is a problem with serial print.
Two Cases:
A) Analog Pin is Pulled Up
B) Analog Pin is ground.

float SpannungR2; 
int AnalogPin=5; //ATMEGA Pin 28
float Quellspannung=5.0; //5 Volt Betriebspannung;
long Messwert;
int anzahlSMS=0;

#include "LowPower.h"

void setup() {

  // initialize digital pin 13 as an output.
 pinMode(13, OUTPUT); //ATMEGA Pin 19
 pinMode(12, OUTPUT); //ATMEGA Pin 18
 Serial.begin(9600);
 
}

void loop() {

for(int i=0;i<5;i++)
   {Messwert+=analogRead(AnalogPin);}
   Serial.println(Messwert);
    Messwert=trunc(Messwert/5);
    SpannungR2=(Quellspannung/1023.0)*Messwert;

   Serial.println("Loop");
   Serial.println(SpannungR2);
   delay (1000);
if (SpannungR2<3.5)
  {
    digitalWrite(13, HIGH); //LED an auf Arduino nano Board
    delay(300);
    digitalWrite(13, LOW);
    delay(300);
    
    Serial.println("If Case");
    Serial.println(SpannungR2);
  Serial.println(1.2345);
  Serial.println(SpannungR2);
  delay(20);
  Serial.println(SpannungR2);
  Serial.println(3.4567);
  Serial.println(Messwert);
  Serial.println(98765);
  Serial.println(SpannungR2);
  }
  
   LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
  }

Serial output:
A)
Loop
6.24
6391
Loop
6.25
6393
Loop
6.25
6393
Loop
6.25

B)
see attachment

so, in B) there are these garbage outputs...

strange...

another question is why there are more than 5 volts.
multimeter reading at analog pin is 5 volts/0 Volts

Brewmaster15:
another question is why there are more than 5 volts.
multimeter reading at analog pin is 5 volts/0 Volts

Sorry, I forgot to mention that in my previous post:
You don't reset Messwert to zero at the beginning of loop, so effectively you have a sixth item in an average of five.

Brewmaster15:
so, in B) there are these garbage outputs...

I'm struggling to explain it as well.

So, after the device is awakened from power down mode, it prints variations of the following:

   Serial.println("If Case");
    Serial.println(SpannungR2);    // 0.00
    Serial.println(1.2345);        // 1.23
    Serial.println(SpannungR2);    // r,,j
    delay(20);
    Serial.println(SpannungR2);    // 0.00
    Serial.println(3.4567);        // 3.46
    Serial.println(Messwert);      // 0
    Serial.println(98765);         // 98765
    Serial.println(SpannungR2);    // 0.00

And note too, that SpannungR2 < 3.5 must be true to be inside the if statement - so SpannungR2 and Messwert might even be zero.

WTF? I hope someone else has some ideas.

Hi,

I have simplified my code, so there is no need for floats anymore.
The code works fine, but without the serial sending, that I just needed
for debugging.
But interestingly it´s the same troubles with integer serial sending than with
float. and without sleeping (comment it out) it sends correctly, but after sleep it sends garbage...
so there is some change after sleep...
:astonished:

int AnalogPin=5; //ATMEGA Pin 28
int Messwert;

#include <RCSwitch.h>
#include "LowPower.h"

RCSwitch mySwitch = RCSwitch();

void setup() {

 pinMode(13, OUTPUT); //ATMEGA Pin 19 - LED
 pinMode(12, OUTPUT); //ATMEGA Pin 18 - 433 Modul V+
 Serial.begin(9600);
    
 mySwitch.enableTransmit(7);  // Transmitter is connected to Arduino Pin #7 ATMEGA PIN 13
}

void loop() {
Messwert=analogRead(AnalogPin);
Serial.println(Messwert);

while (Messwert<500)
  {
    digitalWrite(13, HIGH); //LED an auf Arduino nano Board
    delay(300);
    digitalWrite(13, LOW);
    delay(300);
    Messwert=analogRead(AnalogPin);
    Serial.println(Messwert);
    digitalWrite(12, HIGH); //433 Modul an
    mySwitch.send(1305, 24);
    digitalWrite(12, LOW); //433 Modul aus
    delay(100); 
   }

for (int i = 0; i < 2; i++) { 
 
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
    }   
delay(1500);
}

I tried your code myself (with a couple of tweaks) but couldn't reproduce your problem.

I would suggest commenting out anything to do RCSwitch and testing that as well. Maybe disconnect the hardware too. I can't see what it does, and you need to try to narrow down the issue even more.