I2C slave receiving data is causing servo twitching

Hello World,

This is my first time posting so please be gentle. Until now I’ve successfully managed to solve my hardware and coding issues with google searches and good old fashioned troubleshooting, but I’ve hit a roadblock.

First some background on my project:

I’m building a custom controller for one of those generic 17 DOF robot kits. The servos it came with were garbage so I upgraded to nice(er) brushless servos. My robot controller takes input from a PS3 controller through a USB host setup. This is handled by an ATMega328P. The 328P is also taking input from a 6 DOF IMU and kalman filtering the input to give me nice clean orientation data. With all of that processing handled the filtered IMU data and PS3 button info is transferred, through I2C, using the wire library, to an ATMega2560 for joint choreography and servo control. Both MCUs have FTDI setups for serial programming and monitoring (debugging).

The power is supplied by a 2S lipo capable of outputting more amps continuously than all my servos can pull and there is a nice clean, regulated 5V going to all the sensitive logic things.

I am proud to say that everything works (with the exception of the glitch that has brought me here). The PS3 commands are read, the AMU is filtered, all that is sent over I2C to the 2560 that happily runs through it’s code and outputs to the servos.

The issue I’m having is twitching servos. After a lot of frustration and troubleshooting it looks like the I2C transmission is the cause of the twitch. Killing that section of code makes the servos behave nicely again. From what I’ve read the wire library locks up the MCU while receiving. It seems to be well known that the wire library is less than ideal and there are other versions floating around with various modifications.

My question is, does anyone know of a good I2C library to use that won’t screw with my servo outputs?
I found and attempted to understand this, which indicates that the functionality is there but the standard library doesn’t take advantage of it:
http://playground.arduino.cc/Main/WireLibraryDetailedReference
I’ve tried reading through the libraries and most of the code flies right over my head. If there isn’t a prepackaged library that will do what I need, can someone help me code up a fix for this.

Sorry for the long post, and thanks in advance for any help!

Although the Wire library has some issues I think your problem is not that library but how you control your servos. I guess you use a software emulation to generate the PWM signal to control the servos. This emulation relies on interrupts to follow an exact timing. If these interrupts are handled a bit later because an I2C interrupt handler is still running the servos react by moving to a slightly different position.

You can solve that two different ways:

  • Don't use a software emulation to control the servos but use the 15 available hardware PWM pins. For the two remaining servos use either a PWM breakout board or choose servos where the twitching is not that disturbing.
  • Let the Mega2560 be the I2C master and use a software emulation for it. That way you eliminate the I2C interrupts and the communication to your sensor daughter board will be not prioritized which may result in slower communication.

Thank you pylon for the help. I wound up (mostly) solving the problem last night. Unfortunately, reworking the outputs like your first suggestion would be a complete overhaul of the pcb (pictures attached in the first post). Your post got me thinking though, and eventually led me to my solution.

It isn't very elegant, but I managed to sync up the timing on the I2C and servo pulses so the I2C does it's thing in the dead space between the fall of the last servo pulse and the rise of the first in the next cycle. There's some variability in the time each cycle of code takes, but with some work I got the average cycle time of the two MCUs within 10 microseconds of each other (a lot of tuning with the delayMicroseconds and an excel sheet to crunch the output). The servo shake has gone from full body convulsions to a very small and occasional hiccup in an isolated joint. I can live with that.

Thanks again, and if anyone wants more details let me know.