Open MahmoudElgendy95 opened 6 years ago
Likely the problem is the wire leads between the host MCU and MPU9250 are either too thin or too long to support I2C, which is relatively short range communication protocol.
On Wed, Sep 20, 2017 at 6:02 AM, mahmoudelgendy1995 < notifications@github.com> wrote:
hi, in my application i need to use 8 MPU9250 using I2c . I succeeded to connect to just 3 and get an accurate readings from them , but when i tried to increase the number of sensors , i get wrong readings from all of them . so any advice to be able to connect the 8 together !
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/186, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qnibgO_FT-4DpxqHu7MM7YC3qZv6ks5skQzxgaJpZM4Pd1UB .
after what long it will be considered too long for i2c bus ? and if the range is long do you think I2C multiplexer is the solution ?
12 inches should be fine, four feet not so much.
Use large diameter (small guage) copper wire. Might need to shield the wires with GND lines. twist SDL with VCC and twist SCL separately with GND, for example could help.
On Thu, Sep 21, 2017 at 11:51 AM, mahmoudelgendy1995 < notifications@github.com> wrote:
after what long it will be considered too long for i2c bus ? and if the range is long do you think I2C multiplexer is the solution ?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/186#issuecomment-331248261, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qvuirpdX9hEG64X8FvcNxz5sT5XKks5skrBFgaJpZM4Pd1UB .
Hi Kris and mahmoudelgendy1995,
I am trying to do something similar here, but am unable to implement it into my code (I have read through the other issues but to no avail). Would either of you be able to share some code/explain in detail to help me?
Setup: 2 Sparkfun MPU9250s (SJ2 changed to allow AD0 to control the register from 0x68 to 0x69-verified for each IMU that this works) Teensy 3.5 (both IMUs connected to 18, 19), both connected to the same interrupt, AD0s connected to different digitalWrite pins to change HIGH/LOW separately)
Goal: multiplex 2 MPU9250s onto the same bus and Serialprint both sensor's yaw/pitch/roll outputs separately This will be used for a research project to determine angles of someone's wrist (not overly worried about yaw, but Pitch and Roll important)
Code Alterations to original Sketch:
Below is to allow only one MPU to be read, and the logic for the next loop iteration.
A1B0 is cast as boolean:
At the beginning of Void loop(),
{ if(A1B0==true){ digitalWrite(adoPinA, LOW); digitalWrite(adoPinB, HIGH); A1B0 = false; } else { digitalWrite(adoPinA, HIGH); digitalWrite(adoPinB, LOW); A1B0 = true; }
Below is to change what is defined for input into the filter:
` if(A1B0==true){
// Now we'll calculate the accleration value into actual g's
ax = (float)MPU9250Data[0]aRes - accelBias[0]; // get actual g value, this depends on scale being set
ay = (float)MPU9250Data[1]aRes - accelBias[1];
az = (float)MPU9250Data[2]*aRes - accelBias[2];
// readGyroData(gyroCount); // Read the x/y/z adc values
// Calculate the gyro value into actual degrees per second
gx = (float)MPU9250Data[4]*gRes; // get actual gyro value, this depends on scale being set
gy = (float)MPU9250Data[5]*gRes;
gz = (float)MPU9250Data[6]*gRes;
}
else{
// Now we'll calculate the accleration value into actual g's
ax = (float)MPU9250Data[0]*aRes - accelBiasB[0]; // get actual g value, this depends on scale being set
ay = (float)MPU9250Data[1]*aRes - accelBiasB[1];
az = (float)MPU9250Data[2]*aRes - accelBiasB[2];
// readGyroData(gyroCount); // Read the x/y/z adc values
// Calculate the gyro value into actual degrees per second
gx = (float)MPU9250Data[4]*gRes; // get actual gyro value, this depends on scale being set
gy = (float)MPU9250Data[5]*gRes;
gz = (float)MPU9250Data[6]*gRes;
}`
Below is to assign the values to separate variables to be printed `if (A1B0 == true) {
pitch = -asinf(a32);
roll = atan2f(a31, a33);
yaw = atan2f(a12, a22);
pitch *= 180.0f / PI;
yaw *= 180.0f / PI;
yaw += 2.7f;
if(yaw < 0) yaw += 360.0f; // Ensure yaw stays between 0 and 360
roll *= 180.0f / PI;
}
else { pitchB = -asinf(a32);
rollB = atan2f(a31, a33);
yawB = atan2f(a12, a22);
pitchB *= 180.0f / PI;
yawB *= 180.0f / PI;
yawB += 2.7f; /
if(yawB < 0) yawB += 360.0f; // Ensure yaw stays between 0 and 360
rollB *= 180.0f / PI;
}`
Then Print:
if(SerialDebug) { Serial.print("YawA, PitchA, RollA: "); Serial.print(yaw, 2); Serial.print(", "); Serial.print(pitch, 2); Serial.print(", "); Serial.print(roll, 2); Serial.print("\t"); Serial.print("YawB, PitchB, RollB: "); Serial.print(yawB, 2); Serial.print(", "); Serial.print(pitchB, 2); Serial.print(", "); Serial.print(rollB, 2); Serial.print(", "); // Serial.print(digitalRead(adoPinA)); // Serial.print(", "); Serial.println(A1B0);
I also copied the selfTest function and renamed it,, and changed all variables to have them store separately for both MPUs.
My thoughts: I think my error lies in using the same interrupt pin, and or not declaring a separate MPU9250Data for each separate MPU. Or honestly no idea my coding skills are limited. I'm not sure what to do next.
Any help would be greatly appreciated.
Where are you changing the MPU9250 address in the I2C read calls?
On Fri, Nov 17, 2017 at 10:02 AM, iiiBadgeriii notifications@github.com wrote:
Hi Kris and mahmoudelgendy1995,
I am trying to do something similar here, but am unable to implement it into my code (I have read through the other issues but to no avail). Would either of you be able to share some code/explain in detail to help me?
Setup: 2 Sparkfun MPU9250s (SJ2 changed to allow AD0 to control the register from 0x68 to 0x69-verified for each IMU that this works) Teensy 3.5 (both IMUs connected to 18, 19), both connected to the same interrupt, AD0s connected to different digitalWrite pins to change HIGH/LOW separately)
Goal: multiplex 2 MPU9250s onto the same bus and Serialprint both sensor's yaw/pitch/roll outputs separately This will be used for a research project to determine angles of someone's wrist (not overly worried about yaw, but Pitch and Roll important)
Code Alterations to original Sketch: Below is to allow only one MPU to be read, and the logic for the next loop iteration. A1B0 is cast as boolean: At the beginning of Void loop(), { if(A1B0==true){ digitalWrite(adoPinA, LOW); digitalWrite(adoPinB, HIGH); A1B0 = false; } else { digitalWrite(adoPinA, HIGH); digitalWrite(adoPinB, LOW); A1B0 = true; } Below is to change what is defined for input into the filter: ` if(A1B0==true){ // Now we'll calculate the accleration value into actual g's ax = (float)MPU9250Data[0]aRes - accelBias[0]; // get actual g value, this depends on scale being set ay = (float)MPU9250Data[1]aRes - accelBias[1]; az = (float)MPU9250Data[2]*aRes - accelBias[2];
// readGyroData(gyroCount); // Read the x/y/z adc values
// Calculate the gyro value into actual degrees per second gx = (float)MPU9250Data[4]gRes; // get actual gyro value, this depends on scale being set gy = (float)MPU9250Data[5]gRes; gz = (float)MPU9250Data[6]*gRes; }
else{ // Now we'll calculate the accleration value into actual g's ax = (float)MPU9250Data[0]aRes - accelBiasB[0]; // get actual g value, this depends on scale being set ay = (float)MPU9250Data[1]aRes - accelBiasB[1]; az = (float)MPU9250Data[2]*aRes - accelBiasB[2];
// readGyroData(gyroCount); // Read the x/y/z adc values
// Calculate the gyro value into actual degrees per second gx = (float)MPU9250Data[4]gRes; // get actual gyro value, this depends on scale being set gy = (float)MPU9250Data[5]gRes; gz = (float)MPU9250Data[6]*gRes; }`
Below is to assign the values to separate variables to be printed `if (A1B0 == true) {
pitch = -asinf(a32);
roll = atan2f(a31, a33);
yaw = atan2f(a12, a22);
pitch *= 180.0f / PI;
yaw *= 180.0f / PI;
yaw += 2.7f;
if(yaw < 0) yaw += 360.0f; // Ensure yaw stays between 0 and 360
roll *= 180.0f / PI;
}
else { pitchB = -asinf(a32);
rollB = atan2f(a31, a33);
yawB = atan2f(a12, a22);
pitchB *= 180.0f / PI;
yawB *= 180.0f / PI;
yawB += 2.7f; /
if(yawB < 0) yawB += 360.0f; // Ensure yaw stays between 0 and 360
rollB *= 180.0f / PI;
}`
Then Print: if(SerialDebug) { Serial.print("YawA, PitchA, RollA: "); Serial.print(yaw, 2); Serial.print(", "); Serial.print(pitch, 2); Serial.print(", "); Serial.print(roll, 2); Serial.print("\t"); Serial.print("YawB, PitchB, RollB: "); Serial.print(yawB, 2); Serial.print(", "); Serial.print(pitchB, 2); Serial.print(", "); Serial.print(rollB, 2); Serial.print(", "); // Serial.print(digitalRead(adoPinA)); // Serial.print(", "); Serial.println(A1B0); I also copied the selfTest function and renamed it,, and changed all variables to have them store separately for both MPUs.
My thoughts: I think my error lies in using the same interrupt pin, and or not declaring a separate MPU9250Data for each separate MPU. Or honestly no idea my coding skills are limited. I'm not sure what to do next.
Any help would be greatly appreciated.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/186#issuecomment-345317930, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qlErFISfBLghmsAB6Xa0D3NhcBrNks5s3co-gaJpZM4Pd1UB .
Sorry if this isn't what you mean, but this is before void setup `#define ADO 0
Not going to work then.
On Fri, Nov 17, 2017 at 10:28 AM, iiiBadgeriii notifications@github.com wrote:
Sorry if this isn't what you mean, but this is before void setup `#define ADO 0
if ADO
define MPU9250_ADDRESS 0x69 // Device address when ADO = 1
define AK8963_ADDRESS 0x0C // Address of magnetometer
define MS5637_ADDRESS 0x76 // Address of altimeter
else
define MPU9250_ADDRESS 0x68 // Device address when ADO = 0
define AK8963_ADDRESS 0x0C // Address of magnetometer
define MS5637_ADDRESS 0x76 // Address of altimeter
endif `
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/186#issuecomment-345324311, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1quvuPVJStHWJjYtvIWNgSj9m3oJlks5s3dA8gaJpZM4Pd1UB .
Does it need to be moved inside of Void loop() ?
Need someway to change i2c adress, right?
On Fri, Nov 17, 2017 at 10:33 AM iiiBadgeriii notifications@github.com wrote:
Does it need to be moved inside of Void loop() ?
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/186#issuecomment-345325736, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qloO_WMwAdSrZuvmMVCcPhdQdWk6ks5s3dGLgaJpZM4Pd1UB .
So I guess I'm still at a loss of what to do. This is what I did and still not getting individual outputs. I removed "#define ADO 0;" and instead used int ADO = 0; Then I added this
void loop()
{
#if ADO
#define MPU9250_ADDRESS 0x69 // Device address when ADO = 1
#define AK8963_ADDRESS 0x0C // Address of magnetometer
#define MS5637_ADDRESS 0x76 // Address of altimeter
#else
#define MPU9250_ADDRESS 0x68 // Device address when ADO = 0
#define AK8963_ADDRESS 0x0C // Address of magnetometer
#define MS5637_ADDRESS 0x76 // Address of altimeter
#endif
if(ADO == 1){
digitalWrite(adoPinA, LOW);
digitalWrite(adoPinB, HIGH);
ADO = 0;
}
else
{
digitalWrite(adoPinA, HIGH);
digitalWrite(adoPinB, LOW);
ADO = 1;
}
I verified? that I'm only reading one MPU at a time by
byte q = readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250); // Read WHO_AM_I register for MPU-9250
Serial.print(digitalRead(adoPinA));
Serial.print(", ");
Serial.print(digitalRead(adoPinB));
Serial.println(q, HEX);
This allows me to see that the different ADO pins are alternating, and always gettting a who am I of 71. When I unplug one of the MPUs, I get an alternating "71, FF, 71" both times and corresponding to either adoPinA or adoPinB respectively, depending on which one was removed. Putting either of the ADO pins directly to 3.3V also gives me this result.
Any other thoughts/hints/pointing out my naive erros on how to resolve this would be greatly appreciated.
This belongs outside of the main loop and setup:
this:
setup SPI initialize end setup
loop set ADO to read MPU9250ADDRESS_1 read MPU9250_1_data set ADO to read MPU9250ADDRESS_2 read MPU9250_2 data end loop
Is this really that hard?
On Fri, Nov 17, 2017 at 6:19 PM, iiiBadgeriii notifications@github.com wrote:
So I guess I'm still at a loss of what to do. This is what I did and still not getting individual outputs. I removed "#define ADO 0;" and instead used int ADO = 0; Then I added this
void loop() {
if ADO
define MPU9250_ADDRESS 0x69 // Device address when ADO = 1
define AK8963_ADDRESS 0x0C // Address of magnetometer
define MS5637_ADDRESS 0x76 // Address of altimeter
else
define MPU9250_ADDRESS 0x68 // Device address when ADO = 0
define AK8963_ADDRESS 0x0C // Address of magnetometer
define MS5637_ADDRESS 0x76 // Address of altimeter
endif
if(ADO == 1){ digitalWrite(adoPinA, LOW); digitalWrite(adoPinB, HIGH); ADO = 0; } else { digitalWrite(adoPinA, HIGH); digitalWrite(adoPinB, LOW); ADO = 1; }
I verified? that I'm only reading one MPU at a time by byte q = readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250); // Read WHO_AM_I register for MPU-9250 Serial.print(digitalRead(adoPinA)); Serial.print(", "); Serial.print(digitalRead(adoPinB)); Serial.println(q, HEX);
This allows me to see that the different ADO pins are alternating, and always gettting a who am I of 71. When I unplug one of the MPUs, I get an alternating "71, FF, 71" both times and corresponding to either adoPinA or adoPinB respectively, depending on which one was removed.
Any other thoughts/hints/pointing out my naive erros on how to resolve this would be greatly appreciated.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/186#issuecomment-345411411, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qlaGLYoqn_THZt5e4-EsluV3og8aks5s3j61gaJpZM4Pd1UB .
hi, in my application i need to use 8 MPU9250 using I2c . I succeeded to connect to just 3 and get accurate readings from them , but when i tried to increase the number of sensors , i get wrong readings from all of them . so any advice to be able to connect the 8 together !