Antenna Switching project

Here is a brief description of an automatic antenna switching project that uses the pre-observation script. You will need the pre/post observation modifications implemented by Chibill for this to work (see the mods at https://gitlab.com/librespacefoundation/satnogs/satnogs-client/blob/0/satnogsclient/observer/observer.py particularly those around the pre and post observation parts with the variables being passed to the scripts). For this to work you need to install wiring-pi which you can do with sudo apt-get install wiringpi

Firstly, run sudo satnogs-setup, go into advanced and set parameter SATNOGS_PRE_OBSERVATION_SCRIPT to /home/pi/preob.sh -f {{FREQ}}

Set parameter SATNOGS_POST_OBSERVATION_SCRIPT to /home/pi/postob.sh

Create file /home/pi/preob.sh with the following contents:

#!/bin/bash
#set the ports up and to known state
gpio mode 21 out
gpio mode 22 out
gpio mode 23 out
gpio mode 24 out
gpio write 21 0
gpio write 22 0
gpio write 23 0
gpio write 24 0

date=`date +%F" "%T`
freq=0

while getopts f: option
do
case "${option}"
in
f) freq=${OPTARG};;
esac

if ([ $freq -ge 136000000 ] && [ $freq -lt 139000000 ]) ;
then
    echo "$date 136 to 138 selected" >> /home/pi/freqset.txt
    gpio write 23 0
fi

if ([ $freq -ge 144000000 ] && [ $freq -lt 146000000 ]) ;
then
    echo "$date 144 to 146 selected" >> /home/pi/freqset.txt
    gpio write 23 0
fi

if ([ $freq -ge 399900000 ] && [ $freq -lt 405000000 ]) ;
then
    echo "$date 399.9 to 405 selected" >> /home/pi/freqset.txt
    gpio write 23 1
fi

if ([ $freq -ge 430000000 ] && [ $freq -lt 440000000 ]) ;
then
    echo "$date 430 to 440 selected" >> /home/pi/freqset.txt
    gpio write 23 1
fi

if ([ $freq -ge 460000000 ] && [ $freq -lt 470000000 ]) ;
then
    echo "$date 460 to 470 selected" >> /home/pi/freqset.txt
    gpio write 23 1
fi
done

write the file, then chmod +x /home/pi/preob.sh and chown satnogs:satnogs /home/pi/preob.sh

Create file /home/pi/postob.sh with the following contents:

#!/bin/bash
gpio write 21 1
sleep .2
gpio write 21 0
sleep .2
gpio write 22 1
sleep .2
gpio write 22 0
sleep .2
gpio write 23 1
sleep .2
gpio write 23 0
sleep .2
gpio write 24 1
sleep .2
gpio write 24 0
sleep .2
echo "Antenna switch reset" >> /home/pi/freqset.txt

write the file, then chmod +x /home/pi/postob.sh and chown satnogs:satnogs /home/pi/postob.sh - the post observation script is designed to cycle the relays to make sure the contacts are kept ‘fresh’ and losses minimized.

touch /home/pi/freqset.txt and chown it to satnogs:satnogs - this is the log file for antenna switching.

The picture above shows the basics of the switcher. I’ve tried to use parts that you can go and buy from eBay. Search for 4 channel optocoupler to find the above board. For coax relays, use something appropriate to the bands you want to switch. I used MD951 relays because they were in the junk box, you could push the boat out and use a nice SMA 18GHz multipole relay. Once you have the hardware installed, test it by writing to the various GPIO pins. I soldered an LED + 1.2K resistor across each of the relay coils as an easy way to see the various status’s of each relay.

Modify the /home/pi/preob.sh script to suite your frequency bands, and adjust the GPIO outputs to toggle the appropriate relay. There is scope for additional control such as switching in a down converter, toggling voltage up the coax to power LNA’s etc. If you make the above script better, please publish it on this thread - thanks.

The above picture shows the implementation here. 3 coax relays can be seen in the background, these are interconnected with semi-rigid 50 ohm coax. The right had relay connects to the SDR and selects the outputs of the pair of input select relays. The bottom relay is currently used to switch between VHF and UHF. The top relay will be used to select L-Band and probably S-Band IF. It is possible to add another relay using the spare opto-isolated port on the board, this could be for switching between two VHF antennas where losses will be less than at L-Band etc.

Any questions, please ping me in the @satnogs IRC, my nick is pjm.

I hope this is useful and some of you build it to expand your stations capabilities.

Paul M0EYT - Station #91

10 Likes

Hopefully eventually the MR will be merged in to the current stuff. :slight_smile:

2 Likes

Hi chilbill. I have a few small micro antenna relays, 3 in each sealed unit, and a handfull of Arduinos that I need to use for something.

If I could get the Arduino to read the antenna id codes, especially from the I/O pin from the RPI3, then the Arduino could switch many antennas and combinations as needed.

Would you be willing to discuss this change in your project?

bob
w4ush

For reference the MR was

And is currently part of the main code.

Want to add relevant information for if people search this up.

Sorry for digging out a 2 year old thread.

I’m looking into a similar project: being able to select an antenna, or switch between filters/lna on a single antenna, from an observation pre-script.

My idea would have been be to use a RF switch IC, i got a bunch of HMC190 around, controlled by a littlle attiny microcontroller over USB.

Would it be better to use a coaxial relay ? Do they have less insertion loss ?

I don’t have experience in RF PCB design so for a start i’d be happy if it works well for VHF, to switch for example between a narrow 137MHz and a wider VHF filter.

GM everybody!
this is a follow-up of nice contribution of UHF-satcom.

In my realization I try to follow the “KISS approach”, both in the hardware and in the software, as well as trying to have as few electrical connections as possible to minimize RFI leakage. This setup has only a USB cable between RPI and the RF switch; it is also useful to use ferrite clamps on each cable… we are listening to objects that transmit very weak signals!

As some of you know, I made a small controller with an ARDUINO nano capable of switching some RF relays via a serial link. This is the link [https://sourceforge.net/projects/ardu-rf-switch/] to this board. Any customitation to fulfill different setup it’s quite simple.

The hard part it’s about the integration with the Satnogs… that’s turned out not so simple, mainly due to how the microcontroller circuit is implemented. In particular, the DTR signal of the serial transceiver is used to “reset” the board in order to load the software via bootloader.
This process can be summarized as follows:

  • Arduino IDE open the serial port
  • the first transition on serial port trigs DTR and after abt 1.5 sec the board it’s ready to receive the code
  • compiled sketch it’s sent via serial to the board
  • once verified Arduino IDE shuts down the serial port and the device it’s ready to repeat this process every time.

The problem is in the last point: the serial port is closed and so any attempt to write to that port via
echo "somecommand" > /dev/ttyUSB0
does nothing but reset the board at each attempt.

Looking for a solution and to check if the controller was working correctly, I tried to command it through cutecom, a Linux application for communications via serial ports.
Everything ok, it works, but much more, once cutecom is closed it is possible to send commands to the board via consolle with echo ... !!!

So the trick is “open the serial port, then exit but without close the serial device”.

The magic trick is performed at RPI4 boot through a script (actually the same script used by the Satnogs client), activated by creating a service, considering that the different solutions via rc.local are no longer usable.

I followed this nice link. Below a quick recap:

sudo nano /lib/systemd/system/ARDU-RF.service

then insert the following text into this file, modify as per your setup; note that ‘preob.sh’ is the script executed by satnogs client “before” each observation ( it’s described below)


[Unit]
Description=Fake access to ARDU-RF board to avoid Arduino DTR issue
After=multi-user.target
[Service]
ExecStart=/home/pi/tests/preob.sh
[Install]
WantedBy=multi-user.target

  • Save and exit with ctrl + x, followed by y when prompted to save, and then enter.
  • sudo systemctl daemon-reload
  • sudo systemctl enable ARDU-RF.service
  • sudo reboot

At each boot the serial port has a “fake” use and then it’s leaved ‘open’

This is the content of preob.sh and postob.sh, invoked by the client to switch the correct antenna ( but they can do more for us :wink: ).

  • preob.sh : called just before observation starts, set the right antenna and write to the satnogs log.

#!/bin/bash
\# original scripts by UHF-satcom aka pjm
#set the ports up to known state and disable close between calls
stty -F /dev/ttyUSB0 9600 -hupcl

date=\`date +"%d/%m/%y %H:%M:%S %Z"\`
freq=0

while getopts f: option
do
case "${option}"
in
f) freq=${OPTARG};;
esac

if (\[ $freq -ge 399900000 \] && \[ $freq -lt 470000000 \]) ;
then
    echo "$date --> 399.9 to 470 frequency, ANT0 selected" >> /home/pi/tests/satnogs_log.txt
    #sleep 5
    echo -e "ANT0\\n" > /dev/ttyUSB0
fi

if (\[ $freq -ge 136000000 \] && \[ $freq -lt 150100000 \]) ;
then
    echo "$date --> 136 to 150.1 frequency, ANT1 selected" >> /home/pi/tests/satnogs_log.txt
    #sleep 5
    echo -e "ANT1\\n" > /dev/ttyUSB0
fi

if (\[ $freq -ge 24000000 \] && \[ $freq -lt 30000000 \]) ;
then
    echo "$date --> 24 to 30 frequency, ANT2 selected" >> /home/pi/tests/satnogs_log.txt
    #sleep 5
    echo -e "ANT2\\n" > /dev/ttyUSB0
fi
done

  • postob.sh : called at observation end, puts RF relays in ‘deactivated’ position do not waste energy unnecessarily[!!!], and to setup a know position.

#!/bin/bash
# original scripts by UHF-satcom aka pjm
# disable all relays... no power waste! 
date=\`date +"%d/%m/%y %H:%M:%S %Z"\` 
echo -e "ANT0\\n" > /dev/ttyUSB0 
echo "$date antenna switch reset " >> /home/pi/tests/satnogs_log.txt

Please take note about the following mandatory permissions, because the scripts are executed as “satnogs” user:

  • sudo usermod -a -G dialout satnogs, to access serial device by satnogs user
  • sudo usermod -a -G pi satnogs, to permit execution tro satnogs as member of pi group
  • touch satnogs_log.txt, to create the log file
  • chmod 666 satnogs_log.txt, to permit everybody writing on this file
  • chmod +x preob.sh, set script to be executable
  • chmod +x postob.sh, set script to be executable

To test the whole stuff try to esecute:

./preob.sh -f 435000000
./postob.sh
tail ./satnogs_log.txt

and satnogs_log.txt should contain:

18/02/21 12:15:25 GMT --> 399.9 to 470 frequency, ANT0 selected
18/02/21 12:30:23 GMT antenna switch reset 

So, sorry if this post isn’t that concise, I tried to keep it short… but I hope that shall be useful!

73’s de I3VFJ, Vittorio ( @vittben on TWTTR)

EDIT: added wiki page here

2 Likes

One year later … ahem,
I have a Pimoroni automation hat sitting on my RPi and can successfully command it to activate one of two relays depending on the frequency that is directly passed to a little Python script as a suffix, e.g. ../satnogsclient $ ./antswitch.py 136000000.

My aim is to pass the frequency from the SatNOGS client to this ‘antswitch’ pre-observation script using the {FREQ} variable in SatNOGS setup, i.e.
../satnogsclient/antswitch.py {FREQ}

The statement in the script freq = int(sys.argv[1]) unfortunately causes this error:
ValueError: invalid literal for int() with base 10: '{FREQ}'
So apparently I’m not transferring over a numeric value but a text value, in spite of using the int() function. I’m sure someone who knows how to code properly in Python will spot my error very quickly and help me solve this little problem. Then I can publish the full working solution :slightly_smiling_face:

I think the trick is to use {{FREQ}} instead of {FREQ}.

Hi,
i believe you using WiringPi witch is not include in Bullseye distro.
Is this any way to install it…? Real

Hi, I’ve allready have some parameters in SATNOGS_PRE_OBSERVATION_SCRIPT
Did i have to replace
{{FREQ}}
by
/home/pi/preob.sh -f {{FREQ}} in parameters line…???
VE2DSK

Hi Paul
Got this error in the preob.sh lines…

if ([ $freq -ge 136000000 ] && [ $freq -lt 146000000 ]) : [: satnogs-pre: integer expression expected
if ([ $freq -ge 440000000 ] && [ $freq -lt 460000000 ]) : [: satnogs-pre: integer expression expected

(The $freq question is include in the satnogs-pre file)

Any idea? VE2DSK

Add set -x at the top of the script. This will show what the variables expand to which can be super useful.

Run shellcheck (shellcheck.net or the command line version) on the script to ensure the script has correct syntax and follows best practices.

Many thanks mfalkvidd
I believe the “&&” argument is maybe the problem…
Here the log with your suggession set -x
I also bebieve that interfere with my gr_satellite option…
To bad… So thanks again… VE2DSK

Jul 28 00:30:14 raspberrypi satnogs-client[10779]: + gpio -g mode 21 out
Jul 28 00:30:14 raspberrypi satnogs-client[10781]: ++ date ‘+%F %T’
Jul 28 00:30:14 raspberrypi satnogs-client[10779]: + date=‘2023-07-28 00:30:14’
Jul 28 00:30:14 raspberrypi satnogs-client[10779]: + freq=0
Jul 28 00:30:14 raspberrypi satnogs-client[10779]: + getopts f: option
Jul 28 00:30:14 raspberrypi satnogs-client[10779]: + case “${option}” in
Jul 28 00:30:14 raspberrypi satnogs-client[10779]: + freq=satnogs-pre
Jul 28 00:30:14 raspberrypi satnogs-client[10782]: + ‘[’ satnogs-pre -ge 136000000 ‘]’
Jul 28 00:30:14 raspberrypi satnogs-client[10782]: /home/pi/preob.sh: line 16: [: satnogs-pre: integer expression expected
Jul 28 00:30:14 raspberrypi satnogs-client[10783]: + ‘[’ satnogs-pre -ge 440000000 ‘]’
Jul 28 00:30:14 raspberrypi satnogs-client[10783]: /home/pi/preob.sh: line 22: [: satnogs-pre: integer expression expected

There seems to be an error in the position of the arguments. The freq variable is set to “satnogs” (instead of the frequency integer value). When checking if satnogs is greater than 136000000 there is an error, because the string satnogs is not an integer.

Can you share the full value of SATNOGS_PRE_OBSERVATION_SCRIPT ?

Hi…
I just tried different forum reading sample I’m not a coder. VE2DSK
The example came from this thread, 5yr ago…

satnogs_pre_observation_script: /home/pi/preob.sh -f satnogs-pre {{ID}} {{FREQ}} {{TLE}} {{TIMESTAMP}} {{BAUD}} {{SCRIPT_NAME}}

Original script
satnogs_pre_observation_script: satnogs-pre {{ID}} {{FREQ}} {{TLE}} {{TIMESTAMP}} {{BAUD}} {{SCRIPT_NAME}}

Sorry, I am not able to find this in any forum thread. But thanks for sharing. Then the error becomes clear: preob.sh expects the value after -f to be the frequency. But the value is satnogs.

Impossible to give advice on how to fix it without access to the full script, and a bit hard even with the script without fully understanding how it is designed to work.

yeah, nah. that is not what it should be. more like:
/home/pi/preob.sh {{ID}} {{FREQ}} {{TLE}} {{TIMESTAMP}} {{BAUD}} {{SCRIPT_NAME}}
and pick ${2} as frequency.

Also related thread here.

1 Like

The idea come from the “pjm” Antenna Switching project here…

VE2DSK

Thank Dan…
Did you mean freq=${2} instead of freq=${OPTARG} …?
VE2DSK

As I said in the other thread, ditch the getopt and go for positional arguments as they’re reliable when launched from satnogs-client.
freq=${2} and remove the while getopt thingy.
launch with the line I showed yesterday, no -f or any extra stuff.

If switching VHF/UHF you can simplify the script by just comparing if it’s above or below a certain frequency.

#!/bin/bash
# launch with pre obs script set to: /home/pi/preob.sh {{ID}} {{FREQ}} {{TLE}} {{TIMESTAMP}} {{BAUD}} {{SCRIPT_NAME}}
gpio mode 23 out
gpio write 23 0

FREQ=${2:-0}
if [ "$FREQ" -ge 300000000 ]; then
    echo "UHF antenna selected"
    gpio write 23 1
else
    echo "VHF antenna selected"
    gpio write 23 0
fi

The antenna selection will be shown in the log for client service (or how you run it).