Skip to content

TheBushBoy/airmodem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

airmodem

Acoustic data modem operating in air, built on ESP32. Two identical half-duplex nodes exchange short ASCII messages over an audio link (BFSK), with framing, CRC error detection and stop-and-wait ARQ.

Designed as a proof of concept of the techniques used in underwater acoustic communication, transposed to air to remove the transducer and channel complexity.

Use of the ESP32 with ESP-IDF for firmware development.

References:

The first reference is mainly used for understanding the architecture and operation of a marine acoustic modem. Several design choices were derived from these references. Goertzel detection instead of FFT, low and deterministic CPU cost for a two-tone problem ; BFSK instead of OOK, magnitude-ratio decision, insensitive to distance and volume, which was the main weakness reported by the Cornell project ; and Hann-windowed bursts on TX to limit spectral leakage.

Signal parameters

The sample rate is 16 kHz, well above the Nyquist limit for the highest tone of 1.9 kHz. The two BFSK frequencies are 1100 Hz (space, bit 0) and 1900 Hz (mark, bit 1), chosen so that the Goertzel bin index k = N*f/Fs is an exact integer for both, k = 11 and k = 19 with a block size of N = 160 samples. With N = 160 at 16 kHz gives a bit duration of 10 ms and a raw bit rate of 100 bps, consistent with short-range acoustic modems.

Repository structure

lib/        portable C, signal processing and framing
firmware/   ESP32 application, I2S drivers, FreeRTOS tasks, ARQ
simulation/ Python loopback, modulator, AWGN channel, demodulator
webapp/     Flask web interface, serial bridge to the modem

Library

File Role
modem_config.h Definition of all signal and frame parameters
goertzel.c Coefficient computation and power estimation at a single frequency
crc8.c CRC-8/CCITT error detection (poly 0x07, init 0x00)
frame.c Frame encoder and byte-by-byte decoder state machine
bitsync.c Bit-to-byte assembly with silence detection and reset
modulate.c BFSK modulator, generates Hann-windowed int16 samples for a byte buffer

Each module has a corresponding test in lib/tests/. Run on host with:

cmake -B build && cmake --build build && ctest --test-dir build

Emission workflow

payload (bytes)
    │
frame_encode [0xAA 0xAA | 0x7E | LEN | payload | CRC8]
    │
modulate (Hann-windowed BFSK bursts, 160 * int16 per bit)
    │
signal data

Reception workflow

I2S samples (160 × int16)
    │
goertzel_power on both frequency
    │
goertzel_decide (-1 / 0 / 1)
    │
bitsync_feed (8 bits grouped by byte)
    │
frame_decode (state machine)
    │
frame_t

Firmware

Two FreeRTOS tasks share the acoustic channel through mutex s_channel so that RX and TX never overlap.

Task Role
rx_task Reads I2S samples, runs Goertzel, feeds bits to bitsync. On a DATA frame, prints [RX] <message> and emits an ACK. On an ACK frame, gives s_ack_sem to unblock tx_task.
tx_task Waits for a line on stdin (USB serial), encodes and modulates it, transmits. Retries up to ARQ_MAX_RETRIES times with a ARQ_TIMEOUT_MS timeout.

Pin wiring

Signal GPIO
INMP441 SCK 14
INMP441 WS 27
INMP441 SD 16
MAX98357A BCLK 19
MAX98357A LRC 32
MAX98357A DIN 21

INMP441 powered at 3.3 V, MAX98357A at 5 V, common GND.

Build and flash

cd firmware
idf.py build flash monitor

Webapp

Web interface to send and receive messages over USB serial.

cd webapp
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python app.py

Open http://localhost:5000, select the serial port of the target ESP32, connect, then type and send messages.

Simulation

File Role
config.py Shared signal parameters
bindings.py ctypes declarations, loads libairmodem_lib.so and exposes C functions
simulate.py End-to-end test, encode, BFSK modulate, AWGN channel, demodulate, decode
cd simulation
python3 simulate.py --snr 6 --wav demo.wav

Encodes a message, applies AWGN noise at the given SNR, decodes and verifies.

Bill of materials

Qty Part Role
1 ESP32 DevKit (WROOM-32) MCU, two I2S peripherals, FreeRTOS
1 INMP441 I2S MEMS microphone (RX)
1 MAX98357A breakout I2S DAC + 3 W class-D amplifier (TX)
1 Speaker 4 ohm / 3 W Acoustic emission
1 Perfboard and soldering stuff Wiring

About

Acoustic data modem operating in air, built on ESP32

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors