APRS is a digital communication mode using a VHF radio, a modem, and a computer. Packets are sent over the air in a manner similar to the internet. It's used to send text messages, email, weather reports, and positions of emergency response assets.
Years ago I bought a muli-color LCD display from Adafruit for my Raspberry Pi 2. I finally got around to assembling it and was looking for an application. I figured if I wrote an app to monitor and decode APRS packets it would be an opportunity to better understand this interesting protocol.
The first part of this system consists of a Baofeng BF-F8HP radio and a interface board that I described in an earlier post. The Raspberry Pi 2 has no audio input, so I had to use a USB sound card dongle. This used up one of the Pi's two USB ports. I was going to plug the Pi's other port into the interface board's "Push to Talk" (PTT) port, and then get the Pi on the network using an Ethernet cable, but since the code I'm running is very experimental, I thought it more prudent to use a WiFi dongle on the second port and keep the Pi on my guest network. Although PTT is not needed for this part of the project, I should be able to add it later using the Pi's GPIO pins.
I installed Direwolf, a Terminal Node Controller (or modem), on the Pi with "sudo apt install direwolf". The sound card configuration in direwolf/config file looks like this:
ADEVICE plughw:1,0
ACHANNELS 1
I started ~/direwolf/direwolf but it wasn't decoding the received messages. There turned out to be two problems with the soundcard dongle. One was that it couldn't handle the nearly 4 volt DC offset coming from the Baofeng, and the other issue was that the dongle was expecting microphone level signals. To handle the offset I added 0.15 µF capacitor to the signal line. Next I cut the signal level down by a factor of 20 by making a voltage divider using a 470 ohm resistor and a 10K ohm resistor.
Now for the Python stuff. I wanted to make a networked connection to Direwolf's so-called KISS (Keep It Simple Stupid) interface. I reality, I don't think it's that simple! I looked at two ways to access this interface. Using the Python KISS library, or just opening a TCP socket.
Capturing packets in KISS
ki = kiss.TCPKISS(host='localhost', port=8001)
ki.start()
ki.read(callback=print_frame2)
Capturing Packets with a TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', TCP_PORT)
sock.connect(server_address)
while(True):
data = sock.recv(1024)
I settled on the KISS library because I was hoping that it would handle much of the packet assembly and disassembly. It was a little trickier that I though. I had to import the parse functions from both the aprs library and the aprslib library. These two functions do slightly different things. The aprs function really does a decode, and the aprslib function does the actual parsing.
decoded_msg = str(aprs.parse_frame(msg))
decoded_msg = decoded_msg.replace('*','')
print('Decoded Message = ' + decoded_msg)
parsed_msg = aprslib.parse(decoded_msg)
prettyprint.prettyprint(parsed_msg)
Next:
Add meaning to the colors. Currently the screen backlight color is random. Each type of message (position, wx report, text) should have an assigned color.
Add the ability to transmit.