Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EWD – Einstellwinkeldifferenz (Angle of Attack Difference Gauge)

Firmware for a wireless gauge to measure the difference in angle of attack between the wing and the horizontal stabilizer of RC aircraft. The device measures absolute angles relative to gravity with a statistical stability check, then displays the difference between two captured angles — all through a browser-based and phone-friendly web interface, no app installation required.

How It Works

  1. Reference measurement — Place the gauge on the wing, press Start, and hold still. The device samples the accelerometer at 10 Hz for 10 seconds. Once the window is full and the standard deviation drops below the configured threshold, the measurement is accepted and automatically stored as the reference angle.
  2. Second measurement — Move the gauge to the horizontal stabilizer and press Start again. After the same stability check, the firmware calculates and displays the incidence angle difference (EWD).
  3. Verification by reversal — To eliminate any zero-offset error of the sensor, repeat both measurements with the gauge flipped upside down. Average the two EWD readings — the sensor offset cancels out and the result is more accurate.
  4. Reset — Clears both measurements so a new reference can be captured.

Hardware

Assembled gauge

Component Description
MCU Seeed XIAO ESP32S3
Sensor LIS2DH12 3-axis accelerometer (SPI)

No additional components are required.

SPI Wiring (LIS2DH12 module / Seeed XIAO ESP32S3)

Sensor Pin XIAO ESP32S3 Pin
VCC 3V3
GND GND
SCL (SCK) D8 (GPIO7)
SDA (MOSI) D10 (GPIO9)
SDO (MISO) D9 (GPIO8)
CS D7 (GPIO44)

Note: Verify pin assignments against your specific breakout board and update include/config.h accordingly.

Firmware

Built with the Arduino framework on PlatformIO, targeting the Seeed XIAO ESP32S3.

Prerequisites

  • PlatformIO (VS Code extension or CLI)
  • USB-C cable for flashing

Build & Flash

# Clone the repository
git clone https://github.com/<your-org>/ewd.git
cd ewd

# Create your local configuration
cp include/config.h.example include/config.h
# Edit include/config.h to set Wi-Fi mode, credentials, and pin assignments

# Build
pio run

# Flash (connect the XIAO ESP32S3 via USB)
pio run --target upload

# Open serial monitor (115200 baud)
pio device monitor

Configuration

All settings live in include/config.h (copied from include/config.h.example). This file is listed in .gitignore and will never be committed.

Wi-Fi

The device supports two modes:

Mode Description
Access Point (AP) The device creates its own Wi-Fi hotspot. No router needed.
Station (STA) The device joins an existing Wi-Fi network.
// Wi-Fi mode: "AP" or "STA"
#define WIFI_MODE   "AP"

// Access Point settings (AP mode)
#define AP_SSID     "EWD-Gauge"
#define AP_PASSWORD "12345678"   // min. 8 characters; "" for open network

// Station settings (STA mode)
#define STA_SSID     "your-network"
#define STA_PASSWORD "your-password"
  • In AP mode the web interface is reachable at http://192.168.4.1
  • In STA mode the assigned IP is printed to the serial monitor on boot

mDNS

In both modes the device advertises itself via mDNS. With the default hostname the interface is reachable at http://ewd.local on any device that supports mDNS (macOS, iOS, Linux with Avahi, Windows 10+).

#define MDNS_HOSTNAME "ewd"

SPI Pins

#define PIN_SPI_SCK  7   // D8 on XIAO ESP32S3
#define PIN_SPI_MOSI 9   // D10
#define PIN_SPI_MISO 8   // D9
#define PIN_SPI_CS   44  // D7

Web Interface

Web interface screenshot

Open the device's IP address (or http://ewd.local) in any browser on the same network - a phone works fine. The single-page interface updates every 500 ms and shows:

Card Content
Last Measurement Accepted angle (mean over the measurement window)
Reference (Wing) Stored reference angle and its σ
Difference (EWD) Angle difference between last measurement and reference
Status Live σ and sample progress during an active measurement

Controls:

  • Start — begins a new measurement; disabled while measuring
  • Abort — cancels the current measurement without saving
  • Reset — clears all stored angles and the reference
  • Max σ — stability threshold; the measurement is only accepted when the standard deviation over the full window is at or below this value (default 0.2°)

Measurement Algorithm

Each measurement runs a 10-second sliding window (100 samples at 10 Hz).

  1. Raw accelerometer data is pre-filtered with an exponential moving average low-pass filter (α = 0.02, ~0.03 Hz cutoff) to suppress vibration and building-structure noise.
  2. The tilt angle is derived from the filtered X-axis acceleration: angle = atan2(ax, sqrt(ay² + az²)).
  3. Samples are collected into a circular buffer of size WINDOW = 100.
  4. After every new sample the mean and sample standard deviation over all buffered values are recomputed.
  5. The measurement is accepted once the buffer is full (n = WINDOW) and σ ≤ threshold. If the device is still moving when the window fills, sampling continues (oldest samples are overwritten) until stability is reached.
  6. The first accepted measurement is automatically stored as the reference. Subsequent measurements show the difference.

The UI shows n / 100 samples while the buffer is filling, and live σ once the window is full.

Project Structure

ewd/
├── data/
│   └── index.html              # Web UI source — edit this file
├── include/
│   ├── config.h.example        # Configuration template (copy to config.h)
│   ├── lis2dh12_platform.h     # SPI wrapper for LIS2DH12
│   ├── measure.h               # Measurement state machine and snapshot API
│   ├── web_server.h            # Web server interface
│   └── web_ui.h                # Auto-generated (do not edit)
├── src/
│   ├── main.cpp                # Application entry point, sensor loop
│   ├── lis2dh12_platform.cpp   # SPI read/write callbacks
│   ├── measure.cpp             # Windowed mean/σ measurement logic
│   └── web_server.cpp          # HTTP routes and JSON API
├── tools/
│   └── generate_web_ui.py      # Pre-build: converts index.html → web_ui.h
├── test/
└── platformio.ini

Web UI Build Pipeline

data/index.html is the only file you edit. On every pio run, the pre-build script tools/generate_web_ui.py gzip-compresses it and writes the result as a C byte array into include/web_ui.h. The web server serves the compressed file directly with Content-Encoding: gzip — no flash filesystem required.

Dependencies

Dependencies are managed by PlatformIO and declared in platformio.ini.

Library Source Purpose
ESP32 Arduino core platform = espressif32 MCU support
lis2dh12-pid GitHub (STMicroelectronics) LIS2DH12 sensor driver
mathieucarbou/ESP Async WebServer PlatformIO registry Non-blocking HTTP server
bblanchon/ArduinoJson PlatformIO registry JSON API responses

lis2dh12-pid is the official platform-independent C driver from STMicroelectronics. The thin SPI wrapper that connects it to the ESP32 Arduino SPI API lives in src/lis2dh12_platform.cpp / include/lis2dh12_platform.h.

License

Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)

Copyright (c) 2025 clausgf

You may freely use, share, and adapt this project for non-commercial purposes, provided you give appropriate credit. Commercial use is not permitted.

About

EWD – Einstellwinkeldifferenz (Angle of Attack Difference Gauge)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages