For one, I wanted to learn “voice-enabled” technology. We’ve had desktops and laptops for decades. Why don’t we talk to our computers? The Dot is a computer. It has WiFi, security, audio processing, a visual interface, a web server and so on, all wedged into a spiffy little $50 hockey puck-shaped package. How does it work? Why do we talk to the Dot and not our Linux notebooks?
The other reason was to study interfaces. Interfaces are an integral part of the Off-The-Shelf Hacker physical computing stack tool box. The Dot’s primary interfaces are voice recognition and replies, via the microphone/speaker. It also communicates over a web interface that’s accessible on a nearby notebook or super-phone.
And, the Amazon Echo Dot light ring is fascinating. It’s multi-colored and the way the little light runs around the ring has various meanings as the Dot does its thing. Most of all, I’d like to find out how I can use the Dot’s various interface models in my own physical computing prototype projects.
Hooking Up The Hardware
I figured I’d start simple. Let’s take inspiration from the Dot and explore how to use a simple tri-color LED with the Mosquitto Under Glass data hub. We already have the MQTT broker and subscription/publishing parts working. The LED connects the virtual to the visual.
Adding a tri-color LED to the CHIP-powered data hub is pretty straightforward.
There are two types of 4-wire, tri-color LEDs. A common anode and a common cathode. One lead is common and the other three connect to the red, green and blue elements. I used the common cathode variety.
You should always use a current limiting resistor, for each LED, when hooking up to the pins on a microcontroller. The CHIP can safely handle about 25 mA of current through each pin at 3.3 volts. Using a 100-ohm resistor, we can limit the current to 20 mA or so. Each microcontroller can handle different currents and voltages, depending on their specs.
For this exercise, I simply soldered a resistor to each leg of the LED. The other side of the resistor went to a male connector pin, using 24-gauge wire that plugs into the CHIP’s female general purpose input/output (GPIO) header.
The following photo shows details of the LED, resistors and pins. Note the wire color. Black is the common. Blue corresponds to the blue LED element. Sadly, I didn’t have any red or green wire handy so I substituted orange for red and gray for green. It relates, metaphorically.
The common was plugged into the VCC-3.3 V pin, on the inner, right-hand side CHIP header. Blue went to the XIO-P0 slot. Likewise, the orange wire went to XIO-P2 and the gray went to XIO-P4.
I wrapped the wires around the upper brass cross member of the CHIP’s support frame temporarily and will soon build a decorative bracket to hold the LED in place above the board.
The main function of the MQTT/CHIP data hub is to pass messages back and forth from edge devices. A secondary function, since the Mosquitto Under Glass device sits on my desk, is to give me a visual status of various physical things happening around me, much like the Dot.
For example, if someone comes to the front door, it would be useful for the red LED on the data hub to flash. Or, we could light the red LED if a moisture sensor in the garage detects a leak around the water heater. There are tons of uses for this kind of functionality. Don’t forget that we’re using a tri-color LED, so we are not just limited to one color.
The following Python code shows how to turn the LEDs on and off, using messages from an MQTT broker. Actually, the broker and the program run on the CHIP itself. If you had another CHIP or a Raspberry Pi, you could light LEDs on those devices, as well, simply by subscribing to the “mqtt” topic, back on the CHIP data hub. Get information on the Paho library and examples here.
#!/usr/bin/python import CHIP_IO.GPIO as GPIO import paho.mqtt.client as mqtt GPIO.setup("XIO-P0", GPIO.OUT) GPIO.setup("XIO-P2", GPIO.OUT) GPIO.setup("XIO-P4", GPIO.OUT) GPIO.output("XIO-P0",GPIO.HIGH) #HIGH actually turns LED off since operating as current sink GPIO.output("XIO-P2",GPIO.HIGH) GPIO.output("XIO-P4",GPIO.HIGH) # The callback for when the client receives a CONNACK response from the server. def on_connect(client, userdata, rc): # print("Connected with result code "+str(rc)) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. client.subscribe("mqtt") # The callback for when a PUBLISH message is received from the server. def on_message(client, userdata, msg): # print(msg.topic+" "+str(msg.payload)) if str(msg.payload) == "b-on": GPIO.output("XIO-P0",GPIO.LOW) elif str(msg.payload) == "b-off": GPIO.output("XIO-P0",GPIO.HIGH) elif str(msg.payload) == "r-on": GPIO.output("XIO-P2",GPIO.LOW) elif str(msg.payload) == "r-off": GPIO.output("XIO-P2",GPIO.HIGH) elif str(msg.payload) == "g-on": GPIO.output("XIO-P4",GPIO.LOW) elif str(msg.payload) == "g-off": GPIO.output("XIO-P4",GPIO.HIGH) else: print(msg.payload) client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect("172.20.0.1", 1883, 60) # Blocking call that processes network traffic, dispatches callbacks and # handles reconnecting. # Other loop*() functions are available that give a threaded interface and a # manual interface. client.loop_forever()
Notice that after the usual library imports and initialization, we set the three output pins (XIO-P0 to XIO-P4) to “HIGH.” This ensures that the LEDs are off. Current sink mode for an output pin effectively acts as a switch between the microcontroller pin and ground. We usually think of an output pin as able to provide current to a device when it is turned on. Many microcontrollers like the CHIP can only typically provide current in the tens of microamps range as a “powered” output. Even LEDs (at around 20 mA) would draw too much current from the pin.
The way around this problem is to hook up the LED in a current sink configuration. One side of the LED is connected to 3.3 volts, through the 100-ohm resistor and the other end attaches to the output pin. When the pin is “HIGH” it effectively has high resistance and the LED is off. Switch the output to “LOW” or low resistance and the LED comes on. Current sink mode (on the CHIP) can handle about 25 mA or so of current. Our LEDs draw less than 20 mA at 3.3 volts, so everything works without worry.
The code has to be running on the CHIP and can be started with the following line.
chip% sudo python gpio2.py
The code was tested by publishing various MQTT messages from a command line on my Linux notebook.
drtorq-notebook% mosquitto_pub -h 172.20.0.1 -t mqtt -m b-on
“b-on” in this case means “turn on the blue LED.” Conversely, “b-off” turns the LED off. Feel free to set up a control scheme to suit your own requirements.
One happy consequence of using a nano-Linux system like a CHIP (or Raspberry Pi) and programming languages like Python for physical computing projects is that program complexity is not a problem. Firmware-based microcontrollers, like an Arduino or ESP8266, have limited program space and it’s often challenging to fit all your code into those spaces. As a result, the Arduino is pretty single-minded in its approach to physical computing capability.
I always like to point out this huge difference between the Arduinos (firmware-based) and Raspberry Pi/CHIP (Linux-based) microcontroller camps. With the CHIP, Linux can run multiple programs simultaneously, each having perhaps hundreds or even thousands of lines of code, without any problem. Arduinos are single program hardware, with the program burned into the firmware.
Lots of techies still don’t understand the difference and when you’d use one or the other. Feel free to spread the word.
We’ve touched on the basics of controlling a three-color LED. There are lots of opportunities for expansion.
Flashing an LED could be accomplished by coding in a little loop that turns the LED on/off rapidly for a certain number of cycles. Or, maybe you’d like to rotate through the colors with each MQTT message. Use another loop to turn an LED on, wait a short period, then turn it off, then do the same with the other colors.
You could also try setting up your messaging through a cloud-based MQTT broker, such as from Adafruit.
See what you come up with and be sure to take inspiration from existing already working devices like the Dot.