Float numbers in interrupt handler

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
kjarke
Posts: 5
Joined: Wed Jun 17, 2015 12:28 am

Float numbers in interrupt handler

Post by kjarke » Thu Jul 23, 2015 4:25 am

I'm building a small robot driven by stepper motors. To implement smooth starting and stopping I'm trying to program a simple motion controller. The code is executed in regular intervals as a timer interrupt handler.
It all works well if all numbers inside the interrupt handler are int. I wasn't able to make it work if even one of them is a float. Even if I declare them as float they seam to be turned to int within the interrupt handler automatically.
It would be great if I could specify a float number for self.acc. One is quite large and zero is obviously too small. Here are some code extracts:

Code: Select all

def __init__(self): 
        # Variables
        self.speed_R = 0         #speed counter. If >255 step will be executed
        self.speed_L = 0         #speed counter. If >255 step will be executed
        self.sspeed_R = 0        #set speed
        self.sspeed_L = 0        #set speed
        self.dist_R = 0          #distance counter
        self.dist_L = 0          #distance counter
        self.target = 0          #motion control position target
        self.acc = 1             #motion control acceleration
        self.dts = 0.0           #motion distance to stop
        
def Motion(self, t):
        self.dts = (self.acc * (self.sspeed_L // self.acc) ** 2) // 512

        if self.sspeed_L < 0:
            self.dts *= -1
        
        if self.target > (self.dist_L + self.dts) and self.sspeed_L < 256:
            self.sspeed_L += self.acc
            self.sspeed_R += self.acc
        elif self.target < (self.dist_L + self.dts) and self.sspeed_L > -256:
            self.sspeed_L -= self.acc
            self.sspeed_R -= self.acc
        elif self.target == self.dist_L and abs(self.sspeed_L) < 50:
            self.sspeed_L = 0
            self.sspeed_R = 0
        
        self.MoveStep(1)
        
def SetMotion(self, value):
        if value == 0:
            self.tim1.callback(None)
        if value == 1:
            self.tim1.callback(self.Motion)

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

Re: Float numbers in interrupt handler

Post by dhylands » Thu Jul 23, 2015 5:23 am

Currently you're not allowed to allocate any memory inside an interrupt handler, which means that you can't use floats or ints which go outside of the small int range (30 bits plus sign).

kjarke
Posts: 5
Joined: Wed Jun 17, 2015 12:28 am

Re: Float numbers in interrupt handler

Post by kjarke » Fri Jul 24, 2015 12:46 am

I'm aware that I can't assign memory within an interrupt handler. It just looks like I can't do any calculations with float numbers inside an interrupt handler. Even if the variables have been declared outside of the interrupt handler. I did another simple test. If I add 0.5 to the float number I get a MemoryError. For some reason the if statement with the float number works even if I change 1000.0 to 1000.5.

Code: Select all

def __init__(self):
    self.test1 = 0.0
    self.test2 = 0
    
def Test(self, t):
    if self.test1 < 1000.0:                  # it also works if I change 1000.0 to 1000.5
        self.test2 += 1                        # this line is working
        #self.test1 = self.test1 + 0.5   # if I un-comment this line I get MemoryError

def SetInterrupt(self, value):
    if value == 0:
        self.tim1.callback(None)
    if value == 1:
        self.tim1.callback(self.Test)

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Float numbers in interrupt handler

Post by blmorris » Fri Jul 24, 2015 1:32 am

I had a more detailed reply, but it got eaten by my phone. Basically the 0.5 in your statement 'self.test1 = self.test1 + 0.5' causes a float to be allocated. You might try preallocating to a class variable, but the floating point addition may also cause a temporary float object to be allocated, though I'm not certain of that and need to check.
-Bryan

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

Re: Float numbers in interrupt handler

Post by dhylands » Fri Jul 24, 2015 1:50 am

In normal python, even the statment x = 1 needs to allocate memory to hold the integer 1.

In Micropython, small intergers (31-bit signed integers) have been optimized to not require any memory allocations.

The statement x = 0.0 requires a memory allocation.

Post Reply