Skip to content

[Bug] UBX-ESF-RAW message parsed incorrectly #32

Closed
@nparker2020

Description

@nparker2020

Subject of the issue

When a UBX-ESF-RAW packet is received, the byte offset for the raw sensor data is incorrect, and as a result sensor data is incorrectly parsed/stored.
I am referencing the ZED-F9R Interface Description document (Revision R02) 3.11.4 UBX-ESF-RAW message description. In order to avoid breaching Ublox NDA, I will not reference specific fields on the document.

The F9R module I am using is upgraded to the most recent firmware version HPS1.20.

Your workbench

  • What development board or microcontroller are you using?

Issues replicated on ESP32 Dev Module, and a Teensy 4.1.

  • What version of hardware or breakout board are you using?

Sparkfun U-blox Zed-F9R GPS-RTK Breakout (Qwiic)

  • How is the breakout board wired to your microcontroller?

I2C lines are hard-wired to the microcontroller.

  • How is everything being powered?

The GPS board, as well as the micros are powered over the same USB tether.

  • Are there any additional details that may help us help you?
    I have resolved the issue on a fork and have submitted PR.

Steps to reproduce

  1. Connect Sparkfun GPS-RTK Zed-F9R breakout (Running firmware HPS1.20) to SDA, SCL, +5V and Ground on micro.
  2. Upload provided sketch
  3. Observe garbled sensor data in Serial Monitor
  4. To compare with UBX-ESF-RAW output in U-center
    a. Connect Sparkfun GPS-RTK Zed-F9R to Host PC running U-center over USB-C connection
    b. Navigate to View-->Messages View->UBX-->ESF-->RAW
    c. Right click, select ‘Enable Message’

Expected behavior

The expected behavior is that the raw sensor data, when parsed from the UBX_ESF_RAW_sensorData_t structs within SFE_UBLOX_GNSS::packetUBXESFRAW, matches what is presented in U-Center when examining UBX-ESF-RAW packet.

Actual behavior

Running the current version of the library on branch main,
The library provides garbled/nonsensical raw sensor data that does NOT match what is presented by U-Center when the UBX-ESF-RAW message is enabled.

Provided Sketch:

//Needed for I2C
#include <Wire.h>

#include "SparkFun_u-blox_GNSS_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS
SFE_UBLOX_GNSS myGPS;
UBX_ESF_RAW_sensorData_t gRawSensorDataStruct;

#define X_AXIS_ACCELERATION 0
#define Y_AXIS_ACCELERATION 1
#define Z_AXIS_ACCELERATION 2
#define X_AXIS_ROTATION     3
#define Y_AXIS_ROTATION     4
#define Z_AXIS_ROTATION     5
#define GYRO_TEMPERATURE    6


void setup() {
  Serial.begin(9600);
  Wire.begin();
  while(myGPS.begin() == false) //Connect to the Ublox module using Wire port
  {
    Serial.println("Ublox GPS not detected at default I2C address. Please check wiring. Freezing.");
    delay(100);
  }  

  //  //Set comms to be on the I2C port, and contain UBX/RTCM3 packets (turn off NMEA noise)
  myGPS.setI2COutput(COM_TYPE_UBX);
  myGPS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX);

}

int32_t parseSensorData(uint32_t allData)
{
  //the sensor data is a 3 byte, signed integer (bits 0 - 23)
  uint32_t sensorData = (allData & 0x00FFFFFF);

  //check out the sign bit
  uint32_t signBit =    (allData & 0x00800000) >> 20;

  int32_t signedData = 0;

   //if the number is negative, we need to fill the extra byte with 1s
  if(signBit != 0)
  {
    signedData |= 0xFF000000;
  }

  signedData |= sensorData;
  
  return signedData;
}

void requestRawSensorData()
{ 
  myGPS.getRawSensorMeasurement(&gRawSensorDataStruct, X_AXIS_ACCELERATION);
  int32_t xAccelInt = parseSensorData(gRawSensorDataStruct.data.all);
  double xAccel = (double)xAccelInt / 1024.0;
  Serial.print("Acceleration X, Y, Z: (");
  Serial.print(xAccel);
  Serial.print(", ");
  
  myGPS.getRawSensorMeasurement(&gRawSensorDataStruct, Y_AXIS_ACCELERATION);
  int32_t yAccelInt = parseSensorData(gRawSensorDataStruct.data.all);
  
  //the acceleration values are given in m/s * 2^-10
  double yAccel = (double)yAccelInt / 1024.0;
  Serial.print(yAccel);
  Serial.print(", ");
  
  myGPS.getRawSensorMeasurement(&gRawSensorDataStruct, Z_AXIS_ACCELERATION);
  int32_t zAccelInt = parseSensorData(gRawSensorDataStruct.data.all);
  double zAccel = (double)zAccelInt / 1024.0;
  Serial.print(xAccel);
  Serial.println(")");
  Serial.print("   Rotation: X, Y, Z: (");
  
  myGPS.getRawSensorMeasurement(&gRawSensorDataStruct, X_AXIS_ROTATION);
  int32_t xGyroInt = parseSensorData(gRawSensorDataStruct.data.all);

  //angular rate is given in degrees/second * 2^-12
  double xGyro = (double)xGyroInt / 4096.0;
  Serial.print(xGyro);
  Serial.print(", ");
  
  myGPS.getRawSensorMeasurement(&gRawSensorDataStruct, Y_AXIS_ROTATION);
  int32_t yGyroInt = parseSensorData(gRawSensorDataStruct.data.all);
  double yGyro = (double)yGyroInt / 4096.0;
  Serial.print(yGyro);
  Serial.print(", ");
  
  myGPS.getRawSensorMeasurement(&gRawSensorDataStruct, Z_AXIS_ROTATION);
  int32_t zGyroInt = parseSensorData(gRawSensorDataStruct.data.all);
  double zGyro = (double)zGyroInt / 4096.0;
  Serial.print(zGyro);
  Serial.println(")");

  //commented out for a cleaner serial output.
  //Serial.print("Gyro temp: ");
//  myGPS.getRawSensorMeasurement(&gRawSensorDataStruct, GYRO_TEMPERATURE);
//  int32_t gyroTempInt = parseSensorData(gRawSensorDataStruct.data.all);
//  double gyroTemp = (double)gyroTempInt;
}

void loop() {
  requestRawSensorData();

  myGPS.checkUblox();

  delay(250);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions