Analog Read crash?!

So I,m trying to read a Current Sensor (AC current).
To get rid of interference (caused by wifi activity) I take 10 measurements within a second.
Get the peak to peak value of each and keep the 8 smallest measurements (works well enough).
Then average them and print out the result.

void setup() {
  Serial.begin(74880);
  Serial.println("setup");
}

void loop() {
  delay(10);
  double fck = AvgPeak2Peak();
  Serial.print(fck);
  fck = (AvgPeak2Peak() / 1024);
  Serial.print("   - - - - - - - -   volt ->");
  Serial.println(fck,5);
} 

int Peak2Peak()
{
  int sensorValue;
  int maxval = 0;
  int minval = 1024;
  int Peak2Peak;
  uint32_t start_time = millis();
  while((millis()-start_time) < 100)
  {
    sensorValue = analogRead(A0);
    if (sensorValue > maxval)
    {
      maxval = sensorValue;
    }
    if (sensorValue < minval)
    {
      minval = sensorValue;
    }
  }
  Peak2Peak = (maxval - minval);
  return Peak2Peak;
}

double AvgPeak2Peak(){
  int i = 0;
  int Peak2PeakSum = 0;
  double Peak2PeakAvg;
  int maxm0 = Peak2Peak();
  int maxm1 = Peak2Peak();
  int curValue;
  while (i<8)
  {
    curValue= Peak2Peak();
  if ((curValue <= maxm0) && (curValue <= maxm1))
    {
      Peak2PeakSum += curValue;
    }
    else if ((curValue > maxm0) && (curValue > maxm1))
    {
    if(maxm1 <= maxm0)
    {
      Peak2PeakSum += maxm1;
      maxm1 = curValue;
    }
    else
    {
      Peak2PeakSum += maxm0;
      maxm0 = curValue;
    }
  }
  else
  {
    if(maxm1 < maxm0)
    {
      Peak2PeakSum += maxm1;
      maxm1 = curValue;
    }
    else
    {
      Peak2PeakSum += maxm0;
      maxm0 = curValue;
    }
    }
  i++;
  }
  Peak2PeakAvg = (Peak2PeakSum / 8);
  return Peak2PeakAvg;
}

And of course it crashes as I'm fairly new to all this.

17.00   - - - - - - - -   volt ->0.01660
17.00   - - - - - - - -   volt ->0.01660
17.00   - - - - - - - -   volt ->0.01465
17.00   - - - - - - - -   volt ->0.01563
17.00
Soft WDT reset

ctx: cont 
sp: 3ffef710 end: 3ffef970 offset: 01b0



Decoding stack results
0x40201132: __analogRead at C:\Users\Nisteri\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\core_esp8266_wiring_analog.c line 33
0x402020ce: Peak2Peak() at C:\Users\Nisteri\Documents\Arduino\LIGHTS.v.0.1/LIGHTS.v.0.1.ino line 24
0x4020211b: AvgPeak2Peak() at C:\Users\Nisteri\Documents\Arduino\LIGHTS.v.0.1/LIGHTS.v.0.1.ino line 48
0x40202198: loop() at C:\Users\Nisteri\Documents\Arduino\LIGHTS.v.0.1/LIGHTS.v.0.1.ino line 10
0x40202880: loop_wrapper() at C:\Users\Nisteri\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\core_esp8266_main.cpp line 121

So please point out where I have messed up....
Thanks in adv!

1 Like

Either disable the watchdog or pat it once in a while :slight_smile: As the last thing in the loop "while((millis()-start_time) < 100)" try to call "yield()" or put in a small delay.

Danois90:
Either disable the watchdog or pat it once in a while :slight_smile: As the last thing in the loop "while((millis()-start_time) < 100)" try to call "yield()" or put in a small delay.

hmmm.. very interesting, read up on that... I had no clue.
So correct me if I'm wrong but for loops that take a long time to finish and prevent background processes to execute you need to add yield(). (not sure exactly what that does though...
Thanks Danois90!!!

I edited the code and after a long while running smoothly :slight_smile: I got this.... :frowning:

.
.
.
.
.
23.00   - - - - - - - -   volt ->0.02246
23.00   - - - - - - - -   volt ->0.02344
24.00   - - - - - - - -   volt ->0.02246
24.00   - - - - - - - -   volt ->0.02246
23.00   - - - - - - - -   volt ->0.02441
24.00   - - - - - - - -   volt ->0.0
Exception (0):
epc1=0x402026a2 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont 
sp: 3ffef750 end: 3ffef970 offset: 01a0




Decoding stack results
0x40202692: Print::printFloat(double, unsigned char) at C:\Users\Nisteri\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\Print.cpp line 287
0x402026d8: Print::print(double, int) at C:\Users\Nisteri\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\Print.cpp line 149
0x402026f5: Print::println(double, int) at C:\Users\Nisteri\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\Print.cpp line 214
0x402021c8: loop() at C:\Users\Nisteri\Documents\Arduino\LIGHTS.v.0.1/LIGHTS.v.0.1.ino line 13
0x40202888: loop_wrapper() at C:\Users\Nisteri\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\core_esp8266_main.cpp line 121

