Arduino Freezes on i2c - SOLVED!

Hi,
I have been working with arduino for a while now and this is the first time I'm encountering such an issue. Before coming to the issue, I'll briefly explain what all I have done.

The project is to make a simple autonomous robot. I'm using the QMC5883L to get the directional data through i2c. I also have a L298N breakout module to drive the wheels (BO motor setup), a battery pack with a switch that I'm using to power the motor driver and arduino. The battery pack is li-ion in 1S5P config. So I'm using a boost converter to step up the voltage to 12v for the L298N and a buck converter to bring down the 12V to 5V for arduino and 5883L. I understand this may not be the most efficient way to do it but this is just a temporary setup.

I have just started this project, as the first step I have managed to successfully obtain the data from the 5883L. Initially I didn't use pull up resistor on i2c, now I'm using 2k7 resistor for pullup (5883L is working on 5V). Now I'm trying to orient the robot to a direction (using north direction for the test). If the robot is facing towards east it'll turn counter clockwise to get oriented to north and if it is facing towards west it'll turn clockwise. This is the idea for the second step and the Issue starts here. The arduino is hooked up to the USB and is working fine. As soon as I turn on the battery pack switch (with the USB still connected), it runs for a moment and then freezes. It'll just run the last executed line. The motor doesn't start to run until I turn the battery pack on.

I tried to debug using serial monitor. The code is running fine but for some reason freezes when the motor is turned on. I made sure the GND is connected properly. I tried disconnecting one of the motor terminal from the L298N module and the code seems to work perfectly fine. The moment I connect a motor to the driver module, the serial monitor seems to slow down a bit. The code will then run for a very little time and will freeze as the motor gains speed.

Every time the code freezes I'll have to manually reset the board.

I tried to isolate the arduino and motor driver but I still have to ground them together in order for the motor to work, this idea didn't work.

For some reason the code will only freeze when the motor is spinning. I don't know if there is any interference coming from the motor. I tried adding a 1000uF capacitor to the supply of the L298N, added decoupling capacitors to the motor, added pullup resistor to i2c lines (started with 5k ohms and went down to 2k7).

Kindly help.

With decopupling capacitors do you mean this


and did you use small ceramic capacitors?

If the reason is really EMV that you can't suppress
you could use optocouplers to electrically isolate the L298 from the arduino. But electromagnetic noise will still be there.

A QMC5883L is a magnetometer and the motors are creating a magnetic field: Is your QMC5883L close to the motors?

best regards Stefan

@StefanL38

Yes, this is what I meant by decoupling capacitor.

I made sure to keep the magnetometer away from the rest of the setup.

If I were to use optocouplers, I would need quite a few of them right? There are 6 signals going from the arduino to the L298.

This freezing only happens where there is an i2c connection. I tried running the motor driver alone it was working fine. But when I combine i2c and and L298, things go south.

Which Arduino board do you use ? I assume a 5V Arduino board ?

Do you have flyback diode with that motor ? Perhaps a few ?

Which QMC5883L module do you have ? Can you give a link to where you bought it ?
The QMC5883L is a 3.3V sensor with a 3.3V I2C bus. Its SDA and SCL pins can have maximum 3.6V.

The Wire library can halt a sketch when there is a problem on the I2C bus.
There is timeout to solve that, but that is not turned on yet by default. You can turn it on yourself.

Is the GND wire or the 5V or 3.3V wire for the sensor connected to something else ? The wires from the magnetometer should go directly to the Arduino board and not be used for something else.
Suppose you have a breadboard and the motor and the sensor are connected to the breadboard. Then they probably share a GND wire to the Arduino board. That will go wrong for sure.

Do you use long wires to the sensor ? I hope you don't have a flat ribbon cable.

I wrote a long Wiki about I2C on Github. If you are interested in the I2C bus, then you might read it.

@Koepel

I tested with both uno and mega. yes it is a 5v board.

I haven't used any flyback diode. I'm not sure if it comes with the driver module.

sorry, I don't have any link from where I got the QMC5883L. But it looks similiar to this - link. I know the name says HMC5883L but its i2c address is 0x0D instead of 0x1E and it does not run with any of the HMC library, I looked it up and found if the address is 0x0D it is most probably QMC module. I tested it with a QMC5883L library and it was then working fine. The site does mention it works with 3-5v. Initially I tested with 3.3v it was working fine and then I tested with 5v and it was working good.

