W7IY Antenna Switch
UPDATE: We now have W7IY Antenna Switch Version 3.0 - which is based on this effort, but the programming for both the server and client are written in Java.
This is version 2.0 of the W7IY antenna switch. At W4RM, we use two Array Solutions SixPak relay systems to feed four contest stations. Each SixPak can connect one of six antennas to two stations. Since we have four stations, we need a way to combine two SixPaks ensuring no two stations select the same antenna. Version 1.0 uses a FPGA and some canabilzed relay boards found at a hamfest. I built a transistor array to control the relays, sense the SixPak control box positions and provide LED feedback to the user. The code was written in VHDL.
After serveral years of successful operation, the relay driver transistors in version 1.0 started to fail. The relays have built in reverse diodes, so I'm not sure why they are failing. Since the antenna switch is a critical component to the station, we decided to build version 2. The point to point wiring on version 1 always caused me concern (but never really failed), so I decided to design new circuit boards.
We also wanted to take the opportunity to network enable the system, which caused me to look at the beagelbone as a controller. The beaglebone worked well for our battery sensor, with some exceptions. Notably, the microSD cards kept failing. Suspecting well know Solid State Disk short comings, I tweaked the code and mounting parameters to reduce 'writes' to the card. I also added USB sticks for the root system, which seemed to help.
After a Google search, I found a company selling relay boards for a great price. Futurlec was selling boards with 8 relays and almost all the necessary logic for multiplexing and latching the relays. They also sell cards with optical couplers and interface logic, which I used on the 'input' side of the system. The cost of the boards and parts would have been about the same if I home brewed the circuit boards. So we decided to buy the hardware and turn this into a software project. Thanks to Jack, W4NF, for funding our effort.
However - Futurlec is located on the other side of th world and their business model is terrible. It took me 12 weeks to get my order. I had to generate several nasty e-mails. All of my parts arrived and the boards work great, but I was not expecting such a long lead time.
To provide 'feedback' about the relay positions, I wrote a C# applicaition. The app shows the antenna status and lets the operator know which station has a specific antenna. "Who has the Stack?" is a FAQ during the contest. The C# application runs under Windows 64 and XP using the .NET 4.0 framework. Microsoft's VisualStudio is a fantastic IDE.
The application on the BB uses perl because execution speed is not critical. The OS is based on Angstrom, which I compiled on my local computer so I could get all the latest perl modules built. Much of this work is based on the temperature sensor project. Updates to the application are sent via multicast to the network. Bill and I are really pleased with the response time.
- media:MANUAL ET-DCIN8.pdf - Input board with schematics.
- media:User' s manual ET-REL8.pdf - Relay board manual with schematics
- media:Switch-cape-input.pdf - Wiring diagram/schematic for interfacing the input board to the beaglebone.
- media:Switch-relay-output-mod.pdf - Wiring diagram/schematic for interfacing the output board to the beagelbone.
The input and output boards are multiplexed to reduce the number of pins required to connect the BB to the boards. Bus and address lines connect to BB General Purpose IO pins, which are properly configured by the perl code.
The output bus is 8 bits wide with 4 address lines. I added a 74HCT573 latch to each relay board. The perl code writes the desired relay configuration to the bus and pulses the appropriate address line. The pulse sets the latch, which in turn drives the relays. The relays provide the necessary control voltages to the remote relays mounted at the tower. (i.e. SixPak) A separate 12V power supply reduces the chance that a nearby lightning strike might damage the electronics. The latch mounted nicely on top of the jumper pins. Boards are interconnected using ribbon cable and standard 34 pin connectors. Note, only six relays are used per board, leaving a total of 8 unused relays. We plan to use these relays to drive a RATPAK.
I modified the input boards to connect the 'enable' pins for the on-board 74LS245 drivers to the input address bus. By driving this line high, the outputs are in a high impedance mode. Driving one address pin low puts the data onto the input bus. There are 8 unused optical couplers.
The boards have plenty of status LEDs to provid a good visual indication of the power supply, Input selection and relay conditions.
The power supplies are mounted in the lid of the cabinet.
DB-25's provide a place for connecting the control boxes (in the station) and the relay control lines. The DB-25's are wired to allow for interconnection, if the switch box totally fails.
We added a SPST button to one of the I/O pins to provide a shutdown signal. Since the BB is a linux computer, it's best to conduct an orderly shutdown when we want to power cycle the equipment. A separate perl program monitors the I/O pin (pin 28 on P8). When it detects the pin going low, it will issue a 'shutdown now' command to the BB. This same mechanism can be used to shutdown the BB during a power outage.
In version 3.0, we plan to eliminate the SixPak control boxes. We can remove the input boards, then.
The server application is written in perl. Not the best for performance, but sure is easy to code and make changes.
Additional perl modules required: (in addition to the modules loaded from the battery monitoring project page)
opkg install perl-module-io-file perl-module-io-seekable opkg install perl-module-fcntl perl-module-file-spec perl-module-file-spec-unix opkg install perl-module-constant
The pseudo code:
Initialize the variables, including GPIO mux labels and I/O values. Initialize relays do while(1) read the input bus if(valid change) set/clear relays broadcast UDP multicast packet to network endif end while
I use cacti to poll SNMP variables from switch over SSH every 5 minutes. This lets us know the BB is alive and well.
The switch application resides on each contest station and provides information about the state of the switch. The buttons turn colors and the current station assignment is listed next to the button. This way, each station 1) can see which antenna they have selected, 2) which antennas are in use and 3) which station has a particular antenna. In the past, the operators didn't have all this info.
Of course, the next step is to remove the hardware controller (SixPak switches) and enable the switching function in the application. This will allow the operator to grab an unassigned antenna by clicking on a button.
The application is written in C#. When the antenna status changes, the beaglebone (switch) sends a UDP multicast packet to the local area network with the current switch status. A background thread in the application listens for multicast packets and updates the GUI when a packet arrives. The network is not heavily loaded, so only single packets are sent on switch changes. So far, this seems adaquate. (UDP is stateless delivery.)
Each application pings the beagleboard every 30 seconds to make sure the switch is alive. The antenna labels are configurable and can be different for each station as is the BB IP addresses.
The code was developed in Microsoft Visual Studio 2012. Building a multicast listener and using background threads were new challenges for me. We originally tried a polling mechanism via SNMP, but this was slow and overly complicated. SNMP would be much more useful in a situation where you wanted to pull data every minute or so using standard tools. (e.g. cacti) I'll be able to take the lessons learned here and use them in a GUI for our battery monitor.