External interrupts, different behavior between Arduino and MicroPython

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
donVictorio
Posts: 3
Joined: Sun Oct 18, 2020 4:20 pm
Location: Poland, Cracow

External interrupts, different behavior between Arduino and MicroPython

Post by donVictorio » Sun Oct 18, 2020 5:11 pm

Hi,

I use ESP8266 NodeMcu V3 board and built circuit similar to this one https://i.ytimg.com/vi/eFeOSiL-IBQ/hqdefault.jpg
At the beginning I tried to count "frequency"
In code bellow i expected -/+ 100 ticks per second (50Hz), but I got 200-208.

Code: Select all

import micropython
micropython.alloc_emergency_exception_buf(100)    

import machine
import time
from machine import Pin

counter = 0

def handler(pin):
    global counter
    counter += 1
    
pin = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP)
pin.irq(trigger=Pin.IRQ_RISING, handler=handler)

while (True):
    time.sleep_ms(1000)
    print(counter)
    counter = 0
I created similar C++ code and the same circuit works as expected.

Code: Select all

int counter = 0;

void setup() {
  Serial.begin(115200);   
  pinMode(12, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(12), zcDetect, RISING);
}

void loop() {
    delay(1000);
    Serial.println(counter);
    counter = 0;
}

ICACHE_RAM_ATTR void zcDetect() {
  counter += 1;
}

Why is that?
Any suggestions?

User avatar
Roberthh
Posts: 2177
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: External interrupts, different behavior between Arduino and MicroPython

Post by Roberthh » Sun Oct 18, 2020 5:48 pm

On ESP8266 with MicroPython I have seen multiple trigger at slow ramps. That could happen here. So you have to either increase the slope of the signal, e.g. with a schmitt-trigger gate, or you could try to clear the second interrupt in the ISR. In my application I choose the second way (see code below). But that might not work in your case, if the slope is too slow.

Code: Select all

#
# Clear Interrupt status
#
@micropython.viper
def clear_isr(mask: int):
    ptr32(0x60000324)[0] = mask
It was called with
clear_isr(0x20) # clear interrupt mask of Pin(5)
You have to change the 0x20 value according to the pin you use.

donVictorio
Posts: 3
Joined: Sun Oct 18, 2020 4:20 pm
Location: Poland, Cracow

Re: External interrupts, different behavior between Arduino and MicroPython

Post by donVictorio » Mon Oct 19, 2020 5:23 pm

Thank you for your suggestion Roberthh.

Before I posted this topic, I had read and followed your suggestion from this one viewtopic.php?f=2&t=6840#p38861 clearing the second interrupt. But result was the same.
In the end of the "handle routine" when I call clear_isr there is no "waiting" interrupt.

I measure time in microseconds between each call and receive results like this:
call no|result
1|
2|9580
3|238! (this should not take place)
4|9790
5|211! (this should not take place)

I expected :
1|
2|9580
3|9790
It is "crossing zero" interval for 50hz.

And this is what i get using Arduino C++ code.
This is something that puzzles me.

Right now i don't have possibilities to test it using "Schmitt-Trigger gate"

User avatar
pythoncoder
Posts: 4575
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: External interrupts, different behavior between Arduino and MicroPython

Post by pythoncoder » Tue Oct 20, 2020 6:06 am

I wonder if this would best be done using polling. The idea being that you respond to the first transition on the line and ignore the rest. Pseudocode:

Code: Select all

while True:
    wait for pin to assume ON state
    t = ticks_ms()  # Get run time.
    wait for correct phase (ensure < 10ms)
    trigger output
    trun = ticks_diff(ticks_ms, t)
    if trun < 7:
        sleep_ms(7 - trun)  # Now nearing end of half cycle
Here I'm measuring run time but another option may be to calculate it.

It's perhaps worth noting that ESPx aren't the best platforms for applications requiring ms level timing.
Peter Hinch

donVictorio
Posts: 3
Joined: Sun Oct 18, 2020 4:20 pm
Location: Poland, Cracow

Re: External interrupts, different behavior between Arduino and MicroPython

Post by donVictorio » Tue Oct 20, 2020 2:50 pm

Thanks for yours suggestions.

Over last few days i tried to solve this problem using software approach by codding, flashing ect... without any success.
Finally inspired by Roberthh i created hardware solution based on NPN

... but i still dont know why the same circuit behaves differently, driven by C ++ and MicroPython

User avatar
pythoncoder
Posts: 4575
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: External interrupts, different behavior between Arduino and MicroPython

Post by pythoncoder » Wed Oct 21, 2020 10:53 am

Nor do I. But slow signals on interrupt pins are a bad idea on any hardware. At the very least the outcome will be sensitive to electrical noise.
Peter Hinch

Post Reply