Skip to content
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

analogRead forces WiFi to disconnect #1634

Closed
renno-bih opened this issue Feb 15, 2016 · 54 comments · Fixed by #7981
Closed

analogRead forces WiFi to disconnect #1634

renno-bih opened this issue Feb 15, 2016 · 54 comments · Fixed by #7981

Comments

@renno-bih
Copy link

renno-bih commented Feb 15, 2016

Hello,
I'm trying to make sound detection with my esp8266 and this is part of code I'm using:

sample = analogRead(NOISE_SENSOR);
if (sample < 1024) // toss out spurious readings
{
if (sample > signalMax)
{
signalMax = sample; // save just the max levels
}
else if (sample < signalMin)
{
signalMin = sample; // save just the min levels
}
}

Every 10-20 seconds WiFi disconnects. When I use delay(3); after analogRead it works without disconnecting WiFi but with this delay I don't get enough samples.
Any idea what I'm doing wrong?

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

@chaeplin
Copy link
Contributor

I am using EmonLib(Electricity monitoring using analog CT sensor) with esp8266 without problem.
https://github.com/openenergymonitor/EmonLib/blob/master/EmonLib.cpp#L175-L209

Can you share your sketch ?

@supersjimmie
Copy link

Have you tried using yield() instead of delay(3)?
Might be that you have a too tight (while?) loop or something, but that is hard to see without your complete code.

@renno-bih
Copy link
Author

Here is code:

const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;

WiFiManager wifi;

void setup() 
{
  //analogReference(EXTERNAL);
  Serial.begin(115200);
  if (!wifi.autoConnect("esp_test")){
    Serial.println("not connected");
  }
}

 void loop() 
{
while (WiFi.status() != WL_CONNECTED) {

    Serial.println("notready");

  }

   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level
   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;

   // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(A0);
      delay(3);
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save just the min levels
         }
      }
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
   double volts = (peakToPeak * 3.3) / 1024;  // convert to volts
   Serial.println(peakToPeak);
}

Yep, I tried using yield();after analogRead but without success.

@chaeplin
Copy link
Contributor

@renno-bih I ran a test without delay(3) at least 10 mins, no problem at all.

@krzychb
Copy link
Contributor

krzychb commented Feb 15, 2016

@renno-bih,

This is the clue I have been looking for 😄

I observed similar issue of Wi-Fi connection being dropped after intensive analogRead(A0) when calibrating light sensor for max and min light intensity. I suspected my code doing something wired that should be tracked down before it does something worse.

I have checked your code and I observe this issue every 5 – 6s using your sketch after slight modification to see seconds when the connection is lost. There are no issues at all if delay(3) is but back.
analogRead-vs-WiFi.ino.txt

For testing I have been using: Arduino IDE 1.6.7 with core 2.0.0 and flash settings below:
capture

@chaeplin

You are our hope of using core version, flash settings or something else that does not produce this issue. Could you share your settings and thoughts?

BTW – I enjoy your huge number of projects with esp, nRF24, Arduino, ATtiny85, etc. Watching pictures of variety of your porotypes is fun 👍

Krzysztof

@chaeplin
Copy link
Contributor

@krzychb I use git version of esp8266/Arduino with Arduino IDE 1.6.7, 80M/4M(1M)/ESP-12.
edit: + not using WiFiManager. STA mode.

@renno-bih
Copy link
Author

@chaeplin WiFi Manager library is used just for configuring SSID and Pass for the first time. It doesn't make any effect on this.

I tried running the same code in AP mode and I have problems there too.
When using delay(3) everything works fine but if I run it without delay I cannot see SSID of my ESP on my smartphone. Looks like it conflicts with AP mode too.

@chaeplin
Copy link
Contributor

@renno-bih I have tested again and have no reconnect.
But when I covered antenna area, reconnect occurred.
I think disconnect is caused by weak wifi signal.

My AP : dlink 868L/dd-wrt, B/G/N, Beacon 100ms, DTIM 1

  Serial.print((millis()-millisConnected)/1000);
  Serial.print(" - mode : ");
  const char* phymodes[] = { "", "B", "G", "N" };
  Serial.print(phymodes[(int) wifi_get_phy_mode()]);
  Serial.print(" - rssi : ");
  Serial.print(WiFi.RSSI());
  Serial.print(" - peakToPeak : ");
  Serial.println(peakToPeak);

41 - mode : N - rssi : -67 - peakToPeak : 1
41 - mode : N - rssi : -67 - peakToPeak : 1
not connected...........
0 - mode : N - rssi : -71 - peakToPeak : 1
0 - mode : N - rssi : -71 - peakToPeak : 1

