Getting started with Arduino Yun and Autobahn

, Tobias Oberstein

Real-time charting in HTML5 of sensor values from Arduino Yun over WebSocket with Autobahn.

Introduction

The Arduino Yun is a small embedded computer which can be used as a flexible platform for all kinds of hardware projects:

Arduino Yun
Arduino Yun

The Yun actually is 2 computers in one:

  • a tiny 8-Bit AVR MCU (ATmega32u4 with 32kB Flash and 2.5kB RAM running at 16MHz)
  • a small 32-Bit MIPS CPU (Atheros AR9331 with 16MB Flash and 64MB RAM running at 400MHz)

The MCU runs in hard real-time: you can use it to e.g. directly control servo motors or interface to sensors. The CPU on the other hand is powered by an embedded Linux (Linino) that does not run in hard real-time, but is capable of doing full flavored TCP/IP networking over Ethernet and Wifi. The MCU and the CPU are connected via a serial interface.

Now, while the Arduino Yun (like all Arduinos) already allows you to create awesome hardware oriented projects, wouldn't it be great if you could connect your Arduino Yun to other devices, browsers or mobile apps, communicating in (soft) real-time over the Web?

Enter Autobahn, an open-source (soft) real-time communication framework for Web, Mobile and the Internet of Things:

Autobahn WebSocket

The Autobahn project provides open-source implementations of the WebSocket and WAMP protocols. WebSocket allows bidirectional real-time messaging on the Web and WAMP adds asynchronous Remote Procedure Calls and Publish & Subscribe on top of WebSocket.

Here is an example of what you can do with Arduino Yun and Autobahn:

  • stream sensor readings in real-time from the Arduino Yun via WebSocket to HTML5 browsers on desktop and mobile
  • control LEDs directly from your browser (again in real-time with very small latency)

Arduino Yun Real-time Charting over WebSocket with Autobahn

The demo shows a shield on the Yun with 2 potis, 3 LEDs and 2 buttons, which are controlled from a simple sketch running on the Arduino. The sketch communicates over serial with Autobahn running on the Linux side of the Yun. And Autobahn in turn runs as a bridge that shuffles data from/to serial and to WebSocket/WAMP clients (here, Chrome running on desktop and on Nexus 4) connecting to Autobahn over Wifi.

What we cover

We show how to do a project like the above step-by-step. Everything. In detail.

This is the first part of a series of blog posts which will get you up and running with Arduino Yun and Autobahn. Further posts will cover how to use Crossbar.io, an open-source multi-protocol application router that builds on Autobahn and allows to create sophisticated distributed systems and applications.

Contents:

  • System recovery
  • Network configuration
  • Software installation
  • Running the demo

What you need

To follow this tutorial you'll need

  • an Arduino Yun
  • a micro SD card (at least 128MB, I use a 1GB card for 5 Euros)
  • 2 Potis and 1 LED wired to the Yun

System Recovery

Should anything go wrong with your experiments here, don't worry - the Yun includes mechanisms to:

  • reset Wifi network configuration to factory default
  • restore Linux system image to factory default

The relevant button to perform both these functions is called "Wifi Reset button" in the Yun documentation and is located here:

Arduino Yun
Arduino Wifi-Reset (and Linux-Restore) Button
  1. Pressing the Wifi Reset button for >5s (but less than 30s) and then releasing will reset the Wifi configuration to factory default

  2. Pressing the Wifi Reset button for >30s and then releasing will restore the Linux system image to factory default

Both functions will also immediately reboot the Yun.

Network Configuration

The Yun has two network interfaces:

  • Ethernet (100Mb)
  • Wifi (bgn)

where each network interface has it's own MAC address.

Wifi

When the Arduino Yun is first powered on, the Wifi will be starting in AP-Mode ("Access Point Mode") and the Yun creates a new wireless network on the IP range

192.168.240.0/24

When you scan for Wifi networks, you should see a new network with a SSID as

Arduino Yun-XXXXXXXXXXXX

