Table of Contents
NinoTNC
The N9600A is a USB interfaced multi bitrate USB KISS TNC, supporting modulations suitable for all bands and both FM and SSB. The NinoTNC is designed by Nino KK4HEJ for use in Amateur Radio packet data networks. The 2400 baud DPSK modem supports many microphone-audio transceivers, and 4800 baud GFSK is great for use in data-radio/9600 transceivers which don't quite cut it for 9600 baud. On top of that, it supports both AX.25 for compatability with legacy TNCs, and a new link-layer encoding scheme called IL2P which is a Forward Error Correction equipped protocol designed to be more efficient than AX.25, recently with added CRC for better error rejection.
The N9600A NinoTNC provides a USB serial interface at 57600 baud.
Group Buys
OARC has run two successful UK/EI group buys, with around 250 kits distributed across two rounds.
There are no current plans for another group buy, however never say never.
Board + CPU sets are available in the UK, see below.
Here is information on ordering a set of components to build up a NinoTNC. It's fast and easy.
UK Stock
By agreement, Tom M0LTE holds stock of PCB + microcontroller only kits in the UK. These are available with circa 2 day shipping from https://ko-fi.com/s/981d919ea3. Two sets of components from Mouser takes you over their free shipping threshold.
Operating modes
Current modes as of firmware release 3.40 / 4.40 / v40 (all refer to the same version)
# | Mode | Baud | bps | Mod | Proto | Usage | BW | Typical use |
---|---|---|---|---|---|---|---|---|
1 | 0001 | 19200 | 19200 | 4FSK | IL2Pc | FM | 25k | High SNR links between dedicated data radios. v41 firmware required in practice. |
3 | 0011 | 9600 | 9600 | 4FSK | IL2Pc | FM | 12.5k | High SNR links between dedicated data radios. Suitable for UK 2m band. |
2 | 0010 | 9600 | 9600 | GFSK | IL2Pc | FM | 25k | Current recommended mode for new 70cm (25kHz) links where both ends are compatible |
5 | 0101 | 3600 | 3600 | QPSK | IL2Pc | FM | 12.5k | For situations where only a speaker/mic connection is available but > 1200 baud is desired |
11 | 1011 | 1200 | 2400 | QPSK | IL2Pc | SSB/FM | 2.4kHz | HF - quadrature version of 1200 BPSK, twice the throughput for +3dB SNR. |
10 | 1010 | 1200 | 1200 | BPSK | IL2Pc | SSB/FM | 2.4kHz | HF - use for circuits where wider transmission is acceptable. |
9 | 1001 | 300 | 600 | QPSK | IL2Pc | SSB | 500Hz | HF - quadrature version of 300 BPSK, twice the throughput for +3dB SNR |
8 | 1000 | 300 | 300 | BPSK | IL2Pc | SSB | 500Hz | HF - slowest but best performing mode. ~7dB better than classic 300 baud FSK AX.25 |
14 | 1110 | 300 | 300 | AFSK | IL2Pc | SSB | 500Hz | CRC improvement of IL2P 300 baud AX.25. Recommended if you can't do BPSK / QPSK on HF. |
- | 1111 | n/a | n/a | n/a | n/a | n/a | n/a | Allows the mode to be set by a SETHW KISS command (v41+). |
IL2Pc is shorthand for IL2P plus CRC.
Superseded (but still supported) modes:
# | Mode | Baud | bps | Mod | Protocol | Superseded by | Usage | BW | Typical use |
---|---|---|---|---|---|---|---|---|---|
0 | 0000 | 9600 | 9600 | GFSK | AX.25 | 9600 GFSK IL2P | FM | 25k | Backwards compatibility with legacy G3RUH modems |
4 | 0100 | 4800 | 4800 | GFSK | IL2Pc | 9600 4FSK IL2Pc | FM | 12.5k | Was the recommended mode for new 2m (12.5kHz) links where both ends are compatible, until 9k6 4FSK came along |
7 | 0111 | 1200 | 1200 | AFSK | IL2P | 4800 GFSK IL2Pc | FM | 12.5k | Improvement over 1200 AFSK IL2P, where none of the GFSK modes are possible |
6 | 0110 | 1200 | 1200 | AFSK | AX.25 | 1200 AFSK IL2P | FM | 12.5k | VHF APRS, backwards compatibility with classic / legacy TNCs like PK232 |
12 | 1100 | 300 | 300 | AFSK | AX.25 | 300 AFSK IL2P | SSB | 500Hz | Backwards compatibility with legacy HF packet modems. Modulation invented c. 1962! |
13 | 1101 | 300 | 300 | AFSK | IL2P | 300 AFSK IL2Pc | SSB | 500Hz | IL2P improvement of AFSK 300 baud AX.25. |
Prefer:
- 4FSK > QPSK > BPSK > DPSK > AFSK
- IL2Pc > IL2P > AX.25
- SSB > FM
Baud is symbols per second, bps is bits per second. Where baud=bps, that means each symbol carries 1 bit (i.e. a symbol can have two states, 0 or 1). Where baud is 2x bps, that means each symbol carries 2 bits (i.e. a symbol can have four states: 00, 01, 10, 11).
Signals settings
Cheat sheet
- Switch 1 is TX audio range selection - on/up is high level for louder transmitted audio, off/down is for quieter transmitted audio
- Switch 2 is RX audio sensitivity - on/up is low sensitivity for loud radios, off/down is high sensitivity for quiet radios
- Switch 3 is AC/DC coupling - normally should be off/down apart from specific radios
- Switch 4 is external carrier detect - normally should be off/down unless you need it for a specific purpose
Radio | Signals | Notes |
---|---|---|
Yaesu FT-450D | 0000 | Requires low level TX audio - the FT-450D is very sensitive. RX audio setting probably doesn't matter, control with appropriate RF gain / AGC, but off/down works. |
Tait TM8100 / 8200 | 1100 | Requires high level TX audio, else the transmitted audio is too quiet in the range of the pot. Requires low level RX audio, else CRC is always lit. Requires AC coupling to block the DC which is present on the TX audio pin. Works with 19k2!! |
Tait T2010 I & II | 1100 | Tested up to Modes 0100 4800 GFSK IL2P+CRC |
Yaesu FTM-300D | 1100 | Tested up to Modes 0100 4800 GFSK IL2P+CRC |
Kenwood TK-90 | 0100 | TX audio is pretty sensitive, works better in mic range. |
Switch 1 - Transmit audio range selection - DATA/MIC
The data / on / up position increases the TXA level so the TX-LEVEL potentiometer adjustment is in the range needed by the Data radio.
The mic / off / down position reduces transmit audio to the range needed by a microphone-level-input radio.
Switch 2 - Receive audio sensitivity - 1x/11x
The on / up / 1x position is about the right level for a speaker output, and is also appropriate for a data radio output.
The off / down / 11x position is used for radios which have a very low level of receive audio, e.g. perhaps when taken from a speaker mic connection.
Switch 3 - Transmit audio coupling control - DC/AC
Leave in the off / down / AC position unless you have a rare case where having the voltage into the modulator track the TNC’s output, exactly, is required (DC coupling).
Switch 4 - External carrier detect - EN/CD
Leave in the off / down / CD position unless you want to provide external transmit inhibit using pin 2 of the DB9 connector.
Some content courtesy https://tarpn.net/t/nino-tnc/n9600a/n9600a_operation.html
Definitions
- DPSK - Differential Audio Phase Shift Keying - works through mic / speaker connections
- BPSK - Binary Phase Shift Keying (1 bit per symbol) - new, good for HF (SSB)
- QPSK - Quadrature Phase Shift Keying (2 bits per symbol) - new, good for HF (SSB)
- AFSK - Audio Frequency Shift Keying - typical for VHF
- G3RUH - Classic 9600 baud modem design, described here
- GFSK - Gaussian Frequency Shift Keying - as utilised in G3RUH 9600 baud classic mode, often used on UHF for many years, but also implemented in other modes.
- AX.25 - Basic over-the-air protocol utilised for packet radio
- IL2P - Improved Layer 2 Protocol - effectively implements AX.25 but with some over-the-air improvements, transparent to the host software at both ends.
- IL2P+CRC - IL2P with added checksum. Co-developed by Nino KK4HEJ and Jonathan G4KLX to resolve corruption found with IL2P in practice.
- BW - in this context, for FM: channel spacing, and for SSB: audio bandwidth.
- Baud - symbols per second
- bps - bits per second. Effective throughput. For modes with 1 bit per symbol, baud == bps. For modes with 2 bits per symbol, effective throughput is 2x the baud rate.
Experimental new modes
Packet radio on HF is typically 300 baud (and bits/sec), using the Bell 103 modem standard. This was released by AT&T Corporation in 1962. It is extremely susceptible to interference and performs poorly with weak signals common in amateur radio.
61 years later, we have far more processing power at our disposal, which means it is possible to achieve much better performance using the same RF bandwidth. While there are some interesting projects around, e.g. FreeDV / Codec2, nothing so far has been found which is easily accessible for amateurs to deploy in a packet radio setting.
Until now.
Nino, KK4HEJ, has been developing a number of new modes which can be added to the NinoTNC with a simple firmware upgrade. Instead of frequency-shift keying (i.e. tone changing in pitch), the new modes are based on phase-shift keying (i.e. phase of a continuous sine wave changing). BPSK (binary phase shift keying) devices modulate input signals by 0° and 180° phase shifts. QPSK (quadrature phase shift keying) devices modulate input signals by 0°, 90°, 180°, and 270° phase shifts, thus in QPSK mode, each symbol can have one of four values, meaning it is possible to transmit two bits of data in each symbol as opposed to just one, doubling the effective throughput in the same bandwidth, at the expense of requiring a bit more signal-to-noise ratio.
The great news is that these modes are now present in the latest firmware.
These new modes are then selectable using the Signals DIP switch. The software node / client settings can be left as-is - the modulation is completely transparent to them, and this can be used for any kind of packet radio traffic. However, given these are new modes, which may perform quite differently (likely better!) than Bell 103, new values for other parameters such as maxframe, frack, paclen may need to be found, but the Network 105 recommendation of paclen=60, maxframe=1, frack=5000 are probably a good starting point until more is known about how these modes perform in the wild.
Until we know more, suitable BPQ port settings might be:
PORT PORTNUM=1 ID=HF TYPE=ASYNC PROTOCOL=KISS KISSOPTIONS=ACKMODE COMPORT=/dev/ttyACM0 SPEED=57600 FRACK=7000 PACLEN=80 NODESPACLEN=60 DIGIFLAG=0 MAXFRAME=1 RETRIES=10 QUALITY=192 MINQUAL=100 TXDELAY=100 TXTAIL=300 RESPTIME=100 T3=300 ENDPORT
Obviously, there is no cross- or backwards-compatibility with any old modes or indeed any other model of modem or software out there at this point. You switch exclusively to this on-air scheme using the Signals DIP switch on the NinoTNC.
Some notes from Nino:
The speeds refer to gross bit rate, not including IL2P overhead. The baud rates are 300 for the narrow modes and 1200 for the wide modes. Net bit rate will obviously be slightly less.
Precise tuning will always be an advantage on SSB, but these have more inherent frequency mismatch tolerance than AFSK. 300 can deal with up to about 50 Hz. 1200 should work up to about 100 Hz. The QPSK modes are slightly less, respectively.
In addition, the wideband PSK modes should work better than AFSK over FM, e.g. on 2m. I also expect these to work through mic/speaker connections or direct modulator/discriminator connections. Data port not required, but also not an obstacle.
The old 2400 bps audio mode at 0100 and 0101 will go away. It wasn't based on any widely-used standard and 2400 QPSK is far superior.
Performing the firmware update is easy- follow the instructions here on Windows or Linux. Be sure to take the precautions mentioned on that page.
Once you have updated, you can set your signals switch to one of the new modes as per the table above.
To switch back to the previous mode, just change your signals switch settings. You don't even need to restart your software - the change is immediate and totally transparent to the software running on the PC.
Given these are new modes, it is at the very least good manners that we ID regularly in a well-known mode. To that end, this firmware IDs every 9 minutes in BPSK/QPSK modes, modulated in 1600/1800 AFSK AX.25.
On transmit, like any data mode, it's important to make sure that your signal is linear, i.e. clean. My recommendation is to turn your rig power up fairly high, turn your TX DEV pot on the TNC down to zero, hold down the TX TEST button on the NinoTNC until it goes into transmit test mode where it repeatedly transmits frames, let go of the button, then turn up the TX DEV pot on the TNC until you are transmitting the desired power level. Press and hold the TX TEST button for a moment and the TNC will come out of TX test mode.
Usage and testing in any scenario is encouraged:
- between nodes
- accessing a node
- keyboard to keyboard, e.g. using QtTermTCP at both ends
- on QO-100
- even HF APRS! (Maybe someone will put up a BPSK or QPSK iGate?!)
Don't use this on established FSK packet channels - this will be QRM to anyone else on frequency - pick a clear channel anywhere in All Modes / Data sections of bands.
Please be sure to feed back your experiences to Nino and others via OARC Discord.
Usage with QtSoundModem
The user must:
- choose “IL2P Mode”→“IL2P RX+TX” or “IL2P Only” under the Settings→Setup Modems menu in QTSM
- and ensure the center frequency in QTSM is set to 1500.
Surface-mount versions
There are a few known SMD variants of NinoTNC in various stages of development:
- Jason K4APR / Nino KK4HEJ: https://groups.io/g/ninotnc/topic/95654607, https://groups.io/g/ninotnc/message/2475
- Nigel M0ZFJ
- A friend of G0NZO
Please update this section if you know more about any of these.
NinoTNC 3D printed cases
Here are some of the case models we've been able to locate:
NinoTNC A4 Housing - the “official” case
Nino TNC Case - Modified case with a tighter fit (and relocated LEDs) by: Jez - M0JXW
NinoTNC standoff - a simple open standoff frame with split pins
The pins just fell off mine straight away - print settings probably need some work.
NinoTNC mounting plate - a basic standoff mounting plate for the A2, A3, and A4. Uses M3 hardware. Has two countersunk holes for wood screws etc.
More forgiving case by Matt M0MFZ - a case with some clever features to allow for ‘less than perfect’ kit builds
LEDs in a line - modified by Jeremy M0JXW
SLOTTIME and PERSIST
Credit Nino:
The NinoTNC firmware honors the SLOTTIME and PERSIST settings sent from the host through KISS commands. Since version 27, It also honors TXDELAY if the hardware TX_DELAY potentiometer is set to minimum.
Those settings are used to implement the Carrier Sense Multiple Access (CSMA) scheme described here: http://www.ka9q.net/papers/kiss.html. Scroll down to “6. Persistence”.
PERSIST is the probability that the TNC will transmit immediately when the channel is clear. SLOTTIME is the time the TNC will wait if it decides not to transmit. The KISS PERSIST command setting is expressed as an 8-bit value, where higher values reflect higher probabilities. A PERSIST setting of 255 means the probability of transmit is 100%, when the channel is clear. SLOTTIME is also expressed as an 8-bit value, in units of 10mS.
The CSMA algorithm in the TNC generates an 8-bit pseudorandom number and compares it to the PERSIST value. If the number is greater than PERSIST, then the TNC waits SLOTTIME before transmit.
I made a slight revision to my implementation of the CSMA algorithm in firmware version 3.31/4.31. In 31 and later, the TNC computes the CSMA lottery while the channel is busy. So you probably won't see a SLOTTIME delay on a dead channel with firmware 31 or 32. In earlier versions, the TNC computed the CSMA lottery every time it was about to start a transmission. So you probably would see some SLOTTIME delays on a dead channel in earlier versions. I made the change to simplify what had become a very complicated logic tree for starting transmissions. I'm not sure which is more correct… or if it matters much.
Other small but measurable time delays you'll see between received and sent packets probably have to do with demodulation processing, serial host communication, host processing, packet assembly, etc.
If you want to see the effect of SLOTTIME and PERSIST, try setting high SLOTTIME and low PERSIST. Repeat your send-and-reply experiments with the storage oscilloscope. You should start to see SLOTTIME delays appearing before replies.
Tuning NinoTNC Deviation
This video demonstrates how to set the transmit deviation for an N9600A TNC using the built-in 999Hz tuning tone and a cheap USB SDR.
In the test setup, an N9600A2 TNC is connected to a TAIT TM8105 radio set to transmit on 145.510 MHz. Software is SDR Console v3.0.14 on a Windows 10 PC. Receive bandwidth on the SDR software is set to 250kHz, AGC on, WFM.
The TX DEV potentiometer on the TNC is at minimum at first, then slowly increased while holding the TEST TX button. Proper deviation is reached when the center spike in the spectrum display is dipped to minimum. This takes advantage of the first “Bessel Null”, which happens when FM deviation is 2.405 times the frequency of the transmitted tone (999Hz in this case). 2.4kHz provides minimum-shift deviation for 9600 baud transmitted data.
After this video was taken, the setup was tested against an IFR 1200 service monitor to verify transmit deviation. The monitor showed 2.42kHz, which is perfect for 9600 or 1200 baud data.
Random excerpt from conversations on the subject
Link to conversation on Discord
IL2P 1200 radio is 25kHz channel - that generates a 1248 Hz tone with the test button, you set 3kHz deviation
If you want to calibrate for a 12kHz channel, set the TNC to a 4800 baud mode, like 0011. That will generate a 500 Hz tone with the test button, which will dip the first null at 1.2kHz deviation, which will work with a 12kHz channel.
In a 25kHz channel, 3kHz works great
If you set a 9k6 mode on the TNC, you'll get a 999 Hz test tone. That's aimed to set deviation at 2.4kHz with the first null, which gives “minimum shift keying” at 9k6. Though it will work at 3kHz deviation as well.
It's also useful to measure the peak-to-peak voltage of the transmit audio signal fed to the radio after proper deviation is set, using an oscilloscope. In this case it was 690mV. This will serve as a “good enough” deviation setting in the future for this particular radio, and likely for similar radios of the same model.
The FM modes tones are as follows:
0000, 0001: 999 Hz tone for 2.4kHz deviation
0010, 0011: 500 Hz tone for 1.2kHz deviation
0110, 0111: 1248 Hz tone for 3.0kHz deviation
0101: 2079 Hz tone for 5.0kHz deviation
Misc Linux Notes
For convenience, udev can be used to create a symlink with a consistent unique name in /dev
for each of your NinoTNCs:
- /etc/udev/rules.d/99-ninotnc.rules
# Create a handy symlink to make refering to NinoTNC's easier SUBSYSTEM=="tty", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="00dd", SYMLINK+="NinoTNC-%s{serial}"
After creating said file, run udevadm trigger
for it to take effect without rebooting.
If you have more than 1 TNC connected to the same device, it can be tricky to distinguish between them. The MPC2221a chip in the NinoTNC can be configured to expose a unique serial number, and udev rules can be set to ensure these get allocated consistent /dev nodes between reboots/cable swaps etc.
Serial number enumeration is disabled on the MPC2221a chip by default, it can be enabled using the tool at https://github.com/g5dsg/2221aTool.
git clone https://github.com/g5dsg/2221aTool.git
sudo python3 ./2221aTool.py enum-serial 1
The chips have unique serial numbers which If preferred, the same tool can be used to specify a serial number for the device. The serial can be up to 16 characters (including unicode!)
sudo python3 ./2221aTool.py set-serial 0123456789
You can then update the udev rules to use the serial number you've set (or obtained from the output of dmesg / inspecting ls -l /dev/serial/by-id, if you keep the chip's original serial)
Example udev rules for 2 TNCs with serials 0123456789 and 987654321:
- /etc/udev/rules.d/99-ninotnc.rules
# Create a handy symlink to make refering to NinoTNC's easier SUBSYSTEM=="tty", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="00dd", ATTRS{serial}=="0123456789", SYMLINK+="tnc-2m" SUBSYSTEM=="tty", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="00dd", ATTRS{serial}=="9876543210", SYMLINK+="tnc-4m"
(Thanks to Nathan, MM3NDH for the udev rule.)
Remote mode switch
KISS SETHW command
As of firmware v41, NinoTNC supports setting the mode remotely using a SETHW KISS command in combination with all four MODE DIP switches being set to 1.
From the release notes:
Use KISS SETHW command (6) followed by mode number in range 0-14. Mode number is in the modes table above.
The KISS MODE setting is written to flash memory. To prevent an immediate flash memory write, add 16 to the mode number in the KISS SETHW command - for example, the value 14 would become 30.
BPQ supports this via the KISS
command. For this command to work, you must set the mode DIP switches to 1-1-1-1 (or on-on-on-on), and be in SYSOP mode. To enter SYSOP mode, type password
at the prompt. The prompt will respond with OK
. At this point, enter the command below:
kiss <port> 6 <value as determined above*>
* Remembering to add 16 to the value if you don't want the setting written to memory.
GPIO
With Raspberry Pi GPIO, put /usr/bin in the crontab path, and add the following to /etc/crontab:
# 1000 - BPSK300 0 * * * * root raspi-gpio set 5 op dh && raspi-gpio set 6 op dl && raspi-gpio set 13 op dl && raspi-gpio set 19 op dl # 1001 - QPSK600 30 * * * * root raspi-gpio set 5 op dh && raspi-gpio set 6 op dl && raspi-gpio set 13 op dl && raspi-gpio set 19 op dh
dl = drive low, dh = drive high.
Wire the numbered GPIO pins to the bottom of the MODE DIP switch, turn all the switches off, and it'll mode-switch automatically. I've gone for BPSK300 for the first half of each hour, and QPSK600 for the second half.
I picked GPIOs 5, 6, 13 and 19 (consecutive physical pins) to map to the DIP switch pins from left to right as you look at the PCB.
MCP2221A
The MCP2221A USB chip has four GPIOs which can be used to control the mode, instead of the DIP switches. This can be useful particularly on a remote site, and removes the need for a second cable (and works with a machine without its own GPIO interface).
This is experimental and is likely to change. See https://github.com/g5dsg/2221aTool for up to date info. Thanks to Dan for working on this.
General steps:
git clone https://github.com/g5dsg/2221aTool.git
Install python3.
then, once (persistent):
sudo python3 ./2221aTool.py setup-gpio
this will configure the GPIO pins as outputs, and make them all low at power on.
then, when required (non-persistent):
sudo python3 ./2221aTool.py set-gpio 1111
where 1111 is the state of the four switches, left to right.
Wiring as follows. NOTE - you MUST either remove the DIP switch or leave all four switches set permanently off with the jumpers in place.
Note: bit of an edge case, but it is required to run sudo python3 ./2221aTool.py setup-gpio
at least once on a TNC before it can be flashed with new firmware, or indeed just used normally at all, at least while some of the MODE DIP switches are set to zero.
Pinout
Firmware
To upgrade the firmware, see https://github.com/ninocarrillo/flashtnc/blob/master/README.md.
TL;DR:
# save a headache sudo systemctl disable linbpq sudo reboot # then... sudo apt install -y python3 python3-pip python3-serial git git clone https://github.com/ninocarrillo/flashtnc cd flashtnc python3 flashtnc.py N9600A-v3-35.hex /dev/ttyACM0 # don't forget to... sudo systemctl enable linbpq sudo systemctl start linbpq
Use v3 firmware unless you know you have a 512kb chip, which is none of the OARC UK kits (i.e. ignore the v4 firmware - it's the same, but for the bigger chip).
If you get dire warnings about bricked TNCs, know is this highly unlikely. Unplug TNC, reboot system, plug TNC, try again.