New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fluctuating ADC with stabilized source #2070

Closed
supersjimmie opened this Issue May 30, 2016 · 128 comments

Comments

Projects
None yet
@supersjimmie

supersjimmie commented May 30, 2016

I supply the ADC with a stable voltage, supplied by a separate LM1117 3.3V with 100uF capacitor a resistor voltage divider. The LM1117 will provide 3.3V regardless of the load of the ESP's own voltage regulator, the capacitor takes away any noise and the 2 resistors make a fixed voltage suitable to be read by the ADC.
(GND for both the ESP and the LM1117 are connected)

Then, based on this article, I tried to add more stability to the readings:
https://www.quora.com/Why-is-a-little-delay-needed-after-analogRead-in-Arduino
So I do subsequent readings and only use the last one. I even do it 3 times instead of 2, and then only use the last one because that one is supposed to be stable.

#define ANALOGPIN A0;
...
analog = analogRead(ANALOGPIN);
delay(1);
analog = analogRead(ANALOGPIN);
analog = analogRead(ANALOGPIN);
Serial.print(F("Stablized Analog pin: "));
Serial.println(analog);

Readings are done and stored every minute.

The ADC reading has 2 fluctuations, a slow drift and spikes.
This show the ADC output:
analogRead fluctuations

This has been tested with the mentioned 'external' 3.3V regulator and with the 3.3V output from the ESP itself. I also tried with or without the subsequent readings. I don't really mind the spikes because I can add some code to flatten those, but the "long" wave-like fluctuation makes it all useless.

(I need this to read an MQ135 sensor.)

Using current core stable and Arduino IDE 1.6.9.

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie May 31, 2016

Full code, when logging to the IDE's Serial Plotter:

#include <Arduino.h>
void setup() {
  Serial.begin(115200);
}

void loop() {
  int A;
  A = analogRead(A0);
  A = analogRead(A0);
  Serial.println(A);
  delay(60000);
}

I've had this code running for a few hours on a ESP with only the 2 resistors on the A0, one connected to Gnd and one connected to an LM1117 3.3v output.

supersjimmie commented May 31, 2016

Full code, when logging to the IDE's Serial Plotter:

#include <Arduino.h>
void setup() {
  Serial.begin(115200);
}

void loop() {
  int A;
  A = analogRead(A0);
  A = analogRead(A0);
  Serial.println(A);
  delay(60000);
}

I've had this code running for a few hours on a ESP with only the 2 resistors on the A0, one connected to Gnd and one connected to an LM1117 3.3v output.

@igrr

This comment has been minimized.

Show comment
Hide comment
@igrr

igrr Jun 1, 2016

Member

I've set up a circuit to test this, so far I'm getting readings within 1 LSB of average. The thing will run for a few hours, and I'll post a graph by end of day.

Here's my schematic, for the record:
adc_test_1
ESP8266 is mounted on a test board, which is powered by a SY8088 dc/dc step-down regulator. 3.3V to ADC input is supplied by another identical board, which doesn't have an ESP on it (so the regulator is only loaded by ADC divider).

Member

igrr commented Jun 1, 2016

I've set up a circuit to test this, so far I'm getting readings within 1 LSB of average. The thing will run for a few hours, and I'll post a graph by end of day.

Here's my schematic, for the record:
adc_test_1
ESP8266 is mounted on a test board, which is powered by a SY8088 dc/dc step-down regulator. 3.3V to ADC input is supplied by another identical board, which doesn't have an ESP on it (so the regulator is only loaded by ADC divider).

@igrr

This comment has been minimized.

Show comment
Hide comment
@igrr

igrr Jun 1, 2016

Member

No drift, just random noise mostly within 1 LSB:

adc_test

Member

igrr commented Jun 1, 2016

No drift, just random noise mostly within 1 LSB:

adc_test

@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie Jun 1, 2016

Strange, had it running on a separate ESP (NodeMCU), which is powered through USB, and the ADC powered like this:
connection
Yesterday it kept going up and down about 10, currently it runs smooth.

supersjimmie commented Jun 1, 2016

Strange, had it running on a separate ESP (NodeMCU), which is powered through USB, and the ADC powered like this:
connection
Yesterday it kept going up and down about 10, currently it runs smooth.

@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie Jun 7, 2016

@igrr , I think I made some progress.
I've done several tests:

  • with 2 different 'external' 3.3V power sources or with the 3.3V line from my NodeMCU board,
  • with one or two subsequent analogRead calls,
  • intervals ranging from 100ms to 60s,
  • two different nodeMCU boards,
  • with or without some WiFi related libraries loaded and connect/webclient calls.
    In all cases it kept jumping up and down with a difference of about 10.

Then I noticed that after a reset, it was stable for only a few seconds.
So that made me think about the fact that even without any WiFi library loaded and without any WiFi.begin(), the modules are still using their last save Wifi settings.
So I added #include <ESP8266WiFi.h> and in the setup I just called WiFi.disconnect() and then it was totally rock stable!

Then I added the WiFi.begin(..) again and it got unstable.

So this issue is related to WiFi.

supersjimmie commented Jun 7, 2016

@igrr , I think I made some progress.
I've done several tests:

  • with 2 different 'external' 3.3V power sources or with the 3.3V line from my NodeMCU board,
  • with one or two subsequent analogRead calls,
  • intervals ranging from 100ms to 60s,
  • two different nodeMCU boards,
  • with or without some WiFi related libraries loaded and connect/webclient calls.
    In all cases it kept jumping up and down with a difference of about 10.

Then I noticed that after a reset, it was stable for only a few seconds.
So that made me think about the fact that even without any WiFi library loaded and without any WiFi.begin(), the modules are still using their last save Wifi settings.
So I added #include <ESP8266WiFi.h> and in the setup I just called WiFi.disconnect() and then it was totally rock stable!

Then I added the WiFi.begin(..) again and it got unstable.

So this issue is related to WiFi.

@ibaranov-cp

This comment has been minimized.

Show comment
Hide comment
@ibaranov-cp

ibaranov-cp Jun 9, 2016

To me, this looks like the power draw from WiFi is distorting the onboard ADC.
This is honestly not too surprising, and unless there is an on-board external reference input, it is difficult to combat in software. Perhaps an I2C attached external ADC would serve your purposes if you need actual precision?
The onboard 10bit ADC is most likely a SAR type (simplest and cheapest).
So, if it is possible to control sample timing, giving the ADC more time to do its job may also help.

ibaranov-cp commented Jun 9, 2016

To me, this looks like the power draw from WiFi is distorting the onboard ADC.
This is honestly not too surprising, and unless there is an on-board external reference input, it is difficult to combat in software. Perhaps an I2C attached external ADC would serve your purposes if you need actual precision?
The onboard 10bit ADC is most likely a SAR type (simplest and cheapest).
So, if it is possible to control sample timing, giving the ADC more time to do its job may also help.

@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie Jun 9, 2016

Using an 'external' adc is not an option for my setup, simply because I don't have any empty usable digital pins left on the module. How could I control the sample timing?

supersjimmie commented Jun 9, 2016

Using an 'external' adc is not an option for my setup, simply because I don't have any empty usable digital pins left on the module. How could I control the sample timing?

@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie Jun 11, 2016

Until now I have this as a work-around to do a reading every minute:

void loop() {
  unsigned long starttime = millis();
  WiFi.disconnect();
  delay(10);  // allow a short time to disconnect wifi
  Serial.println(analogRead(A0));
  WiFi.begin(ssid, password);
  while ((WiFi.status() != WL_CONNECTED)) {  // wait for connect wifi
    delay(500);
  }
  delay(60000-(millis()-starttime));  // make loop time 60 sec
}

Only this introduces another issue, that the ESP doesn't always (re)connect to wifi causing it to hang.

supersjimmie commented Jun 11, 2016

Until now I have this as a work-around to do a reading every minute:

void loop() {
  unsigned long starttime = millis();
  WiFi.disconnect();
  delay(10);  // allow a short time to disconnect wifi
  Serial.println(analogRead(A0));
  WiFi.begin(ssid, password);
  while ((WiFi.status() != WL_CONNECTED)) {  // wait for connect wifi
    delay(500);
  }
  delay(60000-(millis()-starttime));  // make loop time 60 sec
}

Only this introduces another issue, that the ESP doesn't always (re)connect to wifi causing it to hang.

@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie Jun 15, 2016

I have the issue with 3 NodeMCU boards, so I tried to find out if it was perhaps related to the small power regulator on those board. Instead of powering over usb or with an external 5V powersupply to the Vin pin, I now used a LM1117 3.3V reguator to supply to the 3.3V of the board. (thus bypassing the small onboard voltage regulator)
This still gives the same jumpy values.

supersjimmie commented Jun 15, 2016

I have the issue with 3 NodeMCU boards, so I tried to find out if it was perhaps related to the small power regulator on those board. Instead of powering over usb or with an external 5V powersupply to the Vin pin, I now used a LM1117 3.3V reguator to supply to the 3.3V of the board. (thus bypassing the small onboard voltage regulator)
This still gives the same jumpy values.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jun 16, 2016

Same problem for me see:

http://bbs.espressif.com/viewtopic.php?f=66&t=2286&p=7367#p7367
https://www.mikrocontroller.net/topic/399791#4616103

Even tried battery powered and entire Board shielded with foil.
Definitive the transmitting is causing this

After wifi.disconnect() the reading is ok!
In the Beginnin good readings then fluctuating

Gorkde commented Jun 16, 2016

Same problem for me see:

http://bbs.espressif.com/viewtopic.php?f=66&t=2286&p=7367#p7367
https://www.mikrocontroller.net/topic/399791#4616103

Even tried battery powered and entire Board shielded with foil.
Definitive the transmitting is causing this

After wifi.disconnect() the reading is ok!
In the Beginnin good readings then fluctuating

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jun 16, 2016

Btw as for me I also have no pins for external ADC which probably would be the best choice.

Gorkde commented Jun 16, 2016

Btw as for me I also have no pins for external ADC which probably would be the best choice.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jun 16, 2016

Isn't there a way to check if wifi is transmitting and poll the ADC when it's not?

Gorkde commented Jun 16, 2016

Isn't there a way to check if wifi is transmitting and poll the ADC when it's not?

@arizzi

This comment has been minimized.

Show comment
Hide comment
@arizzi

arizzi Jun 17, 2016

same problem here... is there a way to "pause" the wifi radio without really disconnecting?

arizzi commented Jun 17, 2016

same problem here... is there a way to "pause" the wifi radio without really disconnecting?

@arizzi

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie Jun 17, 2016

