PySense 2 + Lopy4 threading and accelerometer

  • Hello,
    My use case is :
    I'm reading the value of the LIS2HH12 (accelerometer) at ~ 250 Hz and when I've 512 reading, I send them to my PC with UART.
    It's working fine without thread but I was trying to optimize it because the UART part takes 2 seconds so I thought I could use the main thread for the accelerometer reading and another thread for sending in UART (I'm using locks so if the reading finish before the previous UART sending, I'm just waiting in a while loop).

    The problem if I use the function : LIS2HH12.acceleration() (which is returning the acc for x,y,z), it crashs with the error :
    Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

    I'm pretty sure that the problem is coming from this function because when I don't use it and just use random value, the code is working perfectly without any crash.

    I'm guessing the problem is that LIS2HH12.acceleration() code is using readfrom_mem and so it may read from some memory allocated for my other thread ?

    def acceleration(self):
            x = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_X_L_REG, 2)
            self.x = struct.unpack('<h', x)
            y = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_Y_L_REG, 2)
            self.y = struct.unpack('<h', y)
            z = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_Z_L_REG, 2)
            self.z = struct.unpack('<h', z)
            _mult = self.SCALES[self.full_scale] / ACC_G_DIV
            return (self.x[0] * _mult, self.y[0] * _mult, self.z[0] * _mult)``````

    Is there a way to make it works ? Like allocating the thread memory to a specific place ? Or at least a function to check where the thread memory is allocated so I could know if i'm right or not ?

  • @g0hww Sorry for the delay, it was holliday in my country yesterday ^^

    I thought of doing something like you described but the problem is that I want to do an FFT so I have to collect samples with the minimun sample time I can get, currently I'm limited with a rate of 250Hz because when I call the 'acceleration()' method it takes arrounds 3200 us.
    That's one of the reason I wanted to use threading.

    Currently, my solution is to get the maximun of sample I can get without exceeding the Lopy's 4 memory of the Lopy4 (arround 14 second) and then sending it even if it takes a lot of time.
    If someone has a solution for threading, I would be glad to hear it.

  • Why not send the acceleration data through the UART immediately after reading the set of values?
    You could send an STX char, a frame size byte, then a number of data frames (6 bytes each), keeping a running checksum until the desired number of samples to fill the message have been sent, then send that, followed by an ETX char.
    The receiving code could check for the frame formatting and checksum validity.
    If you send 25 samples per message, that would be 150 bytes of payload per message, sending 10 messages per second. That's 1540 bytes per second including the format overhead, or 15400 bits (assuming 8 data bits, no parity and 1 stop bit) so a baudrate of more than 19200 bits per second should give enough headroom. though faster baudrates would give more headroom.
    The existing approach you described collects 512*6 bytes then sends that. That's 30720 bits, which would take around 3.2 secs at 9600 baud, or 1.6 secs at 19200 baud.

Log in to reply

Pycom on Twitter