ISR code example gives an error on microbit

Questions and discussion about running MicroPython on a micro:bit board.
Target audience: MicroPython users with a micro:bit.
Post Reply
rivandemo
Posts: 4
Joined: Sun Oct 27, 2019 9:52 am

ISR code example gives an error on microbit

Post by rivandemo » Sun Oct 27, 2019 10:09 am

Hello,

I found an example of using ISR on this page: https://docs.micropython.org/en/latest/ ... rules.html but when i flash it on my microbit card it generates an error "no module named pyb".

Here is the code:

Code: Select all

import pyb, micropython
micropython.alloc_emergency_exception_buf(100)
class Foo(object):
    def __init__(self, timer, led):
        self.led = led
        timer.callback(self.cb)
    def cb(self, tim):
        self.led.toggle()

red = Foo(pyb.Timer(4, freq=1), pyb.LED(1))
green = Foo(pyb.Timer(2, freq=0.8), pyb.LED(2))
and i'm using Mu-editor 1.0.2 on Mac OSX 10.12.6 Sierra.

Btw, i had to split the first line in two import lines as multiple imports on one line is not accepted by Mu-editor.
Should i install the pyb module? And how?

Thanks for help,
Richard

shaoziyang
Posts: 279
Joined: Sun Apr 17, 2016 1:55 pm

Re: ISR code example gives an error on microbit

Post by shaoziyang » Sun Oct 27, 2019 12:37 pm

pyb module is for stm32/pyboard, microbit has no pyb module.

rivandemo
Posts: 4
Joined: Sun Oct 27, 2019 9:52 am

Re: ISR code example gives an error on microbit

Post by rivandemo » Sun Oct 27, 2019 1:22 pm

Thank you!

Is there any way i can use interrupt (ISR) on a microbit? Iaw could you tell me where i can find documentation about this?

Thanks a lot,
Richard

shaoziyang
Posts: 279
Joined: Sun Apr 17, 2016 1:55 pm

Re: ISR code example gives an error on microbit

Post by shaoziyang » Sun Oct 27, 2019 2:39 pm

microbit use nRF51822, and it has 16kb ram only. So some feather can't use in it.

Document for microbit:

https://microbit-micropython.readthedocs.io/en/latest/

User avatar
jimmo
Posts: 892
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia

Re: ISR code example gives an error on microbit

Post by jimmo » Sun Oct 27, 2019 11:10 pm

The micro:bit uses a different version of MicroPython -- based on v1.9.2 https://github.com/bbcmicrobit/micropython
Because it's such a small microcontroller and because it's targeted at education, a lot of features are not available, including interrupts.

Depending on how adventurous you're feeling, you can actually compile the upstream version of MicroPython for micro:bit -- https://github.com/micropython/micropyt ... /ports/nrf which will give you access to some core features like interrupts, but you will lose some other features. And you probably won't be able to use Mu, etc.

What are you trying to do, perhaps we can find a way to do it without interrupts? (I've spent a lot of time teaching with the micro:bit and while we certainly did find the lack of interrupts frustrating, we did find a lot of ways around that limitation too).

rivandemo
Posts: 4
Joined: Sun Oct 27, 2019 9:52 am

Re: ISR code example gives an error on microbit

Post by rivandemo » Mon Oct 28, 2019 4:57 pm

A few weeks ago i block-coded a simple program for my grandson to show him how to display his name on a microbit when button A was pressed and stopping the display when B was pressed. The issue was that when pressing button A again the display restarted from the beginning and not from the last character displayed. I then switched to Python and used a list and an index. The result was better but not completely satisfactory as the "button B pressed" check has to be synchronous with the "while True" loop.

I tried this:

Code: Select all

import microbit

disp = 0
index = 0
maxIndex = 5
marcelList = ["M", "A", "R", "C", "E", "L"]

while True:
    if microbit.button_a.is_pressed():
        disp = 1

    if microbit.button_b.is_pressed():
        disp = 0

    if disp == 1:
        microbit.display.show(str(marcelList[index]))
        index = index + 1
        if index > maxIndex:
            index = 0
        microbit.sleep(1000)
I searched then on Internet an interrupt-based solution..

This being said, my problem is far from being important or urgent.

Richard

User avatar
jimmo
Posts: 892
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia

Re: ISR code example gives an error on microbit

Post by jimmo » Tue Oct 29, 2019 1:40 am

hi Richard,

I'm not sure that interrupts necessarily make this easier.

The key thing though is that while the micro:bit is sleeping, it can't be doing anything else. So it helps to imagine how the sleep function itself works:

Code: Select all

def sleep(delay_ms):
  t = running_time()
  while running_time() < t + delay_ms:
    pass
You can kind of implement your own version of sleep into the main loop of your program. In this case we figure out when the next letter should be shown.

Code: Select all

import microbit
marcelList = ["M", "A", "R", "C", "E", "L"]
maxIndex = 5
next_letter_time = 0
disp = False
letter_delay = 1000
index = 0
while True:
  if microbit.button_a.is_pressed():
        disp = True
        next_letter_time = microbit.running_time() + letter_delay
  if microbit.button_b.is_pressed():
        disp = False
        next_letter_time = 0
  if disp and microbit.running_time() > next_letter_time:
    microbit.display.show(str(marcelList[index]))
    index = index + 1
    if index > maxIndex:
      index = 0
    next_letter_time = microbit.running_time() + letter_delay
I genererally prefer to use was_pressed unless there's a specific reason to use is_pressed. The letters can be a string too, instead of a list. So here's a simplified version -- you also kind of don't need the "disp" variable anymore because next_letter_time != 0 implies disp = True.

Code: Select all

import microbit
marcel = "MARCEL"
next_letter_time = 0
letter_delay = 1000
index = 0
while True:
  if microbit.button_a.was_pressed():
        next_letter_time = microbit.running_time() + letter_delay
  if microbit.button_b.was_pressed():
        next_letter_time = 0
  if next_letter_time > 0 and microbit.running_time() > next_letter_time:
    microbit.display.show(marcel[index])
    index = (index + 1) % len(marcel)
    next_letter_time = microbit.running_time() + letter_delay
You might want to display.clear() when b is pressed too?

FYI I wrote this blog post about this exact topic a while back for my previous employer -- there might be some useful bits. https://medium.com/groklearning/become- ... b8b4e2d747 You might find their micro:bit simulator useful too (which you can access for free by starting the micro:bit course and going to any problem -- https://groklearning.com/microbit/), I used it to test the above code.

rivandemo
Posts: 4
Joined: Sun Oct 27, 2019 9:52 am

Re: ISR code example gives an error on microbit

Post by rivandemo » Sat Nov 02, 2019 5:53 pm

Thanks a lot Jimmo,

I'll try the solution you recommend (sorry for this late answer, i have been busy these last days), and look at the two links you mention (actually i think i already followed the "Grok learning" course).

I used the "sleep" function to write this little program "quick and dirty" but i agree, i never use the equivalent function on Arduino (delay()) and always prefer the use of millis() combined with two variables (prevStep, increased each time the cycle occurs and cycleInterval, a self explanatory constant)

Thank you again,
Richard

Post Reply