Playing with Interrupts

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

Re: Playing with Interrupts

Post by dhylands » Wed Jul 30, 2014 6:19 pm

Getting proper tracebacks from errors inside interrupt handlers is now possible in the latest codebase.

You need to add the following lines to your python code:

Code: Select all

import micropython
micropython.alloc_emergency_exception_buf(100)
When I run the original buggy code I posted at the beginning of this thread:

Code: Select all

import pyb
import micropython

class Heartbeat(object):

    def __init__(self):
        self.tick = 0
        self.led = pyb.LED(4) # 4 = Blue
        tim = pyb.Timer(4)
        tim.init(freq=10)
        tim.callback(self.heartbeat_cb)

    def heartbeat_cb(self, tim):
        if self.tick <= 3:
            led.toggle()
        self.tick = (self.tick + 1) % 10

micropython.alloc_emergency_exception_buf(100)
Heartbeat()
I now get this error:

Code: Select all

>>> import heartbeat_irq
Uncaught exception in Timer(4) interrupt handler
Traceback (most recent call last):
  File "0://heartbeat_irq.py", line 15, in heartbeat_cb
NameError: name 'led' is not defined

fma
Posts: 160
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: Playing with Interrupts

Post by fma » Wed Jul 30, 2014 6:32 pm

Great!
Frédéric

inaugurator
Posts: 23
Joined: Tue Sep 30, 2014 4:02 pm

Re: Playing with Interrupts

Post by inaugurator » Tue Oct 07, 2014 6:53 pm

Hi all.
I try this:

Code: Select all

import pyb

class Check:
    def __init__(self):

        self.sw = pyb.Switch()
        self.sw.callback(lambda: self.onClick())
        self.red = pyb.LED(1)
        self.green = pyb.LED(2)
        self.orange = pyb.LED(3)
        self.blue = pyb.LED(4)
        self.listleds = [self.red, self.green, self.orange, self.blue]

    def onClick(self):
        for i in self.listleds: i.toggle()

ch = Check()
When I run it I get error in the callback

Code: Select all

Uncaught exception in ExtInt interrupt handler line 3
MemoryError:
There is not allocate in the memory. What is wrong?
Thank you.
Evgeny

PinkInk
Posts: 61
Joined: Tue Mar 11, 2014 3:42 pm

Re: Playing with Interrupts

Post by PinkInk » Wed Oct 08, 2014 1:20 am

You allocated memory for i? I think it'll work if you use an existing property of the class in the loop.

User avatar
dhylands
Posts: 3260
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Playing with Interrupts

Post by dhylands » Wed Oct 08, 2014 3:32 am

I was able to get this version to work:

Code: Select all

import pyb

import micropython
micropython.alloc_emergency_exception_buf(200)

class Check:
    def __init__(self):

        self.sw = pyb.Switch()
        self.sw.callback(self.onClick)
        self.red = pyb.LED(1)
        self.green = pyb.LED(2)
        self.orange = pyb.LED(3)
        self.blue = pyb.LED(4)
        self.listleds = [self.red, self.green, self.orange, self.blue]

    def onClick(self):
        for i in range(len(self.listleds)):
            led = self.listleds[i]
            led.toggle()

ch = Check()
You can pass self.callback directly as the callback. No need to use a lambda. I'll have to look and see why the other version allocates memory.

User avatar
dhylands
Posts: 3260
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Playing with Interrupts

Post by dhylands » Wed Oct 08, 2014 4:03 am

When you use:

Code: Select all

for i in self.istleds
it needs to allocate an iterator, and thats what fails.

inaugurator
Posts: 23
Joined: Tue Sep 30, 2014 4:02 pm

Re: Playing with Interrupts

Post by inaugurator » Wed Oct 08, 2014 9:43 am

Thank you, Dave, for the best solution.
Evgeny

User avatar
shell
Posts: 15
Joined: Tue Aug 12, 2014 8:31 pm
Location: Germany
Contact:

Re: Playing with Interrupts

Post by shell » Tue Oct 21, 2014 8:21 pm

I'm playing with "your interrupts" too:

Code: Select all

import pyb
import mpr121

import micropython
micropython.alloc_emergency_exception_buf(200)

class lcd_skin(object):
    def __init__(self):
        self.tick = 0
        self.m = mpr121.MPR121(pyb.I2C(1, pyb.I2C.MASTER))
        tim = pyb.Timer(8)
        tim.init(freq=1)
        tim.callback(self.lcd_skin_keys)

    def lcd_skin_keys(self, tim):		
		print(self.tick)
		if self.tick == 5:
			print(self.m.touch_status())
		self.tick = (self.tick + 1) % 10
lcd_skin()
So why do i get the following error:
uncaught exception in Timer(8) interrupt handler
Traceback (most recent call last):
File "lcd_skin.py", line 20, in lcd_skin_keys
File "mpr121.py", line 44, in touch_status
MemoryError: memory allocation failed, heap is locked

User avatar
dhylands
Posts: 3260
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Playing with Interrupts

Post by dhylands » Tue Oct 21, 2014 8:57 pm

That error message:
uncaught exception in Timer(8) interrupt handler
Traceback (most recent call last):
File "lcd_skin.py", line 20, in lcd_skin_keys
File "mpr121.py", line 44, in touch_status
MemoryError: memory allocation failed, heap is locked
tells me that you're trying to allocate memory from within the ISR handler, which currently isn't allowed.

User avatar
shell
Posts: 15
Joined: Tue Aug 12, 2014 8:31 pm
Location: Germany
Contact:

Re: Playing with Interrupts

Post by shell » Tue Oct 21, 2014 9:05 pm

Ok.
I'm trying to build a class that can do callbacks on button press of the lcd skins.
Any idea how can i do that?

Post Reply