Mark McGinty
Mark McGinty

Reputation: 756

Interrupt during network I/O == crash?

It seems that when an I/O pin interrupt occurs while network I/O is being performed, the system resets -- even if the interrupt function only declares a local variable and assigns it (essentially a do-nothing routine.) So I'm fairly certain it isn't to do with spending too much time in the interrupt function. (My actual working interrupt functions are pretty spartan, strictly increment and assign, not even any conditional logic.)

Is this a known constraint? My workaround is to disconnect the interrupt while using the network, but of course this introduces potential for data loss.

function fnCbUp(level)
    lastTrig = rtctime.get()
    gpio.trig(pin, "down", fnCbDown)
end

function fnCbDown(level)
    local spin = rtcmem.read32(20)
    spin = spin + 1
    rtcmem.write32(20, spin)
    lastTrig = rtctime.get()
    gpio.trig(pin, "up", fnCbUp)
end

gpio.trig(pin, "down", fnCbDown)
gpio.mode(pin, gpio.INT, gpio.FLOAT)

branch: master

build built on: 2016-03-15 10:39

powered by Lua 5.1.4 on SDK 1.4.0

modules: adc,bit,file,gpio,i2c,net,node,pwm,rtcfifo,rtcmem,rtctime,sntp,tmr,uart,wifi

Upvotes: 3

Views: 3803

Answers (2)

Mickbaer
Mickbaer

Reputation: 11

I have nearly the same problem. Running ESP8266Webserver, using GPIO14 Interrupt, with too fast Impulses as input , the system stopps recording the interrupts. Please see here for more details.

http://www.esp8266.com/viewtopic.php?f=28&t=9702

I'm using ARDUINO IDE 1.69 but the Problem seems to be the same. I used an ESP8266-07 as generator & counter (without Webserver) to generate the Pulses, wired to my ESP8266-Watersystem.

The generator works very well, with much more than 240 puls / sec, generating and counting on the same ESP.

But the ESP-Watersystem, stops recording interrupts here at impuls > 50/ second:

/*************************************************/

/*  ISR Water pulse counter                      */

/*************************************************/

/**

 * Invoked by interrupt14 once per rotation of the hall-effect sensor. Interrupt

 * handlers should be kept as small as possible so they return quickly.

 */


 void ICACHE_RAM_ATTR pulseCounter()

    {

      // Increment the pulse Counter

      cli();

      G_pulseCount++;

     Serial.println ( "!" );

     sei();

    }

The serial output is here only for showing whats happening. It shows the correct counted Impuls, until the webserver interacts with the network. Than is seams the Interrupt is blocked.(no serial output from here) By stressing the System, when I several times refresh the Website in an short time, the interrupt counting starts for an short time, but it stops short time again.

The problem is anywhere along Interrupt handling and Webservices. I hope I could help to find this issues.

Interessted in getting some solutions. Who can help?

Thanks from Mickbaer Berlin Germany Email: [email protected]

Upvotes: 1

Marcel Stör
Marcel Stör

Reputation: 23535

Not sure if this should be an answer or a comment. May be a bit long for a comment though.

So, the question is "Is this a known constraint?" and the short but unsatisfactory answer is "no". Can't leave it like that...

Is the code excerpt enough for you to conclude the reset must occur due to something within those few lines? I doubt it. What you seem to be doing is a simple "global" increment of each GPIO 'down' with some debounce logic. However, I don't see any debounce, what am I missing? You get the time into the global lastTrig but you don't do anything with it. Just for debouncing you won't need rtctime IMO but I doubt it's got anything to do with the problem.

I have a gist of a tmr.delay-based debounce as well as one with tmr.now that is more like a throttle. You could use the first like so:

GPIO14 = 5
spin

function down()
    spin = spin + 1
    tmr.delay(50)                    -- time delay for switch debounce
    gpio.trig(GPIO14, "up", up)      -- change trigger on falling edge
end

function up()
    tmr.delay(50)
    gpio.trig(GPIO14, "down", down)  -- trigger on rising edge
end

gpio.mode(GPIO14, gpio.INT)          -- gpio.FLOAT by default
gpio.trig(GPIO14, "down", down)

I also suggest running this against the dev branch because you said it be related to network I/O during interrupts.

Upvotes: 1

Related Questions