ExtInt not working properly

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: ExtInt not working properly

Post by dhylands » Sat Jan 27, 2018 5:49 am

Your callback didn't declare data to be global, so it sets a local variable called data which goes out of scope as soon as the callback exits.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: ExtInt not working properly

Post by nikhiledutech » Sat Jan 27, 2018 7:00 am

I have corrected that mistake and still its not able to display on LCD.

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

Re: ExtInt not working properly

Post by pythoncoder » Sat Jan 27, 2018 7:09 am

@nikhiledutech I've now had time to investigate this properly. The trigger() method of the Delay_ms class does allocate memory and hence can't be called from an interrupt handler. This is because it calls loop.create_task(coro()). So there is a more general conclusion, that you can't launch a uasyncio coroutine from an interrupt context.

Regarding this general issue I assume the allocation occurs when the generator function runs and instantiates a generator i.e. the coro() call. Because uasyncio.core is designed to be allocation free.

Regarding the specific issue of the Delay_ms class I should be able to modify this so that trigger() is non-allocating. This would be a worthwhile improvement and hopefully I'll have something later this morning.

Apologies for the confusion.
Peter Hinch
Index to my micropython libraries.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: ExtInt not working properly

Post by nikhiledutech » Sat Jan 27, 2018 7:32 am

No problem sir.
but cant we use a global variable and update it in ISR. and use that updated variable in another async function to display on LCD.

The code is mentioned in my above post.
#Write a program to interface vibra Sensor board.
import pyb
import pyb,micropython
from pyb import LED, Pin, ExtInt
import uasyncio as asyncio
import utime as time
from alcd import LCD, PINLIST
micropython.alloc_emergency_exception_buf(100)

lcd = LCD(PINLIST, cols = 16)
vibra_value = pyb.Pin('PE7',Pin.IN,Pin.PULL_DOWN)
data = 0

#async def sensor():
# lcd[0] = "Vibration Detected"
# await asyncio.sleep(1)




def callback(_):
global data
pyb.LED(4).toggle()
pyb.LED(3).toggle()
data = 1
#while data == 1:
# lcd[0] = "Vibration Detected"
# await asyncio.sleep(1)
# data = 0


ext = pyb.ExtInt('PE7', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_UP, callback)

async def lcd_update():
global data
if data == 1:
lcd[0] = "Vibration Detected"
await asyncio.sleep(1)
elif data == 0:
lcd[0] = " "
await asyncio.sleep(1)
data = 0
return data
while True:
loop = asyncio.get_event_loop()
loop.run_until_complete(lcd_update())
thank you
Last edited by nikhiledutech on Sat Jan 27, 2018 7:37 am, edited 1 time in total.

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

Re: ExtInt not working properly

Post by pythoncoder » Sat Jan 27, 2018 7:36 am

Yes you can, and Dave Hylands explained how. Any Python function which is required to modify a global variable needs a global statement in the function body otherwise it creates a local variable with the same name and discards it when the function terminates.
Peter Hinch
Index to my micropython libraries.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: ExtInt not working properly

Post by nikhiledutech » Sat Jan 27, 2018 8:22 am

Okay. I get the real issue here. Global variable is working fine but their is some other problem occurring, which i cant find out.

So below is my code :
import pyb
import pyb,micropython
from pyb import LED, Pin, ExtInt
import uasyncio as asyncio
import utime as time
from alcd import LCD, PINLIST
micropython.alloc_emergency_exception_buf(100)
data = 0
lcd = LCD(PINLIST, cols = 16)
vibra_value = pyb.Pin('PE7',Pin.IN,Pin.PULL_DOWN)


async def sensor():
lcd[0] = "Vibration Detected"
await asyncio.sleep(1)

def callback(_):
global data
data = 1
pyb.LED(4).toggle()
pyb.LED(3).toggle()
pyb.LED(2).toggle()
pyb.LED(1).toggle()


ext = pyb.ExtInt('PE7', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_UP, callback)

async def vibra_sensor():
global data
if data == 1:
print("working")
data = 0

while True:
loop = asyncio.get_event_loop()
loop.run_until_complete(vibra_sensor())

There are two situations now:
1) LCD not connected to M4 board, above program works fine and is giving desired O/P (i.e Printing on terminal and LED toggling)
2) LCD connected to M4: Above program don't work, neither its blinking nor, its printing on terminal.

But one think i will like to bring in notice is that I have interfaced LCD properly, as i have tried to print simple character on LCD and it work.

So can anyone help me to find out, whats the error here, is it program or any other erroneous thing happening in background.

thank you

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

Re: ExtInt not working properly

Post by pythoncoder » Sat Jan 27, 2018 11:45 am

I've now pushed an update to aswitch.Delay_ms. The constructor takes an optional arg can_alloc defaulting True. If trigger() is to be called from an ISR, can_alloc should be False. So the following sample should work with the new version.

Code: Select all

import pyb,micropython, aswitch
from pyb import LED, Pin, ExtInt
import uasyncio as asyncio
from alcd import LCD, PINLIST
micropython.alloc_emergency_exception_buf(100)

delay = aswitch.Delay_ms(can_alloc=False)
lcd = LCD(PINLIST, cols = 16)

async def lcd_update():
    await asyncio.sleep(1)
    ext = pyb.ExtInt('PE7', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_UP, callback)
    while True:
        lcd[0] = 'Vibration Detected' if delay.running() else ' '
        await asyncio.sleep(1)

def callback(_):
    delay.trigger(1000)
    pyb.LED(4).toggle()

loop = asyncio.get_event_loop()
loop.create_task(lcd_update())
loop.run_forever()
Thank you for pointing out this issue. Evidently you're the first to have tried this, but it's an entirely valid use-case. I'd appreciate your feedback on whether this works.
Peter Hinch
Index to my micropython libraries.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: ExtInt not working properly

Post by nikhiledutech » Mon Jan 29, 2018 6:53 am

Hello Sir,
Thank you for updating aswitch.py module. But i am facing a problem. It giving me an Attribute error in asyn module. Below is the code and error.

Code:::

import pyb,micropython, aswitch
from pyb import LED, Pin, ExtInt
import uasyncio as asyncio
from alcd import LCD, PINLIST
micropython.alloc_emergency_exception_buf(100)

delay = aswitch.Delay_ms(can_alloc=False)
lcd = LCD(PINLIST, cols = 16)

async def lcd_update():
await asyncio.sleep(1)
ext = pyb.ExtInt('PE7', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_UP, callback)
while True:
lcd[0] = 'Vibration Detected' if delay.running() else ' '
await asyncio.sleep(1)

def callback(_):
delay.trigger(1000)
pyb.LED(4).toggle()

loop = asyncio.get_event_loop()
loop.create_task(lcd_update())
loop.run_forever()
Error:
File "asyn.py", line 231, in <module>
AttributeError: 'module' object has no attribute 'CancelledError'
So guide me through this.

Thanks
Nikhil Komalan

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

Re: ExtInt not working properly

Post by pythoncoder » Mon Jan 29, 2018 8:30 am

You have an old version of uasyncio. Please use upip to upgrade it.
Peter Hinch
Index to my micropython libraries.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: ExtInt not working properly

Post by nikhiledutech » Mon Jan 29, 2018 9:37 am

Hello Sir,
Good news, code is working properly now. Thanks for the update in the module. Its will truly help people in future.

Now i tried same method to interface touch key sensor and i have few doubts and i tested all that doubts in programming and its working fine but its displaying character little bit slowly on LCD. But i doubt is this the right method, as i am using multiple triggers for each touchkey.

So please kindly go through my code and help to improve or correct it.
#Interfacing Touch key and displaying key on LCD
import pyb,micropython, aswitch
from pyb import LED, Pin, ExtInt
import uasyncio as asyncio
from alcd import LCD, PINLIST
micropython.alloc_emergency_exception_buf(100)

#Initialisation
A_delay = aswitch.Delay_ms(can_alloc=False) #Retrigerable timer
B_delay = aswitch.Delay_ms(can_alloc=False) #Retrigerable timer
C_delay = aswitch.Delay_ms(can_alloc=False) #Retrigerable timer
D_delay = aswitch.Delay_ms(can_alloc=False) #Retrigerable timer

lcd = LCD(PINLIST, cols = 16) #LCD_Initalising
A = pyb.Pin('PE7',Pin.IN,Pin.PULL_UP) #a_Input
B = pyb.Pin('PA3',Pin.IN,Pin.PULL_UP) #b_Input
C = pyb.Pin('PA0',Pin.IN,Pin.PULL_UP) #c_Inputd
D = pyb.Pin('PE6',Pin.IN,Pin.PULL_UP) #d_Input


def callback(_):
if A.value() == True:
A_delay.trigger(1000) #Trigerring timer
pyb.LED(1).toggle()

elif B.value() == True:
B_delay.trigger(1000) #Trigerring timer
pyb.LED(2).toggle()

elif C.value() == True:
C_delay.trigger(1000) #Trigerring timer
pyb.LED(3).toggle()

elif D.value() == True:
D_delay.trigger(1000) #Trigerring timer
pyb.LED(4).toggle()



#Main program
async def touchkey_sensor():
# await asyncio.sleep(1)
ext_A = pyb.ExtInt('PE7', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_UP, callback)
ext_B = pyb.ExtInt('PA3', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_UP, callback)
ext_C = pyb.ExtInt('PA0', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_UP, callback)
ext_D = pyb.ExtInt('PE6', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_UP, callback)

while True:
lcd[0] = "A" if A_delay.running() else " "
await asyncio.sleep_ms(500)

lcd[0] = " B " if B_delay.running() else " "
await asyncio.sleep_ms(500)


lcd[0] = " C " if C_delay.running() else " "
await asyncio.sleep_ms(500)


lcd[0] = " D " if D_delay.running() else " "
await asyncio.sleep_ms(500)



loop = asyncio.get_event_loop()
loop.create_task(touchkey_sensor())
loop.run_forever()
The problem is if i tap on " C" key, LED starts toggling but i have to do multiple taps for displaying C on LCD. Any suggestions ?

Thanks.

Post Reply