Simply tested that.
Doing WiFi.forceSleepBegin(100); disconnects indeed, but it seems to be buggy because it never reconnects anymore. I needed to add WiFi.forceSleepWait() after the analogRead(). Then it has to re-connect (re-associate?) wifi, which takes 4-5 seconds. So any subsequent code that needs a connection will fail...

The resulting analogRead looks stable.

supersjimmie commented Jun 17, 2016

Simply tested that.
Doing WiFi.forceSleepBegin(100); disconnects indeed, but it seems to be buggy because it never reconnects anymore. I needed to add WiFi.forceSleepWait() after the analogRead(). Then it has to re-connect (re-associate?) wifi, which takes 4-5 seconds. So any subsequent code that needs a connection will fail...

The resulting analogRead looks stable.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jun 27, 2016

Another Thing I noticed.... When using Blynk App in my sketch and doing Blynk.Write every 100ms it seems to be stable as well so the unstability might be just when Wifi starts or stops transmitting.

Gorkde commented Jun 27, 2016

Another Thing I noticed.... When using Blynk App in my sketch and doing Blynk.Write every 100ms it seems to be stable as well so the unstability might be just when Wifi starts or stops transmitting.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jun 28, 2016

I also noticed it just starts getting wrong readings once it seems the WIFI connection has been established the first time (some seconds after powerup).

It then gets wrong radings in the range 1-7 above (always!) the correct reading with seldom a correct reading in between.

If I put AIN to GND I get readings 0-1 which schould be normal but as soon as the connection is established the readings are 0-7 where most of them are in the 5-7 range.

I now used a sketch to read for some time and only use the lowest reading which works but is VERY slow because as soon as I sample readings for less than around 100ms it seems to miss the seldom correct (low) readings and I get wrong ones sometimes in my result.

int ReadAIN()
{
  int Ergebnis = analogRead(0);

  for (int i = 0 ; i < 50 ; i++)
  {
    int Messung = analogRead(0);
    if (Messung < Ergebnis)
    {
      Ergebnis = Messung;
    }
    delay(2);
  }
  return (Ergebnis);
}

BTW... I also use the same voltage regulator, maybe a problem with that one (LM1117V33)?

I also found this (09bb758) and would like to try if that's solving my problen but don't know how. Just integrating it in my sketch doresn't seem to work. Any advice?

REMARK: If the ESP has established a connection once it automatically will after powerup so you will see this problen only if the ESP has been connected before or if it gets connected by WiFi.begin() command

Closed my other Issue since it's the same as this.

Gorkde commented Jun 28, 2016

I also noticed it just starts getting wrong readings once it seems the WIFI connection has been established the first time (some seconds after powerup).

It then gets wrong radings in the range 1-7 above (always!) the correct reading with seldom a correct reading in between.

If I put AIN to GND I get readings 0-1 which schould be normal but as soon as the connection is established the readings are 0-7 where most of them are in the 5-7 range.

I now used a sketch to read for some time and only use the lowest reading which works but is VERY slow because as soon as I sample readings for less than around 100ms it seems to miss the seldom correct (low) readings and I get wrong ones sometimes in my result.

int ReadAIN()
{
  int Ergebnis = analogRead(0);

  for (int i = 0 ; i < 50 ; i++)
  {
    int Messung = analogRead(0);
    if (Messung < Ergebnis)
    {
      Ergebnis = Messung;
    }
    delay(2);
  }
  return (Ergebnis);
}

BTW... I also use the same voltage regulator, maybe a problem with that one (LM1117V33)?

I also found this (09bb758) and would like to try if that's solving my problen but don't know how. Just integrating it in my sketch doresn't seem to work. Any advice?

REMARK: If the ESP has established a connection once it automatically will after powerup so you will see this problen only if the ESP has been connected before or if it gets connected by WiFi.begin() command

Closed my other Issue since it's the same as this.

@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie Jun 30, 2016

@Gorkde I think that code fails on rom_i2c_writeReg_Mask? I cannot find where that should come from, probably something that only existed in older SDK?

@igrr I have tested it with the latest GIT version, which includes SDK 1.5.4. In the rellease notes of that SDK is a note about a fix of analogread:
8. Revised the issue that API system_adc_read and system_get_vdd33 may return wrong value.
But no luck it still does exacly the same.

supersjimmie commented Jun 30, 2016

@Gorkde I think that code fails on rom_i2c_writeReg_Mask? I cannot find where that should come from, probably something that only existed in older SDK?

@igrr I have tested it with the latest GIT version, which includes SDK 1.5.4. In the rellease notes of that SDK is a note about a fix of analogread:
8. Revised the issue that API system_adc_read and system_get_vdd33 may return wrong value.
But no luck it still does exacly the same.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jun 30, 2016

@supersjimmie:

I wrote that piece of code to make my sketch work until the issue is fixed.

When I do analogread I found the readings always go up from the correct reading.

Therefore I wrote a read function that samples readings an just uses the lowest of them because that's the correct reading.

But as I said, it's just for the time being until the issue is fixed.

Maybe this is an hardware issue of the modules we have or the voltage regulator?

Which one do you use?
Will buy another one for testing purposes but I really don't think that's the reason.

Gorkde commented Jun 30, 2016

@supersjimmie:

I wrote that piece of code to make my sketch work until the issue is fixed.

When I do analogread I found the readings always go up from the correct reading.

