Created on: 28 March 2013
Part 15 of the Arduino Ethernet Shield Web Server Tutorial
A gauge component is used to display the analog value from one of the Arduino's analog pins on a web page. The dial gauge is updated using Ajax.
The gauge is written in JavaScript and uses the HTML5 canvas. The gauge is used as a component (unmodified) and is simply set up to display the analog value of one of the Arduino analog pins. The value is updated every 200ms.
This video shows the gauge on the web page that is hosted by the Arduino web server.
The gauge component is written by Mykhailo Stadnyk and can be downloaded from Mikhus at github. Also see a blog article on the gauge.
The JavaScript code from the file gauge.min.js (downloaded from the above github link) was used on the web page in this part of the tutorial.
The Arduino sketch for this part of the tutorial is shown here.
/*-------------------------------------------------------------- Program: eth_websrv_SD_Ajax_gauge Description: Arduino web server web page displays Arduino analog value on a dial gauge. The web page is stored on the SD card. Ajax is used to update the analog value on the web page. Hardware: Arduino Uno and official Arduino Ethernet shield. Should work with other Arduinos and compatible Ethernet shields. 2Gb micro SD card formatted FAT16. Potentiometer interfaced to A2 analog input. Software: Developed using Arduino 1.0.5 software Should be compatible with Arduino 1.0 + SD card contains web page called index.htm References: - WebServer example by David A. Mellis and modified by Tom Igoe - SD card examples by David A. Mellis and Tom Igoe - Ethernet library documentation: http://arduino.cc/en/Reference/Ethernet - SD Card library documentation: http://arduino.cc/en/Reference/SD - Gauge from: https://github.com/Mikhus/canv-gauge Date: 27 March 2013 Modified: 19 June 2013 Author: W.A. Smith, http://startingelectronics.org --------------------------------------------------------------*/ #include <SPI.h> #include <Ethernet.h> #include <SD.h> // size of buffer used to capture HTTP requests #define REQ_BUF_SZ 50 // MAC address from Ethernet shield sticker under board byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 0, 20); // IP address, may need to change depending on network EthernetServer server(80); // create a server at port 80 File webFile; // the web page file on the SD card char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string char req_index = 0; // index into HTTP_req buffer void setup() { // disable Ethernet chip pinMode(10, OUTPUT); digitalWrite(10, HIGH); Serial.begin(9600); // for debugging // initialize SD card Serial.println("Initializing SD card..."); if (!SD.begin(4)) { Serial.println("ERROR - SD card initialization failed!"); return; // init failed } Serial.println("SUCCESS - SD card initialized."); // check for index.htm file if (!SD.exists("index.htm")) { Serial.println("ERROR - Can't find index.htm file!"); return; // can't find index file } Serial.println("SUCCESS - Found index.htm file."); Ethernet.begin(mac, ip); // initialize Ethernet device server.begin(); // start to listen for clients } void loop() { EthernetClient client = server.available(); // try to get client if (client) { // got client? boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { // client data available to read char c = client.read(); // read 1 byte (character) from client // buffer first part of HTTP request in HTTP_req array (string) // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1) if (req_index < (REQ_BUF_SZ - 1)) { HTTP_req[req_index] = c; // save HTTP request character req_index++; } // last line of client request is blank and ends with \n // respond to client only after last line received if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); // remainder of header follows below, depending on if // web page or XML page is requested // Ajax request - send XML file if (StrContains(HTTP_req, "ajax_inputs")) { // send rest of HTTP header client.println("Content-Type: text/xml"); client.println("Connection: keep-alive"); client.println(); // send XML file containing input states XML_response(client); } else { // web page request // send rest of HTTP header client.println("Content-Type: text/html"); client.println("Connection: keep-alive"); client.println(); // send web page webFile = SD.open("index.htm"); // open web page file if (webFile) { while(webFile.available()) { client.write(webFile.read()); // send web page to client } webFile.close(); } } // display received HTTP request on serial port Serial.print(HTTP_req); // reset buffer index and all buffer elements to 0 req_index = 0; StrClear(HTTP_req, REQ_BUF_SZ); break; } // every line of text received from the client ends with \r\n if (c == '\n') { // last character on line of received text // starting new line with next character read currentLineIsBlank = true; } else if (c != '\r') { // a text character was received from client currentLineIsBlank = false; } } // end if (client.available()) } // end while (client.connected()) delay(1); // give the web browser time to receive the data client.stop(); // close the connection } // end if (client) } // send the XML file containing analog value void XML_response(EthernetClient cl) { int analog_val; cl.print("<?xml version = \"1.0\" ?>"); cl.print("<inputs>"); // read analog pin A2 analog_val = analogRead(2); cl.print("<analog>"); cl.print(analog_val); cl.print("</analog>"); cl.print("</inputs>"); } // sets every element of str to 0 (clears array) void StrClear(char *str, char length) { for (int i = 0; i < length; i++) { str[i] = 0; } } // searches for the string sfind in the string str // returns 1 if string found // returns 0 if string not found char StrContains(char *str, char *sfind) { char found = 0; char index = 0; char len; len = strlen(str); if (strlen(sfind) > len) { return 0; } while (index < len) { if (str[index] == sfind[found]) { found++; if (strlen(sfind) == found) { return 1; } } else { found = 0; } index++; } return 0; }
This sketch is a slightly modified version of the sketch from the previous part of this tutorial (part 14).
The sketch sends a single analog value from Arduino pin A2 to the web browser which is then fed to the dial on the web page. The analog value is updated on the web page using Ajax and the value is sent as part of an XML file from the Arduino.
The web page hosted by the Arduino web server is stored on a micro SD card on the Arduino Ethernet shield.
The web page for this example is shown here.
The web page is a modified version of the web page used in the previous part of this tutorial.
The gauge is made available to the web page by inserting the gauge code between the script tags in the head of the web page HTML code.
The gauge is displayed by using the HTML5 canvas tag in the body of the HTML.
The analog value from the Arduino is received in the same way as it was in the previous part of this tutorial and displayed at the top of the web page in the same way as the previous part of this tutorial. The analog value is also saved to the JavaScript variable data_val so that it can be used by the gauge.
The value in data_val is fed to the gauge by using the line of JavaScript in the data-onready property of the canvas tag:
setInterval( function() { Gauge.Collection.get('an_gauge_1').setValue(data_val);}, 200);
The 200 in the above line tells the gauge to update every 200ms (200 milliseconds).
The gauge updates every 200ms, and the Ajax request for an analog value is also set to 200ms.
The timing for the Ajax refresh of the analog data is done in this line of JavaScript code from the web page:
setTimeout('GetArduinoInputs()', 200);
This refresh rate may cause a problem on a busy or slow network. If there are any problems, try changing this value to 1000 to make the analog value refresh every second.
Wire up the potentiometer as shown in the circuit diagram of part 9 of this tutorial – leave the push buttons shown in the diagram off, they will not be used.
Copy the web page (index.htm) to a micro SD card and insert it into the card slot of the Arduino Ethernet shield.
Load the above sketch to the Arduino web server. The web page is available for download below.
Download the web page source code (index.htm) for this part of the tutorial here:
Arduino_web_gauge.zip (6.3 kB)
The license for the gauge is included in the download as a text file.