Arduino Yún Reliability Problems

I've been testing out the Arduino Yún recently with a view to making use of one in a project. I've come across a problem or two and solutions that were probably worth making a note of, so I thought that I'd write them here as somewhere to come back to in future.

One little problem I've faced is the reliability of running the Yún: doing a job whilst maintaining a working network interface. I've found that even a simple task, such as using the Bridge library and Yún server and client libraries together to create a REST query-able thermometer have proved problematic. Yúns with the early software version, (2014-04-10 11:08:41 CEST) I believe, seem prone to stopping responding after a few hours. I've made a note here of how to hopefully resolve that.

Other smaller, not exactly problems, just things that make it a nicer beast to work with are things such as setting the Yún up just the way you want it on a network. I've noted a couple of things here.

Updating the Yún Software

Likely you'll want to know which version of the software your Yún has installed. This is easily done by SSHing to the Yún and looking at a particular file:

foobox:~$ ssh root@arduino.local

BusyBox v1.19.4 (2014-04-10 11:08:41 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:~# cat /etc/arduino/openwrt-yun-release
 built=Tue Jul 15 21:14:21 CET 2014

The date you see after built= can be compared against the change log present in the arduino/openwrt project, right here in raw form. My version number above means the software was built as release 1.4, on July 15th, 2014.

So how about updating? This is actually quite easy. First, download the latest OpenWRT - Yún (which was version 1.5.3) upgrade image from here. Unzip the package and extract the bin file on to a micro SD card. Power down the Yún and plug the card into the card slot on the underside.

Now power the Yún back up, making sure that you have a network cable plugged in. SSH to the Yún and execute run-sysupgrade with a path to the bin file on /mnt/sda1.

root@Arduino:~# run-sysupgrade /mnt/sda1/openwrt-ar71xx-generic-yun-16M-squashfs-sysupgrade.bin
Sending TERM to remaining processes ... uhttpd dbus-daemon dnsmasq avahi-daemon thd ntpd uSDaemon blkid syslogd klogd hotplug2 ubusd netifd
Sending KILL to remaining processes ... uhttpd
Switching to ramdisk...
Performing system upgrade...
Unlocking firmware ...

Writing from <stdin> to firmware ...  [w]

Upgrade completed
Rebooting system...

After a few moments you should be able to log in again and hopefully note that the build date has changed - in my case:

root@Arduino:~# cat /etc/arduino/openwrt-yun-release
built=Fri Nov 14 03:53:51 CET 2014

According to the previously mentioned change log, that means I'm fully up to date.

Changing eth1 to be Static

I always prefer bits of kit that will be permanently installed on the network to have a fixed IP address. In my usual manner I like to keep systems undertaking certain types of job grouped in specific number ranges.

Finding the current IP address:

foobox:~$ ping arduino.local
PING arduino.local (192.168.100.134): 56 data bytes

It just so happens that 192.168.100.134 is in a dynamic portion of my local IP range. Let's log into the Yún and sort things out.

root@Arduino:~# cat /etc/config/network

config interface 'loopback'
    option ifname 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'

config interface 'lan'
    option proto 'static'
    option ipaddr '192.168.240.1'
    option netmask '255.255.255.0'

config interface 'wan'
    option ifname 'eth1'
    option proto 'dhcp'
    option metric '10'

So just change the wan part (because I want a static IP at 192.168.100.11) to:

config interface 'wan'
    option ifname 'eth1'
    option proto 'static'
    option 'ipaddr'  '192.168.100.11'
    option 'netmask' '255.255.255.0'
    option 'gateway' '192.168.100.1'
    option 'dns'     '192.168.100.1'
    option metric '10'

Once that is saved, just issue a /etc/init.d/network reload command and eventually your Yún will appear at the desired address.

Final check, back on your local machine:

foobox:~$ ping arduino.local
PING arduino.local (192.168.100.11): 56 data bytes

Changing the Yún Host Name

I know at some point that I'll end up hosting another Yún on the network, so changing the host name would be a good thing to do. This is quite easy, as it turns out.

Ascertaining that arduino.local is indeed what the Yún responds to at the moment:

foobox:~$ ping arduino.local
PING arduino.local (192.168.100.11): 56 data bytes
64 bytes from 192.168.100.11: icmp_seq=0 ttl=64 time=4.399 ms
64 bytes from 192.168.100.11: icmp_seq=1 ttl=64 time=1.544 ms

Once again, SSH to arduino.local and edit /etc/config/system, changing option hostname from Arduino to whatever you desire. How about Unicorn?

root@Arduino:~# vi /etc/config/system
config system
        option hostname Unicorn
        option timezone UTC

config timeserver ntp
        list server     0.openwrt.pool.ntp.org
        list server     1.openwrt.pool.ntp.org
        list server     2.openwrt.pool.ntp.org
        list server     3.openwrt.pool.ntp.org
        option enable_server 0

Next, also change the host name using the hostname on the command line and restart the avahi-daemon:

root@Arduino:~# hostname Unicorn
root@Unicorn:~# /etc/init.d/avahi-daemon restart

Now log out, and back on your local machine, ping unicorn.local to see whether it works or not:

foobox:~$ ping unicorn.local
PING unicorn.local (192.168.100.11): 56 data bytes
64 bytes from 192.168.100.11: icmp_seq=0 ttl=64 time=3.955 ms
64 bytes from 192.168.100.11: icmp_seq=1 ttl=64 time=4.428 ms

And... success! You may want a slightly more meaningful name than unicorn, but that is, of course, up to you.

Just note that some patience may be required, or perhaps the flushing of DNS caches - the way your network is set up no doubt differs to mine, so it may take some time for the new host name to be picked up by other machines on your network. It was pretty instant on mine, and I had no troubleshooting to undertake, that's all I'll say.

Restoring the Bridge after a Yún Reboot via SSH

When faced with a Yún based web service that has stopped responding, my natural fallback position is to SSH in and reboot the Yún. This is not a successful strategy, as I am then faced with a message that says the following:

Could not connect to YunServer 146 Connection refused

The only action I found that did fix the situation was a button press on YÚN RST or a power cycle. In a nutshell, once up and running, the web facing REST interface works well. Then after a few hours I start getting zero byte responses from the interface . Whilst the Yún is still up and running and responding to pings and able to be SSHed into, the Bridge software interface seems to stop passing data back and forth from the Arduino side of things. Disclaimer here... that is only my guess at what may happening under the hood and I could easily be wrong.

In order to understand what the Bridge library does it would be helpful to briefly explain the Yún architecture. The Yún has two processors on board: the ATmega32U4, which is the 8 bit MCU beating heart of many an Arduino, and an Atheros AR9331 processor, which runs Linino (based on the OpenWRT Linux distribution).

The Bridge library itself enables communication between the two on board processors, giving Arduino sketches the ability to run shell scripts, communicate with network interfaces, and receive information from the AR9331 processor. The USB host, network interfaces and SD card are not connected to the ATmega32U4, but the AR9331, and the Bridge library also enables the Arduino to interface with those peripherals.

Anyway, after a bit of rooting about on the Yún's file system, I discovered a reset-mcu command. This command sits in the file: /etc/rc.local. The rc stands for run control, and this file is normally executed once all the system services are up and running at the end of a process of switching to a multiuser run level (levels 2-5 in most Linuxes). It is an ideal location to start custom services or run special commands. Here is the output of rc.local on my Yún:

root@Unicorn:~# cat /etc/rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

wifi-live-or-reset
boot-complete-notify

# Uncomment the following line in order to reset the microntroller
# right after linux becomes ready

#reset-mcu

# Uncomment the following line in order to disable kernel console
# debug messages, thus having a silent and clean serial communication
# with the microcontroller

#echo 0 > /proc/sys/kernel/printk

exit 0

And there is the magic -

# Uncomment the following line in order to reset the microntroller

# right after linux becomes ready

So after uncommenting the reset-mcu line I rebooted the Yún from the command line and as I hoped, it came back up with a working bridge.


Comments

comments powered by Disqus