World Domination Using Arduinos and Websockets

Arduino Websocket Client Arduino Pusher Client Pusher – Real Time Push Notifications Follow Me On Twitter: @kevinrohling

If you don’t have your very own Arduino yet you should get one. What exactly are you waiting for? Arduinos are tons of fun, especially once you hook up some servos and start driving them around. Add a few pieces of military grade weaponry and you have your very own deathbot!

One of the first things you have to figure out once you’ve decided to personally catalyze the robot apocalypse is how to remotely control your robots, i.e. tell them when to turn left, turn right, stop, and of course… fire rocket launchers. There’s a number of ways you could do this. One of the more common I’ve seen is to open up a server port on your Arduino, connect to it and send it messages directly. The problem I ran into doing this was two fold: 1) I have to know the IP address of the Arduino on my network to make the connection and 2) I have to be on the same network as the Arduino. None of these things are very convenient and IP addresses and networks can change.

The solution I came up with was to use Pusher, a real-time push notification service that runs over WebSockets. Since the native Arduino libraries come with support for TCP connections, making this work involved writing a WebSocket Client library, as one does not appear to have previously existed, and building a Pusher client on top of that. Because the Arduino is connected to a Pusher Channel I don’t have to know anything about the actual device to control it, I just send messages to the Channel. My mechanized Arduinos of destruction are free to roam around, switching networks and destroying civilization, meanwhile I can still control them with my iPad from a hammock in the Bahamas.

Building the WebSocket Client

WebSockets are an interesting hybrid between HTTP and raw TCP connections. They start life very much like a normal HTTP GET request. In the request the client sends a bit information asking for an “upgraded” connection. Once the server sees this, if WebSockets are supported it sends a response back with a status code of 101 indicating that the connection was successfully upgraded. Then, and here’s where things diverge from HTTP, nobody closes the connection. Both the client and the server remain connected to each other. Here’s what this looks like at the socket level:

Client Requests a WebSocket Connection

GET /app/yourpusherapikey?client=js&version=1.9.0 HTTP/1.1 Upgrade: WebSocket Connection: Upgrade Host: ws.pusherapp.com:80 Origin: ArduinoWebSocketClient

Server responds indicating that the upgrade was successful

HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: WebSocket Connection: Upgrade WebSocket-Origin: ArduinoWebSocketClient WebSocket-Location: ws://ws.pusherapp.com:80/app/yourpusherapikey?client=js&version=1.9.0 Connected

Now that they’re connected both the client and the server can send each other messages any time they want using a process called Data Framing. Data Framing is a protocol for indicating the start and end of discrete messages on the socket. The Arduino Websocket Client Library currently only supports Text Frames, which use a 0x00 byte to indicate the start of a message, a 0xFF byte to indicate the end, and UTF-8 data in between. The WebSocket Specification also allows for Binary Frames, which use a length prefix followed by binary data. Here’s what the Arduino code looks like for sending a WebSocket message:

void WebSocketClient::send (String data) { _client.print((char )0 ); _client.print(data); _client.print((char )255 ); }

Building the Pusher Client As I mentioned before Pusher is a real-time push notification service that operates over WebSockets. Like any WebSocket implementation they use Data Framing for passing messages back and forth but they’ve built their own messaging protocol on top of Data Framing. Each message sent to or received from Pusher is formatted as JSON. This is good for the Arduino because JSON is light weight and also easy to parse. Once the Arduino WebSocket Client was built developing the Arduino Pusher Client was a matter of implementing support for sending/receiving the right messages.

Sending a message is called “Triggering An Event”:

void PusherClient::triggerEvent(String eventName, String eventData) { _client.send("{\"event\": \"" + eventName + "\", \"data\": " + eventData + " }"); }

Receiving a message from Pusher:

void PusherClient::dataArrived(WebSocketClient client, String data) { String eventNameStart = "event" ; String eventName = parseMessageMember("event" , data); if (_bindAllDelegate != NULL ) { _bindAllDelegate(data); } EventDelegate delegate = _bindMap.getValueOf(eventName); if (delegate != NULL ) { delegate(data); } }

Controlling our servos of destruction in response to events received from Pusher:

PusherClient client("your-api-key-here"); //Setup delegates for the Pusher Events client.bind("forward", moveForward); client.bind("backward", moveBackward); client.bind("turn_left", turnLeft); client.bind("turn_right", turnRight); client.bind("stop", stopMoving); //Subsribe to our Pusher Channel client.subscribe("robot_channel"); void moveForward(String data) { leftServo.write(0); rightServo.write(180); } void moveBackward(String data) { leftServo.write(180); rightServo.write(0); } void turnLeft(String data) { leftServo.write(0); rightServo.write(0); } void turnRight(String data) { leftServo.write(180); rightServo.write(180); } void stopMoving(String data) { leftServo.write(95); rightServo.write(95); }

All Wired Up

We’ve now solved what is likely the most challenging part of developing your Arduino army.

Pusher messages being received:





Tremble in fear of the Pusher Powered Arduino-Bot:





