Reading from SPI Accelerometer and networking out data at 2000hz

Greg Corson
Posts: 35
Joined: Sun May 20, 2018 9:16 pm

Reading from SPI Accelerometer and networking out data at 2000hz

Postby Greg Corson » Tue Apr 30, 2019 12:15 am

I'm working on a setup to get data from an SPI accelerometer/gyro chip (IMU) and send the data out on WiFi over UDP or TCP.

The main issue is I need to read from the SPI IMU at around 2000hz, these reads take 40-100us. I'm seeing non-blocking calls to TCP or UDP taking 500us to 1500us, so obviously the SPI reads and the networking can't be in the same task/loop. The reads from the IMU need happen on time, get time stamped, buffered up and then sent out the network as bigger blocks of data.

I'm wondering how best to do this, I could run a high-res timer at 500us that reads the IMU and put the network stuff in another task, but from what I've been reading, spending 40-100us in the high-res timer callback doing SPI reads might be too long. About 40 bytes of data is being read from the IMU every 500us. Will this approach work or do I need something different like having the IMU read in a high priority task that the timer interrupt preemptively "wakes up"?

In short, how to I make the IMU reading task execute on-time and let everything else run in the background?

ESP_Sprite
Posts: 9769
Joined: Thu Nov 26, 2015 4:08 am

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby ESP_Sprite » Tue Apr 30, 2019 1:34 am

What specific type of IMU do you use? Most of them have the option to collect samples into a FIFO internally; you can then read them out more-or-less at your leisure.

Greg Corson
Posts: 35
Joined: Sun May 20, 2018 9:16 pm

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby Greg Corson » Tue Apr 30, 2019 8:46 am

This is part of an imu test rig so it needs to work with a variety of imu.

This rig needs to sample several imu at once so they can be compared

Regardless, even fifos generate an interrupt and then need to be read on a fairly regular schedule (when the sample rate is 2k) so I’m wondering if the read should happen in the interrupt routine or if there is a way to have the interrupt wake up a task (quickly) to do the reading.

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby meowsqueak » Mon May 20, 2019 11:30 pm

Greg Corson wrote:
Tue Apr 30, 2019 8:46 am
This is part of an imu test rig so it needs to work with a variety of imu.

This rig needs to sample several imu at once so they can be compared

Regardless, even fifos generate an interrupt and then need to be read on a fairly regular schedule (when the sample rate is 2k) so I’m wondering if the read should happen in the interrupt routine or if there is a way to have the interrupt wake up a task (quickly) to do the reading.
Did you come up with a good solution to this? I'm attempting to do almost exactly the same thing - an IMU sensor test rig, via an ESP32. I'd be very interested in learning more about your methodology and findings.

ESP_Sprite
Posts: 9769
Joined: Thu Nov 26, 2015 4:08 am

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby ESP_Sprite » Tue May 21, 2019 1:38 am

Specifically with a device with a FIFO, I've used a timer interrupt to wake a task using a semaphore to read out the device succesfully before. Nowadays, you could probably also use an esp_timer callback.

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby meowsqueak » Tue May 21, 2019 1:43 am

ESP_Sprite wrote:
Tue May 21, 2019 1:38 am
Specifically with a device with a FIFO, I've used a timer interrupt to wake a task using a semaphore to read out the device succesfully before. Nowadays, you could probably also use an esp_timer callback.
That's roughly what I was thinking - have the device automatically fill the FIFO at the configured rate, then make sure a callback runs often enough to read out the fifo. Is it best for the callback to simply signal a high-priority task to do the "heavy" reading, or have the callback read and push the data itself into a queue for another task to process? Not sure what the implications are of having a long-running callback.

ESP_Sprite
Posts: 9769
Joined: Thu Nov 26, 2015 4:08 am

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby ESP_Sprite » Tue May 21, 2019 1:56 am

You want to do the reading of the device in a task, as it's a PITA and/or impossible to do in an interrupt context as a whole bunch of calls won't work there. Hence, if you decide to use a hardware timer, you must use a semaphore or something to unblock a task to do the reading for you. esp_timer callbacks already run in task context, so you don't need to unblock another task. (However, as far as I remember, esp_timer callbacks are serialized, so you a. don't want to spend too much time doing what you need to do there and b. you can expect a bit more jitter in the callback at times.)

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby meowsqueak » Tue May 21, 2019 2:07 am

ESP_Sprite wrote:
Tue May 21, 2019 1:56 am
However, as far as I remember, esp_timer callbacks are serialized, so you a. don't want to spend too much time doing what you need to do there and b. you can expect a bit more jitter in the callback at times.
Thanks for your advise so far. What would be "too much time"? For example, let's say I want to read 4kB of samples from the FIFO via 400kHz I2C - assuming I could read that in a single I2C transaction (thanks to smart "wrap around" FIFO registers) - then that would take approximately 10 milliseconds, which is in the order of a tick. Is that too long? If it is, would you suggest reverting back to unblocking a task instead?

ESP_Sprite
Posts: 9769
Joined: Thu Nov 26, 2015 4:08 am

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby ESP_Sprite » Tue May 21, 2019 8:28 am

It depends. If you have nothing else that depends on the timely handling of esp_timer callbacks, you can happily place it there, but if not, I'd unblock a task.

Greg Corson
Posts: 35
Joined: Sun May 20, 2018 9:16 pm

Re: Reading from SPI Accelerometer and networking out data at 2000hz

Postby Greg Corson » Tue May 21, 2019 5:17 pm

What I ended up doing was setting up interrupt routines for each IMU that read whenever data is ready and pack it into a buffer. So far this is taking from 40-90us depending on the device using 5mhz spi clock. The setup is double buffered, one buffer dedicated to reading the IMU while the other is being sent out the network by the main process. When the interrupt buffer fills, the buffers are swapped, if the network buffer isn't empty by then, a buffer overrun is reported.

So far, using two 1400 byte buffers and UDP, I haven't seen any buffer overruns with 2 IMUs running at 2khz.

The interesting thing is that networking seems much faster with the IMUs being read in interrupts than when they were being read in a regular task.

With this setup I send a 1400 byte UDP packet about 90 times a second, usually the packet send is very quick but sometimes can take up to 3ms. The transmit never seems to fail though I still need to check the receive end to see how often packets are dropped.

The only downside I can see is that you need an extra pin for the interrupt for each IMU.

Also compared to using i2c, the reads are a LOT faster. For an MPU9250 I2c was taking 2-3ms, SPI takes just 50us.

Who is online

Users browsing this forum: asargent and 51 guests