Skip to content

stephanelsmith/micro-aprs

Repository files navigation

Micro APRS MODEM

A python/micropython based library for encoding/decoding, modulating/demodulating APRS/AX.25 packets in AFSK.

The purpose of this library is to thread-the-needle of both enabling APRS/AX.25/AFSK from PC to microcontroller while maintaining portability and readability of python. This library is optimized for embedded systems, especially micropython supported targets and platforms and small computers, not to mention Cpython and Pypy!

In practice this means we:

  • Avoid floating point and math libraries and dependencies in critical sections.
    • 👍 Integer math only
    • 👍 NO external libraries (numpy/scipy/pandas).
  • Special care for memory allocation
    • 👍 Pre-computing buffer/array sizes and modifying in place
    • 👎 Dynamically appending items to a list
  • Single threaded, multitask friendly
    • 👍👍 Asyncio

Micro-Aprs decodes 1000+ error-free frames on the TNC CD Track 2. That's 1010 👀 in a balanced mode at 1014 🎆 in a more computational intensive mode!

(TNC CD Track 2 is the universal test for APRS demod, this performance is very good!)

🎓 Tutorials

As many who've gone down this path have mentioned, there's really just not a lot of information out there covering these topics. I hope these tutorial sections will provide you additional information on getting started!

🐍 Python Compatibility

Care has been taken to make the source fully compatible across target python versions:

  • Python (for the lazy)
  • Micropython (for embedded)
  • Pypy3 (for speed!)

📡 APRS to AFSK Modulation

aprs_mod.py provides conversion from APRS string(s) into raw 16 bit signed integer raw format with a default sampling rate 22050.

Arguments

  • Command line options showing with help flag -h
python aprs_mod.py -h
APRS MOD
(C) Stephane Smith (KI5TOF) 2023

Usage:
aprs_mod.py [options] (-t outfile) (-t infile)
aprs_mod.py [options] (-t infile)
aprs_mod.py [options]
aprs_mod.py

OPTIONS:
-r, --rate       22050 (default)
-vox, --vox      Vox mode, pad header flags to activate radio vox
-v, --verbose    verbose intermediate output to stderr

-t INPUT TYPE OPTIONS:
intype       aprs strings
infile       '-' (default)

-t OUTPUT TYPE OPTIONS:
outtype       raw 16 bit samples
outfile       '-' (default) | 'null' (no output) | '*.wav' (wave file) | 'play' play audio

Examples

  • aprs_mod.py micropython generated wav file, decode with:
    • Direwolf atest
    • Multimon-ng
    • aprs_demod
echo "KI5TOF>APRS:>hello world!" | micropython aprs_mod.py | sox -t raw -b 16 -e signed-integer -c 1 -v 1.0 -r 22050 -  -t wav test.wav
echo "KI5TOF>APRS:>hello world!" | python aprs_mod.py -vox -t test.wav -t -
atest test.wav
sox -t wav test.wav -t raw -b 16 -e signed-integer -c 1 -r 22050 - | multimon-ng -t raw -A -a AFSK1200 -
sox -t wav test.wav -t raw -b 16 -e signed-integer -c 1 -r 22050 - | micropython aprs_demod.py -t -
echo "KI5TOF>APRS:>hello world!" | python aprs_mod.py -vox -t play -t -
  • aprs_mod.py python inline decode
echo "KI5TOF>APRS:>hello world!" | python aprs_mod.py -t - -t aprs - | multimon-ng -t raw -A -a AFSK1200 -
echo "KI5TOF>APRS:>hello world!" | python aprs_mod.py | multimon-ng -t raw -A -a AFSK1200 -
echo "KI5TOF>APRS:>hello world!" | python aprs_mod.py -v | python aprs_demod.py -v -t -

📡 AFSK Demodulation to APRS Strings

aprs_demod.py reads in raw 16 bit signed integers from standard input or file and output detected APRS strings.

Arguments

  • Command line options showing with help flag -h
python aprs_demod.py -h
APRS DEMOD
(C) Stephane Smith (KI5TOF) 2023

Usage:
aprs_demod.py [options] (-t outfile) (-t infile)
aprs_demod.py [options] (-t infile)
aprs_demod.py [options]
aprs_demod.py

OPTIONS:
-r, --rate       22050 (default)
-v, --verbose    verbose intermediate output to stderr

-t INPUT TYPE OPTIONS:
intype       'raw' 16 bit signed samples
infile       '-' (default stdin) | 'filename.raw' raw file | 'rtl_fm' input from rtl_fm

-t OUTPUT TYPE OPTIONS:
outtype       'aprs' strings
outfile       '-' (default stdout)

Examples

  • Demod with python, micropython, and pypy
