Arduino icon indicating copy to clipboard operation
Arduino copied to clipboard

External interrupt is delaying after a while

Open fpalarminiscenario opened this issue 3 years ago • 13 comments

Basic Infos

  • [x] This issue complies with the issue POLICY doc.
  • [x] I have read the documentation at readthedocs and the issue is not addressed there.
  • [ ] I have tested that the issue is present in current master branch (aka latest git).
  • [x] I have searched the issue tracker for a similar issue.
  • [x] If there is a stack dump, I have decoded it.
  • [x] I have filled out all fields below.

Platform

  • Hardware: [ESP-12]
  • Core Version: [2.6.3]
  • Development Env: [PlatformIO]
  • Operating System: [Linux Mint]

Settings in IDE

  • Module: [Generic ESP8266 Module]
  • Flash Mode: [dio]
  • Flash Size: [4MB]
  • lwip Variant: [Higher Bandwidth]
  • Reset Method: [nodemcu]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [80Mhz]
  • Upload Using: [OTA]

Problem Description

I'm having a trouble with external interrupt measuring zero cross in AC 60 Hz. In high level, my trouble is that my lamp after a while turn off per 2 seconds and turn on again. The frequency for this problem to occur is variable, so 3 times per day, twice/day, sometimes working two days consecutive without problem. I am monitoring the problem over osciloscope and I captured the image below:

20221123_085751 Line yellow: hardware zero cross Line green: LED inverting each zero crossing (60 Hz - frequency, 16,666 ms - period)

It seems that my ISR keeps accumulating and after a while releases a bunch of execution at once. I already got this same problem with software timer. I think this problem is because some task in wifi is harding and the priority wifi is high over external interrupt. Someone has any idea about the solution to this problem? I tried include noInterrupts() and interrupts() inside my ISR but it isn't successfull. Thanks folks

MCVE Sketch


#include <Arduino.h>

bool flagInvert{false};

static void ICACHE_RAM_ATTR ZeroCrossISR(void)
{
    noInterrupts();
    digitalWrite(2, flagInvert);
    flagInvert ^= 1;
    // some logical that isn't relevant to problem
    interrupts();
}

void setup() {
    pinMode(5, INPUT);
    pinMode(2, OUTPUT);
    attachInterrupt(5, ZeroCrossISR, FALLING);
    WiFi.setSleepMode(WIFI_NONE_SLEEP);
    WiFi.begin("MY_SSID", "MY_PASS");
}

void loop() {

}

fpalarminiscenario avatar Nov 25 '22 13:11 fpalarminiscenario

Your code is wrong, you're always setting the same value without changing it.

Flole998 avatar Nov 27 '22 15:11 Flole998

Your code is wrong, you're always setting the same value without changing it.

Sorry, I wrote on the fly here, but the correct is:

#include <Arduino.h>

bool flagInvert{false};

static void ICACHE_RAM_ATTR ZeroCrossISR(void)
{
    noInterrupts();
    digitalWrite(2, flagInvert);
    flagInvert ^= 1;
    // some logical that isn't relevant to problem
    interrupts();
}

void setup() {
    attachInterrupt(5, ZeroCrossISR, FALLING);
}

void loop() {

}

fpalarminiscenario avatar Nov 28 '22 15:11 fpalarminiscenario

@fpalarminiscenario - It also looks like you missed setup calls to pinMode. Details are fuzzy to me, I believe with core version 2.6.3 the SDK may use previously saved WiFi credentials unless you have additional code to prevent that. With the current core, the sketch would default to WiFi off.

mhightower83 avatar Nov 28 '22 15:11 mhightower83

@fpalarminiscenario - It also looks like you missed setup calls to pinMode. Details are fuzzy to me, I believe with core version 2.6.3 the SDK may use previously saved WiFi credentials unless you have additional code to prevent that. With the current core, the sketch would default to WiFi off.

Yes, I omitted simple code like pinMode and WiFi.begin because I believe this isn't relevant to the main problem that is strange behaviour on external interrupt...

fpalarminiscenario avatar Nov 28 '22 17:11 fpalarminiscenario

This is only to demonstrate the device running correctly: 20221128_151752 And sometimes, this problem occur, as if the ISR kept accumulating: 20221123_085751

And, after around 2 seconds, the ISR is stable again

fpalarminiscenario avatar Nov 28 '22 18:11 fpalarminiscenario

In sketch pinMode is very important. If you don't set pinMode correctly your sketch don't work fine.

On Mon, 28 Nov 2022, 19:28 fpalarminiscenario, @.***> wrote:

This is only to demonstrate the device running correctly: [image: 20221128_151752] https://user-images.githubusercontent.com/67068566/204351593-f44e29c1-67c0-41d7-af6b-9684948194bb.jpg And sometimes, this problem occur, as if the ISR kept accumulating: [image: 20221123_085751] https://user-images.githubusercontent.com/67068566/204352300-a807bdb7-adb0-4a57-8c1f-675f2ebc0eee.jpg

— Reply to this email directly, view it on GitHub https://github.com/esp8266/Arduino/issues/8730#issuecomment-1329551728, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIPMDFE6P6PUEUVNTYRULQTWKT2TBANCNFSM6AAAAAASLKBKM4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Bighoneypot avatar Nov 28 '22 18:11 Bighoneypot

In sketch pinMode is very important. If you don't set pinMode correctly your sketch don't work fine.

Ok, I updated the code. But, how I said, this isn't relevant to the problem.

fpalarminiscenario avatar Nov 28 '22 18:11 fpalarminiscenario

this isn't relevant to the problem.

We can't know, or whether that you have tried and dismissed at as irrelevant. Discussion about what's relevant and what's not is another side effect of omitting certain parts:)

I'd suggest to look at WiFi state first, as mentioned in the https://github.com/esp8266/Arduino/issues/8730#issuecomment-1329337477 You'll have to use 4.x.x platform instead of 2.6.3

mcspr avatar Nov 28 '22 19:11 mcspr

I'd suggest to look at WiFi state first, as mentioned in the #8730 (comment) You'll have to use 4.x.x platform instead of 2.6.3

4.x.x? The latest version is 3.0.2, isn't? Or this version that you mentioned isn't core version?

Ok, I will update, but I didn't want to update without know the root of problem. I saw this same problem with software timer, so, I thought that more people had this problem. But, as nobody had this problem, I think the latest version won't work.

fpalarminiscenario avatar Nov 28 '22 19:11 fpalarminiscenario

We can't know, or whether that you have tried and dismissed at as irrelevant. Discussion about what's relevant and what's not is another side effect of omitting certain parts:)

Yes, indeed, but as the problem is involving external interrupt, and to setup a interrupt I need only attachInterrupt and one callback, so I think there is nothing more that can affect the interrupt or has? This is what I want to know. I can rely on timing external interrupt or some task can damage my time precision on interrupt?

fpalarminiscenario avatar Nov 28 '22 19:11 fpalarminiscenario

Software timer is not itself an interrupt, if you mean Ticker / ets_timer. Underlying TIMER peripheral will trigger one, yes, to notify about it's expiration but the execution itself happens in SDK aka SYS task.

WiFi driver can spend a lot of time doing things. e.g. WiFi begin() and a simultaneously started very short timer for 100ms could instead end up executing in ~1sec b/c WiFi is doing some kind of work. Pin interrupt is prone to masking or locking by anyone, you might have better time setting up TIMER1 and periodically reading the pin state.

Not using latest version we run into a problem not reliably testing things yet again. Including our change to WiFi, which you missed out on


PlatformIO uses overarching 'platform' that contains framework, toolchain, upload tools and etc. See PACKAGES when building for Core version translated to our versioning scheme from theirs.

mcspr avatar Nov 28 '22 20:11 mcspr

Pin interrupt is prone to masking or locking by anyone, you might have better time setting up TIMER1 and periodically reading the pin state.

Ok, I already use hardware timer triggering triac, but I also thought this approach to read pin on my hardware timer, this will spend a considered time to adequate my source code but maybe it is the only way...

fpalarminiscenario avatar Nov 28 '22 20:11 fpalarminiscenario

I used to have a similar problem

the problem is related to the threshold voltage value that an ISR could be fired

So the problem basically is your ISR is being fired multiple times at the same falling edge

the solution is to add a _NOP() loop for a tiny amount of time let's say for 500 iterations

OR to disable the external interrupt and re-enable it in your loop code

abdosn avatar Feb 16 '25 16:02 abdosn