where XXXXXXXXXXXX is the MAC address of the Yun's Wifi interface:

Arduino Yun
Arduino Yun Wifi Network in AP Mode

This is the factory default, and when you reset the Wifi configuration, it will be the recovered again.

Note: The ethernet interface has a different MAC address - see below.

You can access the Web configuration interface of your Yun by connecting e.g. your notebook to the above Wifi network and then open the following URL in your browser

http://192.168.240.1

The default administrator password is arduino. You might want to change that (which you can do from the Web configuration interface).

Ethernet

The ethernet interface on the Yun is configured by default to get an IP address via DHCP (as is the Wifi interface in client mode) from a DHCP server on your network (such as your home router).

When you plug in the ethernet, the Yun ethernet interface should get assigned an IP automatically which you can verify from the Web interface:

Arduino Yun network interface status
Arduino Yun network interface status

Wifi Client Mode

When your Yun is connected via Ethernet to your network, the Yun will be able to connect to the public Internet via the default router on your network (your home router).

However, if you plan to have you Yun connecting to the Internet without an ethernet cable connected, you will need to reconfigure the Yun's Wifi to run in Client Mode and have the Yun connect to your router via Wifi as a client, so it can call out to the Internet.

Arduino Yun Wifi Client Mode
Arduino Yun Wifi Client Mode

After reconfiguration, the Yun will reboot, and you now should see both network interfaces on your main LAN and with IP addresses assigned from your router:

Both Yun network interfaces on LAN
Both Yun network interfaces on LAN

Doing the above, the Yun will no longer function as a Wifi access point to which others Wifi clients could connect. As long as the Yuns IP is known to other peers on your network, those peers will however still be able to connect on the TCP/IP level to anything running as a server on your Yun.

Static DHCP

When your Yun gets IP addresses for its ethernet and Wifi interfaces, your router will usually select free unassigned IP addresses randomly (from its IP range) - but these IP addresses can change from time to time (or across reboots of your router).

Some home routers or advanced router OSs such as OpenWRT and DD-WRT allow to configured DHCP to assign IP addresses to certain devices statically (called "static DHCP"). That means the device will always get the same IP address.

Having you Yun get static IPs via DHCP is useful, since e.g. to login from outside into your Yun via SSH will always work with the same IP.

Here is how static DHCP configuration looks on DD-WRT:

Both Yun network interfaces on LAN
Configuration of static DHCP for both Yun interfaces

And here is how the status page for LAN IPs looks on DD-WRT:

Both Yun network interfaces on LAN
Network status of both Yun interfaces (with assigned IP addresses)

SSH

Now that you have networking running for your Yun (either ethernet, Wifi or both), the next thing is to SSH into your Yun. This will allow you to do further software setup and advanced system configuration from a root shell.

Here is how that looks:

$ ssh -l root 192.168.1.150
The authenticity of host '192.168.1.150 (192.168.1.150)' can't be established.
RSA key fingerprint is f9:e0:1e:bd:bb:f9:e1:33:5b:c7:5d:75:da:2c:20:b1.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.150' (RSA) to the list of known hosts.
root@192.168.1.150's password:


BusyBox v1.19.4 (2013-08-07 16:16:02 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

      ___                   ___                       ___           ___
     /\__\      ___        /\__\          ___        /\__\         /\  \
    /:/  /     /\  \      /::|  |        /\  \      /::|  |       /::\  \
   /:/  /      \:\  \    /:|:|  |        \:\  \    /:|:|  |      /:/\:\  \
  /:/  /       /::\__\  /:/|:|  |__      /::\__\  /:/|:|  |__   /:/  \:\  \
 /:/__/     __/:/\/__/ /:/ |:| /\__\  __/:/\/__/ /:/ |:| /\__\ /:/__/ \:\__\
 \:\  \    /\/:/  /    \/__|:|/:/  / /\/:/  /    \/__|:|/:/  / \:\  \ /:/  /
  \:\  \   \::/__/         |:/:/  /  \::/__/         |:/:/  /   \:\  /:/  /
   \:\  \   \:\__\         |::/  /    \:\__\         |::/  /     \:\/:/  /
    \:\__\   \/__/         /:/  /      \/__/         /:/  /       \::/  /
     \/__/                 \/__/                     \/__/         \/__/

            _______                     ________        __
           |       |.-----.-----.-----.|  |  |  |.----.|  |_
           |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
           |_______||   __|_____|__|__||________||__|  |____|
                    |__| W I R E L E S S   F R E E D O M

root@Arduino:~#

I can't give an introduction to SSH here, but personally, on Windows, I use both Putty and the OpenSSH client that comes integrated with Git for Windows (and OpenSSH on Unix-like systems where it is most often installed by default already).

Public Key Authentication

Now, retyping your password each time you log in gets old fast. Public key based authentication for SSH allows you to do password-less, but nevertheless secure logins.

This isn't the place to give an introduction to SSH and public key authentication, however you should have little problems finding tutorials and information on the net. I will only cover stuff that is "unusual" on the Yun compared to a commonly seen Unix.

The Linino/OpenWRT Linux on the Yun does use Dropbear for SSH support (both client and server) - this is a different software package from usual Linux distributions and Unix systems (which is OpenSSHd).

One difference is that to enable public key based authentication for root, the authorized public keys need to be added to the following file (and not the usual /root/.ssh/authorized_keys):

vi /etc/dropbear/authorized_keys
chmod 0600 /etc/dropbear/authorized_keys

A complete tutorial for setting up public key based authentication on OpenWRT can be found here.

SSHFS

Another thing you probably want to do: mount the Yun's filesystem on your desktop via SSH.

Why is that? Mounting over SSH allows you to edit files on the Yun using your favorite editor directly on your desktop. So you don't need to fiddle with vi and such inside a shell;) E.g. I use the awesome SublimeText editor on Windows. Yeah, you probably prefer something else - and that is fine, since it will work too.

This magic works via SFTP (secure FTP), which is a FTP-like protocol that runs over SSH. On the Yun side, you'll need to have the SFTP package installed, login via SSH as root and do:

opkg update
opkg install openssh-sftp-server

Now, on Windows, I recommend Win-SSHFS which you can download from here. It's open-source and installs without hassles. Just "Ok-Install" everything.

You'll get a small Puffy-fish icon in your quicklaunch bar, double click and configure a new virtual drive:

Arduino Yun
Yun's root filesystem mounted as Windows drive "I:"

When done and mounted, a new drive appears on your Windows machine, which maps to the remote Yun's root filesystem:

Arduino Yun
Yun's root filesystem mounted as a virtual drive

On Mac OSX, there is a nice tutorial here that walks you through setting things up with FUSE for OSX.

On Ubuntu, you can use Nautilus or the command line.

With SFTP set up, you now can simply open, edit, create, copy, delete and move files conveniently from your desktop. Which can often be more comfortable than doing everything via command line SSH (and SCP).

Software Installation

The CPU on the Yun runs Linino, a Linux distribution derived from OpenWRT. OpenWRT was originally created and is mainly used as an open-source OS for use with routers like for example the Linksys WRT54G or Asus RT-AC66U.

Autobahn is a Python-based framework. Luckily, the Linux system on the Yun already includes Python 2.7.3:

root@Arduino:~# uname -a
Linux Arduino 3.8.3 #8 Mon Aug 19 16:22:39 CEST 2013 mips GNU/Linux
root@Arduino:~# python -V
Python 2.7.3
root@Arduino:~# python
Python 2.7.3 (default, Aug  8 2013, 22:36:42)
[GCC 4.6.4 20121210 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

However, we need a few more bits. I'll guide you through installation.

Installing Base Packages

The Arduino Yun uses a package system based on the OpenWRT opkg tool which can be used to install binary packages from the repository here.

The first thing to do should be to update the package list cached on the Yun (you need to redo that on every new login since it does not persist). Login to your Yun over SSH and do:

opkg update

Now install a few packages we'll need:

opkg install bzip2
opkg install unzip
opkg install tar
opkg install wget
opkg install fdisk
opkg install e2fsprogs
opkg install openssh-sftp-server
opkg install distribute
opkg install pyopenssl
opkg install python-openssl
opkg install python-crypto
opkg install python-bzip2
opkg install python-sqlite3
opkg install python-ncurses

This might take some time, but the packages are installed into the / root filesystem and will be permanently available from now on.

Create a filesystem

The / filesystem on the Yun only has 8MB space in total (the other 8MB of the total 16MB Flash are used for system recovery):

root@Arduino:~# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                    7.5M      5.7M      1.8M  76% /
/dev/root                 7.0M      7.0M         0 100% /rom
tmpfs                    29.9M    152.0K     29.7M   0% /tmp
tmpfs                   512.0K         0    512.0K   0% /dev
/dev/mtdblock3            7.5M      5.7M      1.8M  76% /overlay
overlayfs:/overlay        7.5M      5.7M      1.8M  76% /

The free space on / isn't enough for the software we will use. And we also want to have space for local data storage. Hence we will create a new filesystem on a micro SD card which we can use for both programs and data.

Make sure you have your SD card inserted. Then, create a new ext4 filesystem on the SD card (WARNING: this will erase all data on that card without any further questions!):

umount -f /mnt/sda1
mkfs.ext4 -O ^has_journal,extent /dev/sda1
mkdir /opt

To manually mount the filesystem you could do

mount -t ext4 /dev/sda1 /opt

A better way however is to have the filesystem automatically mounted at startup of the Yun. For that, add the following new entry to the filesystems configuration in the file /etc/config/fstab:

config mount
    option target       /opt
    option device       /dev/sda1
    option fstype       ext4
    option options      rw,async,noatime
    option enabled      1
    option enabled_fsck 1

and restart filesystem mounting to make it available immediately

/etc/init.d/fstab restart

Note: The restart command will probably warn you umount: can't umount /opt: Invalid argument. Ignore it, thats fine. It's triggered since the restart will first try to unmount everything, but if you hadn't mounted the new filesystem in the first place, that can obviously not work.

To check that the new filesystem actually works

echo "hello" > /opt/hello.txt
cat /opt/hello.txt

To check size and free space

df -h

Lastly, create two new folders (we'll use those later):

mkdir /opt/download
mkdir /opt/build

Creating a Python Virtualenv

Virtualenv is a widely used Python tool that allows to create complete Python environments in different locations and with different setups. We will use Virtualenv to create a Python enviroment on our SD card under /opt/python.

Install Virtualenv into the system Python:

/usr/bin/easy_install virtualenv

Now create a new Python environment on /opt/python (residing on our SD card):

/usr/bin/virtualenv --system-site-packages /opt/python

After that, you should have a new Python here:

root@Arduino:~# /opt/python/bin/python
Python 2.7.3 (default, Aug  8 2013, 22:36:42)
[GCC 4.6.4 20121210 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

From now on, you have two sets of Python binaries, the system Python:

root@Arduino:~# which python
/usr/bin/python
root@Arduino:~# which easy_install
/usr/bin/easy_install

and the binaries inside our new virtualenv:

root@Arduino:~# ls -la /opt/python/bin/
drwxr-xr-x    2 root     root          4096 Nov 29 16:34 .
drwxr-xr-x    5 root     root          4096 Nov 28 21:24 ..
-rw-r--r--    1 root     root          2192 Nov 28 21:30 activate
-rw-r--r--    1 root     root          1248 Nov 28 21:30 activate.csh
-rw-r--r--    1 root     root          2387 Nov 28 21:30 activate.fish
-rw-r--r--    1 root     root          1129 Nov 28 21:30 activate_this.py
-rwxr-xr-x    1 root     root           327 Nov 28 21:27 easy_install
-rwxr-xr-x    1 root     root           335 Nov 28 21:27 easy_install-2.7
-rwxr-xr-x    1 root     root           187 Nov 29 16:34 miniterm.py
-rwxr-xr-x    1 root     root           288 Nov 28 21:30 pip
-rwxr-xr-x    1 root     root           296 Nov 28 21:30 pip-2.7
-rwxr-xr-x    1 root     root       1320853 Nov 28 21:24 python
lrwxrwxrwx    1 root     root             6 Nov 28 21:24 python2 -> python
lrwxrwxrwx    1 root     root             6 Nov 28 21:24 python2.7 -> python

Make sure you use the full path to the Python (or easy_install) you want to use:

/opt/python/bin/python
/opt/python/bin/easy_install

or activate the virtualenv by doing

root@Arduino:~# source /opt/python/bin/activate
(python)root@Arduino:~# which python
/opt/python/bin/python
(python)root@Arduino:~# which easy_install
/opt/python/bin/easy_install

This activation will simply modify your shell environment appropriately, so it isn't anything persisting. Personally, I usually don't bother with virtualenv environment activation, but simply use fully qualified paths.

Installing Twisted

For low-level networking, Autobahn relies on Twisted, an asynchronous Python framework for high-performance, scalable networking.

We need to install Twisted from sources, since Twisted by default wants to build a few Python binary extensions, which won't work since there is no C compiler installed on the Yun. Those Twisted binary extensions however are not really required, so we will skip those during the source install.

Update to the latest Setuptools:

/usr/bin/easy_install -U setuptools

Twisted depends on zope.interface - let's install that via easy_install:

/opt/python/bin/easy_install zope.interface

Now download the Twisted source archive

cd /opt/download
wget --no-check-certificate https://pypi.python.org/packages/source/T/Twisted/Twisted-13.2.0.tar.bz2

Note: Yun does not come with certificates installed, hence we use the option --no-check-certificate. This means the server certificate of the site from which we download is not checked. You can do that, but we skip it for now.

and unpack the archive

cd /opt/build
tar xvjf ../download/Twisted-13.2.0.tar.bz2
cd Twisted-13.2.0

Now edit setup.py and comment out line 54 (see here, here, here and here):

#        conditionalExtensions=getExtensions(),

Note: The number of the line to be commented (L54) might change with future Twisted versions. The relevant thing is to comment the conditionalExtensions=.. statement.

Then build and install Twisted:

/opt/python/bin/python setup.py install

This might take some time. Be patient;) The Yun doesn't have a lot of steam and we are installing onto a micro SD card, which means low filesystem performance on top.

Installing pySerial and Autobahn

Since we want to talk to the MCU from the main CPU via serial, install Python serial support via pySerial:

/opt/python/bin/easy_install pyserial

And finally, for WebSocket/WAMP protocol support install Autobahn:

/opt/python/bin/easy_install autobahn

To test that Autobahn has been installed correctly, you can do

root@Arduino:~# /opt/python/bin/python
Python 2.7.3 (default, Aug  8 2013, 22:36:42)
[GCC 4.6.4 20121210 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import autobahn
>>> autobahn.__version__
'0.6.5'
>>>

Disable Console on Serial

We are using the serial connection between the MCU and the CPU. By default, there is a console attached on the Linux side to the serial, and we need to disable that.

Edit the file /etc/inittab and comment the following line (by preceding it with #):

# ttyATH0::askfirst:/bin/ash --login

The Linux SoC (CPU) and the Atmel MCU are connected via a UART (a serial connection) which maps to the device /dev/ttyATH0 on the Linux side and the serial stream class Serial1 on the Arduino side. The default inittab entry on the Linux side will start a shell connected to that serial port when Linux boots. Then, when your sketch starts the Arduino Yun bridge library (by doing Bridge.begin()), the bridge library writes a command to the serial that will in turn start a script on the Linux side which then connects to the serial port. That Linux script is essentially the Linux-side part of the Yun bridge library and will keep on running regardless of wether you reload a new sketch to the MCU or reset the MCU. It will keep on running until you reset the CPU or reboot Linux (or manually kill the script). However, as long as there is a script running and using the serial port, we cannot use the serial for our purposes. The commenting of the inittab line will disable starting a shell on the serial port altogether in the first place. This means we can use the serial port for our stuff, but it also means you won't be able to use the Yun brigde library anymore.

and reboot Linux:

reboot

Be patient, a reboot (either via the reboot command like above, or by doing a cold boot via power cycling or pressing the "Yun RST" button) can take 60-90s.

Running the Demo

Get the Demo code

The full demo code resides under examples/wamp/serial2ws in the AutobahnPython Git repository here.

You can download an archive containing a snapshot of the complete AutobahnPython repository or you can use Git to clone the repository:

git clone git@github.com:tavendo/AutobahnPython.git

Using Git allows you to easily update to the latest code later by doing

cd AutobahnPython
git pull

Compile the Demo sketch

Compile and upload the sketch to your Yun:

serial2ws.ino

You will need to adjust pins for the hardware you have. The demo uses 2 potis and 1 LED.

Run the Demo bridge

Then copy the following 4 files to the Yun Linux

serial2ws.py
index.html
smoothie.js
autobahn.min.js

either by using the method with the / directory mounted over SFTP to your desktop or by using scp:

cd AutobahnPython/examples/wamp/serial2ws
scp serial2ws.py index.html smoothie.js autobahn.min.js root@192.168.1.150:/root

Here and in the following, replace 192.168.1.150 with the IP address of your Yun.

Now run the server:

/opt/python/bin/python serial2ws.py -p /dev/ttyATH0 --debugserial

and open the page http://192.168.1.150:8080 in your browser (on desktop or mobile).

If everything works, you should see nicely rendered graphs with real-time readings from the 2 Potis and also have 2 buttons to control the LED like in the video above. Hurray;)

Outlook

Now, with the stuff above you already can do some nice projects. You can have a single Yun communicate with browsers in real-time. However, there are some questions that immediately come to mind:

  1. What about multiple Yuns? On one network, or different networks?
  2. What if the Yun runs on a private network (behind NAT), and you want to connect from your browser running somewhere else in the world?
  3. What about data storage? You might want to store your sensor data in a database.
  4. And why do you need to code project specific bridge code with Autobahn at all? Wouldn't it be nice if you could concentrate on your hardware, your sketch and if any, the HTML5/JavaScript that makes up the user experience of your project?
  5. I why do you need to follow so many steps and can't just do opkg install whatever or similar and have everything set up?

Well, yes, yes and yes. And we'll provide answers to those;)

The issues 1., 2. and 3. will involve Crossbar.io, an open-source multi-protocol application router that builds on Autobahn.

The issue 4. will involve SRDP, a generic protocol for serial communication with the MCU that exposes hardware as virtual register devices (think Modbus etc).

And 5. will involve creating Yun packages or install scripts for above.

As you probably can imagine, this is a bigger undertaking. And will take some time to materialize. In the meantime, I'd love to hear from you, any feedback, suggestions and such.

Happy tinkering;)

/Tobias

Resources

  1. Autobahn
  2. OpenWRT
  3. Arduino Yun
  4. Python

Find out how to create component-based, real-time apps for the Web, mobile and IoT in less time and with less complexity using

Crossbar.io name

Crossbar.io is an open-source Unified Application Router created and supported by Tavendo

Learn more

About

Tavendo provides open-source middleware that helps developers create next-gen applications in less time and with less complexity.

We are authors and maintainers of WAMP (Web Application Messaging Protocol), Crossbar.io (Unified Application Router) and Autobahn (Real-time Web Framework).

us on Twitter

Stay Informed

Sign up for our newsletter to stay informed of new product releases and features:

Professional Services

Tavendo offers consulting, support and custom development for Crossbar.io and Autobahn based solutions.

Get in contact and send us an Email describing your project, issue or question.

Recent posts

Atom Feed

Search this Site