0% found this document useful (0 votes)
196 views

Arduino TNC

This document discusses using an Arduino microcontroller as an amateur radio TNC (Terminal Node Controller) to allow digital communication over radio. It provides background on similar projects using AVR chips without modem chips. The author achieved this goal using an Arduino Mega and the BeRTOS software package. The status section describes the current implementation using BeRTOS and issues with the ADC detecting weak audio signals. Updates discuss improving the audio detection circuit by adding amplification and testing performance.

Uploaded by

Ioannis Perperis
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
196 views

Arduino TNC

This document discusses using an Arduino microcontroller as an amateur radio TNC (Terminal Node Controller) to allow digital communication over radio. It provides background on similar projects using AVR chips without modem chips. The author achieved this goal using an Arduino Mega and the BeRTOS software package. The status section describes the current implementation using BeRTOS and issues with the ADC detecting weak audio signals. Updates discuss improving the audio detection circuit by adding amplification and testing performance.

Uploaded by

Ioannis Perperis
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Arduino TNC - KI4MCW https://sites.google.

com/site/ki4mcw/Home/arduino-tnc

KI4MCW
Hamstuff, Balloonery, etc. >
Arduino TNC

This page documents an effort to use an Arduino (and more generically, AVR mega microcontrollers) as a KISS
TNC.

Background:

A while back I purchased Scott Miller N1VG's OpenTracker 1+. I bought the device as a kit, had no trouble putting it
together, and have used it a few times as part of my ammo-can tracker box. The OT1+ uses a Freescale MC08
microcontroller to perform software-based modulation and demodulation of AX.25 audio. I have also read about
Gary Dion N4TXI's WhereAVR, and Byon Garrabrant N6BG's TinyTrak 4, both of which use AVR microprocessors
without additional modem chips to perform mod and demod functions in software. With these as examples, I knew
that the AVR Mega series CPUs were capable of functioning as a TNC with minimal support circuitry.

I recently picked up a desktop scanner on clearance at Radio Shack for under $10. I was already using my TNC-X
with another scanner to listen for ARISS passes, and wanted to add the ability to monitor terrestrial APRS as well.
Wouldn't it be interesting, I thought, if I could use one of my many AVR chips to do the job. Even better, I had
recently received an Arduino MEGA for Christmas, and was looking for a project to use it on - wouldn't it be cool to
use the MEGA, connected to my PC via USB, without having to purchase any shields or other new hardware?

Status:

As of November 2010, the goal of this project - the creation of a simple but effective TNC using Arduino hardware -
has been achieved a couple of different ways. Because of the precise timing required to sample and decode AX.25
audio, it was not possible to build a working solution using the standard Arduino libraries. Instead, each solution has
involved software written in C, calling AVR-libc libraries or manipulating register values directly.

Currently, my efforts are focused on an implementation that uses the freely available BeRTOS package, a collection
of integrated libraries and drivers for embedded platforms. The AX.25 and AFSK modules included with BeRTOS
form a high-performance packet engine that can be modified to function as a KISS TNC. I am working with the
BeRTOS team to integrate KISS functionality into the main package, so hopefully those functions will be available in
future versions of their product. In the mean time, a working example of the code (both source and binary for an
ATmega328p-based Arduino) are attached at the bottom of this page, and a schematic for a simple test circuit is
available from the BeRTOS website.

Also attached at bottom are working versions and prototypes from previous efforts. Detailed descriptions are
included in the "Updates" section below.

Updates:

============
2013-12-14:

Have not looked at this in a looooooong time, but I keep seeing references to this page elsewhere on the Interwebs,
so I thought I would update some things. Mostly I'm working on porting parts of the BeRTOS code base into a native
Arduino sketch, to make it more accessible to those folks who might find BeRTOS overwhelming. In doing this, I
have had to teach myself all of the protocol innards again. It's slow going.

One detail that I had forgotten is just how deaf the ADC is. As mentioned below, the AVR ADC is looking for a
0-5VDC signal; the headphone output of my CD player was barely moving the meter, so decodes were almost
impossible. Even worse, the unsquelched channel noise on Track 2 of Steve WA8LMF's APRS test CD is WAY
louder than the audio of a nice, healthy, full-quieting signal; this means that the usual strategy of adjusting audio
based on signal peaks gives the right amount of noise, but not nearly enough packet audio.
Μετάφραση

1 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

I had previously addressed this signal level issue by running the CD player output through some amplified speakers,
and using that pumped-up audio to drive the ADC input. This time, I wanted something that would fit entirely on the
prototyping shield mounted to my Duemilanove. After a few false starts, I found a page that described the circuit
below, which uses a standard 741 op amp in a single-supply arrangement. This works really well - I set the gain for
about 5x (+7dB or so), and my ADC input went from almost imperceptible to fairly strong. The 741 will not provide
rail-to-rail output, but a little clipping at the limits is not problematic (the decode math cares more about polarity
above/below the bias point than it does the exact phase or amplitude of each sample).

Here's the circuit. It's simpler than it looks here.

I have a couple of other op amps I have not tried in this config yet, but I expect they will work fine. I tried using an
LM386, but the MINIMUM gain of that chip is 20 (+13dB), where I was originally looking for something far more
modest (3-6dB).

I bought myself a new digital oscilloscope for Christmas... here are two screen grabs of the circuit in action. In both
images, both channels are at the same scale (1.0V per major division). Channel 1 is the zero-bias audio input,
centered around the marker at left. Channel 2 is the same signal amplified. The post-amp trace is set with 0VDC
even with the bottom line, which shows its DC bias of about 2.5 volts. The amplified channel is inverted, and delayed
slightly by the capacitors in the circuit.

In the left-hand image, you can see the small amplitude of packet audio coming in, and its amplified version. In the
right-hand image, you can see how very much louder the open-squelch static is than the packet audio. You can also
see that the amplified version of the noise is clipping pretty hard, and that the clipping levels are not symmetrical
(that is, it clips at about 1.3 volts on the low end and 4.4 volts on the high end).

2 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

============
2012-07-27:

Propeller? Yeah, I gots one.

============
2011-01-10:

From an email exchange with Zilvinas LY2SS, I realized that my waffling on the bias circuit (in the history below)
leaves it unclear how the KISS TNC demo should be wired up. When I first started using the BeRTOS code, I re-
wired my circuit to match the schematic on the BeRTOS website, which uses the +5VDC pin as the source. Even
though the power from the USB port on my PC is very noisy, I am still able to get excellent decoding results.

Another point worth mentioning... the program and circuit design used here require a BIG audio signal to decode
properly. Your best bet is probably the "speaker out" jack, with the volume halfway up and squelch wide open. The
low-level audio available from a data jack simply is not loud enough to get the Arduino's ADC moving. Likewise, if
you split the signal from the "speaker out" jack to both the Arduino =and= a low-impedance speaker, the Arduino's
relatively high-impedance input pin will not get enough signal to decode anything. This is resolvable, though, and I
have some ideas in mind.

============
2010-12-05:

Got some great feedback from Francesco Sacchi, one of BeRTOS' lead developers, and the author of the AX.25
module. At his suggestion, I am working to provide an integrated, backward compatible implementation of KISS for
BeRTOS. In the mean time I have submitted a couple of patches for minor issues.

============
2010-11-30:

Some extremely non-scientific test results, to give a general idea of RX performance. Please, no wagering.

I played Track 2 of Stephen Smith WA8LMF's APRS test CD through an old JVC CD player, amplified it with a pair
of powered PC speakers, and ran the signal from the speakers' headphone jack to the devices under test. I'm too
lazy to hook up the o'scope just now, but I think that gives me something like one volt p-p of audio, simulating the
speaker output of a VHF mobile. I made no attempt whatsoever to fine-tune signal levels for the hardware trackers -
I just pumped up the volume until the activity light started flashing on the Arduino with the BeRTOS RX/TX firmware,
and left things at that level for the other devices.

For the sound card-based solutions, I had to use un-amplified line-level output from the CD player plus a voltage
divider to reduce the audio to microphone levels that the sound cards could handle. I then messed around with
audio levels until things started working.

3 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

Hardware Software Input Packets decoded


Arduino Duemilanove (328p) BeRTOS RX only (attached below) Speaker level 871
Arduino Duemilanove (328p) BeRTOS RX/TX (attached below) Speaker level 865
TNC-X standard firmware Speaker level 818
Arduino Duemilanove (328p) arduino_tnc_013 (attached below) Speaker level 770
Argent Data OpenTracker 1+ KISS (4800 bps, 04-12-2008) Speaker level 729
Windows PC AGWPE 2005.127 Line level with pad 500
Linux PC soundmodem Line level with pad 412
Linux PC multimon Line level with pad 130