@renno-bih
Copy link
Author

It doesn't make sense in my case because my smartphone is just few centimeters from ESP.

@chaeplin
Copy link
Contributor

@renno-bih Which version of IDE, esp8266 core and OS do you use ? I will try.

@renno-bih
Copy link
Author

IDE, 1.6.6,
esp8266 core: 1.6.5-947-g39819f0
OS: ubuntu 14.04

Thank for helping me :)

@chaeplin
Copy link
Contributor

I think wifi mode 11B is the root.

tested with
WiFi.setPhyMode(WIFI_PHY_MODE_11B); ----> reconnect
WiFi.setPhyMode(WIFI_PHY_MODE_11G); ----> some(?)
WiFi.setPhyMode(WIFI_PHY_MODE_11N); ---> some(?)

https://gist.github.com/chaeplin/8ff93aedb75266d644d2

@Links2004
Copy link
Collaborator

the ADC is also used from the WiFi part to measure the internal voltage to adjust output power,
may this get problematical when the ADC is in use for too much time in the sketch.

@krzychb
Copy link
Contributor

krzychb commented Feb 16, 2016

@renno-bih,
Is it the option to add delay after taking all the samples inside 50ms window, instead of after every individual sample? After doing so I do not see reconnects. Basing on the above comment by Links2004 I believe we should periodically insert some delay into stream of continuous analogRead(A0).
analogRead-vs-WiFi.ino.txt

645 - mode : N - rssi : -75 - peakToPeak : 3 - reconected : 0
645 - mode : N - rssi : -75 - peakToPeak : 3 - reconected : 0
645 - mode : N - rssi : -74 - peakToPeak : 0 - reconected : 0
645 - mode : N - rssi : -74 - peakToPeak : 3 - reconected : 0
646 - mode : N - rssi : -74 - peakToPeak : 0 - reconected : 0
646 - mode : N - rssi : -74 - peakToPeak : 1 - reconected : 0
646 - mode : N - rssi : -74 - peakToPeak : 6 - reconected : 0
646 - mode : N - rssi : -74 - peakToPeak : 0 - reconected : 0
646 - mode : N - rssi : -73 - peakToPeak : 1 - reconected : 0
646 - mode : N - rssi : -73 - peakToPeak : 6 - reconected : 0
646 - mode : N - rssi : -73 - peakToPeak : 0 - reconected : 0

@chaeplin,
I did the testing with Wi-Fi B, G and N modes for code without delay and each time see the reconnects. I made testing with core 2.1.0-rc2. Still need to check the GitHub version.

Krzysztof

@renno-bih
Copy link
Author

@chaeplin Nice found.
@krzychb True, I don't see reconnects if I'm taking 50ms samples and make delay. But I see other problems. I'm using Websockets and I notice lot of lag when exchanging some data and random disconnects from my websocket server.
This device should run stable without making any delay in communication and without random resets. Hmmm, does it mean that I should forget using analog pin for noise measurements. Hmmm

@krzychb
Copy link
Contributor

krzychb commented Feb 18, 2016

@renno-bih,

This is great we have some break through 😄

I do not like any delays and wasted time in my sketches as well 😄
Now the question is if your application permits taking 50ms samples every 20ms (or so) instead of continuously reading A0.
If so, then instead of delay(20) just trigger them every 20ms (using a state machine).
If not then I would look for an external ADC.

Krzysztof

@renno-bih
Copy link
Author

I'm taking 3ms samples and then block analogRead for additional 3ms. (Using elapsedMillis library).
Looks like it works fine without disconnecting. Need to do some more testings to see if connection is stable.

I know that it is not the best way to detect noise level but it works reasonably good. It can detect claps :)

@krzychb
Copy link
Contributor

krzychb commented Feb 19, 2016

Oooooo! Detecting claps with ESP8266 is on my wish list.
If this is not a secret project I am offering to be a beta tester.
Krzysztof

@renno-bih
Copy link
Author

Purpose of this device is not to detect claps... But to show noise level (scale 0-100). But if it can detect claps it can detect everything else if duration of sound wave is greater than 3ms.

@krzychb
Copy link
Contributor

krzychb commented Mar 4, 2016

@renno-bih,

I did some more testing and now reading A0 every 1ms.

Data transmission for display in browser is done using web sockets by Links2004 (they are working great – thanks, @Links2004 👍). Also at any moment I can trigger continuous sampling of A0 for the period up to 60ms. That produces up 720 samples. Longer sampling creates issues so I need to reconnect web sockets (Wi-Fi connection is not dropped).