Therefore I wrote a read function that samples readings an just uses the lowest of them because that's the correct reading.

But as I said, it's just for the time being until the issue is fixed.

Maybe this is an hardware issue of the modules we have or the voltage regulator?

Which one do you use?
Will buy another one for testing purposes but I really don't think that's the reason.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jul 4, 2016

Did some further investigation.

When printing in Serial plotter it's easy to see the readings are +/-1 which should be normal but once the Wifi is enabled and connected it seems to have a constant minimal positive voltage offset that's causing the problem (no longterm fluctuations fir me, they probably are Vcc related).

So I get 6 +/-1 from then on most of the time.

Tried some Capacitors (100nF and/or 10uF) soldierd directly to Vcc/GND, as well GPIO0, GPIO2, GPIO15 to GND. Same readings.

Therfore I really don't think thats a voltage regulator issue, maybe defective Modules or really some kind of bug in ADC.

@igrr
Did you test with 12E? Do you have 12F that you could test?

@Others
Which Voltage regulator do you use?
Which ESP module do you use? 12E or 12F or other?

Gorkde commented Jul 4, 2016

Did some further investigation.

When printing in Serial plotter it's easy to see the readings are +/-1 which should be normal but once the Wifi is enabled and connected it seems to have a constant minimal positive voltage offset that's causing the problem (no longterm fluctuations fir me, they probably are Vcc related).

So I get 6 +/-1 from then on most of the time.

Tried some Capacitors (100nF and/or 10uF) soldierd directly to Vcc/GND, as well GPIO0, GPIO2, GPIO15 to GND. Same readings.

Therfore I really don't think thats a voltage regulator issue, maybe defective Modules or really some kind of bug in ADC.

@igrr
Did you test with 12E? Do you have 12F that you could test?

@Others
Which Voltage regulator do you use?
Which ESP module do you use? 12E or 12F or other?

@igrr

This comment has been minimized.

Show comment
Hide comment
@igrr

igrr Jul 4, 2016

Member

I tested with an ESP8266 mounted onto a test board, I can repeat with a NodeMCU which has ESP12F on it. Could you please post your sketch so that our tests happens in the same conditions?
Thanks.

Member

igrr commented Jul 4, 2016

I tested with an ESP8266 mounted onto a test board, I can repeat with a NodeMCU which has ESP12F on it. Could you please post your sketch so that our tests happens in the same conditions?
Thanks.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jul 4, 2016

ADC is Grounded and reading should be 0/1

Once I do WiFi.disconnect() every reading is ok again.

// ***** Print ADC Reading *****
#include <ESP8266WiFi.h>

void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, pass);
}

void loop()
{
  int ReadingADC = analogRead(0);
  Serial.println(ReadingADC);
  delay(200);
}

readings

Gorkde commented Jul 4, 2016

ADC is Grounded and reading should be 0/1

Once I do WiFi.disconnect() every reading is ok again.

// ***** Print ADC Reading *****
#include <ESP8266WiFi.h>

void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, pass);
}

void loop()
{
  int ReadingADC = analogRead(0);
  Serial.println(ReadingADC);
  delay(200);
}

readings

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jul 4, 2016

I mounted my ESP on a pcb along with 100nF (also tried 10uF additional) which is plugged in my breadboard.

Voltage is supported by a LM1117V33 with 100nF input and 10uF or 470uF at the output (tried all possible means). VCC of the ESP is connected by a switch (tried with direct connection as well, same result). Also tried on a seperate Breadboard with no other Hardware than Voltage regulator ESP and Caps.

While testing I also noticed the ESP-VCC drops from 3.3V to 3.2 or even 3.0 (at random for each start) as I apply VCC to the ESP (no matter what, the voltage regulator cannot get it up again). Even with very big capacitors directly at ESP-VCC and Voltage regulator directly at the ESP the Voltage drops.

My Voltage regulator is supplied by an 1A power adapter which I tried setting to lower or higher voltage. Doesen't change anything. Also the input voltage doesn't break in below 7V so that's not the problem. Tried another power adapter as well, no change.

The Voltage regulator is rated 800mA so either the ESP is drawing more than that (which shouldnt be the case) or there's some other thing going on that I can't locate with my means of measuring.

But as soon as WiFi connects the voltage goes up to normal 3.3V again.

So at the mysterious voltage drop before connecting I get correct readings (also when ADC is not Grounded but set to any voltage like 0,5V) but when WiFi connects and VCC gets to normal the reading starts getting an offset.

I got no parts here to try ESP12E or another voltage regulator but ordered them. This will take 3 at least 3 weeks until they arrive.

Gorkde commented Jul 4, 2016

I mounted my ESP on a pcb along with 100nF (also tried 10uF additional) which is plugged in my breadboard.

Voltage is supported by a LM1117V33 with 100nF input and 10uF or 470uF at the output (tried all possible means). VCC of the ESP is connected by a switch (tried with direct connection as well, same result). Also tried on a seperate Breadboard with no other Hardware than Voltage regulator ESP and Caps.

While testing I also noticed the ESP-VCC drops from 3.3V to 3.2 or even 3.0 (at random for each start) as I apply VCC to the ESP (no matter what, the voltage regulator cannot get it up again). Even with very big capacitors directly at ESP-VCC and Voltage regulator directly at the ESP the Voltage drops.