Full disclosure - I also tested an Argent Data RadioShield, but decoded very few packets with it. Since that board
seems to work very well with real-world radio traffic, and since it is based on the same microcontroller as the OT1+, I
suspect its low score was a fluke. I have omitted it here to avoid giving any false impressions.

At any rate, my takeaway is that the BeRTOS-based software is working just fine. I'll see if I can lay hands on some
other devices, and try the same test. I know of one guy with an Argent Tracker 2, and maybe another with some
Kantronics gear. And I'll re-visit the RadioShield, to see what I may have done wrong.

============
2010-11-29:

TX and RX working. It took a while to get the two sides to stop stepping on each other - the secret was to use the
deprecated "ser_getchar_nowait" function. RX still seems to miss a packet once in a while, not sure why. I'd like to
merge some of my code into a nice, clean patch to the BeRTOS AX25 module, but the code below ("Attachments"
section at the bottom of the page) is functional enough to start playing with.

============
2010-11-23:

After spending an entire vacation day learning how little I knew about pointers to char arrays (ugh!), I was finally able
to get a KISS version of the BeRTOS demo app to work, and quite well. It turns out that the AX25 modules as
delivered did not retain the "used" flag for each digi in the path (not sure I knew about this before today), so I made
some minor adjustments to those files. The TGZ attached below also contains a compiled binary for ATmega328p
and '328p powered Arduinos. The shell script "p" calls avrdude with the parameters to program the "aprs.bin" file to
flash. Once it's running, the Arduino starts passing KISS packets over USB at 57600 bps.

The AFSK module in BeRTOS uses a standard Fourier transform with 9600Hz sampling. I have not traced all of the
various library details yet, so I can't claim to know too much about the magic under the covers. For example, I have
no idea where the PTT pin is specified. I inserted a bit-bang for a DCD light, but it could certainly be a lot better. I'm
using the (noisy) 5 volt Vcc from the USB bus, which I think is glitching the programming process on occasion (it's
taking 2-3 tries with avrdude sometimes). And of course the TX side is left to implement. But all of this is just a few
hours into exploring these libs... not too shabby.

============
2010-11-22:

Holy cwap! Had not seen this before today... BeRTOS is a kernel / development framework that aims to deliver a
standard set of libraries and services for a variety of embedded platforms (including AVR, ARM, etc.). Their website
features an example project that demonstrates their AFSK and AX.25 modules on an Arduino. The demo comes
with some pre-compiled images - I burned the hex file directly to my Duemilenova (ATmega328p), rigged up the
specified resistor bridge and voltage divider (identical the design I have been using), and was instantly decoding
every packet I could hear. RX performance out of the box was easily twice as good as the results from my own
code, with faint and somewhat scratchy packets decoding perfectly.

4 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

It should be extremely easy to convert the sample code to output incoming packets in KISS format. It should only be
a smidge more complicated to figure out their serial library, and parse incoming KISS serial data for transmission
over RF. Cool!

============
2010-11-20:

Long overdue for an update. Amazing how life can interfere with your hobbies....

I received an email back in June from Kieran Levin, an MSEE candidate at U of Illinois Urbana-Champaign:

Hi Robert,
I just wanted to share with you what I did last week.

I basically took your receive code and wrote on a transmit function based off of whereavr's logic and put
them both together into a fully functional TNC.

I have connected a bluetooth modem to the serial port so I now have a bluetooth to aprs modem which
i can use with my laptop or windows mobile cellphone. it seems to work well as the stations around me
can pick me up and pass my traffic along and I am receiving many stations around me in probably a
50 mile radius using a small yaesu handheld with a Jpole antenna.

I am planning on implementing a few more features in kiss such as the transmit hold off and adjustable
headers and tails settable via kiss.

the hardware is basically the same as whereavr, I found the code in whereavr did not work as well on the
168 so I used your receive code instead. I did however enable Aref to be from Vcc in software and
adjusted your status led pin assignments. It is not at all written for the atmega 128 only the 168 chip will
work with this.

This code is attached below as "arduino_tnc_014_w_tx.pde" - thanks Kieran!

