Issue getting euler angles from Rsx-Um7 using spi pins

Greetings, so we are working on a project. We have rsx-um7 orientation sensor and are trying to get euler angles. Sensor is connected to Raspberry pi using spi pins. The datasheet we have tells us register 0x70 contains roll and pitch angle estimates. Whereas, we can only extract Roll from it. And the register 0x71 is for the yaw angle estimate, which we are getting as well. I’m pasting the Python code and datasheet.
Please guide us through.

UM7_Datasheet_1-3.pdf (1.7 MB)

import spidev
import struct
import time

# SPI Configuration
SPI_BUS = 0
SPI_DEVICE = 0
SPI_SPEED = 1000000  # 1 MHz
UM7_YAW_REG = 0x71  # Yaw register (Euler Psi)
UM7_ROLL_PITCH_REG = 0x70  # Roll and pitch register (Euler Phi & Theta)

# Initialize SPI
spi = spidev.SpiDev()
spi.open(SPI_BUS, SPI_DEVICE)
spi.max_speed_hz = SPI_SPEED
spi.mode = 0  # SPI Mode 0 (CPOL=0, CPHA=0)

def read_um7_register(register_address):
    """Reads a 4-byte register from UM7 over SPI."""
    spi.xfer2([0x00, register_address])  # Send read command
    time.sleep(5e-6)  # Small delay for UM7 to process
    rx_data = spi.xfer2([0x00] * 4)  # Read 4 bytes response

    print(f"Raw SPI Response (0x{register_address:02X}): {rx_data}")  # Debugging: Print raw SPI response

    if len(rx_data) != 4:
        print("Error: Incomplete data received")
        return None

    return rx_data

def get_roll_pitch():
    """Reads roll and pitch from UM7 and converts them to degrees."""
    rx_data = read_um7_register(UM7_ROLL_PITCH_REG)
    if rx_data is None:
        return None, None

    # Extract roll (first two bytes) and pitch (last two bytes)
    roll_raw = struct.unpack('>h', bytes(rx_data[:2]))[0]  # Roll (Phi)
    pitch_raw = struct.unpack('>h', bytes(rx_data[2:]))[0]  # Pitch (Theta)

    # Convert to degrees
    roll_degrees = roll_raw / 91.02222
    pitch_degrees = pitch_raw / 91.02222

    return roll_degrees, pitch_degrees

def get_yaw():
    """Reads yaw from UM7 and converts it to degrees."""
    rx_data = read_um7_register(UM7_YAW_REG)
    if rx_data is None:
        return None

    # Extract yaw (first two bytes)
    yaw_raw = struct.unpack('>h', bytes(rx_data[:2]))[0]  # Yaw (Psi)

    # Convert to degrees
    yaw_degrees = yaw_raw / 91.02222

    return yaw_degrees

try:
    while True:
        roll, pitch = get_roll_pitch()
        yaw = get_yaw()

        if roll is not None and pitch is not None and yaw is not None:
            print(f"Roll: {roll:.2f}°, pitch: {pitch:.2f}°, Yaw: {yaw:.2f}°")
        else:
            print("Invalid data received")

        time.sleep(0.1)  # Read at 10Hz

except KeyboardInterrupt:
    print("Exiting...")

finally:
    spi.close()  # Close SPI when done

Hello.

Just to clarify, it sounds like when you run the code you attached your Raspberry Pi will print roll and yaw angles, but it will not print anything for pitch; is that correct? Can you post a sample of the output?

Another good troubleshooting step would be to check if the UM7 behaves as expected if you use it with the Redshift Serial Interface Software. You can download that software from the UM7 product page under the “Resources” tab.

- Patrick

1 Like

Thanks for the response. I’m able to get the output of pitch as well. Pasting the output.
Now we need help to sort out the drift in euler angles. I don’t see any documentation regarding it. Your guidance will be highly appreciated.

Roll: 5.71°, Pitch: 42.87°, Yaw: 51.68°
Roll: 5.90°, Pitch: 43.04°, Yaw: 51.88°
Roll: 6.03°, Pitch: 43.19°, Yaw: 52.02°
Roll: 6.17°, Pitch: 43.33°, Yaw: 50.76°
Roll: 6.37°, Pitch: 43.51°, Yaw: 50.95°
Roll: 6.50°, Pitch: 42.24°, Yaw: 51.11°
Roll: 6.69°, Pitch: 42.43°, Yaw: 51.30°
Roll: 6.81°, Pitch: 42.56°, Yaw: 51.44°

I am glad to hear that all of the angles are updating now; thanks for letting us know.

As for sorting out the drift, I recommend you try the procedures demonstrated in these YouTube videos:

- Patrick

1 Like

Thank you for your response. I have tried these procedures already.

It is hard to offer any useful additional advice about addressing the drift with the information you provided; can you post more details, like some quantification of the drift?

You might also try checking the DREG_HEALTH register and let us know what that reports.

- Patrick