Hi everyone,
I don't know if I'm on the right section but I hope so. I have been building a custom steering wheel to play racing simulation games on my pc using my Arduino Mega 2560 and the MegaJoy library. Due to complications I needed to move my steering axis on another board (an Arduino UNO R3) and it works by taking the analog value of a potentiometer (on pin A0) and the acceleration on the Y axis with a MPU-6050 (on the dedicated SDA and SCL of the UNO), mapping them in a 0-1024 range. The problem comes when i start using I2C on the UNO. Using it on the mega gave no problems on the reading itself, but when i move the SDA and SCL pins on the UNO the code freezes and never recovers back. The whole code is really long (always enough memory available tho) and I'm not gonna post it because nobody would even read it, but the problem comes even with the most basic test code:
#include<Wire.h>
const int MPU=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
Serial.begin(9600);
}
void loop(){
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU,14,true); // request a total of 14 registers
AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
Serial.print("Accelerometer: ");
Serial.print("X = "); Serial.print(AcX);
Serial.print(" | Y = "); Serial.print(AcY);
Serial.print(" | Z = "); Serial.println(AcZ);
//equation for temperature in degrees C from datasheet
Serial.print("Temperature: "); Serial.print(Tmp/340.00+36.53); Serial.println(" C ");
Serial.print("Gyroscope: ");
Serial.print("X = "); Serial.print(GyX);
Serial.print(" | Y = "); Serial.print(GyY);
Serial.print(" | Z = "); Serial.println(GyZ);
Serial.println(" ");
delay(333);
}
After a few seconds and some measurements (from 10 to even 700) it suddenly freezes. I've tried using a watchdog but it kicks in too slowly for my project (you can notice easily a stop on the data stream and while racing this isn't good because you can't control the car, so i need a better solution.
Please provide a link to the schematic of the board you're using and post a wiring diagram.
What pullups do you have in place for the I2C lines? Do you use a level converter to convert the 3V3 of the MPU-6050 to the 5V of the Arduino or do you simply pull them to 3V3?
You can patch the Wire library to better handle clumsy hardware/wiring but with a correct hardware setup this isn't necessary.
pylon:
Please provide a link to the schematic of the board you're using and post a wiring diagram.
What pullups do you have in place for the I2C lines? Do you use a level converter to convert the 3V3 of the MPU-6050 to the 5V of the Arduino or do you simply pull them to 3V3?
You can patch the Wire library to better handle clumsy hardware/wiring but with a correct hardware setup this isn't necessary.
I'm using a GY-521 breakout board which has a level converter on the 12c lines itself.
The wirin is pretty easy:
ON THE MEGA 2560:
5v - vcc of MPU-6050
gnd - gnd of MPU-6050
ON THE UNO;
gnd - MEGA 2560 gnd (common ground)
sda - sda of MPU-6050
scl - scl of MPU-6050
Code-wise I have no problems with running it on the mega so it should be a connection issue (i was using the sensor on the uno before starting the project and never got problems). Other than connecting the ground togheter, what can i do? Can the problem be related to using another board's power lines?
I'm using a GY-521 breakout board which has a level converter on the 12c lines itself.
Not the ones I know of. It has a voltage regulator for 3V3 and pullups for the I2C lines but no level converter. It might work for some time with that setup but because the Wire library activates the internal pullups to 5V. So the pullups form a voltage divider which results on the I2C lines being pulled to about 3.85V which is above the MPU-6050's specification. It might destroy your MPU-6050 immediately, it might work for weeks and fail at any time later. But you're definitely not inside the recommendations of the manufacturer.
Can the problem be related to using another board's power lines?
I don't think so but measure the 5V on the Mega and the 5V on the UNO. It might be that the voltage on the UNO is lower than the Mega and therefor the above calculation results in a bit better values.
pylon:
I don't think so but measure the 5V on the Mega and the 5V on the UNO. It might be that the voltage on the UNO is lower than the Mega and therefor the above calculation results in a bit better values.
Ok, I had a busy week but I have tried measuring the voltage from the 5V of the Uno and of the Mega, the one on the UNO is about 0,1V higher than the Mega's.
pylon:
Not the ones I know of. It has a voltage regulator for 3V3 and pullups for the I2C lines but no level converter. It might work for some time with that setup but because the Wire library activates the internal pullups to 5V. So the pullups form a voltage divider which results on the I2C lines being pulled to about 3.85V which is above the MPU-6050's specification. It might destroy your MPU-6050 immediately, it might work for weeks and fail at any time later. But you're definitely not inside the recommendations of the manufacturer.
How do you suggest to solve this? Sorry but this is my first time working with the I2C so I have no experience
Thanks for your help.