Projects / Drones

Altitude & Orientation Logger

A flight logger for drones, rockets and RC planes — attitude, heading and altitude at 50 Hz.

Advanced⏱ 3 hours4 ElectroTrical boards

Overview

The ET-S04 BNO085 does its own sensor fusion and outputs ready-made orientation, so the ESP32 doesn't have to run a filter. The ET-S15 BMP390 barometer resolves height changes of a few centimetres.

The logger records roll, pitch, heading and relative altitude to a CSV file in the ESP32's flash at 50 Hz. It runs from a small LiPo through a 5 V boost, and you download the file over USB after the flight.

  • Roll, pitch and heading from on-chip fusion
  • Relative altitude to ±0.25 m
  • 50 Hz CSV logging to flash
  • Light: one LiPo cell, USB-C charging

What you need

ElectroTrical boards

BNO085 9-DoF Orientation IMU
ET-S04BNO085 9-DoF Orientation IMUBNO085 9-DoF orientation with on-chip fusion
AED 79.00Out of stock
BMP390 Precision Barometer
ET-S15BMP390 Precision BarometerBMP390 precision barometer for altitude
AED 39.00Out of stock
TPS61023 5 V Boost
ET-P05TPS61023 5 V Boost5 V boost from the LiPo
AED 15.00Out of stock
MCP73831 USB-C LiPo Charger
ET-P01MCP73831 USB-C LiPo ChargerUSB-C LiPo charger
AED 22.00Out of stock

Boards total: AED 155.00

These boards are being manufactured. Open a board's page to see when it's back, or ask us about a kit.

You'll also need

  • ESP32-S3 DevKitC-1 (or any ESP32-S3 board) with a USB-C data cable. Not sold by ElectroTrical.
  • Qwiic / STEMMA QT cables (JST SH 4-pin) to chain the boards, or jumper wires
  • Small 1S LiPo, 300–1,000 mAh
  • Foam or 3D-printed mount with a small vent hole for the barometer

Wiring

Wire the first board's header to the ESP32 as shown, then link the other I²C boards with Qwiic cables. Every board carries VIN, GND, SDA and SCL through both Qwiic sockets, so the chain needs no extra wires. Addresses: BNO085 0x4A, BMP390 0x77.

Power

FromToNote
LiPo JST-PHET-P01 battery socket
ET-P01 VBATET-P05 VBAT
ET-P01 GNDET-P05 GND
ET-P05 5VESP32 5V
ET-P05 GNDESP32 GND

ESP32 → ET-S04 header

FromToNote
ESP32 3V3VINVIN sets the I²C logic level. Keep it at 3.3 V for the ESP32.
ESP32 GNDGND
ESP32 GPIO8SDA
ESP32 GPIO9SCL
ESP32 GPIO15INTOptional data-ready
ESP32 GPIO16RSTOptional reset

Qwiic chain

FromToNote
ET-S04 QwiicET-S15 Qwiic

Build it

  1. 01

    Set up the Arduino IDE

    Install Arduino IDE 2, add the Espressif ESP32 board package (Boards Manager → “esp32” by Espressif), select “ESP32S3 Dev Module” and turn on USB CDC On Boot so Serial prints over USB. Install the libraries listed above the sketch from Library Manager.

  2. 02

    Choose the flash layout

    In Tools → Partition Scheme, select one with a large SPIFFS/LittleFS area (for example “Huge APP (3MB No OTA/1MB SPIFFS)” or a 16 MB option if your board has 16 MB flash).

  3. 03

    Calibrate the compass

    After power-up, wave the logger slowly in a figure-eight for 20 seconds, away from motors and metal. The BNO085 stores its calibration as it learns.

  4. 04

    Mount it

    Fix the boards with the arrows on the ET-S04 pointing forward. Isolate the board from motor vibration with foam, and shield the barometer from prop wash with open-cell foam over the vent.

  5. 05

    Log a flight

    Power up on the ground — altitude zero is taken at boot. After landing, plug in USB and type d in Serial Monitor to dump the CSV, or x to erase it.

