I am currently working on a Arduino project that combines an InertiaOne IMU sensor board (from Atmel), with an Arduino UNO and two motors driven by a Makeblock driver board. All sensors communicate using I2C, with different addresses. My issue is that the program runs just fine for a while (everything between 1 second and 2 minutes), but suddenly lock up inside the Wire.requestFrom-function that handles I2C communication. More specifically, I believe that the code hangs at one of these points in the Wire library (the code is a direct copy):

// wait until twi is ready, become master receiver
while(TWI_READY != twi_state){
// wait for read operation to complete
while(TWI_MRX == twi_state){

As far as I know, there are only two units that utilise I2C in the system, both of which are embedded onto the InertiaOne circuit board. What I find very strange is that reading these two sensors works just fine when no motors are running, but that the problem occurs when the motors are activated. My first reaction was to use separate power supplies for the motors and sensor board since the issue could have been caused by a dip in the voltage and a reset of the sensor board, but without any change of result.

I am running out of things to try, and do simply not have the required understanding of I2C and embedded systems to see what exactly the issue is. Could it simply be that some of my parts are faulty, or am I perhaps overlooking something?

  • As for my problem: the code that is displayed above is taken directly from the libraries provided by Arduino, and is therefore most likely well programmed; however, I have actually tried both adding timers to the while loop and moving the sensor board 15 cm away from the motors (the motors are small). I unfortunately do not have any sort of debugging equipment, but using simple print statements, I have managed to trace all lockups down to the single ... – Tormod Haugene Jul 16 '14 at 21:05
  • ... two code snippets displayed above. My guess therefore goes to this being some deadlock in the I2C communication, a field of which I am no expert. Although I agree with all of what you suggest, I find either thought very hard to verify. :) – Tormod Haugene Jul 16 '14 at 21:10
  • 1
    If you are using long cables, it might be an EMI issue. Either find an oscilloscope and probe what is happening on the I2C bus on the μC side or try using shorter wires just to see what happens. Also check that the grounds are all connected at some point. A star ground topology might help. Lastly, check to see if the PSU can supply enough current when the motors are turned on. Again, use an oscilloscope and prove the Vcc of the μC. – Evangelos Em Jul 16 '14 at 21:11
  • 1
    When saying you have connected all GNDs, have you tried connecting all circuit grounds together and then connected that point to mains earth? If that didn't work, I have no more insights. You'll need an oscilloscope or logic probe or some other way to debug it. You could try sending debug text to a computer through the serial interface of the UNO. – Evangelos Em Jul 16 '14 at 21:18
  • 2
    "libraries provided by Arduino, and is therefore most likely well programmed" - There's a false assumption right away, especially for the TWI library. – user588 Jul 20 '14 at 21:28

The Wire library has an issue in the lines you posted, that if an interrupt is lost, it will stay in that loop forever. There are two things you could do to fix this:

  • Stop the interrupt from being lost (ie. fix electrical problems)
  • Use a library that has a time-out.

For the electrical issues, I would make sure you have pull-up resistors from SDA and SCL to +5V - typically 4.7k (for each one), but that would depend a bit on whether the device already has them. Also make sure you have decoupling capacitors on the Vcc lines as appropriate.

For the software side, there is an alternative library (master only) at Arduino I2C Master Library.

I haven't personally needed to use that library, as with pull-up resistors and short cable runs, I haven't had problems with the Wire library. However if things are marginal you may well find that it helps.

  • It is a shame that a library which is so horribly bad programmed found it's way into Arduino core. Obviously there must be a timeout! – Elmue Mar 16 '16 at 21:20
  • True, some parts sacrifice reliability for simplicity. The good part is, you can always write your own, or just take the existing one and modify it. It's not like the libraries are distributed in binary form only. – Nick Gammon Mar 16 '16 at 21:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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