ping-rs — Servo-Swept Ultrasonic Radar
A servo-swept ultrasonic radar built on STM32F411RE in async Rust (Embassy), with a live polar-plot display on a 0.96” OLED and streaming JSON telemetry over USB.
An HC-SR04 ultrasonic rangefinder rides on top of an SG90 servo. The servo sweeps 0 → 180 → 0 degrees (~6 s per full scan) while the sensor fires one ping every 50 ms. Each (angle, distance) sample is rasterized to a polar plot on the SSD1306 OLED and simultaneously streamed out the USB CDC ACM port as a JSON line:
{"t_us":1234567,"angle_deg":45,"dist_mm":823}
Hardware
| Part | Purpose |
|---|---|
| STM32 Nucleo-F411RE | MCU + onboard ST-Link for flashing and RTT log |
| HC-SR04 | Ultrasonic time-of-flight rangefinder |
| SG90 | Micro servo, 180 deg sweep |
| SSD1306 0.96” OLED 128×64 | Polar radar display, I2C |
| USB-A to Micro-USB | Power + CDC telemetry to host |
| Logic analyzer (8CH) | Timing capture for the proof-of-correctness screenshot |
Wiring (Nucleo-F411RE)
| Signal | Nucleo pin | MCU pin |
|---|---|---|
| Servo PWM | CN5 D1 | PA0 (TIM2_CH1) |
| HC-SR04 Trig | CN8 A1 | PA1 |
| HC-SR04 Echo | CN9 A3 | PB0 |
| OLED SCL | CN10 D15 | PB8 (I2C1_SCL) |
| OLED SDA | CN10 D14 | PB9 (I2C1_SDA) |
| USB D+/D- | USB | PA11 / PA12 |
| Status LED | onboard | PA5 (LD2) |
HC-SR04 needs 5V; its echo line also outputs 5V and is level-shifted to 3.3V with a 1k/2k resistor divider into PB0.
Software architecture
Three Embassy tasks over a shared SPSC channel:
servo::sweep_task -----> CURRENT_ANGLE (AtomicU8)
|
v
ultrasonic::ping_task -- Sample --> CHANNEL (64 deep)
|
+----------------+---------------+
v v
display::render_task telemetry::usb_task
(SSD1306, 30 fps) (USB CDC, 1:1 sample rate)
Dropping samples is intentional: the ping task uses try_send, so if display or USB stalls, the radar keeps scanning and old readings are discarded rather than backing up the pipeline.
Build and flash
rustup target add thumbv7em-none-eabihf
cargo install probe-rs --features cli
cargo run --release # flashes via onboard ST-Link, attaches RTT log
RTT log prints defmt messages over the ST-Link probe; the USB CDC port is a separate interface used only for telemetry.
Reading telemetry
On macOS the USB CDC shows up as /dev/tty.usbmodem*:
cat /dev/tty.usbmodem* # raw JSON lines