Also, since I cannot leave things well enough alone, I have been working on re-designing my receive code. The
code used in version 013 and in Kieran's mash-up is based on a timer interrupt service routine that is =hundreds= of
lines long. This is conceptually simple, because the entire code block is called every time the sample timer trips, but
it is extremely ugly as interrupt handlers go. My re-design has been focused on limiting the timer interrupt to adding
a correctly timed ADC reading to a buffer. A separate loop checks the buffer for any new entries, and then drills into
the complex code, which is broken into smaller functions. This loose coupling is working ok, but still has a ways to
go.

Random thought...

Having now spent hundreds of hours farting around with this project, there's a lot to be said for the simplicity of
something like the OpenTracker1+ SMT from Argent ($40). Scott's code is more thoroughly tested than mine ever
will be, and packs a lot more features. Since I already have a solderless breadboard attached to a prototyping
shield, it would be dead simple to plug one of these into the breadboard, and use the Arduino for higher level logic.
For some applications (eg telemetry), the OT1+ SMT is capable enough that an Arduino would be unnecessary.

I also have Argent's RadioShield, which is an OT1+ chip and supporting components on an Arduino shield. The
firmware on the RadioShield is not directly usable as a KISS TNC (as I had hoped), but it does provide a very
simple, reliable way to send and receive basic APRS packets from a sketch. I especially like the LCD interface - I
have a 20x4 display connected, and am displaying (simplified) packet contents as they come in.

============
2010-04-22:

TX code is working - it makes all of the appropriate hoots and whistles, and the timing is tight enough that the audio
even decodes correctly in multimon. Unfortunately, it also hangs, screeches, occasionally ignores incoming serial
data, and frequently reboots itself. (Sigh.) Will post code once it is a bit more reliable.

5 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

============
2010-04-20:

Started working on TX code this weekend. The tone generator uses the same timer-plus-lookup-table I have used in
my SSTV encoders, and the multi-value resistor ladder that Gary Dion used in the WhereAVR in place of the R2R
design, which has a higher parts count. The TX works ok in isolation, but the timing is not quite right - it will decode
when received by a TNC-X, but not much else. I'll post an update once that is working.

Also, purchased and received a Radio Shield from Argent Data Systems. Once assembled, this forms an
OpenTracker 1+ in the form of an Arduino shield. The easiest application for this as a KISS TNC would almost
certainly be to load the OT1+ chip with the KISS firmware, and write a minimal Arduino sketch to pass the serial data
back and forth between the shield and the serial/USB port on the Arduino. This might break some of the shield-
specific features, though. I have not put the shield together yet, and of course don't have any code written to
demonstrate this. Fun detail - the shield can also function as a driver for an HD44780-based LCD panel (16x2). I
have such a panel (snazzy white on black) on order from Sparkfun, along with some stackable headers that I'll use
instead of the short pins that came with the Radio Shield. More info as I play with this.

Thank you and hello to Tom in Luxembourg, who confirmed that the RX-only code (lucky version 13, I assume)
works well on his Duemilanove with the ATmega168 CPU. Great news, and thanks for the feedback!

============
2010-04-10:

Even better - lucky version 013 brings in true KISS decode, improved DCD performance (less flashing), and auto-
correcting ADC bias. I've been decoding APRS packets for several hours, and now have an Xastir map full of
stations. Also fixed a couple of random bugs, improved the comments, and cleaned up a few unused variables.
Accuracy seems reasonable, though I'll have to test it against the infamous WA8LMF test CD. It's now starting to
look a little bit like a serviceable TNC, albeit a receive-only one.

I also tried backing out the LPF on the ADC input, and going back to my original one-cap-two-resistor design, but
with the 3.3V source providing a bias source. So far it seems to be working great. The combination of the simpler
math and the self-tuning ADC bias looks to be pretty tolerant.

============
2010-04-09:

Catching on now. I'm a software guy, so I'm not used to dealing with things like noise on analog circuits.

My original hardware design looked like this:

6 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

This is super easy to throw together, but very, very noisy. First among many reasons: the Arduino 5V bus carries a
ton of noise from the USB line. Every time I would move my mouse, the DCD would start flashing like crazy, even
with no audio coming in. On an oscilloscope, the 5V line shows regular blips in the 0.4 volt range that go nuts with
any USB activity (such as mouse movement), plus a thick layer of "fur" where the continuous five volts should trace
a nice thin line across the screen. After some experimentation, I found that the regulated +3.3V line is =MUCH=
quieter. This source has almost no blips, and very little "fur". Wanna see?