echo "KI5TOF>APRS:>hello world!" | python aprs_mod.py -v | python aprs_demod.py -v -t -
echo "KI5TOF>APRS:>hello world!" | micropython aprs_mod.py -v | micropython aprs_demod.py -v -t -
echo "KI5TOF>APRS:>hello world!" | pypy3 aprs_mod.py -v | pypy3 aprs_demod.py -v -t -
  • Decode Direwolf generated sample
gen_packets -r 22050 -o test.wav
sox -t wav test.wav -t raw -b 16 -e signed-integer -c 1 -r 22050 - | micropython aprs_demod.py -t -
WB2OSZ-11>TEST:,The quick brown fox jumps over the lazy dog!  1 of 4
WB2OSZ-11>TEST:,The quick brown fox jumps over the lazy dog!  2 of 4
WB2OSZ-11>TEST:,The quick brown fox jumps over the lazy dog!  3 of 4
WB2OSZ-11>TEST:,The quick brown fox jumps over the lazy dog!  4 of 4
wget https://inst.eecs.berkeley.edu/~ee123/sp14/lab3/ISSpkt.wav
sox -t wav ISSpkt.wav -t raw -b 16 -e signed-integer -c 1 -r 22050 - | python aprs_demod.py -t -
RS0ISS>CQ:>ARISS - International Space Station
  • Decode TNC Test CD
    • Download and convert TNC tests to .wav/.flac files
    • Using bchunk (apt-get install bchunk)
    • Run track 2 test
wget http://wa8lmf.net/TNCtest/TNC_Test_CD_Ver-1.1.zip
bchunk -w TNC_Test_Ver-1.1.bin TNC_Test_Ver-1.1.cue tnc_test
sox -t wav test/tnc_test02.wav -t raw -b 16 -e signed-integer -c 1 -r 22050 - | python aprs_demod.py -t -

📻 Live APRS Decode with RTL-SDR

  • Live decode of APRS on 144.39MHz using rtl_fm:
rtl_fm -f 144.390M -s 22050 -g 1 - | python aprs_demod.py -t -

📡 APRS Rx only IGate

  • Rx Only IGate with APRS forwarding to APRS IS (live viewing on aprs.fi). Note: currently the aprs_is function is somewhat hard coded for me out of convenience, can certainly be better paramerterized.

Arguments

  • Command line options showing with help flag -h
python aprs_is.py -h
APRS IS GATEWAY
(C) Stephane Smith (KI5TOF) 2023

Usage: python aprs_is.py [OPTIONS]
aprs_is.py sends aprs commands from stdin to aprs is servers.

OPTIONS:
    -c, --call         APRS call sign
    -p, --passcode     APRS passcode (https://apps.magicbug.co.uk/passcode/)
    -lat               Beacon lat (decimal notation)
    -lon               Beacon lon (decimal notation)
    -msg               Beacon message, default: micro-aprs-modem 144.390MHz rx only APRS iGate

Examples

  • Send a message to APRS IS, viewable on aprs.fi
echo "KI5TOF>APRS:>hello world!" | python aprs_is.py -c KI5TOF -p xxxxx
  • A 144.390MHz rx only APRS iGate
rtl_fm -f 144.390M -s 22050 -g 10 - | pypy3 aprs_demod.py -t - | python aprs_is.py -c CALLSIGN-10 -p xxxx -lat xxxx -lon xxxx
pypy3 aprs_demod.py -t rtl_fm | python aprs_is.py -c CALLSIGN-10 -p xxxx -lat xxxx -lon xxxx

📱 Termux (Android) based APRS Beacon

  • One goal is use a cell phone to generate beacon audio samples that can then be passed two a handy radio. This is accomplished using Termux, a rad feature packed terminal for phones. You will need to install it from F-Droid and install Termux-Api, which allows for fetching the GPS points. In termux, you can install python3, pypy3, sox, screen and any other goodies that suit your fancy.
  • Modulate and play APRS becaons messages. You will need:
    • Type-C to audio cable connected to the mic of your radio. I opted for one with additional power connector. In the developer settings for Android, I set screen to always be on when plugged in.
    • 3.5 mm TRS to Dual 3.5 mm TSF Stereo Breakout Cable. The mic connector only uses the tip connector, the rest are grounded.
    • A 3.5 mm to 2.5 mm jumper. My handy radio mic input is 2.5mm.
    • For my radio, I also needed to AC couple the the mic pin TIP like so. I couldn't find any suitable cables, so got the soldering iron out! Not difficult!

Examples

To be run in Termux.

  • Fetch GPS points and generate beacon APRS messages
python termux_beacon.py
  • Play APRS beacon messages to radio
python termux_beacon.py | python aprs_mod.py -vox -t play -t -

💡 Future Work

  • Full integration on embedded system with MicroPython
    • I2S embedded audio interfacing
  • Rx/Tx digipeating
  • Deploy as a 🎈 HAB payload!

🙌 Acknowledgements

License

GNU General Public License v3.0

About

A light weight AFSK mod/demod for microcontrollers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published