The wire from the sensor goes directly to the board. The sensor ground goes straight to the board and is not mixed with other ground.

I suppose the wires from the sensor to the arduino is roughly about 20-25cm, and it is jumper wires. Does that pose a problem?

Can you tell me how to implement a timeout to solve the halt issue?

You need to add a few flyback diodes here and there.
In the datasheet of the L298 there are example circuits and they show flyback diodes. According to the datasheet: "An external bridge of diodes are required when inductive loads are driven and when the inputs of the IC are chopped.".

It is not clear which module you have.
The picture shows a module without level shifters for SDA and SCL.
In the "Attachments" tab there is a module with level shifters.
How many black components are on your board. If there are only two, then your voltage levels on the I2C bus are not okay.

Jumper wires of 20-25cm is good.

The timeout is explained here: https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/Wire/src/Wire.cpp#L90.

Wire.begin();
Wire.setWireTimeout( 1000);   // 1000 µs is 1 ms timeout

Hi,
Can you post a link to data/specs of your motors.

Do you have bypass capacitors on the 5V and 12V supply, especially close to the UNO?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

@TomGeorge Hi, Yes I had capacitors on my 5V and 12V. But that did not work out very well.

So Here is an update to all,

I solved the Issue!!

I did a lot of trial and error, trying to figure out what is wrong because whatever I did the issue would still exist.

  • Used pullup resistor on SDA and SCL lines, that didn't do much good.
  • Ground of magnetometer was directly connected to arduino, a separate pin was used (not mixed with other ground connections).
  • Tried using decoupling capacitors on each motor as mentioned by @StefanL38 but that did not work.
  • Was using twisted short wires for motor connection, didn't show any result.
  • Tried using capacitors on supply lines, was not effective.
  • Tried using the timeout method suggested by @Koepel but it didn't work out.
  • Tried isolating the arduino and L298 driver, but couldn't do it properly as the ground of arduino and L298 needed to be connected together. I thought of isolating the both circuits using optocoupler and then powering the arduino and L298 separately. I solved the problem before I could get to this.

Then I had an idea to try out different type of motor, and I happen to have one lying around, so I tried using the new motor and it was working like magic. There was no hanging or freezing. It appears that the particular type of motor I was using had some issues and was interfering with the i2c connection from the magnetometer, most probably electrical noises coming from the motor through the wires.

This was the motor that I first used, the one that caused all the problems.

This is the same motor with its reduction gearbox

This is the motor I had lying around, which causes zero issues. I'm not sure of the model number of this. Used this for testing purpose and I was happy with the result so I ordered similar new ones with gearbox.

This is the new motor with reduction gearbox, this one is similar to the one shown above. I'm getting very good results with it.


I think its model number is rf-500tb-12560, if anyone wants to look it up. I have also used a ferrite core on each motor wiring just to be on the safe side, just one loop through the core. I'm not sure if its even making a difference.

On one of the forums I was going through it was mentioned that if there are interferences coming from the motor, use decoupling capacitor first, between motor terminal and between each terminal and motor body (I know I haven't used capacitor on my new setup) this will reduce the noise to a great extent. If there is still any interference coming out use twisted wires for the connection as this will filter out the ones bypassing the capacitor. And if you are still getting interference use ferrite core to eliminate the rest (although some noise will always find a way to come out).

In my case I believe the motor was the culprit, upon changing to a different one the issue was solved. But I was not able to identify what the exact cause of problem was.

1 Like

Looking at the photos, the new motor seems to be better quality.

Hi,
With this motor did you gnd the case of the motor?

Tom... :smiley: :+1: :coffee: :australia:

@Koepel Yes the new motor is of much better quality.

@TomGeorge No, I did not ground the motor case, only just soldered the caps as you can see in the image. I'm not sure exactly how to do that. if you could, can you tell me how that is done?

Hi,
You solder a wire to the case of the motor and connect the other end to the gnd of the controller.

Tom... :smiley: :+1: :coffee: :australia:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.