Arduino Yun WiFi Example

Prepared by Dr. Aaron Scher
aaron.scher@oit.edu
Oregon Institute of Technology

Back to Aaron's home page.

This example shows how to serve data from an analog input and write to a digital output via the Arduino Yun's built-in webserver using the Bridge library. For the analog input side, we will use the Arduino Yun to monitor temperature and humidity via a DHT22 sensor, and this data will be accessible from a web browser. On the digital-write side, we will be turning a simple LED on and off remotely via the web browser

Note 1: This example draws heavily from Arduino's Temperature Web Panel Example.

Note 2: The example goes step-by-step from unboxing the Arduino Yun to having a working system. I use a PC for this example running Windows 8.

Note 3: It is assumed that your PC is wirelessly connected to your WiFi router.

Material list

  1. Arduino Yun: I happened to purchase mine from Sparkfun.
  2. MicroSD card: I use a SanDisk 8 GB microSDHC. With what we're doing, the exact size and make of the microSD card shouldn't matter much.
  3. DHT-22 temperature/humidity sesor. I happend to purchase mine from Adafruit . You also need a 10 kOhm resistor for the DHT-22 sensor. With my purchase, the sensor included this resistor.
  4. Basic 5mm LED (e.g. something like this would work) and 220 Ohm resistor.
  5. A simple, standard, solderless breadboard and some wire to make connections.

Step 1: Prepare your PC and Arduino Yun

Install the right software on your PC

This is the list of software to have installed on your PC:

  1. The latest Arduino IDE from programing the Arduino Yun. Make sure it supports the Arduino Yun (free software.)
  2. Apple's bonjour Print Services for Windows so your web browser can access the Arduino Yun via its local url as well as its ip addresses. For more information about why you need this software installed, you can consult the Arduino Yun Guide . Also look up "Zero Configuration Networking".
  3. PuTTY (Free Telnet and SSH client for Windows.)
  4. WinSCP (Free SFTP and FTP client for Windows.) You really don't need to have this, but I find it very useful for exploring the files on the Arduino Yun's SD card.
  5. Text editor to create your HTML and Javascript files. The regular Notepad which is bundled with Windows will work fine. However, I personally like to work with Notepad++ (Free source code editor and Notepad replacement.)
  6. Modern web browser. I'm using Firefox.

Configure your Yun's WiFi

This video tutorial shows you how to configure your Yun's WiFi. I also find this video tutorial helpful.

Expand the Yun disk space.

Insert the microSD card into the Yun, and follow this tutorial to expand the Yun disk space. The tutorial shows how to split the SD card in two parts. The first part is formatted as FAT32 and could be read from any computer: you can use it to share files between your computer and your Yun. The second part contains the Linux file system. I somewhat arbitrarily chose to split the sd card down the middle: 4 GB for FAT32 and 4 GB for Linux.

Step 2: WiFi check and understand how to use the Arduino Yun as a webserver.

What is my Arduino Yun's address?

You can address your Arduino Yun by its IP address or the name you give in the WiFi setup procedure. What if you don't remember or don't know them?

You can use the Arduino IDE software to easily determine the address of your Yun. In the Arduino IDE menu bar, go to Tools → Port. As an example, see the screen shot below. Here I have my Arduino Yun connected to my PC via USB, which is why you see "COM3 (Arduino Yun)". My Arduino Yun is also set up for WiFi, which is why you see "AaronYun at 192.XXX.X.X (Arduino Yun)". This gives me the IP address of the Yun (192.XXX.X.X) and the name of my Yun (AaronYun). If I disconnect the Arduino Yun from my PC and connect it to a wall outlet directly, the COM3 port will disapear, but I will still be able to connect to the Yun via WiFi and upload files and Arduio sketches.

Screen Shot of Arduino IDE finding address of Yun

Understand Aruino Yun's File System and how to use the Yun as a web server

It is useful to understand the basics of how the Arduino Yun can be used as a server. Basically, once the Yun is configured to connect via WiFi, you can create a client web page that will be uploaded on the SD card that can be accessed from your web browser. I find the following two articles to be very good in introducing this topic: Arduino Yun: Intro to web server and Arduino Yun: Sensor values to HTML page. If these links don't work, you can download the articles as PDFs here: Arduino_Yn_Intro_to_web_server.pdf and YunServer_Sensor_values_to_HTML_page.pdf. As a prerequisite before continuing on, you should carefully follow and replicate the exercise presented in the first tutorial (intro to web server), and at least skim through the second tutorial.

PuTTY and WinSCP make it easy to navigate the file structure of the Arduino Yun's SD card. I find the following article to be an excellent introduction on this topic: Yun - How to Use SD Card. If this link does not work, you can download the article as a PDF here: Yun - How to Use SD Card.pdf. As a prerequisite before continuing on, you should at least skim through this article.