Arduino code

Written for the ESP32-S3 DevKitC-1 with the Espressif Arduino core. Install these libraries from the Arduino Library Manager:

  • Adafruit BNO08x
  • Adafruit BMP3XX Library
flight_logger.ino
#include <Wire.h>
#include <LittleFS.h>
#include <Adafruit_BNO08x.h>
#include <Adafruit_BMP3XX.h>

Adafruit_BNO08x bno(16);           // RST on GPIO16
Adafruit_BMP3XX bmp;
sh2_SensorValue_t ev;
float roll, pitch, yaw, groundHpa;

void toEuler(float r, float i, float j, float k) {
  roll  = atan2(2 * (r * i + j * k), 1 - 2 * (i * i + j * j)) * RAD_TO_DEG;
  pitch = asin(constrain(2 * (r * j - k * i), -1.0f, 1.0f)) * RAD_TO_DEG;
  yaw   = atan2(2 * (r * k + i * j), 1 - 2 * (j * j + k * k)) * RAD_TO_DEG;
}

void setup() {
  Serial.begin(115200);
  Wire.begin(8, 9);
  Wire.setClock(400000);
  LittleFS.begin(true);

  if (!bno.begin_I2C(0x4A)) Serial.println("BNO085 not found");
  bno.enableReport(SH2_ROTATION_VECTOR, 20000);          // 50 Hz

  if (!bmp.begin_I2C(0x77)) Serial.println("BMP390 not found");
  bmp.setPressureOversampling(BMP3_OVERSAMPLING_8X);
  bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_2X);
  bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  bmp.setOutputDataRate(BMP3_ODR_50_HZ);

  delay(500);
  float sum = 0;
  for (int n = 0; n < 20; n++) { bmp.performReading(); sum += bmp.pressure / 100.0; delay(20); }
  groundHpa = sum / 20;                                   // altitude zero = here

  File f = LittleFS.open("/flight.csv", FILE_APPEND);
  f.println("ms,roll,pitch,yaw,alt_m");
  f.close();
  Serial.println("Logging. d = dump, x = erase");
}

void loop() {
  if (bno.wasReset()) bno.enableReport(SH2_ROTATION_VECTOR, 20000);

  if (bno.getSensorEvent(&ev) && ev.sensorId == SH2_ROTATION_VECTOR) {
    auto q = ev.un.rotationVector;
    toEuler(q.real, q.i, q.j, q.k);
    bmp.performReading();
    float alt = bmp.readAltitude(groundHpa);

    File f = LittleFS.open("/flight.csv", FILE_APPEND);
    f.printf("%lu,%.1f,%.1f,%.1f,%.2f\n", millis(), roll, pitch, yaw, alt);
    f.close();
  }

  if (Serial.available()) {
    char c = Serial.read();
    if (c == 'd') { File f = LittleFS.open("/flight.csv"); while (f.available()) Serial.write(f.read()); f.close(); }
    if (c == 'x') { LittleFS.remove("/flight.csv"); Serial.println("Erased"); }
  }
}

Troubleshooting

Heading drifts or jumps

Redo the figure-eight calibration away from metal, and keep the board away from motors, ESCs and battery leads, which distort the magnetic field.

Altitude jumps when the props spin

Prop wash changes the air pressure at the sensor. Cover the barometer with open-cell foam and keep it inside the frame.

Log stops after a few minutes

The flash partition is full. Choose a partition scheme with more file-system space, or log at 10–20 Hz.

Take it further

  • Add the ET-S41 GNSS receiver for position and ground speed
  • Trigger a parachute servo at apogee for model rockets
  • Use the ET-S27 ICM-42688-P for high-rate vibration logging

Turning this into a product?

We design custom boards that combine these sensors on one PCB, with firmware and production.