2

I'm planning to use an ESP8266 (Wemos D1 Mini) to use as a software SPI monitor to send over WiFi.

As a test, I've done a cut-down sketch that just counts the interrupts, a simple frequency counter. I've made it as simple as possible but it won't stay connected to WiFi and crashes after about 10 seconds.

The input signal to CLKPin is 6667 Hz.

Here's the sketch:

#include <ESP8266WiFi.h>
const char* ssid = "SSID";
const char* password = "PASSWORD";
long nextPrint = 1000; // when to print the next message to serial
const int CLKPin = 5; // Pin connected to CLK
volatile long ClkCount = 0; // number of times clock interrupt has fired
void CLK_ISR() {
 ClkCount++;
}
void setup() {
 Serial.begin(115200);
 long startTime = millis();
 WiFi.begin(ssid, password); // Connect to the network
 Serial.print("Connecting to ");
 Serial.print(ssid); Serial.println(" ...");
 while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
 delay(500);
 Serial.print(".");
 }
 Serial.println("\nConnected to wifi");
 attachInterrupt(CLKPin, CLK_ISR, RISING);
 //Set the CLK-pin to input
 pinMode(CLKPin, INPUT);
}
void loop() {
 if (millis() > nextPrint) {
 Serial.print("Freq is: ");
 Serial.println(ClkCount);
 ClkCount = 0;
 nextPrint += 1000;
 }
 yield();
}

It always gets in a reboot/crash loop (no idea why the first few counts are wrong - I guess the ESP isn't ready yet):

Connecting to SSID ...
.Connected to wifi
Freq is: 1
Freq is: 1
Freq is: 0
Freq is: 0
Freq is: 1
Freq is: 0
Freq is: 2313
Freq is: 6667
Freq is: 6666
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Freq is: 6667
Exception (0):
epc1=0x40202034 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
ctx: sys 
sp: 3ffffc40 end: 3fffffb0 offset: 01a0
>>>stack>>>
3ffffde0: 401067da 00000026 00000000 00000001 
3ffffdf0: c0017025 3ffe8d04 3ffee188 00000001 
3ffffe00: 00000003 00000008 3ffee99c 00000022 
3ffffe10: 3fffc200 401067a0 3fffc258 4000050c 
3ffffe20: 40004384 00000030 00000012 ffffffff 
3ffffe30: 60000200 00000006 30043003 80000000 
3ffffe40: 20000000 3fff0c38 80000000 203fc120 
3ffffe50: 00000000 3fffc6fc 00000001 3fff0c3c 
3ffffe60: 00000154 003fc120 60000600 00000030 
3ffffe70: 40106845 00000080 00000022 3fffc200 
3ffffe80: c0017025 3fffc258 4000050c 00000022 
3ffffe90: 3fffc200 401067a0 3fffc258 00000022 
3ffffea0: 3fffc200 401067a0 3fffc258 4000050c 
3ffffeb0: 40202b20 00000030 00000012 ffffffff 
3ffffec0: 40000f49 3ffee9e8 00000000 3fffd9d0 
3ffffed0: 00000000 00000000 00000000 fffffffe 
3ffffee0: ffffffff 3fffc6fc 00000001 3fffdab0 
3ffffef0: 00000000 3fffdad0 3ffee9e8 00000030 
3fffff00: 3ffee99c 0000000a 3ffe8bc8 402094cc 
3fffff10: 00000000 400042db 3ffeff84 40104580 
3fffff20: 40004b31 3fff0b84 000001f4 003fc080 
3fffff30: 40105aac 000001f4 3ffed190 401004f4 
3fffff40: 40106e4d 3fff0b84 00000000 00f8676f 
3fffff50: 3ffe8bc8 3ffe8d04 3ffed190 40224d02 
3fffff60: 40223d49 40223d52 3ffed004 3ffee1b0 
3fffff70: 40228445 3ffed004 3ffee1b0 00f857fe 
3fffff80: 4022848a 3fffdab0 00000000 3fffdcb0 
3fffff90: 3ffee1c8 3fffdad0 3ffee9e8 40202b43 
3fffffa0: 40000f49 40000f49 3fffdab0 40000f49 
<<<stack<<<
 ets Jan 8 2013,rst cause:2, boot mode:(1,6)
 ets Jan 8 2013,rst cause:4, boot mode:(1,6)
wdt reset

What am I doing wrong, or is it just not possible to stay connected to WiFi while using interrupts on an ESP8266?

ocrdu
1,7953 gold badges12 silver badges24 bronze badges
asked Dec 21, 2020 at 11:53
8
  • Does it still crash if you reduce your CLKPin rate from 6667Hz to something lower? The reason I ask is that I'm not sure what the maximum interrupt rate the ESP8266 but you may be exceeding it. The error is a "wdt reset" which means that you have done something to prevent the watchdog timer from being cleared and so it generated a reset. Commented Dec 21, 2020 at 12:25
  • 1
    If you want to get the time difference of the last counter reset and the actual millis() value then nextPrint += 1000; is nonsense. Use nextPrint = millis() + 1000; if you need to capture the ClkCount for an interval of a second. I'm pretty sure that's the reason for the low values at the beginning. In addition to what @jwh20 said: I'm not convinced that the Watchdog is the cause, I think another Error (perhaps caused by the WIFI lib) crashed the ESP and then the Watchdog did it's job and performed a reset. But it's a guess, jwh20 might be right, so try what he/she wrote. Commented Dec 21, 2020 at 14:47
  • Just tested, and it did stay connected at 5kHz for 15 mins when I stopped testing. Unfortunately I'm not sure if that'll be fast enough for my application. I still would like to know if there's anything I can do to keep the WiFi connected. I don't really mind about missing data but I need the WiFi to stay connected. I hoped that yield() would work. Commented Dec 21, 2020 at 15:01
  • @PeterPaulKiefer I didn't put much thought into getting accurate data for this test, I was just testing if the interrupts would work and stay connected to WiFi, so that timer code is just the first thing that came to mind. Commented Dec 21, 2020 at 15:04
  • What I suspect is going on, but have never tried this myself on an ESP8266, is that you are interrupting so often that the WiFi can't work properly and it disconnects. I'm not sure if you can do what you are trying to do with an 8266. Have you looked at an ESP32? These have a dual-core CPU so you can handle the WiFi on one processor and handle your interrupts on the other. Commented Dec 21, 2020 at 16:18

2 Answers 2

1

Yes possible, but the ESP8266 only has one core and one set of peripherals. WiFi uses time, interrupts, and even the ADC peripheral, and maybe more.

This is why anything timing-critical, or time-intensive, is a pain to get to work properly on an ESP8266. It depends one what you are trying to do, of course, and also on if you can unload what you want to a peripheral the WiFi doesn't use, or if switching off WiFi is an option during parts of your code.

Generally, for applications such as yours, I would get an ESP32 or an Arduino Nano 33 IoT or any other solution that has a core for handling WiFi, and a core for you to use without restrictions. It makes development a more pleasant experience.

If, for some reason, you are bound to using an ESP8266, you would have to be more specific about what your eventual goal is; maybe a workaround can be found.

answered Dec 21, 2020 at 16:41
3
  • 1
    could also use a 2nd ESP8266 w/ wifi disabled, they are cheap, and w/o wifi, very fast and responsive. Commented Dec 21, 2020 at 21:18
  • 1
    Honestly I think ESP8266 is a poor choice for most things except wifi. PWM is flaky, it has no waking from sleep on external interrupt, and relatively high power usage compared to, eg STM32 or AVR. The only thing it's really good for is WiFi and large flash storage. Yes it could be an option in some circumstances, but two won't fit in the application I'm planning for right now. Commented Dec 22, 2020 at 3:29
  • 1
    @localhost fair nuf, I most like the cost and cpu/ram. Tbf, those issues are better w/o wifi; stable pwm, lower power, quick reboots. Commented Dec 22, 2020 at 9:04
1

I found the solution on another forum.

You need to add the ICACHE_RAM_ATTR attribute to the interrupt so it stays in cache.

void ICACHE_RAM_ATTR CLK_ISR() {
 ClkCount++;
}

Now:

Freq is: 332596 - connected for 680s, operating at 160MHz

That's all I tested to, but 330kHz is a bit better than crashing at 7kHz, lol!

edit: I've discovered that it now crashes after exactly 1200s (20mins), repetitively.

I'm still investigating why, but I believe that it's some kind of watchdog timer.

answered Dec 28, 2020 at 5:27

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.