Step 3: Setup the hardware

The Arduino Yun should be connected to the DHT sensor and LED circuitry as shown in the schematic below. For power, the Yun is connected to a mini USB to USB cable, which is connected to a USB wall charger. For reference, a good article on the DHT sensor is provided by Adafruit: Adafruit tutorial on DHTxxx temperature humidity sensor.

Yun hardware setup

The total hardware setup includes Yun + external circuitry (presented in figure above), the WiFi router (which doesn't necessarily need to be connected to the internet), and a PC with WiFi enabled. The basic block diagram of this setup is presented in the figure below.

Yun hardware setup

Step 3: Software

Below is a screenshot of the webpage (which we can access from a browser like Firefox) that is used to send and recieve data from an Arduino Yun via WiFi. This is accomplished using the Yun's built-in webserver and the Bridge library. The webpage itself includes two radio buttons, labeled "LED on" and "LED off", which commands the Yun to turn an LED on and off. The Arduino Yun also collects sensor data (temperature and humidy) from a DHT sensor. At set intervals in time, the webpage requests this sensor data and prints the received data to the same webpage.

Webpage screenshot

To make this all work, we need two elements: the Arduino sketch and the HTML webpage. The client webpage (which is stored on the SD card of the Yun and runs in your browser) is programmed to make a call to the following URLs once a second:

    /arduino/temperature/0       This call is sent if the "LED off" radio button is pressed.

    /aduino/temperature/1       This call is sent if "LED on" radio button is pressed.

I arbitrarily chose the URL calls /arduino/temperature/0 and /arduinotemperature/1 to signify to the Arduino Yun to turn the LED on and off, respectively. I could have chosen a totally different URL like /arduino/turnnoff and /arduino/turnon . Whatever I chose, it is important that it has /arduino/ in the first part of the URL. We will program the Arduino Yun to know what particular URL request translates to "LED on" and "LED off". The Arduino will read this URL request as a command and turn the LED on and off accordingly. Besides turning the LED on and off, the Arduino will also automatically send back temperature/humidity data to the webpage every time a URL request is made.

The Yun's onboard Atheros 9331 (running Linux and OpenWRT) is setup as a server, which is listening for these URL requests from the localhost. When a URL request is detected, the Atheros 9331 sends the URL as a command string to the Yun's onboard ATmega32u4 chip via the Bridge Library. These commands are called REST commands. The ATmega32u4 chip is programmed to listen for incoming REST commands. If one is recieved, then it reads the REST command (URL string), deterimines what the particular request is, and responds with the correct data, which it then sends back to the server via the Bridge libary. The server then passes this data on to the webpage. Once this is complete, the server listens for the next URL request, thus starting the process all over again. From the webpage's perspective, it makes a call to the Yun server every second, waits for the server response, loads the data recieves, and updates the webpage appropriately.

This webpage is saved in a folder called "www". This folder contains the main HTML file named "index", a picture called "cat.jpg", and a folder called "js". The "js" folder contains two files: zepto.min.js (a Jquery library, which can be downloaded from Zepto) and another javascript library file called jsHere.js. Looking back, I have no idea why I named this last file "jsHere.js", but that's what I did. The file structure for the webpage is depicted below.

File screenshot 1

The files and folders inside the folder labeled "www" above are:

File screenshot 1

The two javascript files in the folder labeled "js" above are:

File screenshot 2

These files can be downloaded here.

To move the webpage files from your PC to the SD card of the Yun, you can place them in the sketch folder of the sketch that you will uploading. When you upload the sketch, the webpage files will be saved to the correct location on the Yun. To access the sketch folder from the menu screen in the Arduino IDE select the following menu options Sketch → Show Sketch Folder.

Show sketch folder screen shop

The HTML code for the main webpage (index.html) is presented below:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<img src="cat.jpg" alt="Cute Cat" height="142" width="142">
<br />
<p>Click the button to turn on and off the LED.</p>

<form id="LED_Selection" action="">
<input type="radio" name="LEDCheck" value="off" id="off" />
<label for="off">LED Off</label><br>
<input type="radio" name="LEDCheck" value="on" id="on" />
<label for="off">LED On</label><br>
</form>
<br />
<div id="sensor_content">Loading data from Arduino...</div>
<div id="LED_content"></div>
<div id="LED_content_test"></div>
<script type="text/javascript" src="js/zepto.min.js"></script>
<script type="text/javascript" src="js/jsHere.js"></script>

</body>

</html>

The Javascript code (jsHere.js) is presented below:

$(function() {
getSensorvalue();
});

function getSensorvalue() {
//Every one second, this function obtains sensor values from Arduino Yun and sends to Yun
//a request to turn LED on or off (depending on what radio button is pressed).

var checked_option_radio = $('input[name=LEDCheck]:checked','#LED_Selection').val(); //Check what
//radio button is pressed ("LED on" or "LED off")

if (checked_option_radio =='off') //if the user selected for LED to be off, send request to Arduino
{
$('#LED_content').load('/arduino/temperature/0');
}

if (checked_option_radio =='on') //if the user selected for LED to be on, send request to Arduino
{
$('#LED_content').load('/arduino/temperature/1');
}

setTimeout("getSensorvalue()",1000); //Pole every one seconds.
}

The Arduino code is presented below:

//WiFi_send_receive_example
//In this example an HTML webpage (which we can access from a browser like Firefox)
//is used to send and recieve data from an Arduino Yún via WiFi. This is 
//accomplished using the Yún's built-in webserver and the Bridge library. The webpage 
//itself includes two radio buttons, labeled "LED on" and "LED off", which commands 
//the Yún to turn an LED on and off, respectiely. The Arduino Yún also collects sensor 
//data(temperature and humidy) from a DHT sensor. At set intervals in time, the webpage 
//requests this sensor data and prints the received data. 
//
//To make this all work, we need two elements: this sketch and the HTML page.
//
//The client webpage (which is stored on the SD card of the Yún and runs in your
//browser) is programmed to make a call to the following URLs once a second: 
//      /arduino/temperature/0    (if "LED off" radio button is pressed) 
//      /arduino/temperature/1  (if "LED on" radio button is pressed)
//The Yún's onboard Atheros 9331 (running Linux and OpenWRT) is setup as a server,
//which is listening for these URL requests from the localhost. 
//When a URL request is detected, the Atheros 9331 sends the URL as a command string 
//to the Yún's onboard ATmega32u4 chip via the Bridge Library. These commands are 
//called REST commands. The ATmega32u4 chip is programmed to listen for incoming REST 
//commands. If one is recieved, then it reads the REST command (URL string), deterimines
//what the particular request is, and responds with the correct data,
//which it then sends back to the server via the Bridge libary. The server then passes 
//this data on to the webpage. Once this is complete, the server listens for the next
//URL request, thus starting the process all over again. From the webpage's perspective, 
//it makes a call to the Yún server every second, waits for the server response, loads
//the data recieves, and updates the webpage appropriately. 
//
//Make sure to have a SD card attached to SD card slot of the Arduino Yun. The HTML page
//is to be saved on this SD card. Prepare your SD card with an empty folder in the SD 
//root named "arduino" and a subfolder of that named "www".An easy way to upload the 
//HTML page (which may contain supporting files like images, Javascript, CSS, etc.) from
//your PC to the Yun is to place these files in a folder named "www" inside the sketch 
//folder. When you upload the sketch, these files will also be automatically uploaded to 
//the appropriate directory on the SD card on the Yún (i.e. the Yún will create a link to 
//the SD to the "/mnt/sd" path.) For example, in my sketch folder (which can be accessed 
//via the menu Sketch --> Show Sketch Folder, I have a folder named "www". Inside this 
//folder I have a file named "index.html" that contains my HTML code, a file named 
//"cat.jpg" and a folder named "js", which contains a couple Javascript files.These files
//can be viewed and downloaded from www.aaronscher.com
//
//Created by Aaron D Scher on Sep. 10, 2014
//Two public domain codes were used to write this code:
//TemperatureWebPanel by Arduino and DHT by Adafruit

//Inlude the appropriate libraries
#include "DHT.h"
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

//WiFi setup:
// Listen on default port 5555, the webserver on the Yún
// will forward there all the HTTP requests for us.
YunServer server;
String startString;
long hits = 0;

//Temperature/humidity sensor setup:
#define DHTPIN 2     // The DHT data pin is connected to Yún digital pin 2 
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
//Other notes for DHT sensor setup:
// Connect DHT pin 1 (on the left when looking at the sensor on it's 'grated' side) 
// of the sensor to +5V
// Connect DHT pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from the DHT pin 2 (data) to DHT pin 1 (power) of the sensor

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);
// NOTE: For working with a faster chip, like an Arduino Due or Teensy, you
// might need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It's a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// Example to initialize DHT sensor for Arduino Due:
//DHT dht(DHTPIN, DHTTYPE, 30);

