I2C lockup using MPU6050 and XBee
- Dominant language
- Java
- Stars
- 14.6k
- Forks
- 7k
- PR merge metrics
- No merged PRs in 30d
Description
I have been able to consistently reproduce a problem using an arduino zero, MPU6050 and XBee. MPU6050 is connected via I2C and XBee on pins 0 &1.
Using the following sketch I am able to get the I2C to lockup when sending data to the XBee from the PC. Note the XBee serial port has not been opened. I2C can lockup at "B" or "R":
```
#include
MPU6050 accelgyro;
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;
unsigned long Hz100Loop = 0;
unsigned long Hz10Loop = 0;
unsigned long Hz20Loop = 0;
const int MPU_addr=0x68;
void loop10Hz()
{
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
}
void readMPU()
{
int8_t buffer[15];
Serial.println("B");
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Serial.println("R");
Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers}
Serial.println("L");
int count = 0;
while (Wire.available() && count<14)
{
Serial.print("S");
Serial.println(count);
buffer[count] = Wire.read();
Serial.println("E");
count++;
}
Serial.println("F");
}
void loop100Hz()
{
int16_t ax,ay,az,gx,gy,gz;
//accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
readMPU();
}
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("initializing");
accelgyro.initialize();
accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_2000);
if (accelgyro.testConnection())
{
Serial.println("test ok");
}
pinMode(LED_PIN, OUTPUT);
}
// the loop function runs over and over again until power down or reset
void loop() {
int delta100Hz = millis()-Hz100Loop;
int delta10Hz = millis()-Hz10Loop;
if (delta100Hz>=10)
{
loop100Hz();
Hz100Loop=millis();
}
if (delta10Hz>=100)
{
loop10Hz();
Hz10Loop=millis();
}
}
```
To generate serial data from the PC I am using a simple .Net application which is basically on a timer sending a few bytes of data:
```
serial = new SerialPort("COM4", 57600);
serial.DataReceived += new SerialDataReceivedEventHandler(HandleSerialData);
serial.Open();
...
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 0,0,20);
...
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
if (serial != null)
{
serial.WriteLine(string.Format("B:{0:F0}", 50));
}
}
```
Arduino SDK version 1.6.7. The issue will occur using just the I2CDev library as well - but that just calls Wire anyway. I have also reproduced this on a Leonardo.
As far as I can tell, without sending any data to the XBee port from the PC, the code will run indefinitely.
Contributor guide
Research direction
Start with the Wire implementation behind Wire.beginTransmission(), endTransmission(false), and requestFrom(), then reproduce the provided sketch on an Arduino Zero or Leonardo while sending serial data through the XBee. Done means the I2C read no longer locks up at the reported points, while the existing MPU6050 communication continues to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100