Elixir and the Internet of Things

With the Internet of Things being projected to grow at a massive pace, developers are creating all kinds of new frameworks and services that are meant to help teams build successful connected devices. Many of the tools, languages, and frameworks that were used to build the internet that we know today are not particularly well suited for building applications that interact with these devices. Solutions are often created using a mixture of many different languages and frameworks since very few can run well in embedded environments like the Raspberry Pi.

Erlang and Elixir, however, are particularly well suited for creating connected devices and the backends that support them. The needs of the device and the backend can be very different, but Elixir brings a lot of value to both of these problem spaces.

Elixir on the Device

Erlang has been powering applications since the mid 1980s when processors were pushing 16MHz. While today's version is significantly different than this, Elixir is still an ideal language for running on embedded hardware because it is a compiled language (which perform better at runtime than interpreted languages like Python), it has small memory footprint, and the BEAM core is bulletproof. Some folks in the embedded programming space caught onto this and created the Nerves Project, a framework that makes it easy to build Elixir software for embedded applications. A Nerves project looks like a normal **mix** application, but among many other helpers it adds two key commands: **mix firmware** and **mix firmware.burn**.

$ MIX_TARGET=rpi3 mix firmware.burn
Mix environment
  MIX_TARGET:   rpi3
  MIX_ENV:      dev

Use 3.69 GiB memory card found at /dev/rdisk2? [Yn] Y
|==================================================| 100% (27.51 / 27.51) MB
Elapsed time: 6.578s

These commands use Buildroot and a cross-compilation toolchain to write your program into an SD card that will boot a very lightweight Linux and then run your program. You can connect to a device running Nerves and interact with your hardware through IEx. There are even libraries that let you update your application over SSH or HTTP out of the box.

Elixir on the Backend

Interacting with devices in the field is often more difficult than interacting with, say, a REST API. Unlike with HTTP, embedded processors often prefer to keep a connection open and stream packets over TCP using MQTT or a custom protocol since it is more efficient than constantly opening a connection per transaction. Elixir is perfect for this with its ability to maintain a huge number of concurrent connections. JSON manipulation on smaller devices can also be a major difficulty, so they will often pack their data into a binary form and send that over the wire. Elixir provides an incredibly descriptive syntax for reading, writing, and manipulating binary data coming in this kind of format.

defmodule I2cMessage do
  @moduledoc """
  I2C messages often use 7 bit addressing with 1 bit to denote the direction.
  The rest of the message is the payload. This module defines an Elixir struct
  and gives functions that go to and from the binary representation.

  defstruct [:address, :direction, :payload]

  @doc """
  iex> I2cMessage.parse(<<0xFF, ?t, ?e, ?s, ?t>>)
  %I2cMessage{address: 0x7F, direction: 1, payload: "test"}
  def parse(<< address :: 7, direction :: 1, payload :: binary >>) do
    %I2cMessage{address: address, direction: direction, payload: payload}

  @doc """
  iex> I2cMessage.build(%I2cMessage{address: 0x7F, direction: 1, payload: "test"})
  <<0xFF, ?t, ?e, ?s, ?t>>
  def build(%I2cMessage{address: address, direction: direction, payload: payload}) do
    << address :: 7, direction :: 1, payload :: binary >>

Finally, OTP and umbrella applications make it easy to tie all of the parts of these applications together.

In conclusion, I believe that Elixir will play a big role in the connected device ecosystem moving forward. I am excited that it is bringing fresh ideas and tooling to an area that has not seen the innovation. If you are familiar with Elixir and have been interested in trying out an embedded project, I hope that you will give Elixir and Nerves a shot.