Calling into an Arduino is somewhat more complicated than generating a call because the Arduino doesn’t know exactly when a call is going to be received. Therefore it must either act as a server and wait for connections, or it must maintain a long-term client connection to an external server. Neither of these are possible with http, so we must also write code to take care of the server connections.
A good argument could be made that the best choice is to build a simple server in the Arduino. The Arduino Ethernet Shield can accept up to 4 connections, which should be enough for many applications. However, the down side to this strategy is that the Arduino must have a public IP address. You can get a public IP address on ITP’s floor, but as soon as you take your project to any other venue your chances of getting a public IP address are considerably less. If you’re setting up your Arduino server behind a router then you’ll need to set up port forwarding so that your Arduino gets the packets it’s expecting. Another downside is that you are adding a lot of complexity to your arduino code. In my opinion, the arduino is not the place for server logic.
There may be instances where an Arduino server is a good option, so here’s some sample code for an Arduino server to get you started.
here’s the flow for the server option:
Call -> Asterisk -> AGI script -> internet -> Arduino Server -> Arduino output
The other option is to use the Arduino in “client” mode. In order for this to work, you’ll need to deploy a simple server application that acts as a bridge between Asterisk and the Arduino. As both sides connect, the bridge will relay any messages from one side to the other. The benefit here is that all Arduino has to do is make an initial socket connection and the remote server will take care of server logic. You won’t need to worry about port forwarding and it should work anywhere. I’ve included a simple server that will simply forward the byte value for all button presses. It’s written in Node.js and you should feel free to elaborate on it if you like.
Call -> Asterisk -> AGI script -> local server <-> internet <-> Arduino Client -> Arduino output
Example: The Phone Controlled Carduino
For this example I hacked a cheap remote control car so that I can control the car with a phone’s keypad.
Here’s the car I bought. I’m sure the process would be similar with any cheap RC car.
First of all, I didn’t touch the actual car, and instead decided to simply hack the RC controller. When I opened up the controller I was surprised to see that the interaction was very simple. forward, reverse, left, and right were simply switches. All I needed to do was replace the action of hitting a button with the ardunio’s ability to bring a pin high or low.
Here’s how I connected everything to the arduino. I’m using pins 6,7,8, and 9 to control foward, back, left, and right. I’m using the TIP120 transistor as a switch on the 4.4 volts that the controller uses. Tom Igoe has excellent notes on using the TIP120 to handle different voltages.
The Arduino code will connect to a remote server through the Ethernet Shield and will wait for input from that server. On the other side of the Server is Asterisk, which will send button presses from a phone call into the server with a Ruby AGI script
When the Arduino receives a “2” from the Ethernet Shield it will send the “6” pin high, which will close the circuit on the “forward” switch on the RC controller. An “8” will do the same for the “reverse” switch. A “4” will turn the wheels left, and “6” will turn the wheels right. “5” will turn the wheels straight, and “0” will bring everything to a stop.
Asterisk Dialplan context that launches the AGI script:
[ck987_to_arduino] exten => 1,1,Answer(); exten => 1,n,AGI(/home/ck987/asterisk_agi/tinyphone_simple.rb); exten => 1,n,Hangup();