My Voltage regulator is supplied by an 1A power adapter which I tried setting to lower or higher voltage. Doesen't change anything. Also the input voltage doesn't break in below 7V so that's not the problem. Tried another power adapter as well, no change.

The Voltage regulator is rated 800mA so either the ESP is drawing more than that (which shouldnt be the case) or there's some other thing going on that I can't locate with my means of measuring.

But as soon as WiFi connects the voltage goes up to normal 3.3V again.

So at the mysterious voltage drop before connecting I get correct readings (also when ADC is not Grounded but set to any voltage like 0,5V) but when WiFi connects and VCC gets to normal the reading starts getting an offset.

I got no parts here to try ESP12E or another voltage regulator but ordered them. This will take 3 at least 3 weeks until they arrive.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Jul 4, 2016

For what I can measure the ESP draws around 20-70mA

Gorkde commented Jul 4, 2016

For what I can measure the ESP draws around 20-70mA

@Energybrain

This comment has been minimized.

Show comment
Hide comment
@Energybrain

Energybrain Sep 21, 2016

Yes, I implemented it in setup() so it should be called only once in the beginning. I'm sampling a constant 60 hz signal and noticed I get about 15% less sample points per cycle when using this function with 2.3.0 using the enum NONE_SLEEP_T. If I use either MODEM_SLEEP_T or LIGHT_SLEEP_T, the offset is back and the sample points increase but not to the same amount as 2.2.0. If I use the same code for 2.2.0, NONE_SLEEP_T is slower as well but either LIGHT or MODEM works fine.

Energybrain commented Sep 21, 2016

Yes, I implemented it in setup() so it should be called only once in the beginning. I'm sampling a constant 60 hz signal and noticed I get about 15% less sample points per cycle when using this function with 2.3.0 using the enum NONE_SLEEP_T. If I use either MODEM_SLEEP_T or LIGHT_SLEEP_T, the offset is back and the sample points increase but not to the same amount as 2.2.0. If I use the same code for 2.2.0, NONE_SLEEP_T is slower as well but either LIGHT or MODEM works fine.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Sep 21, 2016

@igrr
Any reason why this should only happen after 2.2.0?
Didn't got time to check or continue my project until now but need to anyway next time.

Gorkde commented Sep 21, 2016

@igrr
Any reason why this should only happen after 2.2.0?
Didn't got time to check or continue my project until now but need to anyway next time.

@supersjimmie

This comment has been minimized.

Show comment
Hide comment
@supersjimmie

supersjimmie Oct 27, 2016

I now noticed that even my DHT22 sensor is sensitive to this problem.
Humidity jumps about 5% up and down with default wifi sleep_t and becomes stable with none_sleep.

supersjimmie commented Oct 27, 2016

I now noticed that even my DHT22 sensor is sensitive to this problem.
Humidity jumps about 5% up and down with default wifi sleep_t and becomes stable with none_sleep.

@timmclaurin

This comment has been minimized.

Show comment
Hide comment
@timmclaurin

timmclaurin Nov 6, 2016

Thanks for the effort on this guys. I found the same thing tonight and spent hours trying to stabilize! Now in bed and found this!! I will try it setting the sleep mode in the morning.

Just wanted to chime in and say thanks!

timmclaurin commented Nov 6, 2016

Thanks for the effort on this guys. I found the same thing tonight and spent hours trying to stabilize! Now in bed and found this!! I will try it setting the sleep mode in the morning.

Just wanted to chime in and say thanks!

@gjt211

This comment has been minimized.

Show comment
Hide comment
@gjt211

gjt211 Nov 23, 2016

Hi,

I have added
wifi_set_sleep_type(NONE_SLEEP_T);
delay(10);
just before my analogRead(A0), and I have added
wifi_set_sleep_type(MODEM_SLEEP_T);
after the analogRead, but it is still jumping all over the place.
I am getting values from 144-165 with about two out of every ten values typically between 69 and 90 (from a pot connected to 3.3v/GND).

I have also tried with just
wifi_set_sleep_type(NONE_SLEEP_T);
at the start of my setup function with similar results.

Has anyone had any better success.

gjt211 commented Nov 23, 2016

Hi,

I have added
wifi_set_sleep_type(NONE_SLEEP_T);
delay(10);
just before my analogRead(A0), and I have added
wifi_set_sleep_type(MODEM_SLEEP_T);
after the analogRead, but it is still jumping all over the place.
I am getting values from 144-165 with about two out of every ten values typically between 69 and 90 (from a pot connected to 3.3v/GND).

I have also tried with just
wifi_set_sleep_type(NONE_SLEEP_T);
at the start of my setup function with similar results.

Has anyone had any better success.

@Fettkeewl

This comment has been minimized.

Show comment
Hide comment
@Fettkeewl

Fettkeewl Feb 6, 2017

Hi guys, I noticed the same problems with the Esp8266 adc hence how I found this thread.

Has anyone successfully written a function to do proper readings? Some sort of comparator that polls multiple reads and calculates some average while ignoring the spikes?
Am I right that the spikes all go towards 0? So polling the highest reads with an specified tolerance could save the day?

I will be using the ADC to calculate battery voltage of a 18650 so I know that my valid values will be in a specific range so I can ignore the most low ones. I'd rather not populate my tiny projects with an I2C ADC such as the PCF8591 for battery voltage monitoring since my project needs to keep the size of a single 18650 battery

