Example Code for Yun using HTTP GET and Post Methods

Hello all, I am new to the forum. I do not have a question to ask, but wanted to share some code for the Yun. The Arduino Yun has two processors. One is the normal Arduino ATmega32u4. The second processor is an AR9331 processor that runs a version OpenWRT Linux. The OpenWRT Linux is a console based Linux (i.e. no mouse or graphic desktop, just typing text commands).

I got the Yun to experiment with Linux and WIFI. I had use an ETHERNET shield with a Uno to control a 3 color LED and report the current for various on/off conditions of the colors. I used the code of Dr. Simon Monk’s Programming Arduino, Getting Started with Sketches as a starting point. The control and reporting with Uno/ETHERNET shield combination was not that difficult.

However, when I tried to do the same for the Yun, I found it was a bit more difficult. In the Uno/ETHERNET shield code, the HTML code was a simple form that Uno passed to the client browser.

The Yun separates the HTML code from the Arduino processor. The Linux processor handles the HTML code and Arduino processor handles the control and measuring functions. The problem area is ensuring the two processors communicate with each other. There is the Bridge library, but, it is not always clear on what to use.

With the Yun, one needs to include javascript code to handle the browser requests and transfers. The Yun Linux web server has two special pages to do this. The first is called /arduino/. The page has no strict format requirements. If one wants to pass string data to the Arduino side, one writes the data to the /arduino/ page. The arduino sketch code after initialization of the client connection, can get the data with client.readString()

The second web page is /data/ for transferring string data to the client browser. This page uses a JSON (Javascript Object Notation) object. The arduino side uses the Bridge.put(“value”, string_data) to place the

data on the /data/ page.

The Linux web server needs to use proper HTML/Javascript code to ensure the data from the two special pages is done correctly. This requires the use of the HTTP methods of GET and POST. The JAXA extension of javascript

provides an object called XMLHttpRequest() with methods to do this. To retrieve the data, one needs to use the GET method with the XMLHttpRequest() for the data on /data/ page. To transfer from the client browser the data to /data/ page, the POST method of XMLHttpRequest() is used. Both are a bit hard to use, especially after learning Arduino coding.

The HTML/Javascript code needs to place in directory that is accessible by the Linux web server. If one has expanded the storage of Yun by the use of a microSD flash card, then there is a directory called arduino on the

first partition of microSD flash card. The arduino director contains a directory named www. The www directory is the place to put the HTML Javascript code.

It took me about two weeks to sort it all out compared to Uno/ETHERNET shield effort of one day. I decided to post this in order that it may help someone else.

Here is the HTML code that I used:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>LED Color Web Page</title>
      <script type="text/javascript">
      var old = 'Current is 99.99 mA'; //inital test value for old
      
	  function selectColor()
	   {
		var pickedColor = color.options[color.selectedIndex];
		var url = "/arduino/" + pickedColor.value
		var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("POST", url, true); //false is synchronous mode, asynchronous is preferred
        xmlhttp.setRequestHeader("Content-Type","text/plain;charset=UTF-8");
        xmlhttp.send(null);
	   }
	   
	  function GetSensor()
	   {
	   var xmlhttp = new XMLHttpRequest();
       var url = "/data/get/";  //this is the only form that works
       xmlhttp.open("GET", url, true); //false is synchronous mode, asynchronous is preferred       
       xmlhttp.onreadystatechange = function() 
        {
       if (xmlhttp.readyState == 4 && xmlhttp.status == 200) 
         {
        var myResponse = xmlhttp.responseText  //needto do string operations on result
        var startPnt = myResponse.indexOf('Current is');
        var endPnt = myResponse.indexOf('mA') +2;
        if (startPnt > 0)
          { //parse out needed data
          var needData = myResponse.substring(startPnt, endPnt);
          if (needData !== old)
           { // have new data for update
            document.getElementById("measured_I").innerHTML = needData;
            old = needData;
           }
	      }
         }
        }
       xmlhttp.send(null);
       }

    setInterval(GetSensor, 380);  //poll for new data every 380 mSec
 
    </script>
  </head>
  
  <body>
    <h1 Align=Center>Arduino Test Web Server
