Bits for hackers.

Tinkering With the Internet of Things

I’ve always had a huge passion for things that connect our physical world to the online world. I’ve always tried to tinker with ways to make my lights turn on at home using my computer and I love products such as Nest, SmartThings and the Belkin WeMo. It was only just recently that I learned that this connection of our physical world to the digital world had a name - the Internet of Things!

According to Gartner, there will be nearly 26 billion devices on the Internet of Things by 2020. ABI Research estimates that more than 30 billion devices will be wirelessly connected to the Internet of Things (Internet of Everything) by 2020. So, I figured that this would be a good area to dig a little deeper on and tinker with.

My Experimentation with the Internet of Things

For my first foray into building an app that connects the physical world to the digital world, I wanted to build something simple - I decided to build a product that triggered an LED light to blink every time I received a new tweet.

For this, I needed an interface to connect to an LED light - I used an Arduino Uno microcontroller to do so.

Setting up the Arduino Uno

Arduino is an open-source electronics platform based on easy-to-use hardware and software. It’s intended for anyone making interactive projects. Arduino senses the environment by receiving inputs from many sensors, and affects its surroundings by controlling lights, motors, and other actuators. You can tell your Arduino what to do by writing code in the Arduino programming language, which apparently resembles Java.

Phase 1: Creating the Circuit for the LED light

For this phase, I built a very simple circuit. I connected an LED light with the anode in pin 13 (a pin which has an electrical current going through it, powered by the USB connection to the computer) and the cathode in the ground (to be a full circuit, you need a place for the electricity to go - the ground).

Phase 2: Sending Electrical Impulses Via Arduino Language

The next step was to then have this circuit board communicate with my computer so that I could have the computer generate on and off signals. This was done in the Arduino language: For us Rubyists used to human-readable code, this code can be a little bit daunting. Let’s break it down step by step:

  1. The first item, int ledPin = 13, is just setting a new variable called ledPin - we set it equal to the pin number where we plugged in the anode (positive end) of the light.
  2. The second part is one that is crucial to every Arduino based app - the setup. Here, we set up the baud rate to 9600. The baud rate is essentially the number of signals that will be sent per second. NOTE: when we get to building the ruby portion of this, it is crucial that the baud rates match up. In this setup section, we also define that pin 13 will be outputting a signal rather than receiving a signal. Finally, we set the initial state of the light to be off, or LOW.
  3. Next, we define the method for blinking the light. We set up a loop that runs 10 times (incrementing the variable i each time) and turns the light on and off every 1/10 of a second (based on the delays that we coded in).
  4. Next, we set up a method that defines WHEN the blinking begins. We set this up so that when it receives the string “b” on the serial port, it will trigger the blink_led method to fire off.
  5. Finally, the last method just checks to see if there is any signal at coming from the serial port. If there is, then to fire off the got_char method
Phase 3: Finally, time for some Ruby!

Now that we have the physical circuit created and we have the Arduino circuit ready to listen to any signal from our serial port and fire off blinking LEDs as a result, it is now time to build in the majority of our application logic.

First of all we have to connect our application to the serial port. The way we do this is by first installing and requiring the serialport gem. Then we instantiate the new serialport object:

1
2
3
4
5
6
7
8
9
require 'serialport'

baud_rate = 9600
port_file = "/dev/tty.usbmodem1411"
data_bits = 8
stop_bits = 1
parity = SerialPort::NONE

port = SerialPort.new(port_file, baud_rate, data_bits, stop_bits, parity)

As you can see here, the baud rate that we’ve set up matches up with the baud rate in the Arduino - this is what allows the two programs to communicate with one another. Next, we set up our port - this will be different for everyone - make sure that you find the USB serial port that the Arduino microcontroller is plugged into. This is all you need to set up the connection with Arduino!

Next, I worked on building in the Twitter API. Lucky, there’s a nice, handy Ruby Gem to make our lives easier. Using this gem, I created a new instance of an authenticated user based on the Twitter Developer consumer access keys and access tokens (I have removed my own credentials for security purposes).

1
2
3
4
5
6
7
8
require 'twitter'

client = Twitter::REST::Client.new do |config|
  config.consumer_key        = "YOUR_CONSUMER_KEY"
  config.consumer_secret     = "YOUR_CONSUMER_SECRET"
  config.access_token        = "YOUR_ACCESS_TOKEN"
  config.access_token_secret = "YOUR_ACCESS_SECRET"
end

Now that we have an instance of a client, there are a TON of methods that we can call on this client. The ones that we are interested in provide us with the latest activity on our timeline and on our mentions.

1
2
last_tweet = client.home_timeline.first
last_mention = client.mentions.first

Once we have pulled these values, we are now ready to write our last bit of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
wait_time = 10

loop do

  check_tweet = client.home_timeline.first
  check_mention = client.mentions.first

  if last_tweet != check_tweet || last_mention != check_mention
    port.write "b"
  end

  last_tweet = check_tweet
  last_mention = check_mention

  sleep wait_time
end

Essentially, what this does is it goes into a loop forever where it checks the latest activity on the timeline and on the mentions again; it compares this with the initial value to see if it changed. If there was a change (i.e., there was a new post on your timeline), it sends the string “b” to the port (remember: this was the string that was the trigger for the LED lights).

One thing to note is that there is a wait_time incorporated between every iteration of the loop. One important thing to note is that the Twitter API (as well as most other APIs, presumably) limit the number of times you can send them a GET request to 180 calls every 15 minutes. The loop above is sending 2 GET requests every time it runs through the iteration, and since we are iterating every 10 seconds, we are sending 12 get requests every minute. Without spacing out the loop, you would get the following error very quickly and be locked out for 15 minutes. So, the entire Ruby code looked like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
require 'serialport'
require 'twitter'

client = Twitter::REST::Client.new do |config|
  config.consumer_key        = "YOUR_CONSUMER_KEY"
  config.consumer_secret     = "YOUR_CONSUMER_SECRET"
  config.access_token        = "YOUR_ACCESS_TOKEN"
  config.access_token_secret = "YOUR_ACCESS_SECRET"
end

last_tweet = client.home_timeline.first
last_mention = client.mentions.first

baud_rate = 9600
port_file = "/dev/tty.usbmodem1411"
data_bits = 8
stop_bits = 1
parity = SerialPort::NONE

port = SerialPort.new(port_file, baud_rate, data_bits, stop_bits, parity)

wait_time = 10

loop do

  check_tweet = client.home_timeline.first
  check_mention = client.mentions.first

  if last_tweet != check_tweet || last_mention != check_mention
    port.write "b"
  end

  last_tweet = check_tweet
  last_mention = check_mention

  sleep wait_time
end

Just a few final thoughts - though this application may seem somewhat trivial, the implications are enormous and exciting. Once you have the connection working between the logic that you create via code and an action with a physical object, the possibilities of what you can do are endless. It is not very hard to start connecting things such as motors, sensors, and buttons to the Arduino, and, with a little practice, it isn’t hard to pull in any API into your Ruby code.