what arduino do you have ? what voltage range do you attach to A0?

while((millis()-start_time) < 100)Don't block for such a ridiculously long time.
Look at blink without delay example for clues.

its actually a ESP-12e, with a range of 0-1v
I use a voltage divider from 3.3v with 5.6k-1k to supply the A0 with ~0.5v and read the voltage across the burden resistor of the CT.
I'm just testing the stability right now so no current passes through the CT.

AWOL:
while((millis()-start_time) < 100)Don't block for such a ridiculously long time.
Look at blink without delay example for clues.

"ridiculously long time" :o I have a lot to learn... but I get what you mean. Will have a look!

Danois90:
Either disable the watchdog or pat it once in a while :slight_smile: As the last thing in the loop "while((millis()-start_time) < 100)" try to call "yield()" or put in a small delay.

What exactly is this "watchdog" good for besides being one more thing that the programmer has to keep track of?

odometer:
What exactly is this "watchdog" good for besides being one more thing that the programmer has to keep track of?

On an ESP, it is there to remind you to make sure the processor has time to service the WiFi.

So a while loop blocks other code from running, but it can run between other commands?
so for example

int i=0;
while (i<a very big number){do stuff}

is bad
and

int i=0;

void loop()
{
  if (i<a very big number)
  {
  do stuff;
  i++; 
  }
}

is ok and will let other code execute?

and if so
is the next still ok?

Serial.println("test-1");
Serial.println("test-2");
Serial.println("test-3");
.
.
.
Serial.println("test-n");

or does it execute only when the loops is "reset"?

WDT reset happens between iterations of loop(), when you call yield() and when you use delay().

DrAzzy:
WDT reset happens between iterations of loop(), when you call yield() and when you use delay().

Perfect!!! Thanks a lot!

the loop() is called regularly from the main() function that is generated automatically for you.

In between 2 calls to the loop(), main will also handle other stuff and likely call yield()

if you do a delay() somewhere in your code, that also calls esp_yield()

You can read more about the behavior here

In your loop method you are calling "AvgPeak2Peak()" twice (one time should be enough), and each call takes at least 1 second and this causes the loop method to take at least 2 seconds to complete - this is really not a good idea. You should modify your code to take one reading for each loop and when you have enough readings, they should be processed.

#define READING_DELAY 10 //millis
#define NUM_READINGS 10 //10 readings with 10 millis delay = 100ms per reading

//lastMillis is initialized to a value which will force a reading during first loop execution
unsigned long lastMillis = 0xFFFF;
int maxValue = 0, minValue = 1024;
byte numReadings = 0;

void loop()
{
  unsigned long ms = millis();

  if (ms - lastMillis >= READING_DELAY)
  {

    lastMillis = ms;

    int value = analogRead(A0);
    if (value < minValue) minValue = value;
    else if (value > maxValue) maxValue = value;

    numReadings++;

    if (numReadings >= NUM_READINGS)
    {
      //Here Peak2Peak would be a non-blocking reading similar to your "Peak2Peak()"
      //but without any watchdog insidents
      int Peak2Peak = maxValue - minValue;

      //Reset for next reading
      maxValue = 0;
      minValue = 1024;
      numReadings = 0;
    }
  }
}

Next step would be to extend the code in order to implement a non-blocking representation of "AvgPeak2Peak()" :slight_smile:

I'm not sure why you get an exception while printing a float. It may be another watchdog insident or it may be caused by an invalid float value (NaN).

Do I miss something here : you said AC current.
How do you convert it in DC voltage so to connect to Analog In?

J-M-L:
You can read more about the behavior here

will do so tomorrow, I've encountered this page before :wink:

Danois90:
In your loop method you are calling "AvgPeak2Peak()" twice (one time should be enough)

yep, that was a typo that I discovered earlier, I meant to use the variable but instead I called the function again.

I'll have to take a look tomorrow at your code in order to understand it. No hope of doing so today...

demkat1:
Do I miss something here : you said AC current.
How do you convert it in DC voltage so to connect to Analog In?

I don't.
This is the "schematic" to my setup.

You can find a lot of info to start with here. if it's an actual question and you're not just testing me :wink:

Kanivaloss:
if it's an actual question and you're not just testing me :wink:

it was an actual question because i didn;t see anything about a converter and thought if you feed in A0, AC.

May I ask where are you from? your nick-name has a meaning in some language

demkat1:
May I ask where are you from? your nick-name has a meaning in some language

Kani valoss - in Finish ?

Greece, Kanivaloss means cannibal.
Although it's spelled wrong.
Correctly it would be more like kannivalos, which is too often taken. So I stick with the wrong version :wink:
But I'm intrigued about that Finish meaning now....

Kanivaloss:
Greece....

That was my guess . Me too.
the Finish approach is interesting too