AFSK (Audio frequency shift keying) was used primarily for slow – 1200baud – packet radio. Today it is mainly used by HAMs for APRS(tm).
The most common setup is to have radio equipment with TNC (terminal node controller) connected to host PC. Host is running some software that understands incoming packets and reacts to them. If you are a HAM you probably have radio and PC already. What you need is the TNC. General problem I found with TNCs is that they tend to cost too much – 100+EUR price tag is not uncommon for 5-10year old equipment, and new TNC models cost 200+EUR (lots of features not necessary for AFSK operation).
This project is based on BeRTOS and inspired by KI4MCW’s site. KI4MCW’s code served as kind of introduction to BeRTOS operating system. One big exception is that instead of Adruino this project uses STM32VL discovery board.
This little board contains STM32F100 chip – 24Mhz clock, 1x 12bit ADC, 2x 12bit DAC, 3x UART, etc. It is a complete development board with ST-link debugger on the same board. Costs ~10EUR. Since this board contains ADC and DAC, all you really need to complete TNC are few external components (2 resistors, 2 capacitors, 1 trim pot) and the right software for the MCU. The total price is far below 100EUR, and it probably even less than 15EUR. This is practical for massive fill-in digipeater deployment.
The BeRTOS package comes with AFSK modulator and demodulator and simple AX.25 protocol “decoder”. All I had to do it implement KISS protocol and the TNC was finished. KISS Protocol was implemented according to this article – all features are implemented (including message queuing and p-persistence). Many routines are used from STM32 standard library as BeRTOS doesn’t have support for STM32 timers, DAC, and ADC. (It does support ADC, but in a way, that is not usable in this project).
Original AFSK demodulator was later rewritten by OM5AMD to use FIR filters (instead of IIR). New demodulator showed slightly better results in testing (tested against TNC Test CD). Both algorithms can run with opened squelch, but none of them provides (reliable) carrier detect functionality. Carrier detect algorithm is implemented at packet level by looking at incoming bytes and checking fixed bytes on certain positions. This is so-called Digital carrier detect, which is of course not perfect, but worked pretty well in field testing. True carrier detect feature is still on TO-DO list and any ideas are more than welcome :-).
The sources for the whole project are available on GitHub. You will need Arm toolchain to build it. I suggest summoning toolchain, which works well. I have also added compiled binary files to the repository, so you can just upload the code to your board and test.
The project is configured to use USART2 interface (PA2 – TX, PA3 – RX), PA1 as analog signal input, PA4 as analog signal output and PA0 as PTT. Whole project is powered by 5V and all necessary LDOs are already on board.
Serial port is 3.3V, so you are going to need MAX(3)232 (or similar) to interface the board to RS232 port. I personally use cheap USB-to-serial converters, which are based on CP2102 chip (3v3 level, 5volt tolerant)
Analog input needs to be AC coupled and biased to “center” like shown on image. This simple circuit works only when connected directly speaker output. Ideal levels are >1.0Vp-p.
TNC connections available on radios usually provide 0.5Vpp signal which is not enough to detect signal correctly! If this is your case, you are going to need opamp to amplify the signal. In my experiments I have used the following circuit. (V_POL = VCC/2, resistors with NA are not populated) MCP602 opamp has been selected, because it works at 3.3volt and is (almost) rail-to-rail. AC coupling and biasing resistors are not necessary, as the biasing is already done by opamp, and ADC input is high-impendance.
Output from the STM32’s DAC is already buffered and requires no external buffer. Signal swing is 3.3Volt p-p, which is probably too high for most radios. Using single trim pot you can adjust the levels to proper values. AC coupling capacitor should be ~10uF (there is error in schematic). This capacitor could probably be omitted if your radio already has AC coupling on the signal input.
Most radios have pull-up on PTT buttons, so NPN transistor is all that you need to drive the PTT. On some radios, like Yaesu VX8, you need extra resistor in series, because the PTT signal is multiplexed with audio signal. The PTT output is routed to the PA0 pin on the Discovery board, which is the same pin that is used for the “USER” button. This is particularly useful when testing, “USER” button works as “PTT” button.
TNC on picture is currently used in a digipeater which we (OM5AMX and OM5AMD) setup near our QTH. For the host computer we used decommissioned Routerboard RB411 with OpenWRT installed and APRX digipeater/I-gate software. Radio used is Baofeng UV-3R, with RadioShack HTA 20. Output power is about 15Watts, and selectivity of UV-3R radio was better in tests than Yaesu VX8 (compared by rate of packets/hour).
This digipeater has been running for about 4 months without any trouble. You can find some statistics on aprs.fi – OM5AMX-1
I don’t really want to go into details of software inner workings, or how to program the MCU. If you have any doubt, just ask, or better figure it out yourself ;-).
Any questions or comments are welcome.
73 OM5AMX, Michal
12 comments
Comments feed for this article
April 7, 2012 at 10:48
A. Dunkel
It might be nice to make the project open source so that others may come to a complete understanding of how this digipeater works.
Sometimes code, hardware, and observation must all three be available to the learner. How did I come to understand electronics? By ripping apart electronic gadgets to see how they worked.
The FCC website is also invaluable in finding schematics for hardware reverse engineering.
April 7, 2012 at 12:15
Michal
Well, the sources are available at https://github.com/robots/APRS. Link is also available in the text.
January 18, 2013 at 04:35
VA7DEO
I managed to build from the sources. I didn’t realize that BeRTOS was an additional install and codelite was used to build the project.
Thanks for sharing the source and the article.
January 18, 2013 at 10:34
Michal
The project is self-contained. I don’t see why you need to install bertos at all.
January 18, 2013 at 21:57
VA7DEO
I just happened to install BeRTOS before codelite. I wouldn’t have known about codelite without installing BeRTOS. I’m a noob with ARM development so it may take a while to figure it out.
The next step is figuring out a debug environment. I’ve build openocd but haven’t had a chance to use it.
April 28, 2013 at 08:54
Igor
I program STM32vldiscovery by discovery_aprs.elf. What is speed of UART? Where is i find terminal command for the TNC? By default on the board 8 MHz quarz. Need 24?
Thank you!
ua6dx
September 10, 2013 at 12:12
Sybrand Strauss
Is there a reason you couldn’t change the Analog Reference? Rather than use the opamp, couldn’t one just feed 0.5v into the AREF? Or even set it to the 1.1V built in reference? Wouldn’t that bring it down far enough?
September 10, 2013 at 12:15
Sybrand Strauss
Oh wait – never mind – that would maybe work for Arduino, but you’re using the STM32VL. Sorry.
November 10, 2013 at 08:34
Michael HE7HIA
Hi Michal,
I was so excited to find this project that I designed and produced a PCB that integrates the microcontroller and everything else here into one little board (it’s about 1×1.5″) I included hardware for STM32s that have USB built in, so with some additional code, you’d be able to plug USB in and hook this straight into a radio without a USB- serial converter.
I may also build a version that has an on-board GPS. At my day job I’ve designed several products that integrate GPS so I know how to make it small and cheap.
But! I’m having some trouble getting it to compile (I’m using my clumsily assembled ARM tool chain with eclipse and OpenOCD, it works for my own development, but I’m still pretty new to STM32 development so I’m not sure how good a job I did), and I am not sure if the pre-compiled binaries are working. I’m trying to get it to run on the discovery board first. I’m new to packet/APRS so that doesn’t help.
It looks like the code uses UART2 at 115200, and it looks like it spits out a message at boot, but I never see one. What commands can I send to it and what responses should I get?
Also, in the images directory on git, there are three files ( a .bin, .hex, and .elf) ST-Link likes the first two and they appear to be identical, what’s the difference?
-Michael KE7HIA
November 11, 2013 at 20:05
Michael HE7HIA
Here’s a picture! I had to whip it up in a few hours to get it in with a PCB order we were doing at work, so it’s not the prettiest PCB I’ve ever made, the next revision will be better. (Also a few parts aren’t populated.)
March 1, 2019 at 23:52
Jerry
I am interested in the Michael HE7HIA latest PCB and could not find a way to contact him using his call sign. I would like to know if the board is an AX25 TNC with onboard GPS? I do not want a KISS TNC and my KPC3 is too big of a foot print. Thank you. Jerry N7YGE
April 29, 2017 at 23:39
Arduino Mobilinkd breadboard KISS TNC – MØLTE's Amateur Radio Blog
[…] https://michaldemin.wordpress.com/2012/02/27/cheap-afsk-tnc/ […]