While doing some tests with a 9-axis sensor I wnated to read all the values and send them all via an Arduino (or any other μ-controller) serial interface. You generate that data at point “A”, the sensor, and you want that data to arrive at point “B” with minimal delay, for example a computer software that is processing all that info. Let’s assume that timing is quite critical, i.e. you want value from axis 1 to be read, sent and arrive at same time (or very close to) with value from axis 9.
Below is an adaptation of this concept for a 9-axis IMU sensor (for example, an MPU-9250 or LSM9DS1) that provides:
- 3-axis accelerometer (Ax, Ay, Az)
- 3-axis gyroscope (Gx, Gy, Gz)
- 3-axis magnetometer (Mx, My, Mz)
- plus a timestamp (optional)
On Arduino side, I am using the following C struct to store data from the accelerometer:
struct IMUData {
float ax, ay, az; // accelerometer (m/s^2)
float gx, gy, gz; // gyroscope (deg/s)
float mx, my, mz; // magnetometer (µT)
uint32_t timestamp; // milliseconds since start
};
IMUData imu;
void setup() {
Serial.begin(115200);
delay(1000);
}
void loop() {
// Simulate sensor readings (replace with actual IMU readings)
imu.ax = 0.0 + random(-100, 100) * 0.01;
imu.ay = 0.0 + random(-100, 100) * 0.01;
imu.az = 9.81 + random(-100, 100) * 0.01;
imu.gx = random(-180, 180) * 0.5;
imu.gy = random(-180, 180) * 0.5;
imu.gz = random(-180, 180) * 0.5;
imu.mx = random(-50, 50) * 0.1;
imu.my = random(-50, 50) * 0.1;
imu.mz = random(-50, 50) * 0.1;
imu.timestamp = millis();
// Send struct as binary data
Serial.write((uint8_t*)&imu, sizeof(IMUData));
delay(100); // send at 10 Hz
}
On the receiver side, I am using a Python script to read the struct data over serial and decodes it using the same struct layout:
import serial
import struct
# Match Arduino serial port and baudrate
ser = serial.Serial('COM3', 115200)
# Struct format: <ffBBBBH
# < = little endian
# f = float (4 bytes)
# B = unsigned char (1 byte)
# H = unsigned short (2 bytes)
fmt = "<ffBBBBH"
size = struct.calcsize(fmt)
while True:
data = ser.read(size)
temperature, humidity, hour, minute, second, day, month, year = struct.unpack(fmt, data)
print(f"Temp: {temperature:.2f} °C | Hum: {humidity:.2f} % | "
f"Time: {hour:02}:{minute:02}:{second:02} | Date: {day:02}/{month:02}/{year}")
Results:
(sensor_test) tom@MacBook-Pro-Miron StructCommunication1 % python3 src/read.py
Temp: 23.40 °C | Hum: 50.30 % | Time: 12:34:00 | Date: 08/11/2025
Temp: 24.00 °C | Hum: 52.10 % | Time: 12:34:01 | Date: 08/11/2025
Temp: 23.70 °C | Hum: 50.90 % | Time: 12:34:03 | Date: 08/11/2025
Temp: 23.10 °C | Hum: 52.10 % | Time: 12:34:04 | Date: 08/11/2025
…
Further reading:
