Upcoming maintenance
Dear Customers and Partners.
This website will be undergoing scheduled maintenance on June 14, 2023. Please be aware there may be disruption to the developer portal website and associated services during the scheduled maintenance period.
This upgrade is essential to ensure the continued performance, reliability, and security of Developer World.
We apologize for any inconvenience.
I2C connection failed
-
I am trying to use MPU6050 with the spresense board. A lot of the time, I need to plug the USB port in and out multiple times until the sensor is detected. When it is detected, the connection drops after some time (I2C connection failed error). I found that the connection is much less stable when I'm trying to use Serial2 or Tx and Rx communication. Here is the code I'm using:
#include <Adafruit_MPU6050.h> #include <Wire.h> #include "math.h" Adafruit_MPU6050 mpu; float AccX[2], AccY[2], AccZ[2]; float VelX[2], VelY[2], VelZ[2]; float PosX[2], PosY[2], PosZ[2]; float gyroX, gyroY, gyroZ; float accPitch, accRoll, gyroAngleX, gyroAngleY, gyroAngleZ; float roll; float pitch; float AccErrorX, AccErrorY, AccErrorZ; float gyroErrorX, gyroErrorY, gyroErrorZ; bool calibrated; bool set_gyro_angles; float dt, currentTime, previousTime; void setup() { Serial.begin(115200); Serial2.begin(38400); while (!Serial) delay(10); Serial.println("Adafruit MPU6050 test!"); // Try to initialize! if (!mpu.begin()) { Serial.println("Failed to find MPU6050 chip"); while (1) { delay(10); } } mpu.setAccelerometerRange(MPU6050_RANGE_8_G); mpu.setGyroRange(MPU6050_RANGE_500_DEG); mpu.setFilterBandwidth(MPU6050_BAND_5_HZ); gyroAngleX = 0; gyroAngleY = 0; gyroAngleZ = 0; calibrated = false; set_gyro_angles = false; } void loop() { if(!calibrated){ Calibrate(); }else{ previousTime = currentTime; currentTime = millis(); / dt = (currentTime - previousTime) / 1000; sensors_event_t a, g, temp; mpu.getEvent(&a, &g, &temp); AccX[1] = a.acceleration.x - AccErrorX; AccY[1] = a.acceleration.y - AccErrorY; AccZ[1] = a.acceleration.z - AccErrorZ; // estimate tilt angles accPitch = atan2(AccY[1], sqrt(AccZ[1]*AccZ[1] + AccX[1]*AccX[1])); accRoll = - atan2(AccX[1], sqrt(AccZ[1]*AccZ[1] + AccY[1]*AccY[1])); gyroX = g.gyro.x - gyroErrorX; gyroY = g.gyro.y - gyroErrorY; gyroZ = g.gyro.z - gyroErrorZ; gyroAngleX += gyroX * dt; gyroAngleY += gyroY * dt; gyroAngleZ += gyroZ * dt; //simple complementary filter: if(set_gyro_angles){ float alpha = 0.025; //alpha for complimentary filter roll = (1-alpha)*(roll + gyroY*dt) + alpha*accRoll; //y-axis rotation pitch = (1-alpha)*(pitch + gyroX*dt) + alpha*accPitch; //x-axis rotation }else{ roll = accRoll; pitch = accPitch; set_gyro_angles = true; } int hook_angle = 180; int pitch_angle = pitch*RAD_TO_DEG + 90; int roll_angle = roll*RAD_TO_DEG + 90; Serial2.write(hook_angle); Serial2.write(pitch_angle); Serial2.write(roll_angle); // Print the values on the serial monitor Serial.print(pitch*RAD_TO_DEG); Serial.print(","); Serial.print(roll*RAD_TO_DEG); Serial.print(","); Serial.print(pitch_angle); Serial.print(","); Serial.println(roll_angle); } }
-
@tamer_ae You should continue your original topic. You already opened the 3rd one.
Can you take a photo of your wiring? Which pins do you use?
I did get I2C errors on the LSM303. But only very very few times.
I use Serial2 constantly talking to a BLE module.
"plug the USB port in and out multiple times" means resetting the board by powering off/on?
See also the documentation https://developer.sony.com/develop/spresense/docs/arduino_developer_guide_en.html#_wire_library
I2C communication requires the use of pull-up resistors.
- The Spresense extension board includes 1k Ohms pull-up resistors so no additional components are required.
The Spresense main board includes 4.7k Ohms pull-up resistors so no additional components are required.
- The Spresense extension board includes 1k Ohms pull-up resistors so no additional components are required.
-
@jens6151-0-1-1 my apologies, I should have continued on the original topic post.
For the wire connections, I have no additional components, I am connecting
MPU6050 -> Sony Extension Board
Vcc -> Vout
GND -> GND
SCL -> SCL (D15)
SDA -> SDA (D14)The code is based on the Wire library as far as I am aware.
As for the "plugging and unplugging", I am not sure if it's a power issue or not, but clicking the reset button does not work.
Many thanks -
@tamer_ae Honestly speaking it is difficult to say what causes the issues in your case. I am no expert in hardware.
It would be good (if not already done) to rule out sources of error.
I asked for a picture with the intention
- to check how the cables look like (poor cables, poor joints, long cables might cause issues you describe)
- to figure out the exact module (to know the schematics, if there are pull-ups. I connected to the main board via this adaptor. The vendor writes a warning about pull-ups. See below.)
- to see if you choose 5V or 3.3V (might affect the issue??)
If you have level shifters, connecting to the main board might be a try.
All in all, it sounds like there is noise on the lines.
I would assume that the code looks fine. You already tried several versions.
I think you said the same module works on another MCU, right? This excludes the module is faulty.In the end, you need to try out step by step to rule out possible errors. (If you think this costs too much time (you are already trying for weeks), changing the IMU or the MCU board might be an option?)
SPRESENSEのI2C信号はSPRESENSEメインボード上で4.7kΩで1.8Vにプルアップされているので、Qwiic基板を接続して動作しない場合はQwiic基板上のプルアップを外してみるといいかもしれません。 Google Translate: The SPRESENSE I2C signal is pulled up to 1.8V with 4.7kΩ on the SPRESENSE main board, so if you connect the Qwiic board and it doesn't work, you may want to remove the pull-up on the Qwiic board.
-
@jens6151-0-1-1 Thank you for your suggestions, I'm more confident now that it's a hardware issue or simply loose cables. I have tried with multiple sony boards, and multiple IMUs. This issue did get me to lose quite some time, but I still managed to test the main functionalities of my project.