This application works very stable on ESP clocked at 80MHz or 160MHz but web sockets run faster at 160MHz. Another observation is that web sockets are processed faster in Internet Explorer than Google Chrome (both tested on Windows 7). FireFox on Ubuntu 14.04 LTS is almost as fast as IE. After connecting a microphone I can easy visualize 1 KHz sinusoid “on-line” in a web browser. Picture below shows taking and displaying about 110 A0 samples about every 41 ms or so. In this example sampling in ESP takes 10ms, the rest is for sending sample request from web browser to ESP, transmission back and displaying in browser.

I can post this application if anybody is interested.

Krzysztof

screenshot from 2016-03-04 17_51_04

@lrmoreno007
Copy link
Contributor

lrmoreno007 commented Mar 4, 2016

Yes! I'm very interested in sample to learn websocket.

Thanks in advance.

@krzychb
Copy link
Contributor

krzychb commented Mar 4, 2016

@renno-bih,

Here is a short manual 😉

Prepare the following s/w components:

  1. Arduino Sketch: WebSocket-Scope.ino
    WebSocket-Scope.zip
  2. WebSockets library by Links2004 - https://github.com/Links2004/arduinoWebSockets. The easiest way to go is installing WebSockets rev. 2.0.0 using Library Manager from Arduino IDE
  3. HTML web page WebSocket-Scope.html that should be saved on a PC in any folder to be then opened in a web browser. No web server is required.
    WebSocket-Scope.zip
  4. CanvasJS JavaScript library v1.8.0 GA – downloaded free from http://canvasjs.com/. From the compressed package you need only one file canvasjs.min.js that should be placed in the same folder as WebSocket-Scope.html. This library is already included in the above zipped folder. I believe this is great, fast and really very well documented application for on-line data visualization in a web browser. I am not sure how I missed it before. Somehow I was not aware that this library can display hundreds of data points in a dozen or so milliseconds 👍

To make it run:

  1. Upload WebSocket-Scope.inoto your ESP module. I have been using Arduino IDE 1.6.7 together with ESP platform package 2.1.0
  2. Check on Serial Monitor if module joined Wi-Fi network and check assigned IP address
  3. Open WebSocket-Scope.html in a web browser. I have tested this application on Windows 7 using IE 11 and Google Chrome 48.0 as well as on Ubuntu 14.04 LTS with FireFox 44.0
  4. Update IP address of your ESP under Host:
  5. Press Connect button
  6. Web browser should establish connection with ESP and start requesting A0 samples
  7. If communication is working you can then adjust number of requested samples using the Sample Size slider
  8. Using Threshold slider you can adjust A0 level to trigger sampling. Keep it below noise level if you like to see continuous sampling.

What you should see:

  1. Samples of A0 are displayed in chart ESP8266 Analog Input Scope at the top
  2. Transmission statistics is displayed on chart Web Socket Throughput at the bottom left
  3. At bottom right you should see sliders to adjust Sample Size and Threshold. Below is Communication Diagnostics that is showing individual data being received from ESP8266, connection status and message size, etc.

Have fun making it run and let me know if it works for you 😄

Krzysztof

@renno-bih
Copy link
Author

Great @krzychb ...
I've just tried your sketch and works great without any disconnects. It is great to see that ESP can achieve this :)

Thank you for this guide.

@krzychb
Copy link
Contributor

krzychb commented Mar 10, 2016

@renno-bih,
Thank you for checking this application and bringing good news!
Krzysztof

@igrr
Copy link
Member

igrr commented Jun 23, 2016

Closing this per OP comment.
I think it would be awesome to add this scope as an example sketch.

@igrr igrr closed this as completed Jun 23, 2016
@krzychb
Copy link
Contributor

krzychb commented Jul 4, 2016

@igrr I have missed your comment
I will be happy to prepare and add this scope as an example sketch.

@williamesp2015
Copy link

@krzychb your done well!!!!. Do you have an example like this scope for Websocket Server or embed the HTML into the ESP8266 not separate files?

@krzychb
Copy link
Contributor

krzychb commented Jul 6, 2016

Thanks @williamesp2015 😄
An example with HTML embedded into the ESP8266 / not separate files, is on my To Do list.
I am planning to prepare it this week-end.

@williamesp2015
Copy link

@krzychb I would be very grateful. A websocket Client+Server could have OTA+web page+web server control, SSID&Password& sampling rate configuration, and Analog data monitor.

@krzychb
Copy link
Contributor

krzychb commented Jul 11, 2016

