Project: Using Arduino YUN to control things remotely

Arduino YUN is very interesting product. Mixing OpenWRT and Arduino in one board is effective. OpenWRT does things related to WiFi connectivity, Arduino YUN does interact with physical world, and standard Arduino library makes connecting both parts easy. Now we need some simple project to demonstrate how You can control things remotely with Arduino YUN

Arduino YUN allow You control physical elements with smartphone or other browser.

Arduino YUN allow You control physical elements with smartphone or other browser.

To demonstrate how easy You can build something using this components we will use Arduino YUN, connect to it with browser (can be in smartphone) and You control some LED using webpage. This project was shown on Robomaticon 2014 in Warsaw to make YUN more understandable. Robomaticon is event for robotics and electronics enthusiasts, so YUN was acting as open hot spot, anybody could connect to it and using http://1.1.1.1 control LEDs. Why numerical address instead of some more userfriendly name distributed via DHCP to clients? Not all phones were accepting .local domain extension, so since whole setup was not connected to Internet we used this easy to enter public address.

First things first – using documentation on arduino.cc configure YUN, remember make REST API open (w/o password). As I said before our setup was in closed environment and somebody hijacking control over LEDs can not make any harm. If You want to control real devices, You have to keep that in mind.

Our project is built from two parts: Web page and sketch for Arduino. Using Arduino IDE 1.5.x and having www subfolder in Your sketch directory makes uploading to YUN both Your sketch and HTML simple task. When uploading via WiFi (another nice YUN feature – wireless upload) sketch is uploaded to Atmega32u4 and www subfolder content is uploaded to /www/sd/<our sketch name>. This works only if You upload through WiFi, when using USB connection only sketch is being uploaded.

One important note – YUN has to be equipped with microSD card, this is a place where our HTML files are be kept. First time You are trying upload HTML files You can get Warning: Problem accessing board folder /www/sd. At begin there is no proper directory. Log onto YUN using SSH and issue command ln -s /mnt/sdcard /www/sd (You can check what is mounting point for SD card issuing command df after card is inserted into YUN (also when logged via SSH).

Arduino YUN: BRIDGE Library

Bridge is standard library for YUN, included with Arduino IDE (as for now YUN is being supported in 1.5.x line). This library makes communication between OpenWRT and Arduino very easy. REST API enabled in basic YUN configuration is bound to /arduino/ endpoint, so each HTTP request to http://arduino.yun.address/arduino/some_string are using Bridge library sent to Arduino. Everything after /arduino/ part is easy to read in our sketch. So let’s look at this simple HTML code (uses jQuery)

<script type="text/javascript">
 function ledon()
 {
 $('#content').load('/arduino/ledon');
 }
 function ledoff()
 {
 $('#content').load('/arduino/ledoff');
 }
</script>

Simple code above defines simple calls to URL begining with /arduino/. As it was said before, all remaining part of URL is easy accessible from Arduino sketch. So, /arduino/ledon is seen from sketch as just ledon. REST API provided out of the box provides simple access to all digitl and analog pins. So sending GET to http://myArduinoYun.local/arduino/digital/13/1 will set digital IO no 13 in HIGH state (it will light led on board). We want to show how to match actions to URLs. Frist we define server object:

YunServer server;

then in setup function we initialize server:

  Bridge.begin();
  server.listenOnLocalhost();
  server.begin();

using server.listenOnLocalhost(); is makes only Bridge server to listen on localhost only – this does not add any security to Your Arduino YUN REST API!

In loop we need to follow this setps:

  • create new instance YunClient from YunServer
  • if there is new connection – process it
  YunClient client = server.accept();

  if (client) {
    process(client);
    client.stop();
  }

process function we can just get command:

void process(YunClient client) {
  String command = client.readStringUntil('/');

And there is only one thing to do – just do what we want to do based on command:

if (command == "ledon") {
       digitalWrite(13, HIGH);
 }
else if (command == "ledoff") {
       digitalWrite(13, LOW);
}

This code does what REST API does out of the box, but has advantage it can be modified to perform more actions than bare REST API can do in one call. With sending command led5on and led5off we can turn all LED on/off:

if (command == "led5on") {
      digitalWrite(13, HIGH);
      digitalWrite(12, HIGH);
      digitalWrite(11, HIGH);
      digitalWrite(10, HIGH);
    }
    else if (command == "led5off") {
      digitalWrite(13, LOW);
      digitalWrite(12, LOW);
      digitalWrite(11, LOW);
      digitalWrite(10, LOW);

Ok, now we take our HTML code and sketch and upload to Arduino YUN via WiFi. If You point Your browser to http://arduino.local/sd/SKETCH_NAME You will see page:

Our control page

Our control page

As You can see from URL our sketch is called webled, and we used 1.1.1.1 IP address for YUN (You can do that only when network is not connected to Internet – in such case You should stick to so called private networks like 10.0.0.0/8 or 192.168.0.0/16). All is working as expected, however there is a noticeable delay – it takes 2-3 seconds to light on/off LED after button is being clicked.

REDIRECT

As I mentioned earlier, project was meant to allow anybody to connect to YUN (which was acting as hot spot) and play with LEDs. This is why we used 1.1.1.1 (as You probably remember not all phones were able to use arduino.local shortcut), but there is ugly /sd/webled URL part – entering that on phone is not very handy. To skip that part we will make redirect from YUN home page to this control page.

We need to connect to YUN via SSH (standard program in UNIX environment, for Windows You can use Putty): -l root arduino.local, enter the same password You have setup on WWW interface and:

cd /www
ls

Before any changes to redirect keep in mind that currently when You access YUN home page, You are redirected to admin interface. When You change default redirect You will have to remember where You should point browser. As for today admin interface is under http://arduino.local/cgi-bin/luci

There should be file index.html, You have to edit it with vi index.html find URL in <meta> tag and replace it with Your own. This vi version (for first time users it will be strange feeling to use vi :) ) should allow You edit whole document after You press i key. When You are done press ESC then enter :wq and press Enter - this will save Your file and finish editing. In case You have messed and don't want to save enter :q! and press Enter to exit not saving any changes to file.

Now, examine URL we have entered – this is exactly URL we were using to get to our app:

Edit meta tag with URL

Edit meta tag with URL

Now You can test it – access Your YUN and You should be redirected directly to LED controll page. Voila!

All data – HTML files, Arduino sketch are available on Google Drive

11 thoughts on “Project: Using Arduino YUN to control things remotely

  1. Pellumb

    can you explain how to upload the www folder?? on the arduino YUN.

    Everyone seems to skip this important step! why?
    You say is easy to do that but in practice that is not quite the case; there is an error showing whilst uploading the arduino sketch .

    Also, how do you upload the www folder ?
    If you know it then please show it in steps otherwise STOP showing tutorials all-together.

    thx

    Reply
      1. nettigo Post author

        As far as I remember (I don’t have Yun to check it) You have to use SD card to get automatic WWW upload feature.

        Any content from www catalog INSIDE of Your sketch folder will be uploaded (when uploading to Yun via WIFi) to /www/sd folder. If You create symlink and there is enough space for HTML in Yun flash,then it should work w/o SD card. Try to find out.

        Reply
  2. nettigo Post author

    @Pellumb
    It is explained in article:

    Log onto YUN using SSH and issue command ln -s /mnt/sdcard /www/sd (You can check what is mounting point for SD card issuing command df after card is inserted into YUN (also when logged via SSH).

    If this is not clear, tell me what step is failing for You.

    I don’t remember and don’t have YUN to test it right now, but in case there is no /www folder You can create it using mkdir /www

    SD card has to be inserted into YUN and it has to be formated to FAT.

    Reply
    1. Lance

      I am also having issues at this point.
      I have created directories as:
      /mnt/sda1/arduino/www/sd/
      I have put the entire contents of the webled folder in the www directory.
      I’ve attached a screenshot of what is going on here: http://imgur.com/4K57obo
      I’ve even made copies of the www folder and put them in different hierarchies within the filesystem, and still no luck???

      Reply
        1. nettigo Post author

          @Lance
          Symlink created with ln -s is permanent, so if You issue second time this command it will report path exists. So, to change symlink to point it to other location – first delete symlink with rm /www/sd and then create it again. From Your screenshots, it looks like naming of mount point has changed (article is 2 years old), so /mnt/sdcard is no longer accurate. Probably ln -s /mnt/sda1/arduino/www/sd /www/sd is what You need in Your project.

          Reply
          1. Lance

            Got It to work. Yeah I wasn’t uploading the sketch correctly. But anyway, point taken. Thanks for the fast response.

          2. Lance

            I have all files now in the correct places. But I am now having issues with making the new bridge sketch as mentioned in your walkthrough, after the part about adding the javascript. I am assuming I just compile it all into one sketch so that it looks similar to this: ( I am using Bridge in place YUN)

            #include
            #include
            #include
            BridgeServer server;

            void setup() {
            Bridge.begin();
            server.listenOnLocalhost();
            server.begin();

            }

            void loop() {
            BridgeClient client = server.accept();
            void process(BridgeClient client){
            String command = client.readStringUntil(‘/’);}
            if (client) {
            process(client);
            client.stop();

            }

            if (command == “ledon”) {
            digitalWrite(13, HIGH);
            }
            else if (command == “ledoff”) {
            digitalWrite(13, LOW);
            }
            if (command == “led5on”) {
            digitalWrite(13, HIGH);
            digitalWrite(12, HIGH);
            digitalWrite(11, HIGH);
            digitalWrite(10, HIGH);
            }
            else if (command == “led5off”) {
            digitalWrite(13, LOW);
            digitalWrite(12, LOW);
            digitalWrite(11, LOW);
            digitalWrite(10, LOW);
            }

            I will buy you a coffee for your time :)

  3. Cem

    Is there any way to prevents delay on commands? Openning a led in 2-3 sec is not good. I tried without web browers it takes 1-1,5 secs to respond. Why ? any idea to do it instantly?

    Reply
    1. nettigo Post author

      @Cem
      I dont think it is possible to remove latency, at least using default tools. On linux side is web server, python script, shell pipe. Since there is not a lot ‘horsepower’ it will take time.

      I guess You could write own software, doing this (listening on web requests and sending it them directly to ATmega) and it could be faster. Solution provided by Bridge and related tools are meant to be versatile and easy to use, not to be super efficient.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *