Problem with programming?

Hi
i try to use platform.io with vs code since a few days now.
I try to get data from an i2c device.
After a lot of trouble with mbed i used a code for arduino framework.
First time I programmed it i got my output as i wanted. For the next run I changed the address of the device, no working output anymore, so I switched back to the old address ( the code worked 2minutes ago, just changed one variable) and now I dont get any correct output anymore.

How is this possible? Do I need more steps to setup the environment?

ty

Such problems require a more detail to solve.

  • can you show a schematic diagram of what components and chips you connect together?
  • can you show the full platformio.ini and the code?

Though a suddenly changing / non-working I2C device sounds more like an electrical issue to me.

I am using a Nucleo F401RE and a gy-521. I connected 5V, GND, SDA, SCL between both boards. On the breadboard where the GY-521 is placed on I connected the GND with the AD0 pin.

That setup worked once. I disconnected the AD0 and Ground to test a different address and it stopped to work, even after putting it back in the old working configuration. I changed the port in the software as well.

I will post the arduino code here, because it worked after the first time of programming and the second time it failed. I have more problems with the mbed platform but could be the same reason.

This is the platformio.ini code

[env:nucleo_f401re]
platform = ststm32
board = nucleo_f401re
framework = arduino

This is the code (found it on the web, working with the mkr1000 and arduino ide) I use to test the board after failing hard with platform.io, vs code and mbed.

#include <Arduino.h>
#include<Wire.h>
const int MPU1=0x68; 
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU1);
  Wire.write(0x6B); 
  Wire.write(0);    
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU1);
  Wire.write(0x3B);  
  Wire.endTransmission(false);
  Wire.requestFrom(MPU1,12,true);  
  AcX=Wire.read()<<8|Wire.read();    
  AcY=Wire.read()<<8|Wire.read();  
  AcZ=Wire.read()<<8|Wire.read();  
  GyX=Wire.read()<<8|Wire.read();  
  GyY=Wire.read()<<8|Wire.read();  
  GyZ=Wire.read()<<8|Wire.read();  
  Serial.print("Accelerometer: ");
  Serial.print("X = "); Serial.print(AcX);
  Serial.print(" | Y = "); Serial.print(AcY);
  Serial.print(" | Z = "); Serial.println(AcZ);  
  Serial.print("Gyroscope: ");
  Serial.print("X = "); Serial.print(GyX);
  Serial.print(" | Y = "); Serial.print(GyY);
  Serial.print(" | Z = "); Serial.println(GyZ);
  Serial.println(" ");
  delay(1000);
}

AD0 is pulled down to GND by 4.7k resistor R6 anyways schematics. If AD0 would be high, the address would change from 0x68 to 0x69.

I don’t see a problem with your wiring. For VCC, either 3.3V or 5V can be used, so that’s ok. Can you try 3.3V regardless?

You can insert a check there wether the device has actually returned 12 bytes.

  if (Wire.available() != 12)
  {
     Serial.println("I2C device failed to respond with 12 bytes");
     return; //early exit
  }

what is the output of the firmware now?

thanks a lot.

I wanted to try it out. My Laptop was shut down and the Nucleo was not conntected.
I just started everything up, compiled the code and programed the nucleo again. Now the code works, output is correct.
I can try to compile it again and program the mcu again without changing anything now

Double check for bad wiring or replace cables if in doubt, too.

I am not able to find the problem, I might test a different IDE :frowning:

#include "mbed.h"
#include<iostream>
#define WHO_AM_I_MPU6050 0x75 // Should return 0x68
#define ACCEL_XOUT_H     0x3B
#define ADO 0
#if ADO
#define MPU6050_ADDRESS 0x69<<1  // Device address when ADO = 1
#else
#define MPU6050_ADDRESS 0x68<<1  // Device address when ADO = 0
#endif
I2C i2c(I2C_SDA, I2C_SCL);
float sum = 0;
uint32_t sumCount = 0;
DigitalOut onboardled(LED1);
int16_t accelCount[3];  // Stores the 16-bit signed accelerometer sensor output
float ax, ay, az;       // Stores the real accel value in g's
char readByte(uint8_t address, uint8_t subAddress)

{
    char data[1]; // `data` will store the register data     
    char data_write[1];
    data_write[0] = subAddress;
    i2c.write(address, data_write, 1, 1); // no stop
    i2c.read(address, data, 1, 0); 
    std:cout<<data[0]<<"\n\r";
    return data[0]; 
}
void readAccelData(int16_t * destination);
void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest);

int main()
{
  //Set up I2C
  i2c.frequency(400000);  // use fast (400 kHz) I2C   
  // Read the WHO_AM_I register, this is a good test of communication
  uint8_t whoami = readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050);  // Read WHO_AM_I register for MPU-6050
  std::cout<<"I am 0x"<<+whoami<<"\n\r"; // Not working !!!!!!!!!
  std::cout<<"I am 0x"<<whoami<<"\n\r";
  printf("I AM 0x%x\n\r", whoami); printf("I SHOULD BE 0x68\n\r");

  // init 

  // mpu6050.initMPU6050(); std::cout<<("MPU6050 initialized for active data mode....\n\r"); // Initialize device for active mode read of acclerometer, gyroscope, and temperature

 

  while(1) {
    readAccelData(accelCount);  // Read the x/y/z adc values
    wait_us(100000);
   // std::cout<<"ACCEL_XOUT_H: "<<ax;
    // printf("ax = %f", 1000*ax);
    }
  }

void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
{     
    char data[14];
    char data_write[1];
    data_write[0] = subAddress;
    i2c.write(address, data_write, 1, 1); // no sto
    i2c.read(address, data, count, 0); 
    for(int ii = 0; ii < count; ii++) {
     dest[ii] = data[ii];
    }

}  

void readAccelData(int16_t * destination)

{
  uint8_t rawData[6];  // x/y/z accel register data stored here

  readBytes(MPU6050_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]);  // Read the six raw data registers into data array

  destination[0] = (int16_t)(((int16_t)rawData[0] << 8) | rawData[1]) ;  // Turn the MSB and LSB into a signed 16-bit value
  destination[1] = (int16_t)(((int16_t)rawData[2] << 8) | rawData[3]) ;  
  destination[2] = (int16_t)(((int16_t)rawData[4] << 8) | rawData[5]) ; 
  std::cout<<"destination inside of lib: "<<+destination[0]<<"\n\r";
  std::cout<<"destination inside of lib: "<<+destination[1]<<"\n\r";
  std::cout<<"destination inside of lib: "<<+destination[2]<<"\n\r";
  std::cout<<" -------------------------------------------"<<"\n\r";
  wait_us(1000000);
} 

It seems like that code is working. The only thing I changed was adding this line
printf("I AM 0x%x\n\r", whoami); printf("I SHOULD BE 0x68\n\r");

without that line my output was always zero. How is that possible?
Are there any problems with platformio and nucleo? I am super confused right now :confused:

now it works without that line. why shouldnt it …
I didnt change anything else here. It feels like a 50:50 chance