@williamesp2015,

This is strange, as I have developed and tested this application with PlatformIO IDE (I believe the latest IDE 1.3.0). Then I have also tested it Arduino IDE 1.6.9.

Later today I will update readme.md with exact versions of IDEs and libraries used.

Just to double check, have you upload the data folder / SPIFFS to your ESP module?

@williamesp2015
Copy link

@krzychb Yes, I didn't know about upload spiffs and after upload the page appears after call the IP but disconnected once I click on connect.
I prepared instruction for PlatformIO:
Uploading files to file system SPIFFS in PlatformIO:
1- copy data directory in the PlatformIo project same level of scr directory
2- build and upload the main project
3- click F7 or go to Run other Target and select PlatformIO:Upload SPIFFS image
and wait to complete

@krzychb
Copy link
Contributor

krzychb commented Jul 11, 2016

@williamesp2015,

Thanks for update regarding SPIFFS.

I have added:

Please check if you were following the same procedure and used the same s/w. Application should start automatically after opening module's IP address in a web browser, without pressing "Connect" button. Later I will verify how it works on Ubuntu 14.04 LTS.

@williamesp2015
Copy link

@krzychb Sorry, after successful connection and open the IP in the browser, disconnected immediately and if I change analogsample function to just get sample and wait 1 millisecond, after few second disconnected and noting displayed.

@krzychb
Copy link
Contributor

krzychb commented Jul 12, 2016

@williamesp2015,

No problem, this is likely some easy to fix issue.
Following this list please confirm what are the exact s/w names and versions you are using:

  1. Arduino Core
  2. Libraries
  3. Programming IDE
  4. Web Browser

@williamesp2015
Copy link

@krzychb my IDE is PlatformIO and I installed ten days ago.
PlatformIO version 1.8.0 (latest version) IDE:1.3.0 CLI:2.11.0
web browser tested with chrome, Internet Explorer and Microsoft Edge with Updated framework-arduinoespressif package. I don't konw which Arduino Core it is using.

@krzychb
Copy link
Contributor

krzychb commented Jul 12, 2016

@williamesp2015,

The s/w releases look OK at the first glance. I have couple of questions:

  1. Do you see any page in a web browser once you enter IP address of ESP module? Could you post a screenshot?

  2. What is shown on serial terminal of ESP once you start it and open it's IP in web browser?

  3. Could you open PlatformIO terminal (icon like [>_]) and type platformio platforms show espressif ? This should show something like:

    ----------
    Package: toolchain-xtensa
    Alias: toolchain
    Version: 2
    Installed: 2016-05-02 12:19:25
    ----------
    Package: tool-esptool
    Alias: uploader
    
    Version: 7
    Installed: 2016-07-11 16:01:53
    ----------
    Package: framework-arduinoespressif
    Alias: framework
    Version: 13
    Installed: 2016-07-11 16:02:01
    ----------
    Package: ldscripts
    Version: 23
    Installed: 2016-07-11 16:02:02
    

    Could you post what is shown for you?

  4. What is your Internet Explorer version?

  5. What is your Windows version?

Krzysztof

EDIT:
Please open an issue under https://github.com/krzychb/EspScopeA0 and post your reply there.
I think I am going off topic in this thread.

@Nakul93
Copy link

Nakul93 commented Mar 13, 2018

Is there a solution to this problem, I am also trying to read analog values then send this data to internet using wifi, even after putting 100ms delay it hangs after 15-20 mins.

@krzychb
Copy link
Contributor

krzychb commented Mar 13, 2018

Hi @Nakul93,

The solution is not to exceed the average sampling rate.
To avoid dripping connections at all (because of using A0), do not take more than 200 samples in a single continuous shoot.

Please see the conclusion of an analysis I made some time ago - https://github.com/krzychb/EspScopeA0/tree/master/Bravo#results

@woutput
Copy link

woutput commented Oct 19, 2019

Sorry to comment on an old and closed thread, but I still run into the same fundamental problem: running analogRead(A0) at full speed gives problems. Can't we solve this properly? For example by returning a cached value (instead of reading from the ADC again) to never sample the ADC too often. This solution is backwards compatible with existing code.
What do you think?

@cstanke
Copy link

cstanke commented Nov 26, 2019

FWIW, I encountered this issue recently using esp8266 Arduino Core 2.6.1 with Digistump Oak while reading a photocell. It took most of a workday to get my head around what was actually happening. Thankfully, enough people have had this problem that I found anecdotal help easily.

