2m FM SSTV with literally just a Raspberry Pi

Stumbled upon this write-up- SSTV from the Raspberry Pi camera, with direct RF synthesis, i.e. no outboard radio required, complete with motion detection and callsign overlay. Neat!

Low pass filter mandatory.

Nothing stopping this being adapted for HF SSB, in fact it would probably work better.


Wouxun KG-UV950P / KG-UV950PL DIY hands free pinout

I have a lovely Wouxun KG-UV950PL 6/4/2/70 mobile radio, but a hands free kit doesn’t seem to be available. So I set about working out the connections required to build one. Here they are:

KG-UV950P - KG-UV950PL mic handsfree pinout

Using a standard RJ45 Ethernet cable:

  • Orange+white / pin 1: RX audio – NC for this application
  • Orange / pin 2: +5V on receive (unverified) – NC for this application
  • Green+white / pin 3: PTT – wire to one side of switch
  • Blue / pin 4: unknown, probably buttons – NC for this application
  • Blue+white / pin 5: unknown, probably buttons – NC for this application
  • Green / pin 6: +8V constant – wire to 2.2k resistor, then to positive side of mic
  • Brown+white / pin 7: ground – wire to ground side of mic and to other side of PTT switch
  • Brown / pin 8: – TX audio – wire to negative side of 100μF capacitor, then positive side of the cap to positive side of mic

Looking forward to building a version for the car and seeing how it is for road noise etc.

According to this, increase resistor size to increase mic output level (sounds counter-intuitive, but hey).

Update: that 2.2k resistor should be a 47k. That seems to produce clean audio and keeps the current through the mic element down. I’ve ordered a MAX9812 module to see whether a pre-amp brings the punchiness of the audio up a bit, since it’s a bit quiet as-is.

Considering a radio

Considering the TH-9800 (4m version) from Sinotel. Looks perfect for Raynet stuff.

Diplexer plans: Make yourself a diplexer courtesy VK3ZAV

Questions posed to the vendor:

  1. Recommend a diplexer to split the 2m+70cm side from the 4m side
  2. Recommend a diplexer to split 2m and 70cm – assuming the rig can’t handle this itself
  3. Can the cross-band repeat function be locked down to only transmit on receipt of a specific CTCSS tone?
  4. Can the TX power be set independently on the two sides of the radio?

New radio for me, if they come back with the right answers…

Baofeng UV-5RA Carrier Detect/squelch open pin


For a project, I need to get a reliable Carrier Detect (or “my squelch is open, I am receiving”) signal out of a cheap and nasty Baofeng UV-5RA.

I’ve succeeded, and have done so by pulling together a few people’s work from around the web. I thought I’d pull it all together here.

This guy has done basically the same thing, using a Baofeng BF-888. Basically you take advantage of the fact the Baofeng powers on its audio amplifier only when the squelch is open. The radio applies 7.6V to pin 2 of the TDA2282 amplifier chip just under the LCD when the squelch is open. (Pin 4 is ground.) Take a feed from pin 2, to a 5k resistor, to the base (centre pin) of a BC547 NPN transistor. Ground the emitter (right pin, looking at the flat side). When the squelch opens, there is continuity between the collector (left pin) and the emitter – that’s your output.

Here’s the chip. Pin two is bottom row, second from the left. Pin 4 is bottom right. I ran very thin insulated wires around the edge of the board and up above the battery clip, behind the plastic cover.

credit: http://alaskareflector.org/zl1nc/UV-COS.html

I’ve stuck a tiny socket up where the belt clip was:

and I’ve shoved my transistor and resistor up behind the outer plastic cover above the battery on the right, dead bug style, hot glued on top of some insulating tape. Quite a bodge, but with some Dremel trimming of the case, it’s all held together fine by the top cover screws.

Multimeter reads continuity between the two output wires (red wire=collector, black wire=emitter) whenever the squelch is open, and open circuit when no signal is being received. Current should flow from the red wire to the black wire in any downstream interface.

Arduino Mobilinkd breadboard KISS TNC

Partly working… documenting my work so far towards a truly inexpensive, standalone, reliable APRS tracker.

I’ve moved away from the Pi and back over to microcontrollers. This is based on practical experience using the Pi at an event. Too much complexity / unknowns. The Pi worked okay, but could have been better.

So this below is based on http://www.mobilinkd.com/2014/09/11/arduino-kiss-tnc/
Which in turn seems to be based on https://sites.google.com/site/ki4mcw/Home/arduino-tnc

There’s actually a bit on KI4MCW’s page about how deaf the ADC design below is, might be worth looking at his improvements which don’t seem to have made it into the Mobilinkd hacking page.

Others doing the same:

So, here’s what is working so far:

  • Arduino Pro mini 5V clone @ approx £3
  • USB – 5V TTL serial cable
  • Baofeng / Wouxun / probably anything with 3.5+2.5mm TRS connector
  • For PTT:
    • 1k resistor
    • BC547B
    • 5V relay
    • diode
  • For TX audio:
    • 100k preset
    • 100nF / 0.1uF capacitor
  • For RX audio:
    • 2x 10k resistors
    • 10nF capacitor

Download firmware file from here or here

avrdude -c arduino -p m328p -P COM3 -b 57600 -U mobilinkd-473-arduino.hex

Grab MobilinkdTncConfig-0.6.1-win32.msi from this page

Ignore the stuff about Bluetooth, fire it up, set delay to 80 (800ms – these radios are properly rubbish), expect no confirmation (there is no save button – the author says (and I have checked) that changes are saved into EEPROM as you click in the UI). Check transmit using 1200Hz tone + Execute button.

Fire up aprsisce/32 or similar

APRSISCE/32 wants a Simply(KISS) port set up, 38400 baud, 8-N-1, and sometimes wants you to disable and re-enable the port before it works. Sometimes have to reset the Arduino too.

Turn the radio volume up quite high.

I plan to use a second Arduino, running a GPS, to push APRS frames in to this unit over serial.

Even better, mod this firmware to talk to a GPS over serial, then format and send its own APRS frames.


(EDIT: the RX circuit above, marked as unverified, is now verified working.)

(Another edit: for better PTT reliability, change the transistor connections as follows:

Collector to relay coil and diode anode
Relay coil and diode cathode to +5V
Emitter to ground
Relay contacts across Baofeng PTT (bare wire / 3.5mm sleeve) and Baofeng ground (blue / 2.5mm sleeve)) – need to update the text below.

Connections, taken down from working (TX, RX and PTT) breadboard:

  1. Headset red -> 100nF cap
  2. cap -> one side of 100k pot
  3. mid pot -> D6
  4. other side of pot -> gnd
  5. Headset blue -> gnd
  6. Headset bare -> BC547B emitter
  7. BC547B base -> 1k resistor
  8. resistor -> D10
  9. BC547B collector -> gnd
  10. Arduino GND -> gnd
  11. Arduino VCC -> vcc
  12. Headset green -> 10nF cap
  13. potential divider: gnd -> 10k resistor -> 10k resistor -> VCC
  14. cap -> mid of potential divider (2.5v)
  15. mid of potential divider -> A10

Baofeng pin assignments are here.


Baofeng / Wouxun common headset wire colours / assignments / PTT control

Green  2.5mm tip     rx audio +
 Blue  2.5mm sleeve  rx audio gnd,  ptt GND, rig gnd
 Bare  3.5mm sleeve  tx audio gnd,  ptt +V, NB NOT rig ground
  Red  3.5mm ring    tx audio +

To key the PTT, current must be able to flow from Bare (3.5mm sleeve) to Blue (2.5mm sleeve).

That is, either short Bare and Blue (sleeve to sleeve), or a current should be able to flow from Bare (3.5mm sleeve) to NPN transistor collector, to emittor, to Blue (2.5mm sleeve). An NPN transistor conducts from collector to emitter when a voltage is applied between base (+v) and collector (gnd)) – 5V + 1k resistor.

In other words:
The radio puts 3.3V down the Bare (3.5mm sleeve) conductor.
To key up, this must be shorted to the Blue (2.5mm sleeve) conductor.

RX audio is present between Green (2.5mm tip) and Blue (2.5mm sleeve)

TX audio should be pushed in to Red (3.5mm ring) and Bare (3.5mm sleeve)

Very cheap and simple RX-only APRS IGate

This is a quick post describing my recent efforts to establish a very minimal receive-only IGate at IO91lk. I’m hoping that this post will make it very easy for anyone to replicate the entire setup – so I’ll include hardware purchase and software download links later on.

tl;dr Raspberry Pi 2, RTL TV stick, 5/8 whip on a SO239, Direwolf.

First off, here’s a terrible photo.

You’re looking at MB7UUU – maybe the only RTL dongle with a callsign?


Grab a Raspberry Pi – I used a Pi 2, but you could you a zero for this to keep costs really low, assuming my SD card image works on the zero – not tried. (£6)

Grab a USB Wi-Fi dongle – mine is just a very cheap one off eBay. Hopefully this image will boot and work on the Pis with Wi-Fi built in – will test soon. (£2)

Grab a 4GB SD card. (£2)

Grab an RTL2832U USB TV dongle, I use this one. (£10)

