DIY Arduino APRS Tracker

Since I wanted to have an APRS tracker, that I can use with any radio, but didn’t want to spend a lot of money, I found a project called MicroModem. It uses a R2R resistor ladder for audio output and if you want to add a display, it can even decode AFSK1200 packets. I took the existing APRS library that was developed for this board.

Since I used GPS for another AVR project already, I included the GPS library from Adafruit again.

After putting everything together on a breadboard, i did a first test and realized, that the audio was somehow interrupted by something. When commenting out the GPS part of the code, everything worked perfectly… except having a hard coded position. So it was time to hook up the oscilloscope to the audio out pin and the GPS RX pin.


yellow: audio | blue: gps serial data

You can see, that the parser for the received NMEA messages is clearly slowing down the audio, when a messaged comes it, even without using interrupts for parsing. The simpliest solution that came to my mind, was to disable the serial port right before TX function and reactivate again afterwards. This only worked for the first message, but if a second message came in before the transmission stopped, it was interrupted there too. Luckily libAPRS uses an LED, that indicates transmission. So i simply wait for the LED to turn of until I activate the serial port again to avoid delay functions.

yellow: audio | blue: gps serial data

yellow: audio | blue: gps serial data

Finally it was working, so I decided to make an Arduino shield for testing it portably, but I want to build a standalone board soon.


I added a jumper to pin 8 to switch between two different APRS SSIDs & symbols for portable and mobile (car) usage. The pinout of the header pins from top to bottom was intended to be audio out, gnd, gnd, PTT, Vin, but sadly my TYT TH-9800 doesn’t provide enough current to power the whole board, so I removed the Vin connection again and power the board over USB, but left the header as it is, in case I need it in the future. The upper left ‘reset’ button was rewired to pin 2 in case i need that too.

I actually wanted to put locationUpdate(); in the ISR, but it doesn’t seem to work inside any ISR, even if I use a timer with a lower priority or disable interrupts while transmitting. However instead of using a delay function or a counter to schedule the transmission, i decided to use the most accurate way – GPS time. Every 30th second of a minute (or any other chosen value) it will transmit audio.

I want to mention, that i slightly modified libAPRS to stop the RX interrupts if the ADC gets some floating values. Just comment out the following line in AFSK.cpp: AFSK_adc_isr(AFSK_modem, ((int16_t)((ADC) >> 2) – 128));