The topic of this presentation will be focused on exploring the world of the “Internet of Things”.
But before we can begin to explore the topic we need to understand what the Internet of Things is really about. While definitions for the term and the subject area vary depending on who you talk to, I think the Internet of Things can be summarised as: “a proposed development of the Internet in which everyday objects have network connectivity, allowing them to send and receive data”, or “the infrastructure of the information society”, or “creating opportunities for more direct integration of the physical world into computer-based systems, and resulting in improved efficiency, accuracy and economic benefit”.
The inspiration for this presentation comes from the previous presentation on September 10th which addressed using a web interface to control a light-bulb that was connected to a Raspberry Pi. This presentation not only sparked a renewed interested in connecting things to the internet, but also drove me to ask myself “There must be a simpler way” to accomplish what had been demonstrated.
Today’s presentation will cover three project within the IoT space that I have been building on and off for some time.
These “Things” are project which involve:
- WAN statistics
- Temperature Sensing
With each of these projects I will cover the hardware components, the software components, issues I encountered, next steps, and of course, how they are connected to the internet.
Before diving into the specifics of any of the project I want to address how they all interact with the Internet. The Adafruit.io IoT platform is the underpinning of all three of these devices functionality, and without it each would be quite meaningless.
Adafruit.io is a web-based platform designed to help connect otherwise “dumb” devices to the rest of the internet. The key to their success (at least with these projects) is their extremely simple and easy to use client libraries that are available for a wide range of programming languages (Python, Ruby, Node.js, API, Go)
With the use of these libraries you are able to easily send and receive data from the device. This data can then be displayed in the cloud as either a raw feed or in the form of a graph, chart, or list. They provide easy to follow documentation with (and crucially so) good examples. I was able to connect my project to this platform in a matter of minutes and it “just worked”.
The WAN Statistics Project came out of me having bought an LCD display, having not used it for almost a year, and then forcing myself to find something to do with it. In the end this device retrieves my apartment’s WAN address, and ping which is then displayed on the LCD screen locally, and sent to Adafruit.
This project consists of a 20×4 HD44780 compatible LCD, a 10K resistor, and jumper wires.
The wiring schismatic for this screen is from the Adafruit guide on using a character LCD display.
The software that drives this screen is written primarily in Python. The bulk of the code that is used to run this screen is derived from the same guide as the wiring but with modifications for the specific results I wanted to display on it.
The code that I ended up using for this project can be found in the github repository I created for this project.
Because I let this project sit for so long before getting around to it, many of the LCD guides had moved on from 16-pin screens to 18 pin screens. This meant that many of the wiring guides available on the internet were unusable with the screen I had.
Probably also do the age of the screen it took ages to find a library that was able to drive this screen. Thankfully the same “outdated” wiring guide I found that worked also included an outdated python library that seemed to be able to drive the screen.
The 20×4 size of the screen (vs the much more common 12×2 size) meant that while the older library could display text on the screen is was unable to correctly perform line wrapping and overflow. This meant that I need to be extra careful about controlling the max length of the text on each line as the results of overflow were less than graceful.
Almost 6 months ago I ordered a series of temperature Sensors on Aliexpress. At the time I had no exact use for them in mind, but knew that in time I would come up with something. This project uses three temperature sensors to collect local temperature data and then relay that to the cloud where it can be monitored.
This project makes use of two DS18B20 1-wire temperature sensor modules and a TEMPer USB temperature sensor. The two DS18B20 modules each came with the required 4.7K or 10K resistor which would have been required with a raw sensor.
The basis for this project came from Adafruit’s guide on utilizing the DS18B20 temperature sensor.
The USB TEMPer sensor made use of the temper-python python program. This program is far from ideal when wanting anything more than to display the temperature in the terminal, but was able to give a reading, and that’s better than nothing.
The resulting code that drives this project can be found in my github repository for this project.
As mentioned, much of the trouble I had with this project came down to the TEMPer sensor which was extremely tough to interact with outside of it being able to display a human-readable temperature value. From the logs in Adafruit it seems like the TEMPer sensor also seems to cut out occasionally. While the thought of a completely self-contained USB temperature sensor was enticing, the TEMPer device was less not worth the effort.
This project takes the concept behind IoT one step further with the introduction of feedback from the cloud. A relay is able to switch a high voltage current (like the mains power) using a low voltage current (like that of the GPIO pins on the Raspberry Pi). Through this process you are able to toggle power to regular household appliances. While I have not determined a permanent use for this project, the concept is part of many project ideas I have that involve lights and powered devices.
The primary component of this project is a BC Robotics 2 channel relay module. This device was chosen primarily due to its ability to accept a 3.3V input for switching. This means that it is able to natively interact with the Raspberry Pi’s GPIO pins which run on 3.3V.
To make use of the relay for this project I spliced an extension cord and a home-made lightbulb socket connected to a plug. This was intended as a simple way to demonstrate the functionality of turning on and off the relay.
Adafruit provides a great guide on how to interact with relays using the Raspberry Pi. Using this guide, along with various other online sources, I was able to connect the light-bulb to Adafruit.io where I was able to control whether it was on or off.
The code that I ended up using can be found on the github repository I created for the project.
Many of the more common Sainsmart relay modules require 5V for switching and thus require a transistor and additional wiring to be used with a Raspberry Pi. So while the module I purchased might have been more expensive, it was significantly less of a headache to set up than having to involve transistors as well.
With the code for each of the three projects completed and able to successfully send data to Adafruit I needed a way for these python script to persist across reboots.
There are dozens if not hundreds of examples online of how to do this on linux. I can say that I tried a fair few of them before I landed on a simple solution that worked for me.
What Failed Me
Many online guides try and get you to run the python scripts at boot using cron through “@reboot python script.py”. I could not get any of those to work. I suspect it may have to do with when it tries to run them during the boot order, the permissions it might have when running it, or the user it tries to run the script as. Whatever the issue was, troubleshooting was tough at best.
I also tried many variations on startup scripts using systemV scripts in init.d. Again, none of these worked consistently and you ended up spending more time trying to see if the daemon was running, or restarting the service, than having it actually run.
After much searching I came across an alternative to SystemV called Upstart.
The reality is that SystemV is crap. What is less clear is whether Upstart or Systemd (another competitor) is the better choice. And in an attempt to keep this on point (and to avoid a religious war) I will stick to my experience using Upstart and not whether it is any better than Systemd.
The reality was that Upstart was very simple to use. Installation required only an “apt-get install upstart”, creating a .conf script in /etc/init and then rebooting. In addition to that it actually worked, has consistently for weeks, and re-spawns the process if it fails at any point.
The simplicity of the script is also helpful. Instead of the 50 lines one needs for a SystemV startup script, it takes just 7 with upstart:
author "email@example.com" start on runlevel  stop on runlevel [!2345] env AN_ENVIRONMENTAL_VARIABLE=i-want-to-set respawn exec /srv/applications/chat.py
While these project are each nearing completion, there is still much to be done to round them off, and much I would like to do to extend their functionality.
I really would like to make each of these projects permanent so the first order of business there is to figure our how to make good cases for them which accommodate their sensors.
Adding more sensors would also be something for the future. The available types of sensors in the Adafruit store are extremely intoxicating and have the potential for many cool other sensing projects (Geiger counter anyone).
Extend the Data
I would also like to extend the data that these projects are generating. Right now I am not able to do more than display the data that comes into the feed. I would like to work on a solution that performs calculations either every so often, or upon certain milestones.
The Beta Adafruit.io integration with Zapier promises to allow for extending the functionality of your data. Unfortunately this is not quite the case as the options are quite limited. The adafruit trigger is limited to when a set feed matches (> = <) a set value and the action option only allows you to send a new data value to a feed. Even attempts to extend adafruit.io with Zapier without the integration is limited when using the API in Zapier. It seems code steps (used to make the API calls in Zapier) are limited to returning just 25 values, far from enough to do any meaningful calculations.
While I was not expecting much from IfTTT when it came to their integration, I was still underwhelmed. There is only one Trigger and action so you have little chance of custom logic or calculations. You can only trigger the IF on new data point or when value is > = < certain set value. The THAT step is also limited to sending a set value back to the feed.
While the premiss of Python Everywhere is enticing (run python code in the cloud) the reality is not quite so simple. While you can install third party libraries, like the Adafruit.io Python library, they install in a weird directory which makes them hard to reference. There also seems to be no internet connection for the scripts as trying to use the Adafruit API also seems to throw 404 errors which are not found when running it on another device.
Run Python code locally
This leaves the simple alternative running the code locally, either on the Pi, or another computer.
This is not out of the question, but does mean dropping back out of the cloud to perform these calculation. It also will probably rely on cron to run the script at set intervals (if they are meant to run all the time). While this seems like it works better than use cron for python scripts at boot, if there were to be any issues I doubt debugging them would be any fun.