Converting integers inside a callback

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
formica
Posts: 8
Joined: Thu Mar 30, 2017 10:47 pm

Converting integers inside a callback

Post by formica » Wed Aug 04, 2021 1:40 pm

Hi guys,
trying to convert an integer to an hex, and put it into a bytearray, inside an interrupt handler, but I obtain a memory error.
The callback is triggered by an external rising interrupt.
Any experience about that?

Code: Select all

import ...
micropython.alloc_emergency_exception_buf(100)

count = 0
ct = bytearray(2)

def callback():
	global count, ct
	count = count + 1
	ct = count.to_bytes(2,'big')


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

Re: Converting integers inside a callback

Post by jimmo » Wed Aug 04, 2021 2:10 pm

formica wrote:
Wed Aug 04, 2021 1:40 pm
but I obtain a memory error.
You can't allocate memory inside a hard IRQ (in this case creating the bytes object inside to_bytes). See https://docs.micropython.org/en/latest/ ... rules.html

So either you can make it a soft IRQ (set hard=False in pin.irq), or ensure that you only do memory allocation outside the IRQ handler. (Do you need to convert it to bytes inside the IRQ handler, can you just do that whenever you reference count later?)

Note that setting "ct = bytearray(2)" doesn't actually re-use the same buffer -- when you write "ct = count.to_bytes(2,'big')" it will allocate a new one each time.

If you want to convert an int to bytes without memory allocation, you can do this:

Code: Select all

# Pre-allocate the bytearray
ct = bytearray(2)

def callback():
  ...
  # big endian uint16 to bytes
  ct[0] = (count >> 8) & 0xff
  c[1] = count & 0xff

Post Reply