In any case, I couldn't read at full loop speed (at 80MHz CPU freq) without WiFi problems but I found that a mere 2 millisecond delay between analogRead calls sufficed to solve the issue without adversely affecting performance of my main functionality.

@usane1
Copy link

usane1 commented Mar 26, 2020

I have the same issue on NodeMCU with the latest core(2.6.3). Is there any solution?

@joba-1
Copy link

joba-1 commented Aug 1, 2020

Just spent a day to find the relation between broken wifi and analog reads.
And then 10 more minutes to find and verify this thread helps: Thank you!

I wonder what is actually required to make it work always, not just empirically find sufficiently long delays in sufficiently short intervals.

Couldn't this be built into the core? I only do one analog read per loop, so plenty of opportunity for the core to step in to do the needful in the code that calls loop() without any explicit delays.

@JAndrassy
Copy link
Contributor

Just spent a day to find the relation between broken wifi and analog reads.
And then 10 more minutes to find and verify this thread helps: Thank you!

I wonder what is actually required to make it work always, not just empirically find sufficiently long delays in sufficiently short intervals.

Couldn't this be built into the core? I only do one analog read per loop, so plenty of opportunity for the core to step in to do the needful in the code that calls loop() without any explicit delays.

see it this way. esp8266 is a WiFi coprocessor intended to work with a host MCU. everything else wasn't planed.

@bodgit
Copy link

bodgit commented Apr 14, 2021

Just ran into this problem; I couldn't work out why I couldn't see the AP provided by the ESP. Caching the result of analogRead() for 10 or so milliseconds seems to have helped and now the WiFi has sprung into life again. This should at least be documented somewhere (ideally in big bold letters in the WiFi section) as it's not at all obvious why the WiFi doesn't work.

@robjmort
Copy link

I've just come across this problem too. The frequency of calling analogRead is not a problem up to 4 or so kHz, but it is the length of time from start that is the limiting factor for me. Even at a low sampling rate of less than 1kHz, the wifi drops out at the same time of about 10secs.

Bodgit - what do mean by "Caching the result of analogRead() ..............."?

@bodgit
Copy link

bodgit commented Feb 14, 2022

@robjmort all I did was store millis() when I called analogRead(), then the next time around, if millis() hadn't increased by enough, rather than call analogRead() again I just returned the previous value. Ultimately I swapped to using an I2C-attached ADC and stopped trying to use the built in analog input.

@robjmort
Copy link

OK thanks. I need to sample the ADC at a constant 2 kHz which the ESP8266 does well using the timer as an interrupt, but the wifi drops out after 10s and so far I haven't found a solution.

@simmonsm
Copy link

just spent hours trying to figure why the wifi stopped working and thankfully found this page. A deal breaker for sound processing application I trying on Lolin NodeMCU V3 at 80MHz as I can only keep wifi if the last analogRead was >= 3ms ago.

@robjmort
Copy link

I eventually used a seperate ESP8266 to handle the wifi.

@simmonsm
Copy link

I've just noticed that there is a 160MHz option for this board in the Arduino IDE but don't know whether that would help or be stable. In any case I suspect you are doing the right thing.

@DrJaymz
Copy link

DrJaymz commented Jan 2, 2023

I'm very very late to the party, but I just found this page whilst trying to debug my problem.
kept seeing ap_probe_send over, rest wifi status to disassoc then got kicked off the wifi and couldn't get back on.

Long story short you cannot do repeated successive analogReads on the esp8266. If you do it looses wifi.
So my main loop has various things that happen every 1000ms every 100ms and stuff that happens every loop. I moved an analogue read into the every loop and it went all screwy. And that has taken me best part of 3 hours to figure out - because it doesn't seem related to it at all.

I have a the NTP class running in the background and I noticed it was having trouble reading the time, getting stuck on 1970 when it normally picks it up before you even see a debug message so basically that was a clue that the main loop was jamming everything up!

UPDATE: Again probably everyone knows this but it turns out that the ADC is used for evaluating the WiFi signal strength - and its when you put too many reads in a row then wifi breaks and because its probably in your main loop once it breaks it doesn't tend to work again until reboot.

@Frank-Bemelman
Copy link

Frank-Bemelman commented May 22, 2023

Ok, this bit me too, and happy to find this page, saved me a lot of time just to know this is an issue.

I did a quick and dirty fix, in my case to read a simple potentiometer value for a dimmer function.

void loop()
{
if((millis()%50)==0) {
DimmerInputVal = analogRead (A0);
}
// more stuff
}

So now it reads the analog port only every 50ms. Which is plenty enough in my case.

Thanks & cheers!
Frank

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.