Skip to content

NUCLEO-F767ZI VS NUCLEO-H74ZI2 I2C IS SLOWER THAN F7 #1125

@Robokishan

Description

@Robokishan

I have bought two boards NUCLEO-F767ZI and NUCLEO-H74ZI2. I was doing some benchmark from stm32examples and as expected H7 has out standing performance compare to F7. But when i tried to run some hardware code H7 was having some significance delay compare to F7. I was reading data from MPU6050 and the results are pasted below also i have tried to paste the code. it is simple just to read bytes from mpu6050.

To reproduce i have pastes code below . if any undefined variables are there just remove them. as we are comparing just i2c.

#include <Arduino.h>
#include<Wire.h>
const int MPU_addr=0x68;
#define gyro_address 0x68
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; //These will be the raw data from the MPU6050.
uint32_t timer; //it's a timer, saved as a big-ass unsigned int.  We use it to save times from the "micros()" command and subtract the present time in microseconds from the time stored in timer to calculate the time for each loop.
double compAngleX, compAngleY; //These are the angles in the complementary filter
#define degconvert 57.2957786 //there are like 57 degrees in a radian.
int now ,t;


// from stm32-esc firmware
int32_t gyro_roll_cal, gyro_pitch_cal, gyro_yaw_cal;
int16_t manual_gyro_pitch_cal_value = 0;
int16_t manual_gyro_roll_cal_value = 0;
int16_t manual_gyro_yaw_cal_value = 0;

float accADCf[XYZ_AXIS_COUNT];

// inav variables 
float linear_x,accelNEU_x,accWeight = 1.0f; 

void setup() {

  delay(100);
  Serial.begin(9600);
  delay(500);
  Serial.print("Booting...");
  delay(3000);
  // Set up MPU 6050:
  Wire.begin();
  delay(500);
  Wire.setClock(400000);
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  //2) calculate pitch and roll
  double roll = atan2(AcY, AcZ)*degconvert;
  double pitch = atan2(-AcX, AcZ)*degconvert;

  //3) set the starting angle to this pitch and roll
  double gyroXangle = roll;
  double gyroYangle = pitch;
  double compAngleX = roll;
  double compAngleY = pitch;
  
  //start a timer
  timer = micros();
}

void loop() {
  double write_timer, wire_timer, request_timer;
  now = micros();
//Now begins the main loop. 
  //Collect raw data from the sensor.
  Wire.beginTransmission(gyro_address);                       //Start communication with the gyro.
  Wire.write(0x3B);                                           //Start reading @ register 43h and auto increment with every read.
  Wire.endTransmission();                                     //End the transmission.
  write_timer =(double) (micros() - now);
  Wire.requestFrom(gyro_address, 14);                         //Request 14 bytes from the MPU 6050.
  wire_timer =(double) (micros() - now);
  
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  request_timer = (double) (micros() - now);
  double dt = (double)(micros() - timer) / 1000000; //This line does three things: 1) stops the timer, 2)converts the timer's output to seconds from microseconds, 3)casts the value as a double saved to "dt".
  timer = micros(); //start the timer again so that we can calculate the next dt.
  
  //the next two lines calculate the orientation of the accelerometer relative to the earth and convert the output of atan2 from radians to degrees
  //We will use this data to correct any cumulative errors in the orientation that the gyroscope develops.
  double roll = atan2(AcY, AcZ)*degconvert;
  double pitch = atan2(-AcX, AcZ)*degconvert;

  //The gyroscope outputs angular velocities.  To convert these velocities from the raw data to deg/second, divide by 131.  
  //Notice, we're dividing by a double "131.0" instead of the int 131.
  double gyroXrate = GyX/131.0;
  double gyroYrate = GyY/131.0;

  //THE COMPLEMENTARY FILTER
  //This filter calculates the angle based MOSTLY on integrating the angular velocity to an angular displacement.
  //dt, recall, is the time between gathering data from the MPU6050.  We'll pretend that the 
  //angular velocity has remained constant over the time dt, and multiply angular velocity by 
  //time to get displacement.
  //The filter then adds a small correcting factor from the accelerometer ("roll" or "pitch"), so the gyroscope knows which way is down. 
  compAngleX = 0.99 * (compAngleX + gyroXrate * dt) + 0.01 * roll; // Calculate the angle using a Complimentary filter
  compAngleY = 0.99 * (compAngleY + gyroYrate * dt) + 0.01 * pitch; 


  // this is position estimator algorithm from inav
  //  original algorithm from inav is 
  // posEstimator.est.pos.x += posEstimator.imu.accelNEU.x * sq(ctx->dt) / 2.0f * accWeight;
  accADCf[0] = (float)AcX / acc_scale;
  accADCf[1] = (float)AcY / acc_scale;
  accADCf[2] = (float)AcZ / acc_scale;
  // linear_x += accelNEU_x * sq(dt) / 2.0f * accWeight;

        
  t = micros() - now ;
  //W00T print dat shit out, yo!
  Serial.print(write_timer);Serial.print("\t");
  Serial.print(wire_timer);Serial.print("\t");
  Serial.print(request_timer);Serial.print("\t");
  Serial.print(t); Serial.print("\t");
  //  print g from acclerometer
  for (int i = 0 ; i < XYZ_AXIS_COUNT; i++)
  {
    Serial.print(accADCf[i]);Serial.print("\t");
  }
  Serial.print(compAngleX);Serial.print("\t");
  Serial.print(compAngleY);Serial.print("\n");
  //Serial.print(pitch);Serial.print("\t");
  //Serial.print(roll);Serial.print("\n");

results from serial.print

FOR NUCLEO-F767ZI I2C BENCHMARK
WRITE REQ READ TOTAL
46.00 344.00 346.00 376 0.12 0.35 -0.93 216.60 -156.12
45.00 344.00 345.00 376 0.12 0.34 -0.93 216.83 -156.28
45.00 343.00 345.00 374 0.12 0.34 -0.93 217.07 -156.45
45.00 343.00 345.00 375 0.11 0.34 -0.93 217.30 -156.62
46.00 344.00 345.00 376 0.12 0.34 -0.93 217.52 -156.78
45.00 344.00 345.00 376 0.12 0.34 -0.92 217.74 -156.95

FOR NUCLEO-H7
48.00 375.00 376.00 390 0.21 0.33 -0.92 240.24 -167.42
48.00 376.00 377.00 391 0.21 0.33 -0.92 240.24 -167.42
49.00 376.00 377.00 391 0.21 0.33 -0.92 240.23 -167.43
48.00 376.00 377.00 391 0.21 0.33 -0.92 240.23 -167.43
49.00 376.00 377.00 391 0.20 0.33 -0.92 240.23 -167.43

AS YOU CAN SEE H7 IS CALCULATING FAST BUT I2C IS HAVING SOME DELAY COMPARE TO F7.
it is new and code is also same
i can provide more info if you want just don't close this issue. i don't have any explanation why i2c is having delay in H7. it has to be more power full compare to f7.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions