.

Web browser accessing Arduino data

rgbled_jsfiddleThis article shows how an external web site can change i/o values on your Arduino.   All you need is a RGB LED and an Arduino with an Ethershield or the newer Arduino Ethernet.  (The other choice was a module around the Microchip ENC28J60.  This has a lower price, but relies of the Arduino for the TCP/IP stack.)

To develop the web page, we use jsFiddle.net that enables rapid prototyping and testing.  The web page consists of HTML, JavaScript and a style sheet.  The JavaScript code handles the communication with the Arduino.  No need to embedding web pages in your sketches, or shuffling an µSD card back and forth each time you want to try something new.

Goal

In this example we use a web interface to control a RGB LED on the Arduino.  The web interface has a slider for each primary color.  When a slider is changed, the new value is sent to the Arduino.  The sketch on the Arduino then adjust the intensity of that color.

User Interface

jQueryMobile lets you build a sleek user interface with minimum effort.  The complete HTML code for the page that we will be using is shown below.  Note that when using jsFiddle, you only need the <body> element  It will add the <head> based the libraries that you select.  For the complete page with the CSS  and JavaScript, please refer to the web page code further down.

<!DOCTYPE html>
<html class="ui-mobile">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
        <base href=".">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,user-scalable=no">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="apple-mobile-web-app-title" content="Web browser accessing Arduino data">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
        <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.2/jquery.mobile.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.2/jquery.mobile.min.js"></script>
    </head>
    <body>
    <div data-role="page" id="pageone" data-theme="b">
        <div data-role="content">
            <div id="slider-r-div">
               <label for="slider-r" class="ui-hidden-accessible">Red:</label>
               <input id="slider-r" type="range" name="r" value="0" min="0" max="255" data-highlight="true" data-role="slider"></input>
            </div>
        <div id="slider-g-div">
                <label for="slider-g" class="ui-hidden-accessible">Green:</label>
                <input id="slider-g" type="range" name="g" value="0" min="0" max="255" data-highlight="true" data-role="slider"></input>
            </div>
            <div id="slider-b-div">
                <label for="slider-b" class="ui-hidden-accessible">Blue:</label>
                <input id="slider-b" type="range" name="b" value="0" min="0" max="255" data-highlight="true" data-role="slider"></input>
            </div>
        </div>
    </div>
</body>
</html>

Challenges

“A life without challenge, a life without hardship, a life without purpose, seems pale and pointless. With challenge come perseverance and gumption. With hardship come resilience and resolve. With purpose come strength and understanding.”  ― Terry Fallis, The High Road

While writing the code, I encountered and tackled a few unexpected things.  First, the Arduino Ethernet library could not support multiple clients to the same server port.  Second, the Ethernet controller didn’t come up reliably.  Last, the same-origin policy, intended to protect web surfers, required a work around.  Let’s look at these issues one by one.

1. Multiple clients

We like to support up to four simultaneous browser sessions that communicate with the Arduino.  Two support this, we need address two things.  First, the Arduino Ethernet library needs to be patched to allow multiple clients to the same server port.  A detailed description can be found here.  Second, the browser needs to periodically read the color values from the Arduino, in case another browser session changed them.  This is done by calling setInterval(scheduduledUpdate, 1000) from JavaScript.

2. Ethernet controller timing

After searching the internet and finally reading the datasheet, I realized that the Wiznet based Ethernet Controller takes longer than the Arduino to come out of reset.  I later found a good write up at freetronics.  It comes down to that the Ethernet Controller needs an additional 50 milliseconds before it is ready to communicate with the Arduino.

3. Same-origin policy (JSON-P)

As a JavaScript developer, you probably used asynchronous JavaScript and XML (Ajax) to exchange data with a server or update a web page.  While sending an Ajax request to a server in the same domain is fairly straight forward, exchanging data with a server on different domain is a different story.  The same-origin policy restricts scripts running in a browser to pages in the same domain. With your web site on jsFiddle.com and your Arduino on your local LAN, we need to work around this policy.  We exploit the fact that <script> tags are not subjected to the same-origin policy.  This is the same method that allows you to include the jQueryMobile library even it it is hosted on Google’s content delivery network.

JSONP requests are made by dynamically requesting a <script> tag from the Arduino.  The Arduino responds with JSON wrapped in a function call.  When making the request, the function name is specified as a callback function. When the server responds, the callback function (which must exist on your page) is executed with the JSON data as parameters.  JSON is a human-readable format consisting of attribute-value pairs

For example, the browser evaluates the code.  It replaces the missing callback name (?) with a unique name for the anonymous function, and adds an unique _= parameter to prevent caching by the browser.

$.getJSON("http://10.0.1.121/json" + "?callback=?", { r: 12 }, function (jsonData) {
    console.log(jsonData);
});

The browser will treat this as the HTML code shown below, and sent it over HTTP to the Arduino.

<script src="http://10.0.1.121/json?r=12&callback=jQuery210046821082942187786_1431057375516&_=1431057377282"></script>

The Arduino receives this as

GET /json?r=12&callback=jQuery210015603271196596324_1431060286376&_=143106

and replies with the current values for red, green and blue

jQuery210015603271196596324_143106028637({ r: 12, g: 20, b: 20 })

The browser then executes this JavaScript.

function (jsonData = { r: 12, g: 20, b: 20 }) {
    console.log(jsonData);
}

That concludes the exchange.

The code

Now where we have all been waiting for.  As mentioned earlier, the web page is hosted on jsfiddle.  The sketch should be placed on the Arduino.  I tested the sketch with the UNO R3 and version 1.6.3 of the IDE.  Other versions may require some adjustments.

Bread board

Use a common cathode  RGB LED, or just three separate LEDs.  On the Arduino, digital outputs 5, 6 and 9 are each connected through a 220Ω current limiting resistor to the corresponding LED anodes.  The cathode is, as you might guess, connected to ground.  (note to self: use KiCAD and embed using CircuitBee.)

RGB-LED_schem RGB-LED_bb

Web page

jsFiddle to develop the HTML, JavaScript and CSS code for the web page.  For development, I use the external resource firebug-lite-debug.js that among many other things shows the debug output (console log).

The web page presents three sliders.  The fiddle is embedded below.  Click on the Edit on the top right to make changes.  Resize the top of the result tab to see the sliders.

Arduino Sketch

The sketch is not very earth shaking.  It gets an DHCP assigned IP address.  Make sure that you change the MAC address in the sketch listed below.  You should use the MAC that was assigned to your shield.  If you don’t have that, at least make sure that the number unique on your network.

The sketch listens on port 80.  It parses the HTTP command into the command itself (GET), the URL and the parameters.  One of the parameters is the name of the callback function as explained when we discussed the JSON-P protocol.  Other parameters may be ‘r’ for red, ‘g’ for green and ‘b’ for blue.  When found, their value is stored in the sketch, and used to adjust the intensity of that primary color  At the end it sends a JSON-P response.  The code is hosted at codebender, and embedded below.  You can also download the archived files, or get them through GitHub.

https://codebender.cc/embed/sketch:114939

https://codebender.cc/embed/serialmonitor

Have fun! You can leave comments below.

Johan Vonk

Johan Vonk

Johan is a student in Los Altos, CA.I see education as the foundation upon which entrepreneurs are able to build innovative organizations and execute their vision for the future.
Johan Vonk

Latest posts by Johan Vonk (see all)

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  

  

  

Protected with IP Blacklist CloudIP Blacklist Cloud