using Java Script</h1>
    <h2 Align=Center>This Manlipulates LED devices attached to a Yun</h2>
    <p Align=Center>Press the button to select a color</p>
    <hr>
    <p>Menu Selection type button</p>
    <p Align=Center>
		<select id="color" name="Select Color" size="1" onclick="selectColor()">
		<option value="black">Black</option>
		<option value="red">Red</option>
		<option value="green">Green</option>
		<option value="blue">Blue</option>
		<option value="yellow">Yellow</option>
		<option value="cyan">Cyan</option>
		<option value="magenta">Magenta</option>
		<option value="white">White</option>
		</select>
	</p><HR>
	<p>Now to get information from a sensor</p>
	<p id="measured_I" Align=Center>Awaiting Arduino Current Update</p>
  </body>
</html>

Here is the Arduino Sketch code for the project:

/*
 wexRGB 2 Feb. 2015, test of Bridge.put to see how it works
 A copy of the wexRGB.html and a copy of zepto.js, a  minimized 
 version of jQuery need to be placed in /mnt/sda1/arduino/www.  If the 
 IDE sees the Yun then it is possible to do this with IDE when the files
 are in sketch directory .  If manually uploaded to 
 yun, rename wexRGB.html to index.html in sda1/arduino/www/webRGB.
 To use, open browser to  http://your_yun_name.local/sd/webRGB/

 RGB LED pins are:
 3 = redPin, 4 = greenPin, 5 = bluePin for LED in array
 
 The common cathode is thru 51 ohm resistor to GND.  This measures current.
 The resistor for the red pin is 330 ohms. Green resistor is 510 ohms.The blue
 resistor is 270 ohms.  The different resistor values compensate for the volt drops
 of color LED devices and help to provide the right color balance.  

 */

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

int ledPins[] = {3, 4, 5}; //Red, Green, Blue

/*LED is common cathode, need +5 for LED ON
  Common cathode is the longest lead, second in from case flat
  for my device.
  common anode, ON = LOW, OFF = High
*/

const boolean ON = HIGH;
const boolean OFF = LOW;
//array defining LED state for color, these can not be constants.
boolean RED[] = {ON, OFF, OFF};
boolean GREEN[] = {OFF, ON, OFF};
boolean BLUE[] = {OFF, OFF, ON};
boolean YELLOW[] = {ON, ON, OFF};
boolean CYAN[] = {OFF, ON, ON};
boolean MAGENTA[] = {ON, OFF, ON};
boolean WHITE[] = {ON, ON, ON};
boolean BLACK[] = {OFF, OFF, OFF};

// Listen on default port 5555, the webserver on the Yun
// will forward there all the HTTP requests for us.
YunServer server;
String readString;
String command;
String currentVal;

void setup() {
  pinMode(ledPins[0], OUTPUT); //pin 3 for red
  pinMode(ledPins[1], OUTPUT); //pin 4 for green
  pinMode(ledPins[2], OUTPUT); //pinn 5 for blue
  // Bridge startup
  Bridge.begin();

  /* Listen for incoming connection only from localhost
  (no one from the external network could connect) */
  server.listenOnLocalhost();
  server.begin();
}

void loop() {
  // Get clients coming from server
  YunClient client = server.accept();

  // There is a new client?
  if (client) {
    // read the command
    String command = client.readString();
    command.trim(); //kill whitespace
 
   //Now to process the command from string to the boolean color array
   
    if (command == "black")
     {
      setColor(ledPins, BLACK);
      currentMeasure();
     }
    if (command == "red")
     {
      setColor(ledPins, RED);
     currentMeasure();
     }
    if (command == "green")
     {
      setColor(ledPins, GREEN);
     currentMeasure();
     }
    if (command == "blue")
     {
      setColor(ledPins, BLUE);
      currentMeasure();
     }
     if (command == "yellow")
     {
      setColor(ledPins, YELLOW);
      currentMeasure();
     }
    if (command == "cyan")
     {
      setColor(ledPins, CYAN);
      currentMeasure();
     }
    if (command == "magenta")
     {
      setColor(ledPins, MAGENTA);
      currentMeasure();
     }
    if (command == "white")
     {
     setColor(ledPins, WHITE);
     currentMeasure();
     }
     
    // Close connection and free resources.
    client.stop();
  }

  delay(50); // Poll every 50ms
}

void setColor(int* led, boolean* color)
 {
 for(int i = 0; i < 3; i++){
  digitalWrite(led[i], color[i]);
  }
 }
 
void currentMeasure()
  {
    int rawVal = analogRead(A0);
    float milliAmp = rawVal / 10.4346;
    String tmp = String(milliAmp);
    tmp= "Current is " + tmp + " mA";
    //Note: Bridge.put does only string
    Bridge.put("value",tmp);
  }

I found W3schools. com tutorials very helpful in doing this project. I hope this helps.