• Category Archives Computers
  • Titanium C1-PLL LNB GPSDO Modification for C-Band ADSC

    You may recall from the very end conclusion of the blog entry on my ADSC C-Band ground station that I had two outstanding issues.
    Tracking the sat.
    Thermal drift on the output.

    The sat issue is the nature of physics.
    The thermal drift is like wise. The problem here is that you only need the tiniest amount of drift in the 25 mHZ crystal to make a massive difference in the output.
    The LNB is sitting out in the sun at the dish focal point and so has no choice but to undergo a major thermal cycle every 24 hours.

    The first one is solved thanks to Node-RED.
    The second has also been solved thanks to a very cool product. Here is how I did it.

    BTW, I bought another LNB so I would not have any downtime, so now I have two… But I think I found a home for one of them….

    You will need to buy a GPS disciplined oscillator from Leo.
    http://www.leobodnar.com/shop/index.php?main_page=product_info&cPath=107&products_id=301
    Shipping to California only took a few days (pre Covid), so you won’t have to wait too long.
    Here is the kit you get;

    Its one of the best presented bit of electronics that I can recall unpacking.
    You get a GPS antenna, the electronics and a USB lead.
    Jump on the website and pull down the little setup utility.
    Sorry for the screen shot of a screen shot, but here is the utility in action.

    You need to set the output to be the lowest.
    Set the frequency to 25 mHZ and that’s it.
    Takes all of about 30 seconds to set up and has been rock solid reliable the whole time I have been running it.

    Now that the easy part has been done, its time to dust off the soldering iron and mod the LNB.
    What we are doing is removing the crystal and installing a coax to inject the output from the GPSDO.

    Here is the unmodified LNB.

    Unsolder each end of the crystal and put it aside (I put mine carefully in the trash! Hey, it caused me a lot of grief over the past year chasing its drift!!).

    Here is what you are left with.

    Now is when we have some real fun.
    Go ahead and power it up on the dish and look at the output on the waterfall.
    You have a 50/50 chance of getting the coax on the right leg of the old crystal pads.
    Of course, I got it wrong and the waterfall was FULL of birdies and no ADSC signals at all.
    So, simply move the center of the coax onto the other crystal pad.

    Water prof the coax and you are done.
    Drift free!

    This little GPSDO clock is a.m.a.z.i.n.g.

    I just cant give Leo enough praise for making such a cool device.

    How you provide 5 volts to the USB input will depend on how you have your dish setup.
    I have a 12 core cable going to the dish to take the position indicator and up/down control, so have plenty of spare pairs to take the volts out to the GPSDO.
    The little GPS puck has a magnet on it, so attaches the dish frame just fine.

    We have been running with the setup since December and its been great not to have to worry about any drift at all.



  • Finding out the feed ID from AircraftList.json

    If you run a VRS (Virtual Radar Server) and want to explore your data a little more deeply, you might end up looking at the main output which is AircraftList.json.
    There is a very brief outline for what options you can append to it here; https://www.virtualradarserver.co.uk/Documentation/Formats/AircraftList.aspx
    But it does not tell you how to find your feed ID….
    What I ended up doing was using FireFox, turns out it has a JSON formatter built in which presented the data in a human readable JSON object.
    Here is how it looked.

    So now you can easily expand each of your feeds and drill down through all your feeds and find the exact ID of the one you want.
    Once you have the id, append it to AircraftList.json?feed=122 like that for an example.
    It will return the aircraft just on that feed rather than your whole VRS install.

    Now you can use Node-RED (for example) get msg.payload.totalAc and see how many aircraft are currently being tracked in that feed.



  • Using Node-RED to read a HF propagation map

    A few things to note.
    1. This ‘trick’ should work for any sort of image that you need to compare color values.
    2. I did not come up with the core code, I just asked the question.

    HF propagation is tricky.
    Thankfully a bunch of smart guys are running the show at the space weather services arm of the Australian BOM.
    They produce cool maps that show you what frequency you need to use to be able to (hopefully) pick up distant stations.
    The map is updated every hour for the past hour. While the data is an hour old, I have found that for what I need, one hour resolution is more than accurate enough.

    Here is what a typical map looks like.

    This one, taken at 3am in the morning (PST) is super ‘simple’, but it clearly shows how you need a higher frequency to cover more ground.
    As simple as it is the burning question remains…. How to automatically select the frequency from the image and so command the receiver to switch to said frequency? And what is said frequency?

    Enter Node-RED.

    Using the image-tools node, you can read the color value for a given x,y value.
    So, we set up a flow to first read and get the values of each part of the scale.
    We then map those color values to the scale frequencies. So in effect you end up with a number that represents the value in MHz for any location on the map.
    Here is a screen shot of the flow and I have clicked the 6MHz inject node to see the values in the debug tab.

    So now that we have that raw color value for that part of the scale, any x,y location will yield its MHz value to us…..
    Here is the flow to read the scale.
    [{"id":"2cdd6244.f73a8e","type":"change","z":"fa1bd60e.5b6d3","name":"","rules":[{"t":"set","p":"pixel","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":1860,"wires":[["86c9c963.a16eb8"]]},{"id":"ceebb092.cb7d3","type":"inject","z":"fa1bd60e.5b6d3","name":"8mhz scale","topic":"","payload":"{\"x\":130,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1760,"wires":[["2cdd6244.f73a8e"]]},{"id":"10a35d70.4e06a3","type":"inject","z":"fa1bd60e.5b6d3","name":"2mhz scale","topic":"","payload":"{\"x\":55,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1640,"wires":[["2cdd6244.f73a8e"]]},{"id":"6b28b2b0.54f2ac","type":"inject","z":"fa1bd60e.5b6d3","name":"4mhz scale","topic":"","payload":"{\"x\":80,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1680,"wires":[["2cdd6244.f73a8e"]]},{"id":"3c247f0f.dcc16","type":"inject","z":"fa1bd60e.5b6d3","name":"6mhz scale","topic":"","payload":"{\"x\":105,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1720,"wires":[["2cdd6244.f73a8e"]]},{"id":"d182e0ef.f5ddf","type":"inject","z":"fa1bd60e.5b6d3","name":"10mhz scale","topic":"","payload":"{\"x\":155,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1800,"wires":[["2cdd6244.f73a8e"]]},{"id":"9926806f.ef6c9","type":"inject","z":"fa1bd60e.5b6d3","name":"12mhz scale","topic":"","payload":"{\"x\":180,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1840,"wires":[["2cdd6244.f73a8e"]]},{"id":"97a5a697.65b2b8","type":"inject","z":"fa1bd60e.5b6d3","name":"14mhz scale","topic":"","payload":"{\"x\":205,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1880,"wires":[["2cdd6244.f73a8e"]]},{"id":"5f692af2.01b914","type":"inject","z":"fa1bd60e.5b6d3","name":"16mhz scale","topic":"","payload":"{\"x\":230,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1920,"wires":[["2cdd6244.f73a8e"]]},{"id":"cb3382d2.55a9","type":"inject","z":"fa1bd60e.5b6d3","name":"18mhz scale","topic":"","payload":"{\"x\":260,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1960,"wires":[["2cdd6244.f73a8e"]]},{"id":"191be3a3.5d41fc","type":"inject","z":"fa1bd60e.5b6d3","name":"20mhz scale","topic":"","payload":"{\"x\":280,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":2000,"wires":[["2cdd6244.f73a8e"]]},{"id":"fd826f9a.89454","type":"inject","z":"fa1bd60e.5b6d3","name":"22mhz scale","topic":"","payload":"{\"x\":305,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":2040,"wires":[["2cdd6244.f73a8e"]]},{"id":"c77c41f4.0a48d","type":"inject","z":"fa1bd60e.5b6d3","name":"24mhz scale","topic":"","payload":"{\"x\":330,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":2080,"wires":[["2cdd6244.f73a8e"]]},{"id":"d6762d1a.9717e","type":"inject","z":"fa1bd60e.5b6d3","name":"28mhz scale","topic":"","payload":"{\"x\":355,\"y\":70}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":2120,"wires":[["2cdd6244.f73a8e"]]},{"id":"86c9c963.a16eb8","type":"jimp-image","z":"fa1bd60e.5b6d3","name":"","data":"http://www.sws.bom.gov.au/Images/HF%20Systems/Global%20HF/HAP%20Charts/Phoenix.gif","dataType":"str","ret":"img","parameter1":"img.png","parameter1Type":"str","parameter2":"","parameter2Type":"msg","parameter3":"","parameter3Type":"msg","parameter4":"","parameter4Type":"msg","parameter5":"","parameter5Type":"msg","parameter6":"","parameter6Type":"msg","parameter7":"","parameter7Type":"msg","parameter8":"","parameter8Type":"msg","parameterCount":0,"jimpFunction":"none","selectedJimpFunction":{"name":"none","fn":"none","description":"Just loads the image.","parameters":[]},"x":610,"y":1860,"wires":[["c9ed63fd.f47b5"]]},{"id":"c9ed63fd.f47b5","type":"function","z":"fa1bd60e.5b6d3","name":"get value","func":"msg.image = msg.payload;\nvar x=msg.pixel.x;\nvar y=msg.pixel.y;\nmsg.payload = msg.image.getPixelColor(x, y); // returns the colour of that pixel e.g. 0xFFFFFFFF\nreturn msg;\n","outputs":1,"noerr":0,"x":760,"y":1860,"wires":[["42a68931.79f2e8","53feaf7a.64449"]]},{"id":"42a68931.79f2e8","type":"change","z":"fa1bd60e.5b6d3","name":"color to freq","rules":[{"t":"change","p":"payload","pt":"msg","from":"4278190335","fromt":"num","to":"2MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"4294902015","fromt":"num","to":"4MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"2155872511","fromt":"num","to":"6MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"8388863","fromt":"num","to":"8MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"16711935","fromt":"num","to":"10MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"16777215","fromt":"num","to":"12MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"8421631","fromt":"num","to":"14MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"65535","fromt":"num","to":"16MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"33023","fromt":"num","to":"18MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"2147483903","fromt":"num","to":"20MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"2147516671","fromt":"num","to":"22MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"4278255615","fromt":"num","to":"24MHz","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"2155905279","fromt":"num","to":"28MHz","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":910,"y":1860,"wires":[["a36c7916.597038"]]},{"id":"a36c7916.597038","type":"debug","z":"fa1bd60e.5b6d3","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1080,"y":1860,"wires":[]},{"id":"53feaf7a.64449","type":"debug","z":"fa1bd60e.5b6d3","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":920,"y":1940,"wires":[]}]

    Next I simply looked up the lat/long for the other locations of interest to me (San Francisco and New York) and put those x,y values into another flow that reads them every hour.
    The flow reads the color value of that pixel and does a look up for its value and converts that value to its MHz value.

    Note how this flow looks identical to the one above so I am not going to include the code for it.

    So now on my dashboard I can display the map and for any selected location on the map the predicted frequency needed to hear a station at that location for any given past hour.

    I then use that frequency to map to the HF ACARS (HFDL) channel number and command the receiver in Phoenix to switch to it every hour.
    Its not perfect, but its way way way better than manually keeping on top of all that.



  • Tracking Inmarsat 4-F3 with Node-RED

    For a year now I have been ‘tracking’ Inmarsat 4-F3 for my C-Band ADSC aircraft receiving ground station.
    It has been very crude tracking, but tracking none the less.
    I used a linear actuator with a position feedback resistor. Its worth noting that the position feedback is really critical. Without it you just don’t know where the dish is pointed.

    The actuator is very compact and was around 100 dollars, so not too bad in the over all cost of the project. Its worth noting that you can buy a version without the feedback resistor for about 20 bucks less, don’t skimp. You must have the feedback for this application.
    It is supposed to be lightly weather proof but even so I have it wrapped in a plastic bag to protect it mostly from the nightly runs of the irrigation system.
    Another thing of note is that the actuator is rated for 12 to 24 volts.
    At that voltage, it is way too fast for what we need…. so I have a 6 volt DC power supply driving the unit.

    Now the tracking.
    As you may recall from my main post on the subject, I knew from reading bit and pieces that the satellite makes a slow figure 8 in the sky over a 24 hour period.
    Here is what that oscillation looks like on a graph.

    You can sort of visualize the up and down and slide to side motion of the satellite over 24 hours.
    When we look at a heat map of what its doing in the sky, it all becomes clear.

    The satellite is up there in space, just over the equator, wobbling about.
    To do the initial tracking of it, I got some code help from my son….
    What we decided to do was to break the 24 hours up into 3 hour time slices and move the dish to a preset resistor location every time slice.
    I have removed the GUI so don’t have a screen shot, but it was a very simple grid of boxes that had the user entered resistor location for each time slot.
    Over a period of 2-3 weeks of me watching the signal strength in SDR# I got a feel for where each time slot needed to be and so tuned the dish tracking.
    It worked pretty good with one major flaw…. The satellite has an oh so slightly longer oscillation period than 24 hours.
    This meant that over the space of a month, I would need to re-tune all my 3 hour time slots (again and again).
    This was just way too high of a maintenance task for me.

    Node-RED to the rescue.
    There a group of three satellite tracking nodes; https://flows.nodered.org/node/node-red-contrib-satellites
    You can do a lot of cool things with them, but in the end we only need the one node. Since Inmarsat is not in its drop down pre-select list, we need the TLE node.
    Using the example flow on github you can pull down the TLE for any given satellite.
    Now we have the latest orbit parameters for the satellite we can now track it very accurately.
    (This is in fact how I got the above screen shots of the orbit oscillation and heat map).

    Every hour we run the orbit check and output the satellite position in x,y and z. (Note, I don’t use y or z).
    As you can see from the graph and the heat map, the longitude and altitude drift are not really enough for me to worry about (Or are they? Since I have only just got this going, I am still collecting data on if I should add another actuator and track azimuth well as elevation).
    The output latitude data simply goes into a range node which remaps the -3 to +3 deg swing to the resistor value in the actuator.
    The output of that node goes into the micro-controller which has some very simple code of making sure the resistor matches the commanded resistor value by switching the up and down motor relays.
    So, in short, every hour we send a resistor value that equates to the satellite position to a motor controller that measures the actual resistor value and adjusts it to match whats coming in.
    Here is what it looks like in action.

    Pretty easy to see where I turned on the new system. 8am Friday morning.
    Here is a week long graph that better shows how my tracking was working over the Node-RED tracking.

    It has transformed the tracking accuracy and will take the burden off me having to watch it and re-tune it.
    I can now just let it run knowing it is going to be super accurate all the time.
    To say I am very happy with how well it came together is an understatement.
    Why then did I not do it this way a year ago? I simply did not know about the TLE Node.



  • Remote control of SDRuno with MQTT and Node-RED

    Getting back to looking at HF ACARS messages again and so with that comes the need to tune to the best HF frequency. (Best is still based on propagation and is a topic for another blog).
    My HF station is in Arizona, and San Francisco is the best ground station for it to hear. New York is a close second.
    SF mostly runs on two frequencies, 6559KHz and 13276KHz with 5508KHz thrown in from time to time. NY is sort of the same but different.
    So, the question (or goal) is to be able to switch between those frequencies on some sort of time schedule. (Sort of based on day and night – ie, follow the HF propagation).

    For the longest time I got fixated on getting SDRuno to do the memory channel switching for me. Spent waaaaay to long looking for plug-ins that would do the job.
    Thought about trying to set up squelch-less scanning to do the job.
    Spent some time looking to get the RSP2 working under SDR# since it seemed to have more plug-ins and options.
    Turns out this was the wrong way of looking at the problem…. All very well to get the program to do the automatic switching – which it can’t do – but what if I want some other frequency at some other time?
    Better to have web site (Node-RED dashboard) control right?
    I mean the decoded data (the ACARS message) is displayed there anyway, so putting a button there just makes sense.
    We spent hours trying to figure out how to make it work, and minutes getting it working once we turned the problem around.

    So, long intro long.
    The key is to remove control from SDRuno and put it in the hands of the website / user / Node-RED.
    Press a button on the dashboard in one location and have it change the VFO frequency in another. Here is how we do that do.

    SDRuno can use a serial protocol called CAT. The software emulates a small subset of those CAT commands for a Kenwood TS-480 transceiver.
    What we need to do is setup a serial connection to SDRuno to send those CAT commands as needed.
    Start with a virtual serial cable. I downloaded and used http://com0com.sourceforge.net/ Simple and free. Hard to beat.
    Set up something like com3 and com4 in that program.
    Go into SDRuno and set up com3 as the CAT serial port. I just accepted the default baud, it does not really matter as even 300 baud will be overkill for changing a few frequencies. It should connect straight away.
    Now, in Node-RED running on the same computer as SDRuno add a serial node that is configured to com4.
    To prove it works, put down 2 debug nodes if you like and use them to change the frequencies back and forth.
    In short, what ever CAT commands you pump into com4 via Node-RED will come out of com3 and thus into SDRuno and the VFO will change frequency.

    Now with that working, add an MQTT node configured to your broker and connect it to your serial node.
    So now, when ever a payload is published to that topic it will be sent to com4.
    On the instance of Node-RED that is running the dashboard then, you add a button that publishes its value to the broker on that topic.
    Done.
    You now have control of the SDRuno VFO A frequency from your web page.