//Setup LED pin
int led=7; //hardware connection: Yún digital pin 7 to LED to 220 Ohm resistor to Ground.

void setup() {
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
  dht.begin();
  
  // Bridge startup
  Bridge.begin();
  // Listen for incoming connection only from localhost
  // (no one from the external network could connect)
  server.listenOnLocalhost();
  server.begin();
   
  // get the time that this sketch started:
  Process startTime;
  startTime.runShellCommand("date");
  while (startTime.available()) {
    char c = startTime.read();
    startString += c;
  }
  
  pinMode(led,OUTPUT); //initialize the digital pin (which controls the LED) as an output.
}

void loop() { 
  int LED_choice;
  // Get clients coming from server
  YunClient client = server.accept();
    
//The client webpage (which is stored on the SD card of the Yún and runs in your browser) 
//is programmed to make a call to the following URLs once a second: 
//      /arduino/temperature/0    (if "LED off" radio button is pressed) 
//      /arduino/temperature/1  (if "LED on" radio button is pressed)
//The Yún's onboard Atheros 9331 (running Linux and OpenWRT) is setup as a server, which
//is listening for these URL requests from the localhost. 
// In the following code, the Yún is checking to see if there is indeed a client request
// If there is, then the Yún checks to see if there is  a "temperature" command 
//in the URL... if there is, then it will process this request.
  
  // There is a new client?
  if (client) { 
    // If there is a request, then read the URL command
    String command = client.readStringUntil('/'); //Read in the string up to the frist
    //forward dash "/".
    command.trim();        //kill whitespace
    
    if (command == "temperature") {  //Check to see if the first part of the URL command 
    //included the word "temperature" 
 
      // get the time from the server:
      Process time;
      time.runShellCommand("date");
      String timeString = "";
      while (time.available()) {
        char c = time.read();
        timeString += c;
      }
     // Serial.println(timeString);
      
      // Note 1: Reading temperature or humidity takes about 250 milliseconds!
      // Note 1: Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
      float h = dht.readHumidity();
      // Read temperature as Celsius
      float t = dht.readTemperature();
      // Read temperature as Fahrenheit
      float f = dht.readTemperature(true);
       
       ////////////////////////////////////////////////////////////////////////
       //I want to work more on this next piece of code later:
       // Check if any reads failed and exit early (to try again).
       
       //if (isnan(h) || isnan(t) || isnan(f)) {
       //  Serial.println("Failed to read from DHT sensor!");
       //}
       ////////////////////////////////////////////////////////////////////////
      
       // Compute heat index
       // Must send in temp in Fahrenheit!
       float hi = dht.computeHeatIndex(f, h);
      
      //Send text data to the client (which will interpretted by client as HTML) 
      //using the client.print command: 
      client.print("Current time on the Yún: ");
      client.println(timeString); //send current time
      client.print("<br>Current temperature: ");
      client.print(t); //send current temperature in degrees C
      client.print(" degrees C");
      client.print("<br>Current temperature: ");
      client.print(f);//send current temperature in degrees F
      client.print(" degrees F");
      client.print("<br>Humidity: "); 
      client.print(h);//send current humidity
      client.print(" %\t");
      client.print("<br>This sketch has been running since ");
      client.print(startString); //Send the length of time the sketch has been running
      client.print("<br>Hits so far: ");
      client.print(hits); //send the number of times the server has had a request
      
      //Remember, the client webpage is programmed
      //to make a call to the following URLs once a second: 
      //      /arduino/temperature/0    (if "LED off" radio button is pressed) 
      //      /arduino/temperature/1  (if "LED on" radio button is pressed)
      //We have already determined that the string "temperature" has been recieved. 
      //Now let's determine if a 0 or a 1 was recieved. 
      
       LED_choice=client.parseInt();
      if (LED_choice == 1) { // the URL "/arduino/temperature/1" was sent 
          client.print("<br>Arduino says LED on."); //Turn the LED on by making the 
          //voltage HIGH
          digitalWrite(led, HIGH);

    }
    
    if (LED_choice == 0) { // the URL "/arduino/temperature/0" was sent
        client.print("<br>Arduino says LED off.");
        digitalWrite(led, LOW); //Turn the LED off by making the voltage LOW
    }
    
    }
     
     // Close connection and free resources.
    client.stop();
    client.flush();//discard any bytes that have been written to client but not 
    //yet read.
    hits++; //increment the "hits" counter by 1.
  }      

} 

Afterer uplading the sketch and webpage files to the Arduino Yun you can use WinSCP to connect to the Yun and see where the webages are located on the SD card.

File structure on the SD card

If you want to make updates to the webpage you can drag the files directly from your PC to the SD card using WinSCP. This method is much faster than having your files "piggy back" on an Arduino sketch that you upload via the Ardiuno IDE (i.e. using the sketch folder technique presented earlier). However, it is advised that you use the Arduino IDE to upload your webpage for the first time, since it creates the correct files for you in the correct directory.

Connect!

Now open up a web browser like Fire fox and type the following into the address field:

http://NAMEOFYOURYUN.local/sd/ where "NAMEOFYOURYUN" is the name you have given your Arduino Yun in the WiFi setup. You will see a list of all the webpages that are stored on the SD card.

Index of SD card seen from browser

Click on the name of your webpage (here we choose "WiFi_send_receive_example")

Let's turn the LED on.

Index of SD card seen from browser

Index of SD card seen from browser