Setting up the software has two parts. Creating the feeds on io.adafuit.com and the actual code running on the HUZZAH. We'll takle the feeds first.
The full project requires four feeds on io.adafruit.com. They are as follows.
Name | Publisher | Purpose |
---|---|---|
left-open-close | iOS app | Garage door open/close button press for left door† |
right-open-close | iOS app | Garage door open/close button press for right door† |
left-reed | HUZZAH | Current state of the left door magnetic switch |
right-reed | HUZZAH | Current state of the right door magnetic switch |
†As of 21 Sep 2017, these feeds can also receive commands from the iOS app.
Adafruit has excellent tutorials and guides for creating an io.adafruit.com account and then creating feeds. Go to io.adafruit.com to create an account if you don't already have one. See this Adafruit guide for basics on creating a feed.
Once the feeds are created, you should set the privacy for each feed.
Setting the Privacy is important. If you leave your feeds public, anyone can tell when your garage is open, or even open it.
To set the privacy of your feeds, select "feeds" on your io.adafruit.com page and click on one of the feed names. A page like the following should appear.
AdafruitIO Feed details
Click or tap on the settings (gear) icon for privacy. You should see an overlay like below. And yes, it is a little confusing as Adafruit calls it "privacy" in one place, and "visibility" in another.
AdafruitIO Feed privacy/visibility
Select "Private" from the drop down menu and then select "Save." Repeat this for all four of your feeds.
If you want to use a web browser to monitor your feeds, here's a quick guide on setting up an AdafruitIO Dashboard.
If you have not already installed the Arduino IDE on your computer, it's time to do that. Once again Adafruit has an excellent guide on this.
Using a Mac? Make sure you have the USB to UART bridge drivers installed. You can find them here.
Download the HUZZAH software here. Unzip the downloaded file and you should find a new folder with two files, garage.ino and config.h.
In the Arduino IDE, use the File->Open command to open the garage.ino file. Switch to the config.h tab.
Arduino IDE with the Garage project
You will need to modify the "config.h" file as follows.
/************************ Adafruit IO Config *******************************/
// visit io.adafruit.com if you need to create an account,
// or if you need your Adafruit IO key.
#define IO_USERNAME "
#define IO_KEY "
/******************************* WIFI **************************************/
// the AdafruitIO_WiFi client will work with the following boards:
// - HUZZAH ESP8266 Breakout -> https://www.adafruit.com/products/2471
// - Feather HUZZAH ESP8266 -> https://www.adafruit.com/products/2821
// - Feather M0 WiFi -> https://www.adafruit.com/products/3010
// - Feather WICED -> https://www.adafruit.com/products/3056
#define WIFI_SSID "
#define WIFI_PASS "
To get your AIO key, go back to https//:io.adafruit.com. Choose settings
AdafruitIO Settings
And then "View AIO Key"
Getting your AIO key
The AIO key can be copied and pasted.
You'll see some warnings scroll by. All of them should be in other libraries. If the compile succeeds, you should see something like the screen capture below.
IDE upload screenshot
When the upload succeeds, the garage app is now running on your HUZZAH. The code provides quite a bit of feedback via the serial monitor. Here a case where it failed to startup:
Serial monitor log of failed startup
It looks like io.adafruit.com did not respond, but in fact the WiFi SSID and password were misconfigured. Not obvious, but that is what happened in this case. Also, note that the code printed out "re-initializing network connection - forced restart" and then some more information. This additional information is the attempt to reboot the HUZZAH. For some reason, the first time this is attempted after uploading the software, the reboot attempt will fail. Subsequent attempts to reboot will succeed. But in this case, you would just end up in a rebooting loop since the installation is mis-configured. A normal startup would look something like this:
Serial monitor log of normal startup
Before we go further, you should note that the code as written restarts itself every 7 minutes. You can read why below. If you're debugging and testing, this is a pain. First because it will hang and not actually restart. Second, if you unplug and replug the HUZZAH, it will reboot just fine each time. But now you've lost the serial monitor. To change this while you are experimenting, look for the following line in the garage.ino source file.
#define kReconnectNetworkPeriod (60*7) // # seconds between restarting the system
Change the 7 to be 30 to give yourself some debugging time. But read the notes below. At present, I recommend you to set it back to 7 when you install your system.
The reports of "Left door => Closed" etc. will depend upon how your magnetic contact switches are positioned. Try moving the magnet portion away from and closer to the sensor part. You will begin to get a feel for how close the parts will need to be in your actual installation.
Now use your web browser to connect to io.adafruit.com and view your dashboard. Or use the iOS app. Once again try moving the magnets away from or next to the switch to see if your dashboard or the iOS app registers the changes.
Next try the "Open/close" buttons on the dashboard (or the equivalent buttons on the iOS app). The serial log should print out notices of the buttons being pushed. If you have hooked up relay(s), you should hear them click when the button pushes occur.
Serial monitor log with open/close button presses
At this point you should have a working system, at least on your table top.
The HUZZAH code blinks the onboard red and blue LEDs. Here's what they indicate:
LED | Rate (sec) | Indicates |
---|---|---|
Blue | 1.0 | Connecting to MQTT broker (io.adafruit.com) |
Red | 0.5 | Application is active (normal operation) |
Blue | 10 | Sent door state updates |
Blue | Intermittent | Data received (door open/close messages) |
Things often work great on the bench and less so when installed. Real life conditions cause errors you might not expect and, hopefully, you learn how to adapt your code. That's why the code I wrote for the HUZZAH is pretty simple and periodically restarts itself.
I started my technical career when network and processing resources were scarce resources. So my first approach was for the iOS client to get the current state of the garage doors when it connected and for the HUZZAH to just report changes in state for the garage doors.
To implement this approach required that there would be a way to get the "current" value from the MQTT broker. After reading through various bits of documentation I tried a number of approaches but couldn't get the current value from the broker.
Scheme 2 was to create a feed that the iOS client would publish on and the HUZZAH would subscribe to. When the HUZZAH received a publication on this feed, it would force out the current state of the doors. This worked, most of the time, but not always. Obviously the iOS client could keep requesting current state until it finally received one.
Scheme 3 (update as of 21 Sep 17): Eventually it became apparent that you could multiplex commands onto the left-open-close and right-open-close subscriptions. Originally these subscriptions received only "0" or "1". The code was slightly tweaked to check the input and if it isn't 0/1, then it assumes its a command. And in the initial implementation it doesn't even look and just assumes it is "STATUS". This results in the current state of the doors being sent on the left-reed and right-reed feeds. This can dramatically speed the time it takes for the iOS app to be able to display the up-to-date status of the garage doors.
However, it seemed that the HUZZAH code would occasionally just go deaf. Under these circumstances the iOS client could issue an infinite number of requests and never get a response. This going deaf problem also impacted the iOS client sending an "open/close the garage door" message. Periodically restarting the HUZZAH got around the deafness problem. Periodically restarting also mitigates other networking problems that might occur.
Another issue I encountered is that the Adafruit supplied libraries limit the number of active feeds in an app. This is probably done to conserve memory on the device. The Adafruit code is written to work on multiple devices, some with far less RAM than the HUZZAH. With some searching I eventually found the parameter limiting the number of feeds and changed it so I could have additional active feeds. When I simplified the implementation, this was not necessary.
In the end, the most reliable implementation on the HUZZAH simply reports the door states every 10 seconds. It reboots itself every 7 minutes. As a result, the iOS client (or web page) waits a maximum of 10 seconds to see the state information. Seemed like a reasonable trade-off.
Finally, if you examine the garage.ino code, you may notice some curious code related to button presses to trigger the relays to open/close garage doors. The reason for this is that sometimes messages seem to get lost. That is, the "on" press might be received by the HUZZAH, but the "off" is never received. Or, sometimes only the "off" was received. And once in awhile, neither "on" or "off" is received by the HUZZAH.
To mitigate these issues, the HUZZAH code remembers when it received the "on" message and then a short time later will essentially fake that it received the "off" message. If the code does receive an "off" message, the code checks to see if it received an "on" recently. If an "on" was heard, then it performs the "off." If an "on" was not heard recently, the code assumes that the "on" was lost and acts as if the "off" was an "on." The normal time out mentioned above will then take care of the "off" which will never arrive.
It was noted that the feather was creating a WiFi access point. This is the default behavior of the code stack provided by Adafruit. I've made a minor edit to the AdafruitIO_ESP2866.h and .cpp files to allow the WiFi hardware to be configured in other modes. In particular, WIFI_STA which should eliminate the access point that some had noticed.
The modified Adafruit files were added to the github repository. I have also sent Email to Adafruit proposing the change be added to the standard distribution. I have no idea what they'll think of the idea.