Fettkeewl commented Feb 6, 2017

Hi guys, I noticed the same problems with the Esp8266 adc hence how I found this thread.

Has anyone successfully written a function to do proper readings? Some sort of comparator that polls multiple reads and calculates some average while ignoring the spikes?
Am I right that the spikes all go towards 0? So polling the highest reads with an specified tolerance could save the day?

I will be using the ADC to calculate battery voltage of a 18650 so I know that my valid values will be in a specific range so I can ignore the most low ones. I'd rather not populate my tiny projects with an I2C ADC such as the PCF8591 for battery voltage monitoring since my project needs to keep the size of a single 18650 battery

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Feb 6, 2017

I did but it didn't work for me since yo do need to read 300ms or more to get correct results all the time.

Gorkde commented Feb 6, 2017

I did but it didn't work for me since yo do need to read 300ms or more to get correct results all the time.

@puttu

This comment has been minimized.

Show comment
Hide comment
@puttu

puttu Feb 6, 2017

I'm getting reasonable stability with a combination of picking the lowest value out of a bunch and calculating an exponential moving average of subsequent minimums:

adc_value = adc.read(0)
ADC_SAMPLES_PER_READING = 10
EMA_ALPHA = 10

function read_adc()
    local lowest_sample, new_sample = adc.read(0)
    for i = 1, ADC_SAMPLES_PER_READING do
        new_sample = adc.read(0)
        if new_sample < lowest_sample then lowest_sample = new_sample end
    end
    adc_value = (EMA_ALPHA * lowest_sample + (100 - EMA_ALPHA) * adc_value) / 100;
end

tmr.alarm(2, 200, 1, function() read_adc() end)

This runs non-stop and I check the global adc_value as a proxy for the actual reading.

puttu commented Feb 6, 2017

I'm getting reasonable stability with a combination of picking the lowest value out of a bunch and calculating an exponential moving average of subsequent minimums:

adc_value = adc.read(0)
ADC_SAMPLES_PER_READING = 10
EMA_ALPHA = 10

function read_adc()
    local lowest_sample, new_sample = adc.read(0)
    for i = 1, ADC_SAMPLES_PER_READING do
        new_sample = adc.read(0)
        if new_sample < lowest_sample then lowest_sample = new_sample end
    end
    adc_value = (EMA_ALPHA * lowest_sample + (100 - EMA_ALPHA) * adc_value) / 100;
end

tmr.alarm(2, 200, 1, function() read_adc() end)

This runs non-stop and I check the global adc_value as a proxy for the actual reading.

@Gorkde

This comment has been minimized.

Show comment
Hide comment
@Gorkde

Gorkde Feb 6, 2017

Did the same but I also had an esp where I had to pick the highest. Also as said takes very long to be sure you get the correct one.

Gorkde commented Feb 6, 2017

Did the same but I also had an esp where I had to pick the highest. Also as said takes very long to be sure you get the correct one.

@puttu

This comment has been minimized.

Show comment
Hide comment
@puttu

puttu Feb 6, 2017

Yeah, it depends on the use case. For me it was acting as a temperature sensor for a PID controller, so stability and repeatability were much more important than speed or absolute accuracy.

puttu commented Feb 6, 2017

Yeah, it depends on the use case. For me it was acting as a temperature sensor for a PID controller, so stability and repeatability were much more important than speed or absolute accuracy.

@Fettkeewl

This comment has been minimized.

Show comment
Hide comment
@Fettkeewl

Fettkeewl Feb 6, 2017

Hello again lads, thank you for your answers.
Have any of you tried system_adc_fast_read API?
I quote

How accurate is the internal ADC?
When connected to routers, ESP8266 will enter modem_sleep in STA mode only, which will cause the changes of the internal chip currents and reference values, and thus result in abnormal ADC sampling.

If a high accuracy is required, please use system_adc_fast_read API. But RF circuitry should be shut down before measuring and Wi-Fi will be disconnected. For an relatively lower accuracy when readings’ difference of 1 or 2 can be tolerated, Wi-Fi can be configured to non_sleep mode.

For lower accuracy, the user may enter sleep mode. Power consumption is lower in this case.

Just read about it over here: https://espressif.com/en/support/explore/faq

Edit:
When I search for it on google I only find the chinese faq mentioning it. Can't read it though, because of .. you know.. reasons.. ..

http://espressif.com/sites/default/files/documentation/espressif_faq_cn.pdf

Fettkeewl commented Feb 6, 2017

Hello again lads, thank you for your answers.
Have any of you tried system_adc_fast_read API?
I quote

How accurate is the internal ADC?
When connected to routers, ESP8266 will enter modem_sleep in STA mode only, which will cause the changes of the internal chip currents and reference values, and thus result in abnormal ADC sampling.

If a high accuracy is required, please use system_adc_fast_read API. But RF circuitry should be shut down before measuring and Wi-Fi will be disconnected. For an relatively lower accuracy when readings’ difference of 1 or 2 can be tolerated, Wi-Fi can be configured to non_sleep mode.

For lower accuracy, the user may enter sleep mode. Power consumption is lower in this case.

Just read about it over here: https://espressif.com/en/support/explore/faq

Edit:
When I search for it on google I only find the chinese faq mentioning it. Can't read it though, because of .. you know.. reasons.. ..

http://espressif.com/sites/default/files/documentation/espressif_faq_cn.pdf

