Introduction: Home Alert: Arduino + Cloud Messaging on a Large Display
In the age of mobile phones, you would expect that people would be responsive to your call 24/7.
Or… not. Once my wife gets home, the phone stays buried in her hand bag, or its battery is flat. We don’t have a land line. Calling or SMSing to ask for a lift home from the train station on a rainy night or calling to ask if my keys are still on my desk is literally wishful thinking.
I have this problem often enough to warrant a solution. A bit of tinkering with an Arduino and a Freetronics Dot Matrix Display (DMD) resulted to a very annoying (for my wife) gadget, but an amazing communication device and information center for me. I love it, and it’s only version 1!
Home Alert is made of these parts:
- A Freetronics Dot Matrix Display, which is an array of 16x32 LEDs. They come in different colours, but I use red to emphasise that this gadget is for “critical” notifications.
- An Arduino Uno with an Ethernet Shield.
- A real-time clock breakout, like this or this.
- A piezo buzzer
- A DHT22 temperature and humidity sensor.
Have a look at the home page (show in the first attached image in this step), where the form awaits a new message from the user.
The first field accepts a numerical hardware code. It’s a code that allows you to target a specific Home Alert system, as each can be given a unique code. Or, you can have multiple Home Alerts sharing the same code, so that the same message is displayed to multiple locations.
The message you want to display goes to the second field. Any text you type in there will be displayed in the DMD.
If you want to make some noise, check the Yes! checkbox, and the buzzer is sure to gain the attention of anyone nearby.
In this article, I’ll show you how to build your own Home Alert system, both Arduino hardware and software, as well as the Sinatra mini web application.
Let’s get started!
Step 1: The Hardware
The DMD is the focal point of the gadget. I could have gone with a small LCD screen, but the main idea for this project was to produce something that can be seen and heard from a distance. For the visual part, I needed something big and bright, and this Freetronics display is exactly what I needed. Each panel contains an array of 16x32 LEDs, and you can stick several of these together to create much larger displays. This is something I’d like to do in the near future.
The DMD comes with an easy to use Arduino library. it communicates with the Arduino via high-speed SPI. I was able to get the library from the Freetronics Github page, then fire up the demo sketch and get it working within minutes of opening the box. I was surprised to see such a bright display using only power from the Arduino. If you want to temporarily blind your viewers, you can attach a dedicated power supply to this DMD. If this doesn’t get their attention, nothing will!
Physically, this display measures 320mm (W), 160mm (H) and 14mm (D).
The back panel contains the connectors for the external power, 5V with at least 4Amps capacity, the Arduino connector marked HUB1, and the connector for daisy-chaining additional displays on the opposite side. According to the documentation, you can daisy-chain up to four DMDs.
The DMD is controlled by an Arduino Uno. Freetronics provides a very convenient “DMDCON” connector that just snaps directly onto the correct SPI and data pins.
Other than the DMD, I used an Arduino Uno, an Ethernet Shield, a real-time clock breakout, a buzzer, and a DHT22. For all of these components, I have created lectures describing their operation in my Udemy course. (Shameless self-promotion: sign up to my email list at arduinosbs.com and receive a coupon that give you discounted access to all 55 lectures).
The real-time clock, a breakout based on the DS18072 clock IC, is an I2C device so it is connected to the Uno’s analog pins 1 and 2, which implement the I2C bus.
The buzzer is connected to digital pin 3, from where I control it using the tone() function.
The DHT22 sensor is connected to digital pin 2. Be careful to connect the 10KΩ pull-up resistor between the 5V line and the data line.
Step 2: The Arduino Sketch
The sketch is not large in terms of the line count, but it almost exhausts the Uno’s available flash memory thanks to all the included libraries. There is lots of room for memory optimisation, but since I am at the prototyping stage, that’s a project for another day. This code is available on Github.
Here is the sketch, with embedded comments (see PDF attachment).
The main responsibility of this sketch is to make the Arduino a consumer of a web service. The web service is a simple web site with two end-points, one for a human user to access via a web browser and submit a text string that they wish to display on the DMD, and another one where the Arduino will access in order to retrieve that text string.
Please download and read the attached PDF file, it contains embedded comments that describe its operation.
Step 3: Sinatra Takes the Stage!
There are many ways to create web sites and web services. From programming languages with web-supporting libraries, to full-featured frameworks, it can be confusing and hard to choose one for this job.
I have used and played with a fair number of web application technologies, and find that Sinatra is ideal for building web services and small web sites. In particular, when I build a web service to support an Arduino gadget, Sinatra is a really good choice.
What is Sinatra, and why is it such a good choice? I’m glad you asked!
Sinatra is a language for the rapid development of web applications. It is build on top of Ruby, a very popular and expressive general purpose scripting language. You may hear Sinatra being referred to as a “DSL”, a Domain Specific Language. The domain here is the Web. The keywords (words) and the syntax created for Sinatra is such that it makes it easy and quick for people to create web applications.
At a time where so-called “opinionated” frameworks for web app development like Ruby on Rails and Django are super popular, Sinatra captures the opposite end of the spectrum. While Ruby on Rails and Django require the programmer to follow a specific convention and way of doing things (which, in turn, implies a steep and long learning curve), Sinatra makes no such requirements.
Sinatra is conceptually much simpler than the Rails and Djangos of the world. You can get up and running with a web application that can interact with your Arduino within minutes.
I will demonstrate with an example. Here’s what a Sinatra minimal web app looks like (just read the following for now, don’t actually do this on your computer because you probably don’t have the prerequisites setup for this yet):
In a single file, let’s call it my_app.rb, add this text:
get '/' do
On the command line, start the app like this:
Your app will start, and you will see this text in the console:
peter@ubuntu-dev:~/arduino/sinatra_demo$ ruby my_app.rb
Puma 2.8.1 starting...
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:4567
== Sinatra/1.4.4 has taken the stage on 4567 for development with backup from Puma
The app is now ready to receive a client requests. Open a browser, point it to http://localhost:4567, and this is what you will see (see attached screenshot).
That’s four simple lines of code in a single file. In contrast, Rails would have required over a hundred files, generated simply to satisfy the framework’s requirements. Don't get me wrong, I love Rails, but really?...
So, Sinatra is simple, and quick to run. I will assume that you know nothing about Ruby, Sinatra, and application deployment to the Cloud, so in the next section I will take you step by step from zero to deployment of your Arduino web service to the Cloud.
Step 4: Setup Your Development Machine
Sinatra is based on the Ruby programming language. So, you need to install Ruby before you install Sinatra.
You will also need to install a key-value store server called Redis. Think of Redis as a database that stores data against a key. You use the key to retrieve the data, and it is optimised for speed rather than flexibility of the data structures that a traditional relational database is designed for. Home Alert stores its messages in Redis.
Step 5: Ruby on Mac or Linux
If you are using a Mac or Linux computer, I recommend you use RVM to install and manage your Ruby installation (RVM: Ruby Version Manager). The instructions for installing Ruby with RVM are in this page, or just copy and paste this command in your shell:
\curl -sSL https://get.rvm.io | bash -s stable --ruby
Sit, back, relax, and wait for the download, compilation, and installation of RVM and Ruby to complete.
Step 6: Ruby on Windows
If you are on Windows, I recommend following this guide on the Ruby Installer for Windows web site, and use the setup application.
Step 7: Check and Set Your Ruby
At the time of writing, the latest stable Ruby release is 2.1.1.p76. You can check the version that was installed with RVM by typing this:
Lot’s of information about RVM and Ruby will appear. In my case, this is the Ruby section:
patchlevel: "2014-02-24 revision 45161"
full_version: "ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-linux]"
I recommend that you also use Ruby 2.1.1, so if you see anything older than that, upgrade like this:
rvm install 2.1.1
This will install Ruby 2.1.1. The RVM project site contains a lot of information about RVM and how to manage your Ruby installation.
Step 8: Install Sinatra (all Platforms)
In Ruby, code is shared as packages called “gems”. The code that makes up Sinatra can be installed on your computer as a gem like this:
gem install sinatra
This line will fetch all code and documentation and install it on your computer.
Step 9: Redis on Mac or Linux
Setting up Redis on Mac or Linux is easy. The process is explained on the Redis web site. Open up the shell terminal, and type in these commands:
$ wget http://download.redis.io/releases/redis-2.8.7.tar...
$ tar xzf redis-2.8.7.tar.gz
$ cd redis-2.8.7
Run Redis by typing:
… and you’r done!
Step 10: Redis on Windows
Redis on Windows is only recommended for development, and you will need to compile it using the free Visual Studio Express development environment. It does require a bit of time to get it running, but it works well and is worth the effort. Follow the instructions on the project’s Github page. There, you will also find a link to the Visual Studio Express page.
Step 11: Create the Web Service Application
Let’s build the application and run it on your development machine. We will adjust the Arduino sketch to connect to this instance of the application while we test it. Once we are satisfied that everything is working well, we’ll deploy to the cloud and update the sketch to use the cloud instance.
Here is the Ruby code, all in a single file named "web.rb" (this code is available on Github).
Important: Download and read the attached PDF file, it contains detailed embedded comments (please do this before you continue!).
You can now try out your Home Alert system. In your sketch, change the WEBSITE and WEBPAGE constants to point to your development machine and port number for your development Sinatra server. In my case, I have a development machine on IP 172.16.115.136, and the development Sinatra server is listening to port 5000, so my sketch settings are:
#define HW_ID "123"
#define WEBSITE “172.16.115.136:5000”
#define WEBPAGE “/get_message/"
This IP address is accessible only for devices in my home network.
The HW_ID setting represents the “hardware ID”, that is, the ID to which the Arduino controlling the DMD will identify itself to the Sinatra application. It is a very basic kind of authentication. The web application will hand over a message to an Arduino asking for it based on the provided HW_ID. You can have multiple devices with the same HW_ID, in which case all devices will display the same message. If you want “privacy”, chose an ID with lots of random characters that other people will not be able to guess. Also beware, no communication is encrypted.
Now go ahead and startup your Sinatra app, type this (assuming you are in the Sinatra project folder):
… and you will see something like this (some details may vary, as long as this doesn’t crash, you’re ok):
10:42:18 web.1 | started with pid 49119
10:42:18 web.1 | Puma 2.8.1 starting...
10:42:18 web.1 | * Min threads: 0, max threads: 16
10:42:18 web.1 | * Environment: development
10:42:18 web.1 | * Listening on tcp://0.0.0.0:5000
Point your web browser to the location that the server is listening to, and you’ll see this (see second attachment).
Upload your sketch to the Arduino, make sure it is connected to your local network. If all goes well, the Arduino will poll your web service once every minute. Give it a message to show: In the HW code field, type in the same ID you set for the HW_ID constant in the sketch. Type anything in the “Your message” field, and check the “Buzz?” checkbox.
Submit, wait for a minute, and see your message appearing in the DMD!
Step 12: Deploy to the Cloud Using Heroku
Now that Home Alert is working in development, let’s get it working on the Cloud. There are countless options available for deploying web applications. Based on the scope and complexity of Home Alert, I decided that setting up my own virtual private server is not worth the effort. Instead, it is better to go for a service like Heroku, an application host. For my scale, Heroku’s free tier is more than enough. Even for the Redis component, I was able to choose a free plan from one of many Redis providers that work with Heroku.
Still, there is a bit of effort involved, which has to do with getting my application slightly modified so that it can comply with Heroku’s specifications. The details are here, but essentially you will need to add these files to your Sinatra project (all of the files that follow can be downloaded from my Github account):
* config.ru: It tells Heroku which file contains the application. Here’s the contents:
The first line points to web.rb, and the second line actually runs your application.
* Gemfile: it contains the Gems (ruby code packages) that are required by the application. Heroku will look inside this file to figure out what other code it needs to install so that your application works. Another way to look at Gemfile is that is contains a list of dependencies for your project. If any of these dependencies are not available, your application will not work. Here’s what’s inside the Gemfile for this app:
First, it sets the source repository of all Gem code to be rubygems.org. Next, it requires the Ruby version 2.1.1 is used to run the application. Then it lists the required Gems: Sinatra, Puma (a great Ruby web application server), and Redis.
* Procfile: it tells Heroku how to startup your server. There is only one line here:
web: rackup -s puma -p $PORT
This line says that “web” is the only kind of service required (you could have others, like “worker”, for background processing), and that to start the service Heroku must use the command that comes after the “:”.
You can simulate what Heroku is going to do by following this sequence on your development machine (only type the test before the arrow; what follows the arrow is only a description of the command):
$>gem install bundler —> installs Bundler, which knows how to handle the Gemfile.
$>bundle install —> Bundler processes Gemfile and installs dependencies.
$>rackup config.ru —> Rackup is a tool that can process the config.ru file. It normally comes with the later version of Ruby, if it doesn't’ install it like this: gem install rack.
The last step results in actually launching your application. You should see the exact same output as when you started it with ruby web.rb earlier. It is the same application running, just with the difference that the second method is how Heroku starts it.
We are almost ready to deploy this application to your Heroku account. If you haven’t got one yet, go ahead and create one now. Then, follow the quickstart guide to setup your account and your local development machine, and especially the Heroku Toolbelt.
The Heroku Toolbelt installs the Heroku command line client, Git (the open source source code management system), and Foreman (a Ruby tool that helps manage Procfile-based applications).
Once you completed the installation of the Heroku Toolbelt following the instructions on the Heroku web site, follow these steps to get your application deployed (everything is typed in the command line, inside the app’s directory):
$>heroku login —> Logon to Heroku via the command line
$>git init —> Initialise a Git repository for your application
$>git add . —> (notice the dot!) Add all files in the current directory to the Git repository
$>git commit -m “init" —> Commit these files into the repository, with a new message
$>heroku create —> Create a new app on Heroku. Heroku will give your app a random name, something like “blazing-galaxy-997". Note down the name, and the URL so you can access it via your web browser later. This URL will look like this: “http://blazing-galaxy-997.herokuapp.com/“. You will also need to copy the hostname (the “blazing-galaxy-997.herokuapp.com” part) of your new application into the WEBSITE constant of your Arduino sketch. Do this now so you don’t forget later.
$>heroku addons:add rediscloud —> Adds the free tier of the Rediscloud Redis service to your application. Configuration settings are automatically created and made available to your application.
$>git push heroku master —> Deploy your code to Heroku. This will automatically transfer the code, setup any dependencies on Heroku, and start the application. At the end of the process, you will see something like this: “http://blazing-galaxy-997.herokuapp.com deployed to Heroku”, which means that your application is now live on the public Cloud! Congratulations!
Go ahead, give it a spin!
Step 13: Putting It All Together
With your web application deployed, upload the updated sketch to the Arduino (remember that you updated the WEBSITE constant to point to your production instance of the web application).
Use your browser to access your app on Heroku. Just like in the introduction, type your hardware ID in the first text box, your message in the second, and check the check box to activate the buzzer.
Your message will appear on the DMD around a minute later if all goes well!
Step 14: Potential
There is so much more you can do with your Home Alert system...
Having a Heroku back end means that you can add a lot of logic that can add amazing functionality. For example, you can add the ability for the application to manage repeat notifications, acknowledgements, or control additional notification hardware like strobe lights etc. You could extend it into home automation territory and control lights and doors. You could add multiple DMDs to display either different messages in each one or a single message in a combined larger display. I am just scratching the surface of what is possible here!