Sony's Developer World forum

    • Home
    • Forum guidelines

    I2C connection failed

    Spresense
    2
    5
    65
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      tamer_ae last edited by

      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);
        }
      }
      
      J 1 Reply Last reply Reply Quote
      • J
        jens6151 0 1 1 @tamer_ae last edited by

        @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.
        T 1 Reply Last reply Reply Quote
        • T
          tamer_ae @jens6151 0 1 1 last edited by

          @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

          J 1 Reply Last reply Reply Quote
          • J
            jens6151 0 1 1 @tamer_ae last edited by

            @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.
            
            T 1 Reply Last reply Reply Quote
            • T
              tamer_ae @jens6151 0 1 1 last edited by

              @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.

              1 Reply Last reply Reply Quote
              • First post
                Last post
              Developer World
              Copyright © 2021 Sony Group Corporation. All rights reserved.
              • Contact us
              • Legal