@lrmoreno007

This comment has been minimized.

Show comment
Hide comment
@lrmoreno007

lrmoreno007 Feb 6, 2017

Contributor

Have you tried with a simple condenser?

Contributor

lrmoreno007 commented Feb 6, 2017

Have you tried with a simple condenser?

@RudyFiero

This comment has been minimized.

Show comment
Hide comment
@RudyFiero

RudyFiero Feb 6, 2017

The noise is not random and does not average around the true value. So a capacitor will not necessarily provide the correct result. If it were consistent then it would be easier to compensate for the deviations.

RudyFiero commented Feb 6, 2017

The noise is not random and does not average around the true value. So a capacitor will not necessarily provide the correct result. If it were consistent then it would be easier to compensate for the deviations.

@leon-v

This comment has been minimized.

Show comment
Hide comment
@leon-v

leon-v Sep 13, 2017

My findings for this were that the internal WiFi circuitry is coupling to the ADC reference of the ADC.
most of the solutions here changed the behavior of the WiFi, which would change what the ADC did, but were not a reliable solution because the chip would just use current at other times..
This is why the system_adc_fast_read() required you to disable interrupts and turn off Wifi.

I might try use it without turning off Wifi and computing the results...

Also, why is the minimum value the correct one? All my tests show that the highest one is the correct one. Unless my LiPo batter really is dropping to 2.3V and up to 3.7V :-p

Note: I am not using Arduino. I use the ESP8266_NONOS_SDK_V2.0.0

I will try to look for some way to interrupt the ic when its not drawing current, like the start of an incoming WiFi packet, assuming its synchronous.
Any one got any idea on this?

Or Does anyone know how the WiFi circuity can be properly decoupled from the ADC?

leon-v commented Sep 13, 2017

My findings for this were that the internal WiFi circuitry is coupling to the ADC reference of the ADC.
most of the solutions here changed the behavior of the WiFi, which would change what the ADC did, but were not a reliable solution because the chip would just use current at other times..
This is why the system_adc_fast_read() required you to disable interrupts and turn off Wifi.

I might try use it without turning off Wifi and computing the results...

Also, why is the minimum value the correct one? All my tests show that the highest one is the correct one. Unless my LiPo batter really is dropping to 2.3V and up to 3.7V :-p

Note: I am not using Arduino. I use the ESP8266_NONOS_SDK_V2.0.0

I will try to look for some way to interrupt the ic when its not drawing current, like the start of an incoming WiFi packet, assuming its synchronous.
Any one got any idea on this?

Or Does anyone know how the WiFi circuity can be properly decoupled from the ADC?

@leon-v

This comment has been minimized.

Show comment
Hide comment
@leon-v

leon-v Sep 14, 2017

OK.. My ideas worked with varying degrees if failure..
My first idea was to use system_phy_set_max_tpw() to make WiFi use less current.. Which sort of worked, but made other things unstable.

I next tried to use wifi_status_led_install() to toggle a pin based on activity, then only used the ADC when that pin was low.. Which again worked, but not as well as i would have expected if that was the issue.

So i tried to hold the CH_PD pin low, which helped a lot, since my design was toggling GPIO14 next to CH_PD, there was noise coupling onto CD_PD and the IC was slowing or stuttering for a bit which was one issue.

I then thought "what if my big fat capacitor does need to be closer to the module?"
I had it in line with short feed wires, but that doesn't seem to be enough.
Putting a big capacitor right on the VCC and GND of the module fixed my issue.
And i must say i am surprised at how much decoupling the ESP8266 needed.
Or maybe i created a resonant circuit ?

Anyway.. My statement above was wrong. And i did have supply decoupling issues.

leon-v commented Sep 14, 2017

OK.. My ideas worked with varying degrees if failure..
My first idea was to use system_phy_set_max_tpw() to make WiFi use less current.. Which sort of worked, but made other things unstable.

I next tried to use wifi_status_led_install() to toggle a pin based on activity, then only used the ADC when that pin was low.. Which again worked, but not as well as i would have expected if that was the issue.

So i tried to hold the CH_PD pin low, which helped a lot, since my design was toggling GPIO14 next to CH_PD, there was noise coupling onto CD_PD and the IC was slowing or stuttering for a bit which was one issue.

I then thought "what if my big fat capacitor does need to be closer to the module?"
I had it in line with short feed wires, but that doesn't seem to be enough.
Putting a big capacitor right on the VCC and GND of the module fixed my issue.
And i must say i am surprised at how much decoupling the ESP8266 needed.
Or maybe i created a resonant circuit ?

Anyway.. My statement above was wrong. And i did have supply decoupling issues.

@timmclaurin

This comment has been minimized.

Show comment
Hide comment
@timmclaurin

timmclaurin Sep 14, 2017

I think it is a hardware problem due to the floating nature. It is like we need a clean reference via a diode... Not saying it can't be accomplished via software just over my head. ;/

timmclaurin commented Sep 14, 2017

I think it is a hardware problem due to the floating nature. It is like we need a clean reference via a diode... Not saying it can't be accomplished via software just over my head. ;/

@devyte

This comment has been minimized.

Show comment
Hide comment
@devyte

devyte Oct 17, 2017

Collaborator

Closing this, because so far I don't really see a possible action within the core. If that changes, please open a new issue with the relevant details, and reference this one.

Collaborator

devyte commented Oct 17, 2017

