kriswiner/EM7180_SENtral_sensor_hub

ESP32 received no Data

Opened this issue · 22 comments

Hello i tried to use the Ultimate Sensor with an ESP32, but it looks like i have no SENtral device information.

Scanning...
I2C device found at address 0x28  !
done

EM7180 ROM Version: 0x00
Should be: 0xE609
EM7180 RAM Version: 0x00
EM7180 ProductID: 0x0 Should be: 0x80
EM7180 RevisionID: 0x0 Should be: 0x02
EEPROM upload successful!
Beginning Parameter Adjustments

and it hangs there...

That i found on the master bus

Scanning...
I2C device found at address 0x50  !
I2C device found at address 0x58  !
I2C device found at address 0x68  !
I2C device found at address 0x76  !
done

any ideas what is wrong?

//  Wire.endTransmission(I2C_NOSTOP);        // Send the Tx buffer, but send a restart to keep connection alive
  Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive

i have changed some of this parts, but nothing happens.

Best regards Malte

Hi, it is a new sensor from here...
https://www.tindie.com/products/onehorse/ultimate-sensor-fusion-solution-mpu9250/

an Adafruit BNO055 works well. And when i look at the "read" and "write" -functions there is no big difference in the codes...

https://drive.google.com/file/d/1qiI_mmkYXjXQ1CANHQXgkCvi_9Lw5-jD/view?usp=sharing

I2C device found at address 0x28  !
done

EM7180 ROM Version: 0xE69
Should be: 0xE609
EM7180 RAM Version: 0x17435
EM7180 ProductID: 0x80 Should be: 0x80
EM7180 RevisionID: 0x2 Should be: 0x02
A barometer is installed
A temperature sensor is installed
EEPROM detected on the sensor bus!
EEPROM uploaded config file!
EM7180 in initialized state!
EEPROM upload successful!
Beginning Parameter Adjustments
Magnetometer Default Full Scale Range: +/-1000uT
Accelerometer Default Full Scale Range: +/-4g
Gyroscope Default Full Scale Range: +/-2000dps
Magnetometer New Full Scale Range: +/-1000uT
Accelerometer New Full Scale Range: +/-8g
Gyroscope New Full Scale Range: +/-2000dps

maybe this looks better... compiled for a Arduino 2560 ;)... so i have to search for the problem! Thanks for the fast support!...

best regards Malte

Edit... it works now on the ESP32...

//	Wire.endTransmission(false);
Wire.endTransmission(); //works fine ;)

Hello,
thanks for the fast support! i think it works now... but i changed to the ESP32 and edited the Wire.h. I will test the arduino later.

but what i dont understand is this

Actual MagRate = 0 Hz
Actual AccelRate = 0 Hz
Actual GyroRate = 0 Hz
Actual BaroRate = 0 Hz
I2C device found at address 0x28  !
done

EM7180 ROM Version: 0xE69
Should be: 0xE609
EM7180 RAM Version: 0x17435
EM7180 ProductID: 0x80 Should be: 0x80
EM7180 RevisionID: 0x2 Should be: 0x02
A barometer is installed
A temperature sensor is installed
EEPROM detected on the sensor bus!
EEPROM uploaded config file!
EEPROM upload successful!
Send '1' for Warm Start, '0' for no Warm Start
!!!Warm Start active!!!
Send '2' to apply Accelerometer Cal, '0' to not apply Accelerometer Cal
!!!Accel Cal Active!!!
X-acc max: 2008
Y-acc max: 2013
Z-acc max: 2073
X-acc min: -2092
Y-acc min: -2077
Z-acc min: -2036
Beginning Parameter Adjustments
Magnetometer Default Full Scale Range: +/-1000uT
Accelerometer Default Full Scale Range: +/-8g
Gyroscope Default Full Scale Range: +/-2000dps
Magnetometer New Full Scale Range: +/-1000uT
Accelerometer New Full Scale Range: +/-8g
Gyroscope New Full Scale Range: +/-2000dps
 EM7180 run status = normal mode
 EM7180 mag calibration completed
 EM7180 magnetic anomaly detected
 EM7180 sensor status = 0
Actual MagRate = 0 Hz
Actual AccelRate = 0 Hz
Actual GyroRate = 0 Hz
Actual BaroRate = 0 Hz

*******************************************
Send '1' to store Warm Start configuration
*******************************************