Build or buy an antenna – I made a 5/8 whip on an SO239 socket, didn’t bother with the loading coil, hung from the rafters by the top, works great. (£2 tops for socket, £1 tops for wire, could be done for free)

Devise a way to connect your RTL dongle to your antenna – I had a pigtail floating around, so I did it properly, but you could probably do fine just bodging the antenna element on to the coax from the antenna the dongle came with.

I make that approx. £20 all-in, £25 if you need a USB power supply as well.


You have two options here, easy mode or hard mode.

Easy mode:

  1. grab this SD card image*
  2. unzip it
  3. burn it on to a micro-sd card using Win32diskimager or dd as appropriate
  4. Eject the SD card, stick it in the Pi, boot the Pi
  5. Run rtl_test as per this page, and get the PPM value for your stick (may take some time to warm up / get stable)
  6. Shut down the Pi, put the SD card in your PC, edit aprsconfig.json on the drive mounted from the SD card (or you can do this directly on the Pi if you want – /boot/aprsconfig.json)
  7. Minimally, fill in Mycall, Lat, Lon, Wifis (SSID/key, and only if you aren’t using wired Ethernet), RTLPPM from rtl_test
  8. Boot the Pi with the SD card, give it a minute and you should see your callsign appear on APRS.fi as soon as it hears traffic – example for my case http://aprs.fi/info/a/MB7UUU

*full disclosure, I just realised I left my ssh key in authorized_keys- remove if you’re bothered- can’t do anything with it unless I’m on your LAN

That’s it. There’s a utility I wrote on the SD card which runs at every boot, takes whatever is configured in /boot/aprsconfig.json and sets everything up. Should be pretty flexible. If you need to reconfigure the IGate, just pull the SD card, edit that file, then boot it again. Likewise if your SD card fails, just burn it again from the link above and drop your aprsconfig.json file on to the card.

The login credentials for the image are: hostname rtlpi, user root, password raspberry.

Here in Tilehurst / Calcot with a 5/8 whip at ~70m ASL / ~5m AGL in an attic, I routinely receive several packets per minute, mainly from the local digipeaters.

The Pi image is theoretically set up with an Icecast server so you can listen to what Direwolf hears on 144.800 through a web browser, to get an indication that things are working, however I think I broke this somehow just before I took the image, while minimising filesystem writes to maximise SD card lifetime. I might do an updated image shortly.

If you’re using Wi-Fi, and your dongle doesn’t register as wlan0, you might have to do some fiddling.

Hard mode

Not going to write this up fully right now, but the secret sauce is the following command line:

ppm=37 # your PPM value here

rtl_fm -f 144800000 -p $ppm - | direwolf -t 0 -c direwolf.conf -r 24000 -D 1 -q d > dw.log

or if you want to include streaming to Icecast:

rtl_fm -f 144800000 -p $ppm - | tee >(direwolf -t 0 -c direwolf.conf -r 24000 -D 1 -q d > dw.log 2>&1) | ices2 /tmp/ices-conf.xml

where direwolf.conf is:

ADEVICE stdin null
MYCALL [your callsign here]
MODEM 1200
IGSERVER euro.aprs2.net
IGLOGIN [your callsign here] [your APRS passcode here]
PBEACON sendto=IG delay=0:30 every=60:00 symbol="igate" overlay=R lat=50^12.34N long=1^1.23W [update with your own position]

and ices-conf.xml is:

<?xml version="1.0"?>
 <name>APRS frequency audio stream</name>
 <param name="rate">24000</param>
 <param name="channels">1</param>
 <param name="metadatafilename">test</param>-->
 <yp>1</yp> <!-- allow stream to be advertised on YP, default 0 -->

I’ve bundled some software into the SD card image which automates the configuration stuff – source code to go up on Github soon.


In the UK, a pedantic reading of the licence terms suggests, in my opinion, that an APRS IGate falls under Unattended and/or Remote Operation (section 2 part 10(3)), and the licence (section 1) also pedantically defines Radio Equipment as transmitting and receiving equipment. So while the regulator is highly likely to not give a damn, filing for an NoV (Notice of Variation) was straightforward and came back extremely quickly – about 40 hours from initial application with RSGB ETCC to having the NoV returned from Ofcom. Superb service, and my thanks to Steve G8SFR at ETCC in particular – so now by any possible reading I’m covered. Steve advised that closedown operators are not required to be named for a receive-only application, and a max transmit power of -60dBW (1 μW) was specified on the application – way above the -80dBm (10pW) local oscillator leakage measured at the RF input connector by G8JNJ – technically required since the LO will leak out of the antenna, even if to an indetectably small degree. If you choose not to go down the NoV route, and clearly this won’t be possible for all, I’m not about to judge, but it’s not on me.