Talk² is all about communication and adding Internet connectivity to your project can easily bring it to the next level! Despite the fact that you can find a couple of alternatives to it, we would like to present our prefered way.
On this post we’ll briefly check the common ways of connecting an Arduino to the Internet, evaluate the Pros and Cons. After we’ll present the Talk² approach to this problem, explaining concepts and queueing techniques to build a much more robust and flexible solution.
The popular options
After some research we easily concluded that the most popular way people are connecting their Arduino to the Internet is by using a direct Ethernet connection. Some cases using shields or expansion modules, others by simply relying on the build-in Ethernet capabilities of the board/MCU.
The other two methods we also find some details about are: the PC’s serial port and specialized software to build a gateway for the Arduino/MCU, which also can be using serial to wireless devices. The last method is using WiFi shields, that are basically the same as the Ethernet shield as they relay on the TCP/IP Stack being coded into the MCU.
The Ethernet/WiFi solution
This method relies on having your MCU talking TCP/IP plus any other protocol on top – which normally seems to be HTTP. Although this method works well for some scenarios, the TCP/IP stack is a big piece of code. It can be difficult to fit a decent TCP/IP stack in many MCUs and it might consume most of the memory available.
Having an Ethernet connection doesn’t means you have your project on the Internet. You always will need to publish it on the outside world. That’s normally achieved by mapping a TCP port from your router/firewall directly to your device. Having some kind of dynamic DNS might also be necessary as many ISPs don’t offer dedicated IPs to Cable/ADSL connections.
From our experience here some Pros and Cons of this method:
- Can be a straight-forward solution for sending commands to your MCU, or reading a status “page” if you have a simple project
- Don’t require a dedicated gateway to route messages to your MCU
- Low cost if running only a few devices
- TCP/IP stack can be complicated and too big to fit in the MCU
- Can be tricky to implement bi-directional communication in low-power applications
- Relies on the direct connection from the Internet client to the MCU
- Challenging to implement device-to-device communication
- Normally won’t implement any security/encryption of data over the Internet
- Commonly based on HTTP protocol, which adds unnecessary overhead to the communication (HTTP request and headers)
Please note that we’re not trying to say that the Ethernet shield is a bad option. We just would like to highlight that this method is limited to a very few applications and has significant drawbacks when trying to create a homogeneous network of devices.
Computer as a Gateway solution
Another option to connect your Arduino to the Internet, which is also popular on the Web, is by using a Computer as a gateway. This option relies on some kind of software which route the messages arriving in the computer to the serial port connected to your MCU.
There are a number of ready-to-use softwares on the Internet to do it, some even create a tiny Webserver on your computer. Again, you’ll need to open your ADSL Router to make this service visible on the Internet.
- Can be a simple approach for small projects
- Don’t require any special hardware
- You can add security/encryption on the gateway (SSL)
- Smaller Flash/RAM foot-print than the TCP/IP Stack
- You need one serial port for each device
- A bit of over-kill is you decide to use a real computer – RPI can be an alternative
- Can be challenging to implement Wireless/RF nodes running on batteries
Some project examples on the Internet try to use an Arduino Ethernet as the Internet Gateway, talking to other Arduinos via RF for example. Although we consider this a reasonable approach, the Arduino still very limited in terms of processing power and features to build a proper gateway device.
The Talk² Approach
If you have read some of our other posts you already know that Talk² is more about broader concepts than simple “copy-n-paste” code examples that work for a single case. Saying that it’s very likely we’ll start publishing some practical application examples in the near future, especially when our first products become available for the public. We believe that a bit of theory and “teaching to fish is a better”.
Now getting to what matters, Talk² in an attempt to overcome the drawbacks of the other Internet connectivity solutions and provide a more professional approach to this problem has put together the following model:
The solution might look much more complicated that the others, but in reality it’s only a more complete design. If you still scared maybe check the Pros and Cons below before stop reading this post, so you can decide if that might be a good solution for your projects.
- Small flash/RAM foot-print
- Simple to code
- Strong security over the Internet and RF
- Resilient to Internet connection failures, can work on-line or off-line and also re-synchronise data
- Message oriented
- Device-to-Device and Internet-to-Device done on the same way
- Support pull (pooling) and push, allowing low-power devices to communicate as well
- No need to punch roles on your Router/Firewall
- Requires a Gateway (normally a Raspberry PI)
- Additional Bus Hardware – Talk² is based on CAN Bus
This might be the most important component on all. Don’t worry if you are not a full-time developer or have never used a message queueing protocol before, it’s a very simple concept and very, very useful for exchanging messages.
First thing to know is that Talk² has decided to use AMQP as the preferred queueing protocol. One of the reasons is because of RabbitMQ, which is a great piece of software. To understand what RabbitMQ does or how AMQP protocol works, you need to know three basic concepts: Producer, Consumer and Queue.
Well imagine waking up in the morning and checking the e-mails you received during the night. Let’s say you got 3 messages. You might simple delete the first one because it was a Spam. You reply to the second e-mail and, finally, you go have a chat with your neighbour as the third message told you a parcel in your name has been left there.
You don’t need to be a genius to understand that your e-mail’s Inbox is the Queue, the persons and systems sending the mails are the Producers and you is the Consumer reading the messages. RabbitMQ manages those three things, routing messages that arrive to specific queues and providing ways for consumers to read it.
Now that you’re an expert in AMQP, you might be asking yourself, why that’s so important?! Here’s the answer: Flexibility. Having queues between components allows modular development, so you don’t need to worry about everything as a single piece of code. You can even simulate components that are not ready yet by simple injecting messages directly on a queue.
We’ll get back to this topic later and also explain why there are two queues on the diagram above. Just have in mind that queues are your friends.
We like to call it nodes, and for Talk², a node can be anything capable of sending or receiving messages on the Bus.
Nodes normally can be of two kinds, sensors or actuators. Many times a node operate on both modes. The classical examples are a temperature sensor and a relay controller.
Talk² is a Bus communication model, more specifically CAN Bus and it offers ways to create virtual wireless Bus extensions as well. Messages published on a Bus should be available to all nodes*.
*The exception here is for wireless low-power nodes or other any device which sleeps for the most of the time. More to that later.
This is the Internet access itself, your ADSL/Cable modem or any other form you have to connect to the Internet.
For the Talk² solutions there’s no need to open ports on your Internet Router. The messages can be shovelled to and from another RabbitMQ server in the Internet. You could have a private server in the a Cloud provider or use services like CloudAMQP for example.
Similar to the “Computer as Gateway” solution above, Talk² solution relies on a Gateway to translate messages from the Bus to the Queue and vice-versa. We call this device “Bridge”. Without the Bridge, there would be too much complexity to be implemented on each single node. Saying that, the Talk² solution can still partially work if you Bridge goes down. That’s because messages from one node to another will rely on the Bus itself and not a single point of failure – CAN Bus doesn’t require a master node.
Instead of a full size computer, we’ve decided to use a Raspberry PI as our Bridge. The hardware can be easily to integrated with CAN Bus, is very fast and are not expensive. Before anyone asks, for us there’s no such thing as RPI being better than Arduino or the opposite, they are two different things so we try to get the best of both.
Those are the persons or applications, producing and consuming the messages. In other words, receiving data and sending remote commands.
Another great thing about using RabbitMQ, is that it offers not only the native AMQP protocol connector, but also has a Web console and REST API. Without much effort you can send messages from your Mobile (or any other Browser) with a simple HTTP Request, using SSL and authentication for security.
How It All Works
Let’s explain how a message gets routed from a node, an Arduino, to a RabbitMQ queue on the Internet and vice-versa.
Our first message is a Temperature reading, which happens to be published every 5 minutes by our Arduino node on the CAN Bus:
- Arduino Node01 puts a message containing the temperature reading on the Bus;
- All Nodes on the same Bus receive the message, many might simply ignore it;
- A small service running on the Bridge reads all messages in the Bus and passes it to another thread, which Publishes it into a RabbitMQ queue named “From_Bus”;
- RabbitMQ, running on the Bridge, accepts the message and pushes it to the Internet using the “Shovel RabbitMQ Plug-in”. The message is basically routed from the local queue “From_Bus” to the remote queue “MyInbox”;
- Finally you might have an Application running on Google Cloud, which will read messages from “MyInbox” and process according to it’s content. Your application might simply save the Temperature Readings inside a Database for later use.
As you can see from the flow above, after the Bridge reads the message we basically rely on RabbitMQ to deliver it to the Internet. The application on the other side don’t need to know anything about the Arduino Node itself or code running there, it just need to know how to interpret the message.
This design also relies on RabbitMQ for all data transmission over the Internet, taking advantage of built-in features like SSL, Authentication and “Shovel Plug-in”. One interesting thing about the “Shovel Plug-in” is that it can be started on any side, to push or pull messages. In this case we keep all Shovel configuration at our local Bridge, so the connections are started from our local network to the Internet, not requiring any special firewall configuration.
Now lets suppose the Internet is down when the Node01 sends the message. No problem, the local RabbitMQ instance will hold the messages until the Shovel link is re-established and no messages are lost.
On the other way around, let’s send a command (or message) from the Internet to the Node99. Imagine that we need to turn a LED on:
- First thing is to publish (or Produce) a message and deliver it to our RabbitMQ running on the Internet. In this case to the MyOutbox queue. The message can be published by many ways, including a simple HTTP(S) request to the RabbitMQ REST API;
- Now the Shovel Plug-in running on our local Bridge will immediately detect the new message and download it, routing to a local queue named “To_Bus”;
- Another very simple service is always watching the “To_Bus” queue and every message published there will be consumed by this process, which puts it over the Bus, making available to all nodes again;
- The Node99 is the only one interested on the message, and after interpreting its content, “turns the LED on”.
Note that the solution is made of tiny, but very efficient pieces of code. It’s easy to see how to simulate processes can be done by “injecting” messages directly in queues. You might decide to configure RabbitMQ to duplicate all messages arriving in “From_Bus” into another queue: “From_Bus_Clone”, so you can check the content manually or create another small application to produce logs, reports, anything.
Having queues in place makes easier to escalate the solution horizontally. Jumping from one or two Bridges sending 100 messages/second from your home to thousands of Bridges, all over the country, sending over 100K messages/seconds to a RabbitMQ cluster on the Cloud.
You might be asking how the Node99 knew the message was addressed to it. If you remember, the Talk² protocol is based on the CAN Bus frame. In that case all message will have a couple of fields, including the message ID. This field is a good place to have some details about the message, for example, reserve the last two bytes for source and destination. The other bits can be used to identify the type of message, if it’s a sensor reading, a command or an event.
Using this method, a node simply needs to ready the message ID and check the destination address, if doesn’t match with its own address simply discard everything.
Talk² hasn’t published a higher protocol yet, and probably won’t do it very soon. That’s because by doing that might restrict the projects it could be used. Soon we’ll publish code examples, including details how we’re using the bytes on each message and that might fit your application as well.
Talking with sleepy nodes
If you’re planning to have low-power nodes, is very likely they will be powered by battery and probably have wireless connection. Those nodes are very likely to sleep for the most of the time but you still can use a very similar process to send the messages to them.
The difference on this situation is that messages addressed to those nodes cannot be published on the Bus immediately. You need to have a dedicated queue and the node will need to implement a pooling command from time to time. Getting back to the example above of sending a command to turn an LED on, the flow might need to change a bit:
- First thing we need to publish (or Produce) a message and deliver it to our RabbitMQ running on the Internet, to the MyOutbox queue;
- Now the Shovel Plug-in running on our Bridge will immediately detect a new message there and will download it, routing to a local queue. As we know that the message is supposed to reach sleepy node, there is no much benefit in sending it to the Bus immediately. Instead we re-route the message to a queue named, let’s say “SleepyNode01” and leave it there;
- The sleepy node will have an internal process to ask the Bus if there’s any message addressed to it and wait couple of milliseconds for a reply before go back to sleep;
- The Bridge will receive the pooling query, and immediately after discovering there’s a message for the SleepyNode01, it’ll delivery it to the Bus;
The SleepyNode01 is the only one interested on this message, and after interpreting the content, it “turns blinks the LED”.
Using a similar process you could even perform a remote firmware upgrade of a sleepy node. Just program your node to stay awake for a bit longer according to the type of message and send the new firmware as multiple binary messages.
Talk² hardware will always allow remote firmware upgrade, independent if it’s a wired or wireless link. The boards will have external Flash memory to store new firmware and code sample will be provided.
It’s easy to see how to take advantages of Queues. If you’re interested in trying this out, download and have a play with RabbitMQ.
Also have a look on the CloudAMQP services, they offer a free tier which is pretty good. If you wish to go a bit further you can rent a Micro VM at Google Cloud or AWS for about $5/month, which is a great deal to have your own server running on a dedicated IP Address and fully customisable.
Please feel free to send your comment or questions. We’ll be happy to hear more about your project, ideas and challenges.