ax = -52.22 ay = -22.94 az = 1008.21 mg
gx = -0.15 gy = -0.15 gz = 0.00 deg/s
mx = -200 my = -135 mz = 363 mG
Software quaternions (ENU):
q0 = 0.06 qx = -0.30 qy = 0.94 qz = 0.17
Hardware quaternions (NED):
Q0 = -0.03 Qx = -0.00 Qy = 0.95 Qz = 0.30
Software yaw, pitch, roll: 227.88, 12.05, 163.10
Hardware Yaw, Pitch, Roll: 158.42, 2.92, -1.34
BMP280:
Altimeter temperature = 25.05 C
Altimeter temperature = 77.09 F
Altimeter pressure = 1008.52 mbar
Altitude = 129.37 feet

then i copy a sensorStatus report in the loop function and it looks like...

 EM7180 sensor status = 0
Actual MagRate = 100 Hz
Actual AccelRate = 200 Hz
Actual GyroRate = 200 Hz
Actual BaroRate = 50 Hz

best regards Malte

i have a look at the sensor status bits in the loop() function

 // Check sensor status
    uint8_t sensorStatus = readByte(EM7180_ADDRESS, EM7180_SensorStatus);
    Serial.print(" EM7180 sensor status = "); Serial.println(sensorStatus);
    if(sensorStatus & 0x01) Serial.print("Magnetometer not acknowledging!");
    if(sensorStatus & 0x02) Serial.print("Accelerometer not acknowledging!");
    if(sensorStatus & 0x04) Serial.print("Gyro not acknowledging!");
    if(sensorStatus & 0x10) Serial.print("Magnetometer ID not recognized!");
    if(sensorStatus & 0x20) Serial.print("Accelerometer ID not recognized!");
    if(sensorStatus & 0x40) Serial.print("Gyro ID not recognized!");
  
    Serial.print("Actual MagRate = "); Serial.print(readByte(EM7180_ADDRESS, EM7180_ActualMagRate)); Serial.println(" Hz"); 
    Serial.print("Actual AccelRate = "); Serial.print(10*readByte(EM7180_ADDRESS, EM7180_ActualAccelRate)); Serial.println(" Hz"); 
    Serial.print("Actual GyroRate = "); Serial.print(10*readByte(EM7180_ADDRESS, EM7180_ActualGyroRate)); Serial.println(" Hz"); 
    Serial.print("Actual BaroRate = "); Serial.print(readByte(EM7180_ADDRESS, EM7180_ActualBaroRate)); Serial.println(" Hz");
    Serial.println(""); Serial.println("*******************************************");
    

in the WarmStart sketch... these are the settings...

// Set accel/gyro/mage desired ODR rates
   writeByte(EM7180_ADDRESS, EM7180_QRateDivisor, 0x02); // 100 Hz
   writeByte(EM7180_ADDRESS, EM7180_MagRate, 0x64); // 100 Hz
   writeByte(EM7180_ADDRESS, EM7180_AccelRate, 0x14); // 200/10 Hz
   writeByte(EM7180_ADDRESS, EM7180_GyroRate, 0x14); // 200/10 Hz
   writeByte(EM7180_ADDRESS, EM7180_BaroRate, 0x80 | 0x32);  // set enable bit and set Baro rate to 25 Hz

So in the loop it looks OK, but why not in the Startup part when the WarmStart values are loaded? But not sure this is a problem...

@themuck: Even with the latest arduino-esp32 code, Wire.endTransmission(false) in I2C read routines from @kriswiner won't run correctly but works fine with Wire.endTransmission(true). With his example code, I also had to use polling in my main loop instead of interrupts, to get the I2C reads to be reliable at 400 KHz clock with no hangs. This might be improved with arduino-esp32 PR #1877. I will try interrupts again! See also comments at arduino-esp32 PR #1717. Seems the ESP32 I2C and USFS board have some relationship problems . . .

The current release of Arduino-esp32 (1.0.0, July 28, 2018) does not work with ReSTART operations. The current GitHub repo has been fixed. If you are using Release 1.0.0, you need to substitute the four i2c from the GitHub repo:

  • \cores\esp32\esp32-hal-i2c.h
  • \cores\esp32\esp32-hal-i2c.c
  • \libraries\Wire\src\Wire.h
  • \libraries\Wire\src\Wire.cpp

Chuck.

I have the sensor board working great on the Teensy 3.6 @ 5khz. Managed to compile for ESP32 but gee its bad at less than 700hz and looks like a huge delay in the loop. Id love to see some proper functioning code for the ESP32 if any of you fellas feel like sharing. As for the I2c files stickbreaker Ill give it a go

Yep chasing my tail on this one, one good reason to have the teensy though just to know how fantastic it can be. Ill send you a mail and perhaps I can get it to have sensible output.

ok little chasing things down. Seems on on STICKBREAKER V0.2.2 for an adapted version for the teensy code (just changed the Wire.endTransmission to true ). Ran some older code from Kris which actually runs at 29khz but the software heading seems a bit wonky while hardware is ok. The wire stuff is kinda baffling though as I had thought that I am actually no loner using stickbreaker but rather official release.

#define STICKBREAKER V0.2.2

hmm what now

@carbonadam you have two choices, modify your release 1.0.0 code or start using the Dev Code.

modification

Dev branch installation instructions

A modified version of my code became the official release. During prerelease testing and debugging, this ReSTART failure was introduced.

Chuck.

So now running with latest github version #define STICKBREAKER V1.0.1

I get the following results. Something still isnt right for the update @ rate = 705.95 Hz Sub par.

Can you post the code that does the scan, maybe i can optimize it.

Chuck.

Not sure which part is causing this to be slow so uploaded the sketch as text.
Cheers Chuck. any insight welcome.
EM7180_MPU9250_BMP280_prepESP32.txt

@carbonadam
Try swapping out these functions:

void readSENtralQuatData(float * destination)
{
  uint8_t rawData[16];  // x/y/z quaternion register data stored here
//  readBytes(EM7180_ADDRESS, EM7180_QX, 16, &rawData[0]);       // Read the sixteen raw data registers into data array
  uint8_t reg=EM7180_QW;
  uint8_t err =Wire.writeTransmission(EM7180_ADDRESS, &reg, 1, false);
  if(err == I2C_ERROR_CONTINUE ){// continue because of ReSTART
    err= Wire.readTransmission(EM7180_ADDRESS, &rawData, 16);

	destination[0] = uint32_reg_to_float (&rawData[0]);
	destination[1] = uint32_reg_to_float (&rawData[4]);
	destination[2] = uint32_reg_to_float (&rawData[8]);
	destination[3] = uint32_reg_to_float (&rawData[12]);  // SENtral stores quats as qx, qy, qz, q0!
  }
}

void readSENtralAccelData(int16_t * destination)
{
  uint8_t rawData[6];  // x/y/z accel register data stored here
//  readBytes(EM7180_ADDRESS, EM7180_AX, 6, &rawData[0]);       // Read the six raw data registers into data array
  uint8_t reg = EM7180_AX;
  uint8_t err = Wire.writeTransmission(EM7180_ADDRESS,&reg,1,false);
  if(err ==  I2C_ERROR_CONTINUE) {// ReSTART
    err = Wire.readTransmission(EM7180_ADDRESS,&rawData,6);
	
	destination[0] = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]);  // Turn the MSB and LSB into a signed 16-bit value
	destination[1] = (int16_t) (((int16_t)rawData[3] << 8) | rawData[2]);  
	destination[2] = (int16_t) (((int16_t)rawData[5] << 8) | rawData[4]); 
  }
}

void readSENtralGyroData(int16_t * destination)
{
  uint8_t rawData[6];  // x/y/z gyro register data stored here
//  readBytes(EM7180_ADDRESS, EM7180_GX, 6, &rawData[0]);  // Read the six raw data registers sequentially into data array
  uint8_t reg = EM7180_GX;
  uint8_t err = Wire.writeTransmission(EM7180_ADDRESS,&reg,1,false);
  if(err== I2C_ERROR_CONTINUE){ // ReSTART
	err = Wire.readTransmission(EM7180_ADDRESS,&rawData,6);
	destination[0] = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]);   // Turn the MSB and LSB into a signed 16-bit value
	destination[1] = (int16_t) (((int16_t)rawData[3] << 8) | rawData[2]);  
	destination[2] = (int16_t) (((int16_t)rawData[5] << 8) | rawData[4]); 
  }
}

void readSENtralMagData(int16_t * destination)
{
  uint8_t rawData[6];  // x/y/z gyro register data stored here
//  readBytes(EM7180_ADDRESS, EM7180_MX, 6, &rawData[0]);  // Read the six raw data registers sequentially into data array
  uint8_t reg = EM7180_MX;
  uint8_t err = Wire.writeTransmission(EM7180_ADDRESS,&reg,1,false);
  if(err ==  I2C_ERROR_CONTINUE) {// ReSTART
    err = Wire.readTransmission(EM7180_ADDRESS,&rawData,6);
	destination[0] = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]);   // Turn the MSB and LSB into a signed 16-bit value
	destination[1] = (int16_t) (((int16_t)rawData[3] << 8) | rawData[2]);  
	destination[2] = (int16_t) (((int16_t)rawData[5] << 8) | rawData[4]); 
	}
}

Chuck.