4×1 WiFi Wireless Antenna Switch for Amateur Radio

Buy one at Tindie

I started playing with electronics back when I was 10 years old in Argentina, where I grew up. Then I got my ham radio operator license when I was 16 years old and I was very active in the ham club and on the air. It was then when I built my first vacuum tube transmitter and refurbished and old receiver (also vacuum tubes) that somebody from the club was throwing away. My interest for science and electronics grew and I ended studying physics but always tinkered with electronics, whenever I could.

I’ve moved a lot around the world for work (oil and gas) so my dedication to ham radio pretty much faded away. But it came back! Just recently, I got my ham radio operator license back and started to get active on 2mtr and on digital.

Due to lack of space outdoors, I had to settle for installing my center fed dipole on the attic (I have a long attic), but I quickly realized I needed more than 1 antenna. 80 mtr, 40 mtr, 20mtr….

And I didn’t want to run multiple lines to the attic, so an antenna switch was necessary.

I bought a 4 position manual antenna switch and very quickly realized (again) that I did not want to go up and down the stairs with kids and wife sleeping to switch the antenna. And more importantly, I did not want to run another set of cables to drive a wired remote controlled one. Wireless was the solution. I checked the prices, and they were outside of my budget for a switch. So, what’s next? I came up with an idea. Get a RaspberryPi and add a relay board and then I have my WIFI wireless relay control. Add some UHF female SO-239s and we have a WIFI Antenna Switch. Well, two problems with this, first it is really clunky connecting all those coaxial cables to the relays and there would be a lot of signal loss (and good luck tuning that), its bulky and pretty difficult to assemble in one unit and that would not work properly; second, it was more expensive than I expected, even DIY it was around 100 dollars. I built it anyway and, well it worked for a while. But I was not happy so I looked around and came up with a better idea (or so I thought!). I found the ESP8266, a WIFI module which is small, cheap, I mean 3-dollars-cheap and fully programmable. Combining this module with a standard relay switch design, I thought I had a solution for way under 100.00 dollars integrated all in one single PCB board, suitable for mounting on a proper box. Lets look at the design.


The brain of the switch

The ESP8266 is a very small WIFI enabled microcontroller. It can be programmed in C by flashing it with the manufacturer’s (Espressif) software development kit (SDK). But it can also be programmed in LUA using the NodeMCU SDK (open source, just Google it or go to GitHub). LUA is a scripting language used widely in the gaming industry and I picked it to program the ESP8266 because of being compact, very high level and allowed rapid prototyping.

The ESP8266 acts as an access point and/or a WIFI station, so once it is configured it acquires an IP address and then you can communicate with it via a web browser or a TCP connection (phone, tablet, computer, etc).


The ESP8266-01 used in this project, has 2 GPIOs, GPIO0 and GPIO2, meaning that we can program the module so it can read and write stuff on these GPIOs. The ‘stuff’ is simply digital signals, a 0 or a 1, or in volts, a few millivolts or 3.3 volts. This is perfect to drive LEDs or relays and make them open or close according to some logic and control either running on the module or instructed via a web or TCP server.

The module features a serial interface so you can communicate with it to program it.

There is plenty of material out there to get anyone going with this little wonder. The key things to know is that you will need a USB to serial module to initially talk to the ESP8266, be familiar with serial communication and able to do some script programming. For USB to serial, any FTDI232 based module will pretty much work, but be careful as they are counterfeit FTDI232 that can render useless, make sure whatever you get is genuine. Then you need to choose a serial terminal to send commands to the serial module that will send commands to the ESP8266. Something like CoolTerm or SSCOM32 would do the job. I use CoolTerm mostly on the Mac. Also, when you start copying LUA code into the module, CoolTerm does a great job.

With this brief introduction to the ESP8266, you can have a lot of fun prototyping all kinds of interesting WIFI projects.



Driving the relays

I looked a several relay types, and for this first version of the switch, I estimated going with something on the lower power side would be a wise choice, something that could handle 100-300 Watts. There is plenty of time to improve the design and make it robust for high power transmitters. I started with a 4 position switch, so I needed to drive 4 low power, low current relays. The ESP8266 has 2 GPIOs (general purpose IO), GPIO0 and GPIO2, but just 2 GPIOs, were not going to be able to drive 4 relays, I needed some logic. I decided to go with the 74HC238, a 3-to-8 line decoder. I just needed a 2-to-4 line decoder but since I had a bunch of these, lets use them, and connect the unused input line to ground. The ESP8266 GPIOs were going to feed the 74HC238 and provide the logic to switch the outputs, then these outputs will drive a Darlington power driver like the ULN2803. To make it safer, I decided to split the 8 ULN2803 outputs into 2 groups of 4, one group feeding the relays, the other the LEDs.


GPIO0 GPIO2 Relay 1 Relay 2 Relay 3 Relay 4
0 0 H L L L
1 0 L H L L
0 1 L L H L
1 1 L L L H

Figure 1


Figure 1 shows the desired truth table for the GPIOs and the Relays.

Now to achieve this logic, I connected GPIO0 to input A0 of the 74HC238 and GPIO2 to input A1. As mentioned above, A2 is connected to ground. This arrangement provides me with the correct output logic from the 74HC238 which I can now connect to the ULN2803. The cool thing here is that at all times, only one output is active, which is what we want when switching antennas. We don’t want 2 antennas connected to the transceiver at the same time! Or do we?

To make convenient I added a reset push button switch and a flash switch, in case I needed to reset the board for whatever reason, or flash it if I had new firmware.


The ESP8266-01 requires 3.3 V, and no more. The rest of the board need 5V, so I needed an LM1117 3.3V regulator to bring the voltage down and keep it stable.

4 LEDs indicate which antenna is active and 4 relays do the switching as instructed by the ESP8266 and the logic circuitry. The input and output connectors are standard panel mount UHF female SO-239.

For safety, I included varistors at the feed point of the relays.


Putting it all together

I programmed the ESP8266 so it can be configured via a web browser to connect to the WIFI router. Once configured, the module acquires an IP address and then I can communicate via TCP protocol. The module responds to the simple commands 1, 2, 3, 4 to switch between the antennas. TCP commands can be sent from a laptop or computer using a simple utility written in Python, for example. If using a mobile device, there are apps that send and receive TCP commands. But better yet, I went ahead and wrote an iPhone app that specifically pairs nicely with the antenna switch. Figure 2 shows a screen dump of the app (which should be available for free on the Apple app store under AntennaSwitch).

Figure2b Figure2a

Figure 2

The final product

Figures 3a and 3b show the final PCB board and components. The finished board can be easily mounted in a metal box for safety and convenience. It only requires a 5 VDC small supply (250 ma). Figure 4 shows the schematic of the switch.


Figure3a Figure3b

Figure 3a and 3b



Figure 4

Final thoughts and future enhancements

I was impressed of the performance and flexibility that the ESP8266 brings. Its small and extremely powerful and if you are interested in the Internet of Things (IoT), this module will allow you to hit the ground running. Being so small and modular it allowed me to integrate the UHF connectors, the relays, the logic circuits and the WIFI module all in one board that is 3 ¼ by 5 inches and can be easily mounted on any box.

Next steps are

  • Increase the power handling to 1kW or more. The PCB board will have to be upgraded to handle this and I will need to find the right relays.
  • Build a 6×1 or even 8×1 switch. Although 2 of the 4×1 can be easily combined, I think a compact 8×1 would be really nice.
  • Foot massage (just kidding).
Posted in Uncategorized | Leave a comment

Open/close sensor with SMS text alarm

Our garage faces the alley and it is not unusual to hear of people leaving the garage door open and get stuff stolen. The trade offs of leaving inside the loop in Houston as it is for any large city in the world (even Oslo). Now it has been 3 times that we forget the garage door open, and this last time we left it overnight! Lucky us, the garage was intact and this is unusual, more than 8 hours open and nothing taken, more than unusual I’ll classify it as miracle. Anyway, I needed to do something about it so I thought of using one of the ESP8266 modules and add an email service in it, but ultimately send SMS messages to me and my wife.

It is a simple mechanism. I pulled a 1k resistor to 3.3 V on  the GPIO2 of the ESP8266 and a switch to ground. When the switch is open, there is voltage in the GPIO2 so its state is 1, when the switch closes, it sends the GIPO2 to ground, voltage is 0, state is 0.

Screen Shot 2015-07-31 at 4.03.43 PM

I programmed the ESP8266 to monitor changes in GPIO2 as follows:

  • If switch closes, wait a number of minutes (typically lets say 5 minutes) before sending a text message.
  • If switch opens before the 5 minutes are passed, do nothing, the door has just been normally opened and closed.
  • If switch is closed and 5 minutes passed, send a text message
  • Keep sending a message every 5 minutes until switch closes

Thats it.




Here is the code:

open_mess_sent = 0

function onAlarm()
value = gpio.read(pin)
if value == 0 then
open_mess_sent = 0
print(“Sending open message”)
tmr.alarm(1,300000,1, open_msg)
elseif value == 1 then
if open_mess_sent == 1 then
print(“Sending close message”)
open_mess_sent = 0

function open_msg()
send_email(“5555555555@txt.att.net”, “WARNING”, “Garage door is open”)
open_mess_sent = 1

function close_msg()
send_email(“5555555555@txt.att.net”, “RESOLVED”, “Garage door is now closed”)

function init_STA()
gpio.trig(pin, ‘both’, onAlarm)

Posted in Uncategorized | 2 Comments

WiFi Analog/Digital Module reads analog or digital data, returns the values and responds according to programmable limits. MQTT protocol

Ready to use boards available at Tindie

WiFi Analog/Digital Module reads analog or digital data, returns the values and responds according to programmable limits. MQTT protocol

The analog/digital control module reads analog data and digital data through its 2 input terminals. Input analog data limits are zero VDC to 3.3VDC, and this maps into output values of 0 to 1024 Input digital data limits are zero, for a digital zero, and 3.3VDC for a digital 1 The module sends the value of the measured analog data periodically every Interval milliseconds, and it sends the value of the measured digital data when this chances from 0 to 1 or from 1 to 0. The user can also request the module to send the measured values of analog and/or digital data at any time by publishing a specific MQTT topic. The module provides a triggering signal whenever the digital data changes (Figure 1) The module provides a triggering signal when the analog signal is less than a preset value or larger than a preset value (Figure 2)

Figure 1: Digital data response

Figure 2: Analog data response
Once the module is connected to the WiFi router it will stablish communication with the MQTT server and port as specified above and will attempt to connect. Wait a few seconds and all 4 LEDs will blink in sequence indicating a successful connection. If this fails, reset the board and wait a few seconds for the LED sequence. The module uses MQTT protocol for communication. MQTT topics are composed of a four letter acronym followed by the ESP822 chipid (the chipid is listed with your documentation), XXXXchipid Once a connection with the MQTT sever is established, the module is ready for communication and therefore reading analog and digital data and sending commands.

A typical MQTT instruction is composed of a topic followed by a message.

MQTT Topics and Messages

RANLchipid : this topic instructs the module to read a sample of the analog data and send it back via an MQTT topic and message. The module in response sends a topic and value as follows:
DANLchipid value ; you can get the analog value by subscribing to the topic DANLchipid and getting the value from the message
RDIGchipid : this topic instructs the module to read a sample of the digital data and send it back via an MQTT topic with the value as a message. The module in response sends a topic and value as follows:
RANLchipid value ; you can get the digital value by subscribing to the topic RANLchipid and getting the value from the message
MANLchipid min_analog_trigger (min 0, max 1024, def 300): this topic allows the user to set the module’s minimum analog value used for triggering the LED and signal . The change takes immediate effect.
XANLchipid max_analog_trigger (min 0, max 1024, def 800):: this topic allows the user to set the module’s maximum analog value used for triggering the LED and signal. The change takes immediate effect.
INTEchipid Interval_in_milliseconds (min 500 ms, max 240000 ms, def 5000 ms): this topic allows the user to set a new interval in milliseconds for receiving analog data. The change takes immediate effect.
RESTchipid: this topic allows the user to reset the module remotely.

Note that the analog value is sent by the module at regular intervals (controlled by the value of Interval_in_milliseconds) as specified during configuration or changed during operation, while the digital value is sent only when it changes. You can always request the analog or digital value at any time by publishing the respective topic.

Posted in Uncategorized | 2 Comments

WIFI Color Detection with the ESP8266 and MQTT messaging

The previous implementation of the WIFI color detection was done with an ad-hoc messaging system. Now, the most bang for the buck would be to have MQTT integrated, as it is much more flexible in terms of the message format and content.

I got the color detection, which involves frequency decoding of each of the filtered signals for R,G,B and no-filter, and MQTT working like a charm.

The protocol is simple. An MQTT message is sent to topic “AcquireColor”. Response is obtained by listening to topics “GetColorP” for color percentage and “GetColorF” for raw frequency (proportional to color intensity). The returned info comes back as a JSON string as follows:


{“RGBP”: [{ “Red:”: “37”, “Green”: “30”, “Blue:”: “32”}]}


{“RGBF”: [{ “Red:”: “6578”, “Green”: “5291”, “Blue:”: “5649”, “All:”: “8695”}]}

This module can be purchased at my Tindie store


Here is the code:

file.writeline([[red=0 ]])
file.writeline([[green=0 ]])
file.writeline([[blue=0 ]])
file.writeline([[all=0 ]])
file.writeline([[IP_posted = 0]])


file.writeline([[– Configuration to connect to the MQTT broker.]])
file.writeline([[BROKER = “your_mqtt_broker_IP_address” — Ip/hostname of MQTT broker]])
file.writeline([[BRPORT = 1883 — MQTT broker port]])
file.writeline([[BRUSER = “user” — If MQTT authenitcation is used then define the user]])
file.writeline([[BRPWD = “pwd” — The above user password]])
file.writeline([[CLIENTID = “ESP8266-” .. node.chipid() — The MQTT ID. Change to something you like]])
file.writeline([[BFSIZE = 16]])

file.writeline([[– MQTT topics to subscribe]])
file.writeline([[topics = {“AcquireColor”} ]])

file.writeline([[– Control variables.]])
file.writeline([[pub_sem = 0 ]])
file.writeline([[current_topic = 1 ]])
file.writeline([[topicsub_delay = 50]])

file.writeline([[– Publishing structures]])
file.writeline([[pub_topic = {}]])
file.writeline([[pub_message = {}]])
file.writeline([[pub_head = 1]])
file.writeline([[pub_tail = 1]])


file.writeline([[print(“heap: ” .. node.heap() )]])
file.writeline([[m = mqtt.Client( CLIENTID, 120, BRUSER, BRPWD)]])

file.writeline([[print “Connecting to MQTT broker. Please wait…”]])
file.writeline([[m:connect( BROKER , BRPORT, 0, function(conn)]])
file.writeline([[ print(“Connected to MQTT:” .. BROKER .. “:” .. BRPORT ..” as ” .. CLIENTID )]])
file.writeline([[ mqtt_sub() ]])

file.writeline([[function mqtt_sub()]])

file.writeline([[ if table.getn(topics) < current_topic then]])
file.writeline([[ init_STA()]])
file.writeline([[ else]])
file.writeline([[ m:subscribe(topics[current_topic] , 0, function(conn) ]])
file.writeline([[ end)]])
file.writeline([[ current_topic = current_topic + 1 ]])
file.writeline([[ tmr.alarm(5, topicsub_delay, 0, mqtt_sub )]])
file.writeline([[ end]])


file.writeline([[function publish_data()]])
file.writeline([[ freq_all =(freq_multi/all)]])
file.writeline([[ freq_red =(freq_multi/red)]])
file.writeline([[ freq_green =(freq_multi/green)]])
file.writeline([[ freq_blue =(freq_multi/blue)]])
file.writeline([[ col_sum =freq_red+freq_green+freq_blue]])
file.writeline([[ perc_red = (100*freq_red)/col_sum]])
file.writeline([[ perc_green = (100*freq_green)/col_sum]])
file.writeline([[ perc_blue = (100*freq_blue)/col_sum]])

file.writeline([[payload = ‘{“RGBF”: [{ “Red:”: “‘ .. freq_red .. ‘”, “Green”: “‘ .. freq_green .. ‘”, “Blue:”: “‘ .. freq_blue .. ‘”, “All:”: “‘ .. freq_all .. ‘”}]}’]])
file.writeline([[m:publish( “GetColorF”, payload ,0 ,0 , function(conn) ]])
file.writeline([[payload = ‘{“RGBP”: [{ “Red:”: “‘ .. perc_red .. ‘”, “Green”: “‘ .. perc_green .. ‘”, “Blue:”: “‘ .. perc_blue .. ‘”}]}’]])
file.writeline([[m:publish( “GetColorP”, payload ,0 ,0 , function(conn) ]])
file.writeline([[payload = nil]])
file.writeline([[function pin1cb(level)]])
file.writeline([[if cur_color == 0 and count == 0 then]])
file.writeline([[ gpio.mode(6,gpio.OUTPUT)]])
file.writeline([[ gpio.mode(7,gpio.OUTPUT)]])
file.writeline([[ gpio.write(6,gpio.HIGH)]])
file.writeline([[ gpio.write(7,gpio.LOW)]])
file.writeline([[elseif cur_color == 1 and count == 0 then]])
file.writeline([[ gpio.mode(6,gpio.OUTPUT)]])
file.writeline([[ gpio.mode(7,gpio.OUTPUT)]])
file.writeline([[ gpio.write(6,gpio.LOW)]])
file.writeline([[ gpio.write(7,gpio.LOW)]])
file.writeline([[elseif cur_color == 2 and count == 0 then]])
file.writeline([[ gpio.mode(6,gpio.OUTPUT)]])
file.writeline([[ gpio.mode(7,gpio.OUTPUT)]])
file.writeline([[ gpio.write(6,gpio.HIGH)]])
file.writeline([[ gpio.write(7,gpio.HIGH)]])
file.writeline([[elseif cur_color == 3 and count == 0 then]])
file.writeline([[ gpio.mode(6,gpio.OUTPUT)]])
file.writeline([[ gpio.mode(7,gpio.OUTPUT)]])
file.writeline([[ gpio.write(6,gpio.LOW)]])
file.writeline([[ gpio.write(7,gpio.HIGH)]])
file.writeline([[if count == 0 then]])
file.writeline([[ start = tmr.now()]])
file.writeline([[if count > s_length then]])
file.writeline([[ if cur_color == 0 then]])
file.writeline([[ all=(tmr.now()-start)/s_length]])
file.writeline([[ cur_color=1]])
file.writeline([[ print(all )]])
file.writeline([[ elseif cur_color == 1 then]])
file.writeline([[ red=(tmr.now()-start)/s_length ]])
file.writeline([[ cur_color=2]])
file.writeline([[ print(red )]])
file.writeline([[ elseif cur_color == 2 then]])
file.writeline([[ green=(tmr.now()-start)/s_length]])
file.writeline([[ cur_color=3]])
file.writeline([[ print(green )]])
file.writeline([[ elseif cur_color == 3 then]])
file.writeline([[ blue=(tmr.now()-start)/s_length]])
ile.writeline([[ cur_color=0]])
file.writeline([[ color_done=1 ]])
file.writeline([[ gpio.mode(pin,gpio.INPUT)]])
file.writeline([[ print(blue )]])
file.writeline([[ publish_data()]])
file.writeline([[ end]])
file.writeline([[ count=0]])

file.writeline([[function init_STA()]]) — 1

file.writeline([[m:on(“message”, function(conn, topic, payload)]])
file.writeline([[print(topic .. “:” )]])
file.writeline([[ –if (payload ~= nil ) then]])
file.writeline([[ — print ( payload )]])
file.writeline([[ –end]])
file.writeline([[red=0 ]])
file.writeline([[green=0 ]])
file.writeline([[blue=0 ]])
file.writeline([[all=0 ]])
file.writeline([[IP_posted = 0]])
file.writeline([[gpio.trig(pin, “down”, pin1cb)]])

file.writeline([[end )]])
file.writeline([[end]]) — 1

Screen Shot 2015-05-29 at 4.08.15 PM

Posted in Uncategorized | 2 Comments

WIFI Color Detection with the ESP8266


The reading of the color components is done via a TCP request to the board. The reading returns a frequency in KHz proportional to the intensity of the color. The frequencies in KHz are returned in a JSON string. The value of the intensity for all colors is also returned. Percentage components of color can be calculated from the frequency readings as these are proportional to the color intensity.

The sequence for reading is done by sending the following strings via TCP on port 9999:


(wait 5 seconds for acquisition to complete)

readf to read the frequency values

readp to read the percent values

The return message is in JSON format as follows:


{“RGBF”: [{ “Red:”: “1640”, “Green”: “1230”, “Blue:”: “2250”, “All:”: “6250”}]}}]}

each number representing a frequency in KHz proportional to the intensity of the light for red, green, blue and unfiltered (all).



{“RGBP”: [{ “Red:”: “33”, “Green”: “42”, “Blue:”: “25”}]}}]}

each number representing a percentage of the intensity of the light for red, green, blue.

This might seem stupid, but given the memory issues on the LUA API, this at least works nicely. Lets see in I can squeeze in MQTT.

Posted in Uncategorized | Leave a comment

MQTT and ESP8266, using i2c sensor things work

Forget the DHT11. Implementing the protocol to read temperature and humidity eats all your memory on the ESP8266 and there is nothing left if you want to support MQTT messaging. However, and I2C sensor works. The I2C implementation using an LM75A can be done and integrated with MQTT.

I am preparing a post with the details on what I did.

Posted in Uncategorized | Leave a comment

MQTT and ESP8266

Got the vibration detection board working with MQTT. This was really an ordeal given that the memory issues with LUA and the ESP8266 are really frustrating. Its trial and error. Finally and after stripping the code to the bare minimum, i.e., remove all the fancy web page interface to the board configuration, things got working pretty good.

I installed my own MQTT broker on a MacBook, Mosquitto, and got it to work without major issues.

MQTT is really great for IoT, of course if you have a broker running or want to go through a public broker, otherwise my ad-hoc messaging solution I think it is a bit easier for home projects. But again, MQTT is the way to go if you want to control several devices, send and receive various commands, etc.

On my future boards I will offer ad-hoc messaging or MQTT, check them out on Tindie

Posted in Uncategorized | 2 Comments