I have a problem. An Arduino Mega and Uno are connected over I2C. The Mega sends data to the Uno. This data transmission over I2C is very simple with an array and works perfectly fine. Now I would like to add a motor controller to the Uno for controlling a motor (AmpFlow E30-150). I have connected a Roboclaw 2x60A from the TX of the Uno to the S1 of the Roboclaw to transmit the control commands. While it is only connected and the motor is not controlled, all data is transmitted over I2C as usually. Now, if I try to send a command to the Roboclaw for turning the motors on, the I2C bus hangs and has issues. It makes the motors turning automatically without doing anything and if I change the command to control the motor it change very slowly or it happens nothing. Sometimes it turns with high speed or the motor turns with the same speed (uncontrollable) and the I2C bus is not working anymore until I reset it!
Now, to post a code is not that easy, because it is not really short and is part of a little system, but perhaps someone has had the same issue or know something what could cause it?
Here is a list what I have already tied:
Only I2C without the Roboclaw connected works perfectly
Roboclaw connected but without the motor works also perfectly
Roboclaw connected with the motor but no command send to turn the motor on works also perfectly
Sabertooth instead of a Roboclaw installed makes no difference, exactly the same problem
Shielded wires does not makes a difference
An I2C terminator from Adafruit LTC4311 helps a very little, but does not solve the problem
Twisted I2C wires does not make a difference
Set the clock speed of the I2C bus higher or lower - sometimes a little better, sometimes it does not works better as the standard 100kHz
Some Ferrite magnets on the motor wires and/or TX/RX wires, does not make any difference
Disconnected GND form the Roboclaw does not make any difference
Installed Ferrite magnets around the power wires from the Roboclaw and/or the motor, does not make any difference
Lowered the pullup resistors from I2C from around 4.7k to 1.8k does not make any difference
Now I have tried to send the commands over RX/TX and the Roboclaw is connected over TX on the Uno as before. This combination works perfectly without issues, but now, if I will add a OLED display over I2C, I have tried to connect it this time to the Uno with SDA/SCL, but exactly the same problem as before! The commands to the Roboclaw for turning the motor causes issues to control them correctly. The wires of the I2C bus are around 30cm. Now I am wondering, if I will make a PCB where I can connect the OLED display directly in, if that will work or causes the same issues. I really do not know why that is a problem. Again, without the motor it works perfectly fine!
To control over RX/TX instead I2C is okay, but the OLED display or any other display has I2C or too many pins to use. A display that works only over TX does not exist or I have not found one.
Now, perhaps anybody out there has a Roboclaw or Sabertooth and knows the problem with I2C?
To make your I2C bus more reliable, I would like to know everything. Show a photo, what are the pullup resistors, how is the GND wire going, which cable is used, give a link to your OLED display, a drawing with distances, and so on.
I put the OLED display in the top 5 of problems. They disturb the I2C bus, mostly for others. See: How to make a reliable I2C bus
That OLED display has probably a 3.3V I2C bus and your Arduino Mega and Uno have a 5V I2C bus. That means you have a voltage level problem and the noise marging has become a lot smaller.
What did you twist with what ? Keep SDA away from SCL. If you put them together in a cable next to each other then 30 cm is indeed too long.
I think that if you fix the voltage level problem and have the right amount of pullup, then a I2C device on the same PCB as the microcontroller is no problem. Unless you forget to put enough decoupling capacitors on the custom board.
You should reconsider your project and try to make it with a single microcontroller/processor.
I will check the Nextion display. Hope it is "easy" to use and do not require a lot of coding and libs.
GND is going to all devices I have in my system. Cable I have used is as described. I have tried a lot of different cables, but no differences. Now I have normal copper wires like the Dupont connector cables. The OLED display I use is the SSD1306. But I never used a display before and had exactly the same issues with only the Roboclaw! And the Roboclaw is connected with the TX from the Arduino. Distances are all about 30cm. But also if I connect the devices shorter, I have had this issues. The only thing what I have not tried is, to connect the display directly onto the PCB without wires. But that is only possible with the display.
SDA and SCL should be separated? and how is this going with the connectors? That is not possible. If that is really the problem of I2C, in this case I will never use I2C again!
SDA and SCL should not be side-to-side in a cable. At a connector is no problem.
The I2C bus was not designed to go into a cable or wires.
The most important wire of the I2C bus is the GND wire. It should be treated with the same care as SDA and SCL. There should be a GND wire from the display to the Arduino board and with nothing else connected to it. Something else could inject noise in the GND wire.
It is possible to twist SDA with GND and SCL with GND. That will increase the capacitance, so perhaps the clock speed (SCL) has to be lowered.
Even if you attach the display directly on the PCB, I prefer that you fix the voltage level mismatch and optimize the pullup.
The Nextion has libraries and is complex when you make more than one page (more than one screen). The ITEAD library is so cringeworthy that many replace it with something else, see: Using Nextion displays with Arduino
The display can do calculations as well. That means that the "intelligence" can be both in the sketch and in the display. Try to avoid that. I process everything in the sketch and the Nextion display is only for display output and button input.