I2C Problem on R4 wifi

Hi all, issues with I2C. For testing purposes I am trying to just get sensible accelerometer data from a MPU6050. Four wire connection. A5, A4, +5v and Gnd. Can anyone throw any light on why this code yields perfectly sensible data on the R3 and nonsense on the R4?

#include<Wire.h>

const int camIMU = 0x68;

float roll, pitch;
float timeStamp;


void setup() {

  Wire.begin();                                      //Initialize
  Wire.beginTransmission(camIMU);                    //Start communication
  Wire.write(0x6B);                                  //Talk to the register 6B
  Wire.write(0);                                     //Make the reset (place a 0 into the 6B register)
  Wire.endTransmission(true);                        //End the transmission
  
  Serial.begin(115200);
  Serial.println("Ready");
  Wait(1000);
}

void loop() {

  timeStamp = micros();
  getRoll();
  Serial.print(roll);
  Serial.print("    ");
  Serial.println(pitch);
  Wait(200);
 // Serial.println(micros() - timeStamp);


}

  
void getRoll() {

  float aX, aY, aZ;
  
  Wire.beginTransmission(camIMU);    //read the sensor data
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(camIMU, 6, true); //get six bytes accelerometer data

  aX = Wire.read() << 8 | Wire.read();
  aY = Wire.read() << 8 | Wire.read();
  aZ = Wire.read() << 8 | Wire.read();

  roll = atan2(aY , aZ) * 180.0 / PI;
  pitch = atan2(-aX , sqrt(aY * aY + aZ * aZ)) * 180.0 / PI;  
  
}


void Wait(int gap){
  unsigned long markMillis = millis();
  while (millis() < markMillis + gap)  {}
}

It might relate to a difference in physical implementation that's not shown in your post.

I.e. please show:

  • a schematic diagram of both setups
  • Photos that show the actual wiring on both setups

Furthermore, can you please be more specific on what 'nonsense' constitutes? What output does the sketch produce on the R3? What's the output that you get on the R4?

As this relates to an I2C issue, part of the troubleshooting process is generally to run an I2C detection sketch to see if the I2C device is indeed recognized correctly. Have you confirmed that this happens on the R4 board as well?

Try by shiting your I2C connections from A4/A5 to SDA/SCL pins at the right edge connector of UNOR4.

Those are the same nets. Refer to UNO R4 schematic: https://docs.arduino.cc/resources/schematics/ABX00080-schematics.pdf

1 Like

From the schematic:

immagine

Have you try to connect external pullup?

Ciao, Ale.

I had already run an I2C scan and the device is found at the same address on both R3 and R4. There is nothing else connected.

This is a sample of the output I am seeing ....


      R4                      R3
_______________        _______________
75.11    -43.79        -0.38     2.43       
74.98    -43.79        -0.47     2.54     
75.15    -43.77        -0.38     2.38     
75.05    -43.75        -0.52     2.35     
75.08    -43.76        -0.73     2.35     
75.14    -43.76        -0.38     2.03     
75.15    -43.77        -0.45     2.60     
75.12    -43.76        -0.87     2.33     
                   
                   
76.50    -6.46          0.25   -26.33   
76.58    -6.46          0.22   -26.08   
0.23    -26.08          0.07   -25.85   
0.03    -26.31          0.04   -26.54   
76.60    -6.49          0.26   -25.91   
0.10    -25.84          0.06   -25.93   
76.52    -6.52         -0.01   -25.94  
0.21    -26.39         -0.25   -25.96  
                   
                   
0.00    -74.94         -1.15    30.94   
0.76    -75.28         -1.25    31.26   
0.71    -74.04         -1.52    30.72   
2.15    -74.85         -1.12    31.16   
2.56    -74.57         -1.32    30.99   
2.37    -74.48         -1.26    31.00   
1.96    -74.80         -1.05    31.10   
2.44    -74.74         -1.27    31.27   
2.91    -75.02         -1.30    31.16   
                   

The first batch is while the 6050 is level and then the other two are with it tilted (approximately) 30 degrees one way then the other. Note not only the weird values but also the wild fluctuations.

These are pictures of the two setups . . . .


Maybe this is a little risky w.r.t. how the compiler optimizes this code. How about breaking it down so that you know for sure that both read()'s are done in the order you want them to be done.

uint16_t bh, bl;
bh = Wire.read();
bh <<= 8;
bl = Wire.read();
aX = float(bh | bl);

I did not test this snippet; it's just offered to illustrate what I mean by 'breaking it down'. Note that the code is formulated in a bit of a 'pedantic'/'for dummies' kind of way, which in part will definitely be unnecessary, but as you'll understand this is done to enforce a predictable order of execution.

It's a definite no-no, I learned the hard way!

I fixed it with

byte lo = Wire.read();
byte hi = Wire.read();
word w = word(hi, lo);
1 Like

Thanks. Tried it but get exactly the same results.

This suggestion gives somewhat different results but just as erratic and nonsensical.

Could this not be some sort of timing issue?

As a matter of interest, does the Wire1 interface on the Qwiiic connector work ?

See https://docs.arduino.cc/tutorials/uno-r4-wifi/qwiic/

I haven't tried. Not sure that I have a Qwiiic connector. Will have to search a bit.

Would there be any point in trying the SDA/SCL connectore on the other side along with some pullups?

As before, please show how they're different. It's impossible for others to spot a possible pattern if the observations are missing.

Also, it may help to make your sketch display the raw data before converting to float. Any bit-wise corruptions would be easier to spot this way. I'd make it print both the hex (or dec) values and bin values to Serial.

Do you have a different I2C device that you can test with the R4 board? Doesn't matter much which it is; just something that allows you to pull some data from it so you can see if anything gets corrupted.

Have you tried adding pullups (e.g. 3k3 or 4k7) to the I2C lines? It's possible that the R3 board juuuust works with the available pullups on your sensor board, but that the R4 struggles. Keep in mind it's a different type of controller and differences in robustness of I2C performance under marginal conditions can be expected.

If I could discern a pattern or even consistency in the output I would certainly feel we were on the right track but honestly, there is nothing there.

I think I have some magnetic encoders that optionally use I2C. I will see what they come up with.

Thanks for the pullup suggestion. As you see above I was wondering about that myself. I will try that as well.

BTW - Everyone's input is really appreciated. I do not take it for granted.

You're overlooking the possibility that there's a pattern that you're overlooking but someone else does recognize. For instance, I do see the start of a pattern in the data you've already posted, but the lack of good data to work with precludes from following that trail.

The whole point of asking others for help is that they may be able to make more of the information available to you than you yourself are.

I accept that criticism however in order to discern anything one really needs quite a lot of data. Not the tiny fragments I posted. Let me try those other two possibilities and if they fail I will log a decent amount of data and send it as a file.

Right at the moment it is month end and if I don't get a tax return in they are going to carry me off in chains so I will revert as soon as I can. Hopefully tomorrow.

A small dataset is better than no dataset. What you posted before is already quite nice, but it would be nicer to have the integer values. If you included the same amount of data for the code variations you tried (see #10), I think it should be possible to spot a pattern if there's any obvious pattern going on. No need to go overboard with hundreds of tuples per set.

LOL

Can you check that Wire.requestFrom() returns (size_t) 6, the expected number of bytes ?

Be careful, the I2C on the Qwiic connector is 3.3v, do not connect to a 5v device.

It should return either the number of bytes requested, or (if I recall correctly) zero if there was an error communicating with the device. The requested number of bytes is read in, regardless of how many are actually sent.