Closing this, because so far I don't really see a possible action within the core. If that changes, please open a new issue with the relevant details, and reference this one.

@dynek

This comment has been minimized.

Show comment
Hide comment
@dynek

dynek Aug 24, 2018

So everyone gave up having a stabilised ADC on the ESP8266?
I have tried everything I read in this thread and nothing helped.
Even worse, flashing same code gives different values each time, also if I power it off and on again, different values (jumping from 600-ish to 700-ish).

dynek commented Aug 24, 2018

So everyone gave up having a stabilised ADC on the ESP8266?
I have tried everything I read in this thread and nothing helped.
Even worse, flashing same code gives different values each time, also if I power it off and on again, different values (jumping from 600-ish to 700-ish).

@leon-v

This comment has been minimized.

Show comment
Hide comment
@leon-v

leon-v Aug 24, 2018

My issues were related to interrupts firing and sleep states. From memory, when I put the ADC conversion code inside a task, instead of an interrupt handler, all was OK. And I added proper decoupling capacitors. The ones I was using were not small enough.

leon-v commented Aug 24, 2018

My issues were related to interrupts firing and sleep states. From memory, when I put the ADC conversion code inside a task, instead of an interrupt handler, all was OK. And I added proper decoupling capacitors. The ones I was using were not small enough.

@dynek

This comment has been minimized.

Show comment
Hide comment
@dynek

dynek Aug 24, 2018

2018-08-24 at 10 49 pm

setup is made of

WiFi.disconnect();
wifi_set_sleep_type(NONE_SLEEP_T);

and reading analog in loop

float analog = 0;
analog = analogRead(A0);
delay(1);
analog = analogRead(A0);
analog = analogRead(A0);
Serial.println(analog);
Serial.print(" ");
delay(1000);

dynek commented Aug 24, 2018

2018-08-24 at 10 49 pm

setup is made of

WiFi.disconnect();
wifi_set_sleep_type(NONE_SLEEP_T);

and reading analog in loop

float analog = 0;
analog = analogRead(A0);
delay(1);
analog = analogRead(A0);
analog = analogRead(A0);
Serial.println(analog);
Serial.print(" ");
delay(1000);
@timmclaurin

This comment has been minimized.

Show comment
Hide comment
@timmclaurin

timmclaurin Aug 24, 2018

Yeah, I gave up and used an external adc. I only needed one input, too. Super sad. looking for a different chip to produce my product. Amazing insight in this thread, but we need a stable pin with wifi on.

timmclaurin commented Aug 24, 2018

Yeah, I gave up and used an external adc. I only needed one input, too. Super sad. looking for a different chip to produce my product. Amazing insight in this thread, but we need a stable pin with wifi on.

@devyte

This comment has been minimized.

Show comment
Hide comment
@devyte

devyte Aug 25, 2018

Collaborator

Not really given up, just stopped discussing for a while.
As a side note, my own experience with the esp12e is not as described here, at least as far as I've noticed. For me it's pretty stable, and I'm reading over wifi via webserver.

Collaborator

devyte commented Aug 25, 2018

Not really given up, just stopped discussing for a while.
As a side note, my own experience with the esp12e is not as described here, at least as far as I've noticed. For me it's pretty stable, and I'm reading over wifi via webserver.

@dynek

This comment has been minimized.

Show comment
Hide comment
@dynek

dynek Aug 27, 2018

This was from an ESP-07 and I can't seem to find a way to have "not too bad" results :-|

dynek commented Aug 27, 2018

This was from an ESP-07 and I can't seem to find a way to have "not too bad" results :-|

@dynek

This comment has been minimized.

Show comment
Hide comment
@dynek

dynek Sep 12, 2018

OK got something not too bad with a 0.1uF cap between the ADC and GND... not perfect but much better so far.

dynek commented Sep 12, 2018

OK got something not too bad with a 0.1uF cap between the ADC and GND... not perfect but much better so far.

@timmclaurin

This comment has been minimized.

Show comment
Hide comment
@timmclaurin

timmclaurin Sep 12, 2018

timmclaurin commented Sep 12, 2018

@dynek

This comment has been minimized.

Show comment
Hide comment
@dynek

dynek Sep 12, 2018

2018-09-12 at 9 27 pm

As I said not perfect but better. Readings fluctuate less and if I power off and on the device I have close to identical results. It wasn't the case before.

dynek commented Sep 12, 2018

2018-09-12 at 9 27 pm

As I said not perfect but better. Readings fluctuate less and if I power off and on the device I have close to identical results. It wasn't the case before.

@dynek

This comment has been minimized.

Show comment
Hide comment
@dynek

dynek Sep 12, 2018

Just removed one of the cap to use an external antenna instead:
https://www.esp8266.com/viewtopic.php?p=35604

And it seems to also improve things... There are still weird results though:
2018-09-12 at 9 39 pm

dynek commented Sep 12, 2018

Just removed one of the cap to use an external antenna instead:
https://www.esp8266.com/viewtopic.php?p=35604

And it seems to also improve things... There are still weird results though:
2018-09-12 at 9 39 pm

@dynek

This comment has been minimized.

Show comment
Hide comment
@dynek

dynek Sep 18, 2018

Just gave an ADS1115 a try and it's damn stable :-)

dynek commented Sep 18, 2018

Just gave an ADS1115 a try and it's damn stable :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment