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?

  • 1
    \$\begingroup\$ Why not just use interrupts in the first place? \$\endgroup\$ Commented Apr 10, 2015 at 21:05
  • 2
    \$\begingroup\$ Why would you be skipping I2C while the 4800 serial takes place? Do they share something in common? \$\endgroup\$
    – brhans
    Commented Apr 10, 2015 at 21:09
  • \$\begingroup\$ See response to answer. Just coming from arduino and unfamiliar with interrupts. Thanks for the help! \$\endgroup\$ Commented Apr 11, 2015 at 20:59

1 Answer 1


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.

  • \$\begingroup\$ Thanks! I will look into this. Honestly, I've only just transferred to AVRs from arduinos. Haven't yet worked with interrupts/ISRs at all. In my limited thinking: "AVRs are single threaded, so they can't do anything else while reading 100Bytes at 4800 baud." I suppose "ISRs" may change this, but I'll really need to dive into it. Thanks Again! \$\endgroup\$ Commented Apr 11, 2015 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.