Acquiring and fusing data from different controllers

avrimuraspberry pisensor

TL;DR: What are some options to fuse data acquired with separate controllers?

I'm developing my own IMU for a quadrotor.

My inputs are an accelerometer, gyro, magnetometer, and barometer all via I2C and my GPS module via serial. The I2C bus updates & transfers much faster (~few ms) than the serial (~1s, 4800 baud).

My outputs would be commands to 4 motors and data logging.

I've been reading the I2C stuff with an AVR because I need quick updates to prevent drift of the quantities I'm integrating (gyro, accel). However, I can't read the gps with the same AVR at 4800 baud without skipping an eternity of I2C data. I concluded I need to read the gps with something else. (currently a raspberry pi)

I've already implemented a kalman filter on the AVR for the gyro/accel/mag/baro. Now I want to fold in GPS.

The simplest option would be to move everything to the pi and run the I2C and serial on separate threads and save to global variables. But getting away from real time data acquisition worries me.

Another option may be to acquire the I2C and Serial with two independent AVRs and save the data to an outside memory module. I'd then need some 3rd device to get all the data off the memory module and run the calculations. (Maybe this is a crazy 'hardware' version of a global variable?)

I'm just getting the sense I'm going about this the wrong way, even if I could brute force it to work. Is there a 'right' way to solve this problem?

Best Answer

The typical way to do this with a single micro is to establish buffers in and stuff them up with ISRs (interrupt service routines) triggered by the reception of serial GPS data or I2C data. Set a flag when an entire message is available in the buffer and read it with your background routine. At 4800 baud you've got a leisurely 2000 microseconds or so between characters so even if the hardware buffer is a single character you have lots of time to do other things. If you double buffer you only have to worry about the inter-message time rather than the inter-character time.

The AVRs have decent interrupt handling and you can probably write everything in C if you want.