As with all of my projects, they typically start by finding a crucial piece of kit that then sparks a whole development. Back in late 2022 I was searching through my shed for something when I happened upon a box of Pine A64 single board computers, that I’d completely forgotten about.
These were purchased from a Kickstarter campaign when 64-bit ARM was in its infancy and 64-bit ARM Linux distributions were not common. These new machines were difficult to get going, which is likely why they ended up in the shed. Needless to say, that box was pulled from the shed and sat on a shelf in my office until inspiration struck… could I build them into a High Altitude Balloon (HAB) telemetry tracking system ?
I’ve been involved with the Project Horus High Altitude Ballooning (HAB) group since August of 2010, my first flight was Horus 7 where we watched it land at our feet just shy of Pinnaroo in the North Eastern region of South Australia. Fast forward some 15 or more years and I’m still out there tracking balloons, having retired from actively chasing after them a number of years ago.
Over time much of the software for tracking these balloons had been ported to various flavours of Python from the original implementations in Java. For better or worse it has meant that this custom tracking software has migrated towards running on small embedded ARM single board computers. In late 2022 I’d heard that some within the Project Horus community were tracking balloons with Raspberry Pi’s and SDR’s, so here was the catalyst for some inspiration and I started to wonder if my original Pine A64’s were up to the task ?
Over the Christmas break in 2023 I cobbled together my first ARM based system and I’ve been experimenting with my High Altitude Balloon Telemetry System ever since. This work has been done on and off, when ever I was able to catch a few hours or days. The main focus typically came a few weeks before an actual balloon launch. This series of blog posts will document what I’ve learnt and how I’ve gone about setting my system up to current time.
The ADLAM Pluto typically connects to your PC using a USB micro connector. When connected it establishes a virtual Ethernet network to allow your computer to connect to the device over TCP/IP. It also presents a USB storage device to allow you to edit config files. I’ve only come across one other device that does this, which was a Beaglebone Black Single Board Computer (SBC). This makes it very easy to connect, configure and use the ADLAM Pluto.
However USB cables are not typically long enough to reach the top of the tower or the back of ones dish. One trick the ADLAM Pluto has up it’s sleeve is the USB OTG support, meaning it can be both a USB peripheral and host device. This means we can connect a USB Ethernet adapter to the ADLAM Pluto and gain a real Ethernet interface, perfect for long cable runs !
Adding Ethernet
From the ADLAM Pluto University the OTG page lists a small number of USB Ethernet chipsets the stock firmware is compatible with. I wanted to use Gigabit Ethernet so went looking for an adapter that used the Realtek RTL8153 chipset. The device I ended up purchasing was a Waveshare USB 3.2 Gen1 Gigabit Ethernet Converter, from Amazon.
From various forums it was noted that the onboard ADLAM Pluto power supplies did not like feeding both the USB OTG Ethernet devices and the board at the same time. Instead a short “in-line” loom should be used, which I also purchased. You can see in the photo below how the USB “in-line” loom, Waveshare USB Ethernet and Pluto USB OTG port have been connected together. In this picture power was supplied from the PC (top right) but the data pins from the PC are not connected to either the Waveshare USB Ethernet or ADLAM Pluto. This works quite well.
Ethernet Configuration
To edit the configuration files we need to plug the ADLAM Pluto into the PC and edit the “config.txt” file on the USB storage device it presents. The ADLAM Pluto stock firmware can configure the Ethernet with a static or dynamic IP. I prefer to use a static IP in preference to running some form of DHCP/Zeroconf networking, YMMV.
Static IP Address
To configure a Static IP address edit the the following lines like so;
You will need to change your Ethernet address and Subnet mask to suit your own network, in which your PC will need to also be connected. If you intend to operate your ADLAM remotely via a VPN or similar, then you’ll need to add the default gateway as well like so;
Make sure when you have finished editing the config.txt file that you save the contents and then “eject” the ADLAM Pluto to ensure it commits it to internal flash.
Dynamic IP Address
To configure a Dynamic IP, simply leave the “config.txt” configuration files like this;
The ADLAM Pluto will then use DHCP to obtain an IP address when ipaddr_eth is left black, using this configuration is OK provided you have both DHCP and Zeroconf configured on your network like Avahi.
SDR Software
Don’t forget to reconfigure your SDR software with the new Ethernet Configuration, this can result in a short period of head scratching. For SDRangel I simply edited the device user arguments like so;
Now that the KK103c1 firmware is finished and capable of generating a 40MHz carrier that is phase locked to my 10MHz Rubidium reference, it’s now time to test everything is indeed working.
ADALM Pluto External Clock Input
So up until now I’ve talked a lot about the ADLAM Pluto Clock input, but as yet have not shown where it is or what it does. From the Analog Devices Pluto University the following image below shows all of the inputs and outputs on the ADLAM Pluto. I’ll be feeding the KK103c1 into the “CLK IN” port, which is one of those lovely UFL connectors that are difficult to plug in without glasses or hellish with fat fingers, sigh.
So to make sure the “CLK IN” will work, we can look closely at the schematic for the Rev-C/D hardware and see what is there.
As per my previous post, the Connor Winfield VCO was not happy driving into a 50Ω load. It would also appear that the ADLAM Pluto has the same input impedance provided by resistor R96. Looking at the output of the KK103c1 driving into a 50 load, I see the output drop to +/-0.46Vp-p which is only just above the minimum input of the LTC6957 buffer being used to re-clock this input. So while this works, I will need to revisit this level and look at if I increase R96 to 200R to improve the signal levels provided by the KK103c1. Good enough for government work at this point in time. There is also a capacitor value that I can change to balance the KK103c1 output signal with the ADF4110 REFIN pin, to be investigated further.
Test Setup
Once the External Clock Input was checked, the KK103c1 was connected by a short UFL-UFL lead to ADALM Pluto. I typically use a pair of tweezers and a microscope to get these things connected. The test setup is shown in the image below.
The 10MHz Rubidium reference was feeding both the Rigol external reference input and the KK103c1 module in the foreground. Again the Icom R10 was being used to listen to the carrier for any signs of instability, usually heard as clicks or warbling. I again used SDRangel to set the ADALM Pluto into transmit on 1296.5MHz wanting to keep this up towards the upper range of the Rigol scope so that any minor changes in the 40MHz clock would show up as error in the output frequency. I also deliberately de-tuned the VCO with the 10MHz reference not present to test that the PLL was in fact going into power down.
Internal vs External Clock Input
Below are the results from configuring the ADLAM Pluto to use it’s own internal oscillator vs the external 40MHz KK103c1 output. The following article from AMSAT DK goes through the process of switching the Pluto from it’s internal clock to external. The span has been reduced to 50kHz and the vertical scale changed to allow the spectrum analyser to find the peak. The results speak for themselves, that’s a lot of zeros.
As can be seen in the image above. With the ADLAM Pluto configured to use the internal oscillator, there is 15kHz of error in the output signal, that simply disappears when clocked using the external 40MHz source. This was confirmed having to re-tune the Icom R10 to follow this change in output.
I’m certainly pleased with this result.
Carrier Spurs from external clock
It is typical to see Spurs appear if the reference oscillator does not have a clean or jitter free output. Widening the span to 10MHz and 100MHz respectfully, the output of the ADLAM Pluto remained spur free. Well at least within the limits of the Rigol DANL. There is some close in phase noise that needs to be checked with better equipment and perhaps when boxed.
I still have to investigate the phase noise from the KK103c1 module when the opportunity presents. I will also be investigating the harmonic output of the Pluto Charon at the same time that phase measurements are made, the poor old Rigol is limited to an upper frequency limit of 1500MHz. Unfortunately the Rigol Spectrum Analyser is not quite metrology grade lab equipment, so this will all have to wait for a bit longer.
Now that I have the output of the ADLAM Pluto locked to my Rubidium source, it’s time to begin boxing this up into an enclosure with the Pluto Charon kit and finishing my 23cm all mode digital SDR radio.
Continuing with the development of an accurate 40MHz clock source for my ADALM Pluto, I recently finished an Arduino library to control the ADF4110 Synthesizer on a KK103c1 VCTXCO module. The KK103c1 module is a daughter board that sits on the back of an Arduino Nano.
I personally use the PlatformIO IDE extension within Visual Studio Code for all of my Arduino based projects. Yes, this even works on a Linux desktop machine. The PlatformIO ecosystem takes away the pain of getting embedded tool chains working, it’s simple and effective. I also don’t have to worry about tool chains that share libraries and break when incompatible versions are installed, and it deals with the library dependency hell problem that plagues the standard Arduino IDE.
Now that I was armed with a library that gave me basic control over the ADF4110 I could concentrate on writing a sketch that would make the KK103c1 do what I wanted it to do.
The code for this project has been published in my GitHub repository, you can find it here. The code has been released under a MIT license.
Firmware Description
The firmware is very simple and provides “just enough” functionality to allow the KK103c1 to externally clock the ADALM Pluto.
When the firmware starts it will load and configure the ADF4110 Synthesizer found on the KK103c1 module and set it to generate a fixed 40MHz unmodulated carrier, that is phase locked to its own 10MHz reference. It also checks that an external 10MHz reference is present using the diode detector on the KK103c1 and will flash the built-in Arduino Nano LED if not found. The MuxOut pin on the ADF4110 is also set to provide a Lock Detect output and a Green LED on the KK103c1 will burn your retina when the Connor Winfield VCO is locked on frequency.
If the external 10MHz reference is not detected or lost during normal operation, the sketch will also place the ADF4110 into power-down allowing the onboard VCO to “free-run”. The Connor Winfield VCO fitted to the KK103c1 is very accurate and stable on its own, so having the VCO free-run will see it hold +/-0.32ppm (+/-13Hz) over temperature, over a 1% voltage range including aging within a 24 hr period. The KK103c1 has a multi-turn pot that can rubber the VCO control voltage and trim the output to exactly 40MHz before the PLL has to do anything, this is a great feature for those that take their equipment out into the field.
The control range or “frequency pull-ability” of the Connor Winfield VCOs is specified as +/-12ppm which translates to +/-480Hz, so it is normal for the ADF4110 to reject the 10MHz reference if it is not within the same accuracy window. I commonly see the lock LED on the KK103c1 begin flashing as my Rubidium 10MHz reference is warming just prior to achieving it’s own atomic lock.
A PC can be connected to the USB serial and debug messages monitored that shows if the ADF4110 is locked or in free-run.
In the spectrum analyser plot above you can see the 40MHz oscillator “locked” to the 10MHz Rubidium reference holding the output frequency to better than +/-1Hz accuracy. The Spectrum analyser was also being fed from the same reference source, to ensure it wasn’t causing any additional error. This was also checked with my Agilent frequency counter again being fed by the Rubidium 10MHz oscillator.
One thing I have noticed is that the output of the KK103c1 was being loaded by the 50Ω input of my Rigol Spectrum Analyser. The Connor Winfield VCO has an internal series impedance of 200Ω so this behaviour is to be expected. I’ll have to look closely at the ADALM Pluto external clock input and see if I can change component values to suit.
With a working 40MHz clock, phase locked to my 10MHz reference, it’s now time to hook this all together and see if I can improve upon the ADALM Pluto frequency accuracy.
In a recent post I was fortunate to obtain a 40MHz VCTXCO module from David VK5KK that I am using to lock an ADALM Pluto to an external 10MHz reference.
David’s design uses the Analog Devices ADF4110 RF Frequency Synthesizer, which offers low phase noise and operation up to 540MHz, more than enough for this application. It was also conveniently packaged as a daughter board for an Arduino Nano.
However upon entering the keywords “Arduino ADF4110 library” into Google & Duck-Duck-Go I was not greeted with any results. Oh dear, I have to write a library myself how strange ! Time to dust off my Arduino development environment.
I am not intending to describe how a Frequency Synthesizer or Phase Locked Loop (PLL) works, there are many YouTube videos and articles on the internet that can describe this better than I. If you are interested in the KK103c1 40MHz VCTCXO module I’m using, you can find it published in Dubus Q3/2022, there David also goes into some detail of how it works.
For this Arduino library the ADF4110 contains three internal 24-bit latches, where we can program the necessary values into counters and configure the hardware to generate the desired frequency output. This is achieved with a series of bit-shifting and bit-manipulations macros within the code, I have followed the names and bit-naming structures as per the Analog Devices ADF4110 datasheet.
The ADF4110-Arduino library essentially consists of five functions, that are described in the README.md. There is the ubiquitous Arduino “begin” function used to configure the SPI communication between the ADF4110 latches and Arduino Nano, there is an “initialise” function to load & initially configure the hardware of the synthesizer, an “update” function to simply change frequency and two utility functions to “print” the frequency to the serial console and another to “powerdown” the synthesizer when necessary. This was all I needed to get my synthesizer going, it should all hopefully be self-explanatory.
Now that I have the ADF4110-Arduino library essentially working, I can now focus on using this to drive the KK103c1 module but that is for another post.
In a recent post I had my ADLAM Pluto transmitting using SDRangel on 1296.5MHz listening to it using an Icom R10 receiver. One thing that I did immediately notice was I had to tune the R10 down 15-18kHz to get both systems “on” frequency. One or both of them had to be off frequency, so which one was it ? After a few measurements with a spectrum analyser, I found the ADALM Pluto was the culprit, surprisingly the Icom R10 was within a 100Hz of where it was supposed to be.
So… the ADALM Pluto was at least 16.667kHz low using its internal 40MHz crystal reference, that is not going to cut the mustard on these higher bands.
I had always planned on phase locking the Pluto to an external 10MHz Rubidium reference. The only catch is the external reference input on the Pluto expects a 40MHz clock and the AD9361 transceiver within the Pluto, cannot be configured to use a reference clock much below 25MHz. So there was no way I was going to make this work with a 10MHz reference without adding something in between.
After some further research I decided I needed a 40MHz VCO that I could phase lock to the external 10MHz reference to solve my problem with the Pluto external clock input. A chance discussion at a conference in Tasmania at the end of 2024 lead me to laying my hands on a KK103c1 40MHz VCTXCO PCBA designed and built by David VK5KK.
David’s 40MHz VCTCXO design was published in Dubus Q3/2022. It was designed as a daughter board directly connected to an Arduino Nano, that it conveniently sits on top of. The specs for this board were perfect for what I was planning to do with the Pluto external clock input;
Both the VCO and PLL are low phase noise varieties and the power supply decoupling is extensive. I was even given a basic Arduino sketch that I could use to test the board, that is provided I had an Arduino Nano. Oh well Nano ordered and should be here soon.
Certainly once I have this board running, I’ll be doing some phase noise measurements and experiments with my Rubidium 10MHz reference. It will be interesting to see what improvement I get in frequency accuracy, along with comparing the phase noise of the internal Pluto clock and seeing if there are any differences. However before this I’ll need to write some Arduino code to tailor this board for my purposes and perhaps a library to drive the ADF4110. That will of course land somewhere in my GitHub repository when ready.
I’ll give a shout out and my personal thanks to David VK5KK for gifting me one these boards and accelerating my ADLAM Pluto project. I certainly can’t wait to get to testing once the postman delivers a Arduino Nano. I know I’ve got some Nano’s somewhere, but for the life me of I can’t find that box.
Recently I came across a novel way to get the ADALM Pluto to generate a 10GHz signal. Jay Francis presented a minimal ADALM Pluto 10GHz transceiver system that used a commercial LNB and some Mini-Circuits high pass filters, to pick off the 3rd harmonic from the TX output. You can watch his video below.
This got me thinking, could you actually build a 10GHz transceiver from the ADALM Pluto like the 23cm Pluto Charon kit I’ve been working on ?
Now I don’t have any of the Mini-Circuits high pass filters and they were a little expensive to get shipped to Australia, but I did know of a 10GHz Frequency Multiplier kit from Minikits being manufactured locally. The Minikits kit comes with a GAL-39, 10GHz pipe cap filter and a NLB310 post amplifier that can be assembled on a universal microwave board. Whilst designed to double a 4-5GHz signal up on to 10GHz, it can also triple a 3-4GHz signal with a bit of tweaking and fine tuning. This was perfect for what I was planning with the ADALM Pluto, so one was ordered and I had to wait for the postman for it to arrive.
While the Minikits multiplier was on its way I also stumbled across N1BUG’sYouTube channel, where he walks you through how he assembles 10GHz pipe cap filters in his workshop. It was quite clear that some “real” heat is required, so I also purchased a Chinese made hotplate to assist with additional heat when soldering the cap itself. You can find more about that adventure here.. So far I’d spent less than the cost of two Mini-Circuits high pass filters.
I’m now sure that 10GHz pipe cap filters look bigger on the computer screen than they do in real life. I was genuinely surprised just how tiny they were. I was also questioning the purchase of a hotplate.
Following the Minikits multiplier kit instructions, I first drilled and tapped a M4 hole in the pipe cap, prepared the probes, modified the board to accept the pipe-cap and then proceeded to solder it down. Since I was using a hotplate, I decided to solder the pipe-cap down first, then solder the probes in after as suggested by N1BUG. This meant I needed to pay attention to the probe straightness and length, so that they would land in the right place once assembled. I was OK with this as I can see the probes through the M4 nut in the top using my microscope before and after soldering.
Now soldering this pipe-cap was genuinely difficult and the hotplate certainly made the job much easier. The flux that I used was not that great, I must try to find some of the really gooey sticky flux that N1BUG was using. However I persevered with my Hakko 50W iron wound up to +450°C with a K-tip and some 0.7mm solder rings, tacking and working my way around the cap. Once I’d placed sufficient solder, I then broke out the hot-air gun set to +400°C and re-flowed the joint, which gave me a much neater and more uniform appearance.
Below is the board after soldering and once I’d cleaned up the excess flux. The Minikits PCB has quite a few holes in the plane, so I used compressed PCBA flux cleaner blown in through the nut to make sure no residual flux was present after soldering. Likewise a small file and knife were used to clean up the blobs of solder around the nut.
For my first attempt at soldering pipe-cap filters I’m happy with the result. I found the hardest part soldering the nut to the top, mainly due to difficulties applying flux and getting the solder to wick to the nut and cap evenly.
So the next steps are to insert the probes and build the associated amplifiers and then test and tune. More to come.
So it’s been a while since I’d looked at my ADLAM Pluto SDR project, to complicate matters I’ve also recently switched to Linux. So it was time to see if I could find new SDR software to drive it.
After a few false starts and some trials and tribulations, I finally settled on SDRangel. I’ve used this app before to demodulate a High Altitude Balloon payload that transmitted a quirky DVB-T modulator using a RTL-SDR and Ubuntu Laptop.
So the only problem, SDRangel is written to natively run on Ubuntu, Windows, Mac and the rest of the distros can either use a snap package or compile from source. Sigh. Linux Mint does not like snaps, LMDE uses only flatpak’s.
SDRangel Flatpak
Now I’m not a big fan of flatpak’s either, to me they are in the same boat as snaps and docker images, unnecessarily slow, however after reading how to compile SDRangel from source, a flatpak was certainly the fastest and easiest way to let me try the software and see if I can get this working.
Thankfully I found SDRangel on Flathub. The following was all I had to do from a command line to install the flatpak, installation instructions were found here.
After a short time downloading and installing it was ready.
SDR plugable UDEV Rules
SDRAngel requires udev rules to be added for the most common SDR’s, since I also intend to try RTL-SDR’s at some point, now as as good as any time to install.
The udev rules can be found here on the SDRangel GitHub repo. I simply downloaded them in a zip file to my local downloads directory, unzipped and moved them into /etc/udev/rules.d. There is an installation script (install.sh) in that same directory as the downloaded udev rules you can use or read for inspiration on the linux commands necessary.
If you find that you still can’t access these devices, check your user has the right permissions to use USB or network devices, trap for young players and outside the scope of this post. Google and Duck-Duck-Go has lots to say on this topic.
Flatpak Permissions
Before starting SDRangel I also loaded Flatseal and checked what permissions the SDRangel flatpak was requesting. Always pays to review flatpaks using Flatseal, I’ve found a few packages that had some very odd permissions and didn’t work on LMDE out of the box.
It makes sense to me to grant SDRangel access to the network, PulseAudio sound server, GPU acceleration (if used), All devices (i.e. SDR’s) and the “Run in Background” option. This is the config that worked for me, YMMV.
SDRangel Configuration
Once SDRangel is loaded, we’re greeted with a big blank screen. From here I added the ADLAM Pluto by clicking Preferences > Devices > User Arguments
I then added “PlutoSDR” in the HwID field, left seq as 0 and hit the ‘+” button which is the add symbol. I then selected the PlutoSDR entry in the lower pane, added “uri=ip:192.168.2.1” in the Args field, and hit OK. After I’d finished my config screen looked like this. Note my IP is the default PlutoDVB value, you can find what yours is set to in the config.txt file from the Pluto storage device it presents when connected to a PC. Now apparently you need to restart SDRangel for this to have any effect. YMMV.
Adding a RX Device
I then added an RX device by clicking on the menu button just to the right of the purple button with a play symbol in it. If you hover over each button, a pop up appears telling you what the button is. From the drop down box, I then selected the PlutoSDR entry which was right towards the bottom of the list.
Two screens appear, but we’ll concentrate on them one at a time. I configured the Receive window like this, more info here;
Now the thing to note. I’ve twiddled the sampling rate for reasons I’ll explain in another post. You should find the initial settings of 2.5MHz work well enough out of the box. I’ve increased the decimation from 1 to 8 in the S field, likewise I’ve selected “slow” AGC. If you then press the purple button with the white play symbol, you would see the next window start to do something interesting like this.
I didn’t change anything here, the out of the box config just worked for me. Now you might notice you don’t hear anything, that is because you have to add a channel/separate demodulator. On the receive window, just to the left of where “PlutoSDR[0:0]” appears is a button you can click to add a channel.
From the pull down box I’d choose the SSB Demodulator, which will appear on your screen. I configured it like this;
I had to play around with the sound settings, especially the audio settings which were hidden under the green speaker symbol (right click) on the right side of the screen just above the Channel Spectrum display. It is worth spending the time to read the documentation on the SDRangel website, once you realise that each part is a software plugin and how configurable this system is things get more interesting.
By the time we have the receiver configured, the spectrum display happening and a channel defined, audio should be appearing out of your speakers. If not then you’ll need to spend a bit more time debugging what’s happened with PulseAudio, mine just came to life.
I’ll also mention that if you try the Narrow Band FM channel plugin, there is a hidden squelch power threshold setting, that you need to wind down to -100 for it to open the squelch and produce white noise. It’s just to the right of “Sq” and a funny button with a triangle on it, you’ll see what I mean.
Adding a TX Device
I’m not going to reinvent the wheel here. I found a great article on the web and a video on YouTube from SignalsEverywhere that explained how to configure the ADLAM Pluto to transmit. You can find the original article from the RTL-SDR site here and the video embedded below;
Putting it all together
To prove that I could get this all working, I put the receiver on 1296.5MHz with the settings previously shown. I configured the transmitter slightly differently adding further decimation to reduce the effective bandwidth. You can see this below;
I then added a Narrow Band Modulator, by clicking the button just to the left of where “PlutoSDR[0:0]” appears in the menu bar (just like a channel button in a receive window) and selecting NFM Modulator from the drop down box. You then configure like so, based entirely on SignalsEverywhere’s YT video.
If you click on the purple button with the white triangle on the TX window, you should be greeted by CW being sent. Just so there was proof, I made and uploaded my own video.
In the above video the audio is being demodulated by the Icom R10 on 1296.5MHz NBFM just so that there was a “Real Radio (TM)” involved. The ADLAM Pluto is transmitting approximately 0dBm into a dummy load. The ADLAM Pluto receiver is displaying the received signal and waterfall, I didn’t bother with a channel/demodulator to listen to my own transmission, the R10 was doing a good enough job on it’s own.
So now that I’ve got that working, I can start to experiment with the ADLAM Pluto and some microwave multipliers to get me up into the higher bands. I also need to check it will still key the Pluto Charon kit and modify as necessary. More to this story shortly.
In my last post on the Pluto External PTT I had done some preliminary testing of the external PTT output using a multi-meter before wiring it to the Pluto Charon and confirming it worked. It was at this point things took a jump to the left and then a step to the right…
What I noticed is I would hit the TX button in SDR-Console and there would be a pause, one, two, three, then click would go the transmit receive (TRX) relay. Hmm that’s not going to do, a 3s delay between the PC software PTT and the Pluto Charon external amplifier ain’t going to work on FM/SSB.
However if I hit the TX button in SDR-Console again the TRX relay would click and go off without any delay. Now that was strange and the asymmetric nature of operation required further investigation.
The first step was to rule out the hardware, so with a C.R.O on the Pluto Charon PTT line (connector A1) and another on the ADALM Pluto GPO0 pin (yellow and cyan respectively) we can check that the switching is nice and clean.
Nope nothing to see here, you can see the transistor on the Pluto Charon PTT board pulling the PTT line low and hitting zero volts in no more than 12us. Problem has to be elsewhere.
So now were into firmware and software territory, sigh this is going to be one of those rabbit holes.
I firstly tried the “for the brave” firmware that can be found on the Mini-kits support website, which is an early version of the PlutoDVB firmware. This changed the behavior entirely and there was a delay of 1-1.5s each time the external PTT changed state from ON to OFF. Not what I wanted, but better and perhaps more usable than the 3s ON and instant OFF I was seeing on the PlutoDVB revision 3.0.3 firmware + Rev C/D patch.
Further reading from the analog devices website suggested that the GPO pin connected my external PTT module could be controlled by some ENSM module within the AD9361-phy linux driver, so I tried some experiments with SDR-Console and the Analog Devices stock v0.38 firmware, that didn’t work either. It was clear that SDR-Console was not using this IIO method to switch the Pluto in to TX or RX.
So I revisited the latest PlutoDVB firmware (perseverance 3.0.3 + Rev C/D patch) once again reading and watching more closely this time.
It was while applying the patch I saw something interesting, I’ve highlighted it in red adjacent. I wonder what that script does ?
The whole reason the patch was required in PlutoDVB Perseverance 3.0.3 firmware was to get the PTT working with revision C & D hardware. I wonder if that is where I start ?
So let me log into the Pluto and take a peek at the script.
#!/bin/sh
#https://www.analog.com/media/cn/technical-documentation/user-guides/AD9364_Register_Map_Reference_Manual_UG-672.pdf
source /root/device_sel.sh
ptton()
{
#PTT on GPIO 0 AND GPIO 2 (GPIO 1 should be not touched)
echo 0x27 0x50 > /sys/kernel/debug/iio/iio:device$dev/direct_reg_access
mosquitto_pub -t plutodvb/status/tx -m true
}
pttoff()
{
echo 0x27 0x00 > /sys/kernel/debug/iio/iio:device$dev/direct_reg_access
mosquitto_pub -t plutodvb/status/tx -m false
}
echo manual_tx_quad > /sys/bus/iio/devices/iio:device$dev/calib_mode
#Manual GPIO
echo 0x26 0x10 > /sys/kernel/debug/iio/iio:device$dev/direct_reg_access
pttoff
while :
do
inotifywait -e modify /sys/bus/iio/devices/iio\:device$dev/out_voltage0_hardwaregain
gain=$(cat /sys/bus/iio/devices/iio:device$dev/out_voltage0_hardwaregain)
if [ "$gain" = "-40.000000 dB" ] ; then
echo "SdrConsole PTT OFF"
pttoff
else
if [ "$gain" = "0.000000 dB" ] ; then
sleep 2
gain=$(cat /sys/bus/iio/devices/iio:device$dev/out_voltage0_hardwaregain)
if [ "$gain" = "0.000000 dB" ] ; then
echo "SdrConsole Power Max PTT ON"
ptton
fi
else
echo "SdrConsole PTT ON"
ptton
fi
fi
done
So reading my way through this script by the time I hit line 24 I had confirmed
SDR-Console does not use the ENSM module within the Pluto ad9361-phy driver
Instead the script uses the sysfs subsystem to read different values from the IIO driver
SDR-Console varies the TX gain within the IIO driver between two limits that the script interprets and drives the relevant GPO pin
In an attempt to prevent a race condition, line 31 introduces a 2s sleep function between successive reads of the gain value
Guess where the 3s delay I’ve been searching for comes from !?!
So a quick bit of hacking on this script, changing line 31 to read “sleep 0.1” or 100ms, then restarting the “watchconsoletx.sh” process increased the speed of the external PTT to the point where the delay between SDR-Console and the TRX relay on the Pluto Charon activating is nearly imperceptible. I’m not sure if using a fraction of one second is valid in this shell, it may have been ignoring it, but it proved my point.
However what I’ve done to this script and the way in which SDR-Console works I’m not convinced will work 100% of the time. The other problem is any changes that are made to these script files are not permanent they are only kept in RAM, so as soon as you reboot they revert to those stored in volatile memory (flash).
So it looks like I may have to reverse engineer the “pluto.frm” file and see if I can hack together a better script to make this work how I want. At least I now know where the 3s delay has come from and that there are possibilities to fix it.
That however will have to wait until the next post.
The next step in the process of using the ADALM Pluto is sorting out a press-to-talk output to drive the Pluto Charon. In this instance I’ve followed the tried and trodden path of adding a small transistor output to one of the GPIO pins and updating the firmware. There are some interesting articles on the ADI website that discuss how to do this via the FPGA, but I decided to learn to walk before I ran.
When I ordered my Pluto Charon kit I also purchased the separate PTT module which you can see here (click). This is very easy to install, just make sure you observe good ESD practices when you remove the Pluto from it’s case and handle it on the bench.
Here’s the photo’s of how I installed mine.
I decided to use a small two pin right angle KK 0.254″ molex connector for the PTT output, as I’d like the capability of unplugging Pluto and Charon boards for service/changes/updates etc.
Now for the hairy scary part of the process. On the Mini-kits website is a URL to some custom firmware written by Evariste F5OEO that can enable a PTT function on a GPIO pin. I was at first a little alarmed by the comment “for the brave”, but it turns out this firmware is part of the PlutoDVB project. You can find later software from 2022 on Christian F5UII’s website (click) and you’ll see some comments about fixing the PTT on the Pluto Rev D boards to work with the latest versions of SDR-Console. I have a Pluto Rev C, which is the same as the Pluto Rev D, so I had no choice but to use this newer firmware and work out what to download.
So after reading most of Christians Website I discovered I had to do two things. Firstly I had to swap from the official ADI Pluto v0.38 firmware to the custom PlutoDVB 3.0.3 firmware. Secondly patch the 3.0.3 firmware to account for the Rev D hardware. This wasn’t obvious where to start.
Below is a summary of the steps I used to swap the firmware.
Connected the Pluto to my PC, checked it had presented a removable drive
Download the firmware from Christian F5UII”s website, I used the PlutoDVB perseverance firmware 0303 (26.6M)
Extracted the pluto.frm from the downloaded zip and stored it on the Pluto removable drive created on my PC (don’t get confused or alarmed by the file name “patch.zip” as this is indeed the entire firmware)
Ejected the Pluto and waited for it to finish doing the upgrade and reboot, once done it reconnected to the PC
Used a web-browser to point to http://192.168.2.1/index.html, confirmed it presented the “Lets go to PlutoDVB” welcome screen, not the ADI reference material.
Then clicked on the “Lets go to PlutoDVB (USB connection)” button which launched into the system setup.php page
From the menu across the top, selected “System ” then “Maintenance” where I found the patching and upgrading firmware mechanism.
For my hardware (Rev C/D) I needed to download and apply the “Patch for PlutoSDR Rev. D hardware”
Applied the patch, saw that within the “Delete Patch” window the updated files were displayed once done
Success !
Now I could configure the PlutoDVB firmware to do what I wanted, which in my case was to use SDR-Console. So from the “system” menu at the top I clicked on the “Pass-through” option and hit apply. That should be all I needed to complete.
There is an error message displayed across the top of the screen about a datv text file not being present. If you enter your call-sign in the respective field on the setup page and your name in the DVB provider field, hit “apply settings” and this will create the right file and the error message disappears.
Once all of this was done, I was able to setup and configure SDR-Console and test that the PTT worked with a multi-meter. Below you can see SDR-Console listening on 23cm ready for me to hit the TX button. The Pluto is sitting right up against the PC, so I’m not surprised there are some birdies in the shack, I’ll only panic once the Pluto and Charon and boxed up together.
For my next trick I intend to hook this up to my CRO and see how long before or after the PTT line is asserted does RF appear at the transmit port. However that will have to wait for the next post.