In both of these pics, the scope is set to ONE VOLT and 5 ms per major division, AC coupled. As I'm sure you've
guessed, that's the 5V bus on the left, and the 3.3V bus on the right.

7 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

Next, I tried another approach to having the AVR tell me what ADC values it was reading. I removed all references
to the "Serial" library from my code, and used the registers directly. The highest speed I could get minicom and the
AVR to agree to was 230400 bps. This worked out very nicely - I could write a single 8-bit byte to the AVR USART at
every 13200 Hz sample, and not disrupt either the ADC, the sample loop, or the USART. The data that came from
this effort showed that I may have been either mistiming the ADC sampler (too low of a freq = too high of a pre-
scale), or that the input audio was overlaid with some higher frequency audio noise. I investigated both, and ended
up using a lower pre-scale value (16 = 1 MHz sampling) and a more complicated LPF for the audio input.

The new design looks like this:

Hopefully L1 and C2 reduce audio noise above the 2200 Hz tone of AX.25. Note that by using the 3.3V line to bias
the input, I have to also apply the 3.3 volts to the Aref pin. This yields extra noise reduction benefits, as having the
Aref pin float invites trouble. Finally, note that I lowered the resistors from 10K to 1K, on the theory that lower input
impedance may help in some small way. The overall effect of these changes was very positive - ADC performance
improved, and the 006 series code came even closer to actually working in real time.

8 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

But that wasn't enough.

I had spent some time reviewing any web articles I could fine that provided detailed strategies for decoding AX.25 /
Bell 202 audio streams. In this research, I came across a paper written by Dennis Seguine, explaining how a mixed-
signal Cypress chip could be used to perform basic DSP calculations on the incoming data. While some of Dennis'
strategy would not work on a AVR (since 8-bit AVRs do not have DSP functions built in), the first half of his algorithm
made sense to me. I played with it on a spreadsheet using some of the ADC-to-serial data captured from the quieter
input circuit. I found that with just a couple of minutes, I was able to decode packets from those samples at about
75% accuracy. Next I ramped up this new approach to a C program on the PC, again reading the ADC-to-serial
data. With a few tweaks, I was decoding data all over the place.

In the mean time, my wife had gotten me a few Arduino doo-dads for my birthday - a Duemilanove with an
ATmega328P, and a protoshield. Instead of porting the new C program back to the Mega, I thought I would dive into
the deep end, and code it for the Due instead. This proved to be a useful exercise - I found several bugs in previous
versions of the 006 series sketches written for the Mega. Soon I had the new 012 code compiled and running on the
Due. I fed it some audio, and was pleasantly surprised to find that it could decode packets immediately. I switched
plugs and fed the Due some open-squelch audio from 144.390, and soon all kinds of data was flowing across the
screen.

Note that the 012 sketch is still a test build - it decodes the packets into a plain-text format intended for monitoring
on a serial terminal. This output will not be useful to AGWPE or Xastir, but it does demonstrate that packets are
being received and decoded. There are still some more accuracy issues to work on, but it's a big step forward.

ADC_13200_opensq.wav.txt Robert Marshall, v.1

arduino_tnc_006.c Robert Marshall, v.1

arduino_tnc_006.pde Robert Marshall, v.1

arduino_tnc_010.pde Robert Marshall, v.1

arduino_tnc_013.pde Robert Marshall, v.1

arduino_tnc_014_w_tx.pde Robert Marshall, v.1

bertos_kiss_tnc_rx.tar.gz Robert Marshall, v.1

bertos_kiss_tnc_rxtx.tar.gz Robert Marshall, v.1

packet2.wav Robert Marshall, v.1

propeller_tnc_2.1.c Robert Marshall, v.1

wav2txt.pl Robert Marshall, v.1

9 από 10 03/04/2020, 07:04 μ.μ.


Arduino TNC - KI4MCW https://sites.google.com/site/ki4mcw/Home/arduino-tnc

Δεν έχετε δικαίωμα προσθήκης σχολίων.

Σύνδεση | Αναφορά κατάχρησης | Εκτύπωση σελίδας | Με την υποστήριξη των Ιστότοπων Google

10 από 10 03/04/2020, 07:04 μ.μ.


This document was created with the Win2PDF “print to PDF” printer available at
http://www.win2pdf.com
This version of Win2PDF 10 is for evaluation and non-commercial use only.
This page will not be added after purchasing Win2PDF.
http://www.win2pdf.com/purchase/

You might also like