Sending an 8-bit Unsigned Char in Java using the Processing Language

In a Processing (which is basically Java) application that I am writing, I need to send a packet of data over the serial port that consists of unsigned bytes that are 8 bits long. In C programming, it would just be a matter of using unsigned char data types. Java or Processing does not have an unsigned char data type.

The requirements for the application are to send a packet of data from an array over the serial port. The first two bytes in the packet are header bytes, followed by various data and command bytes with a checksum at the end. The code already runs on an Arduino with the data packet stored in an array as follows:

byte tx_cmd[12] = { 0x55, 0xAA,             // header
                    0x01, 0x00,             // device ID
                    0x01, 0x00, 0x00, 0x00, // input parameter
                    0x01, 0x00,             // command code
                    0x02, 0x01              // checksum
                  };

In this Arduino code the byte type is an unsigned 8-bit byte  — equivalent of an unsigned char in C, as Arduino programming is basically C / C++.

Processing / Java Data Types Equivalent to C Unsigned Char

Two obvious candidates that look like they should be the equivalent of a C unsigned char are the Java char and Java byte data types. These two data types have the following problems:

Java Char

The Java char data type is 16 bits long. Trying to put the data packet to send over the serial port into a char array would send two 8-bit bytes for every char variable sent. The Java char is also intended for characters, so trying to pack two bytes into a char would be bad programming practice.

Processing char reference.

Java Byte

The Java byte data type is 8 bits long, however it is a signed data type, not unsigned. The range of the byte is from 127 to -128. This differs from the Arduino byte data type which is 8 bits long and unsigned with a range from 0 to 255 (same as a C unsigned char).

Processing byte reference.

Attempting to Use the Byte Data Type

The following Processing code shows the problem when using a data packet array of the byte data type.

void setup() {
  byte[] tx_cmd = new byte[12];
  tx_cmd[0] = 0x55;
  tx_cmd[1] = 0xAA;
  tx_cmd[2] = 0x01;
  tx_cmd[3] = 0x00;
  tx_cmd[4] = 0x01;
  tx_cmd[5] = 0x00;
  tx_cmd[6] = 0x00;
  tx_cmd[7] = 0x00;
  tx_cmd[8] = 0x12;
  tx_cmd[9] = 0x00;
  tx_cmd[10] = 0x13;
  tx_cmd[11] = 0x01;
  
  for (int i = 0; i < 12; i++) {
    println(hex(tx_cmd[i]));
  }
}

When trying to run the code in the Processing IDE, it gives the following error:

cannot convert from int to byte

Which refers to the code in the line:

tx_cmd[1] = 0xAA;

The problem is that the the hexadecimal value of AA which is the decimal value of 170 is too big for the positive range of the byte data type which can have a maximum value of 127. None of the other numbers assigned to the array elements give an error because they are all less than 127 decimal.

 Solution to Sending an Unsigned Byte Using Processing / Java

Although the byte data type is signed, it still stores binary values from 0000 0000b to 1111 1111b (or 0x00 to 0xFF hexadecimal) with the most significant bit (MSB) being the sign bit which is set when the number is negative. The code only treats the byte as negative because the data type of the language being used says that it is a signed number.

When data is sent over the serial port, it is sent as bytes. The device receiving the data bytes on the other side can choose whether to treat the bytes as signed or unsigned, so the solution to sending the bytes is to convert the data bytes with values above 127 to their negative equivalents.

This is actually done very simply by casting the input integer to the byte data type, which cuts off the top bytes of the integer and puts the least significant byte of the integer into the byte variable.

void setup() {
  byte[] tx_cmd = new byte[12];
  tx_cmd[0] = (byte)0x55;
  tx_cmd[1] = (byte)0xAA;
  tx_cmd[2] = (byte)0x01;
  tx_cmd[3] = (byte)0x00;
  tx_cmd[4] = (byte)0x01;
  tx_cmd[5] = (byte)0x00;
  tx_cmd[6] = (byte)0x00;
  tx_cmd[7] = (byte)0x00;
  tx_cmd[8] = (byte)0x12;
  tx_cmd[9] = (byte)0x00;
  tx_cmd[10] = (byte)0x13;
  tx_cmd[11] = (byte)0x01;
  
  // print the array in hexadecimal and decimal
  for (int i = 0; i < 12; i++) {
    print("0x");
    print(hex(tx_cmd[i]));
    print(" = ");
    println(tx_cmd[i]);
    
  }
  
}

The output from the above code:

0x55 = 85
0xAA = -86
0x01 = 1
0x00 = 0
0x01 = 1
0x00 = 0
0x00 = 0
0x00 = 0
0x12 = 18
0x00 = 0
0x13 = 19
0x01 = 1

The number stored in the byte array will be displayed as the desired value when printed as a hexadecimal number. When printed as an integer, it will be displayed as a negative value if it contains a number greater than 127.

As the code shows, it is much easier and more efficient to cast the input integer to a byte and truncate the integer, than to try and calculate the equivalent negative value for the input byte.

Display Text on Arduino LCD from Web Page

The tutorial on how to send text from a web page to an Arduino LCD sets the Arduino, Ethernet shield and micro SD card up as a web server with LCD attached. Two HTML text inputs allow text to be sent to each line of the LCD from the web page hosted by the Arduino.

The image below shows the web page in a web browser that has sent text to the LCD.

Sending Text from a Web Page to Arduino LCD

Sending Text from a Web Page to Arduino LCD

Text is sent to the Arduino from the web browser over the network with an HTTP GET request when the button on the web page is clicked.

Go to the tutorial now →

HTML Text Box to Send Text to Arduino Web Server

An Arduino and Ethernet shield are used as a web server to host a web page that contains a text box. Text can be typed into the web page text box using a web browser and sent to the Arduino by clicking a button on the web page.

An HTML textarea is used in an HTML form to create the text box. JavaScript is used to send the text to the Arduino using a HTTP GET request when the button on the web page is clicked. This is useful for any Arduino project that needs to receive text from a web page using a text box.

The Arduino code for this project follows the format of the Ajax I/O web server from the Arduino Ethernet shield web server tutorial, except that it calls the JavaScript function that sends the GET request when the button on the web page is clicked rather than periodically sending the GET request to the Arduino web server.

The video below shows the Arduino web page being accessed by a web browser and text being sent to the Arduino.

 

Arduino Hardware, Software and HTML Page Setup

Hardware

An Arduino Uno and Arduino Ethernet shield with 2GB micro SD card were used to test the project. Most Arduino boards that are compatible with the Ethernet shield should work.

Setup

Copy the HTML from below to a file called index.htm on the micro SD card and insert it into the Ethernet shield micro SD card socket. Load the Arduino sketch from below to the Arduino — first change the MAC and IP address in the sketch to suit your own network. In the Arduino IDE Serial Monitor window, set the baud rate at the bottom of the window to 115200.

Running the Project

With the Arduino connected to the Ethernet network, first open the Serial Monitor window, then open a web browser and surf to the IP address set in the sketch. Text can be typed into the text box on the web page and sent to the Arduino. The Arduino will display the text in the Serial Monitor window if the line of text is not too long (the length is set by buffer arrays in the Arduino code).

Arduino Text Box Sketch

The Arduino text box sketch listing called text_area is shown below. Copy and paste it to the Arduino IDE.

/*--------------------------------------------------------------
  Program:      text_area

  Description:  Arduino web server that gets text from an HTML
                textarea text box on the hosted web page.
                The web page is stored on the micro SD card.
  
  Date:         23 June 2015
 
  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   90
// size of buffer that stores the incoming string
#define TXT_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
char txt_buf[TXT_BUF_SZ] = {0};  // buffer to save text to

void setup()
{
    // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);
    
    Serial.begin(115200);       // 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
                // limit the size of the stored received HTTP request
                // 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();

                        // print the received text to the Serial Monitor window
                        // if received with the incoming HTTP GET string
                        if (GetText(txt_buf, TXT_BUF_SZ)) {
                          Serial.println("\r\nReceived Text:");
                          Serial.println(txt_buf);
                        }
                    }
                    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();
                        }
                    }
                    // 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)
}

// extract text from the incoming HTTP GET data string
// returns true only if text was received
// the string must start with "&txt=" and end with "&end"
// if the string is too long for the HTTP_req buffer and
// "&end" is cut off, then the function returns false
boolean GetText(char *txt, int len)
{
  boolean got_text = false;    // text received flag
  char *str_begin;             // pointer to start of text
  char *str_end;               // pointer to end of text
  int str_len = 0;
  int txt_index = 0;
  
  // get pointer to the beginning of the text
  str_begin = strstr(HTTP_req, "&txt=");
  if (str_begin != NULL) {
    str_begin = strstr(str_begin, "=");  // skip to the =
    str_begin += 1;                      // skip over the =
    str_end = strstr(str_begin, "&end");
    if (str_end != NULL) {
      str_end[0] = 0;  // terminate the string
      str_len = strlen(str_begin);

      // copy the string to the txt buffer and replace %20 with space ' '
      for (int i = 0; i < str_len; i++) {
        if (str_begin[i] != '%') {
          if (str_begin[i] == 0) {
            // end of string
            break;
          }
          else {
            txt[txt_index++] = str_begin[i];
            if (txt_index >= (len - 1)) {
              // keep the output string within bounds
              break;
            }
          }
        }
        else {
          // replace %20 with a space
          if ((str_begin[i + 1] == '2') && (str_begin[i + 2] == '0')) {
            txt[txt_index++] = ' ';
            i += 2;
            if (txt_index >= (len - 1)) {
              // keep the output string within bounds
              break;
            }
          }
        }
      }
      // terminate the string
      txt[txt_index] = 0;
      got_text = true;
    }
  }

  return got_text;
}

// 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;
}


Text Box HTML Page

Copy the HTML below and save it to a file called index.htm on the SD card.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Text Box using textarea</title>
        <script>

        strText = "";
        
        function SendText()
        {
            nocache = "&nocache=" + Math.random() * 1000000;
            var request = new XMLHttpRequest();
            
            strText = "&txt=" + document.getElementById("txt_form").form_text.value + "&end=end";
            
            request.open("GET", "ajax_inputs" + strText + nocache, true);
            request.send(null);
        }
        </script>
    </head>

    <body onload="GetArduinoIO()">
        <form id="txt_form" name="frmText">
            <textarea name="form_text" rows="10" cols="40"></textarea>
        </form>
        <input type="submit" value="Send Text" onclick="SendText()" />
    </body>

</html>

How the Text Box Sketch Works

JavaScript embedded in the web page sends the text from the text box to the Arduino as part of a HTTP GET request when the button on the web page is clicked.

Format of the String

This image shows what the string looks like before it is sent to the Arduino.

HTML Text Box and Text String

HTML Text Box and Text String

The text from the text box is put between &txt= and &end=end before being sent. The Arduino uses this text to find the string in the incoming HTTP GET request.

When the text reaches the Arduino, it has been altered with the spaces in the text changed to %20 as shown in the image below.

String from the Text Box Received by Arduino

String from the Text Box Received by Arduino

The Arduino sketch must change %20 in the text back to spaces.

Processing the String in the Arduino Sketch

The function GetText() is used to get the text box string from the incoming HTTP GET request. The HTTP_req array holds the beginning of the incoming GET request as shown in the above image — starting with GET /ajax_inputs&txt…

The GetText() function first gets a pointer to the beginning of the text box string by searching for &txt= and then terminating the string when it finds &end. A for loop is used to copy the string to the txt array (which is a pointer to the global txt_buf array). While the copying is taking place, the code looks for spaces that are encoded as %20 and changes them into spaces.

Limitations of the Arduino Text Box Sketch

The sketch is limited by the size of the buffer that saves the incoming HTTP GET request as well as the size of the array that stores the string from the text box. These two array buffers have been kept small so that the code will be able to run on an Arduino Uno.

If the string from the text box is too big for the HTTP buffer on the Arduino so that the string is truncated before the terminating &end, then the text will not be displayed in the Serial Monitor window because the GetText() function will return false.

This is just a simple demonstration that uses GET to send text. It would be better to send the text using POST instead and this will be added as a tutorial at a later stage.

 

Using HTML Drop-down Select Boxes for Hour and Minute on Arduino Web Server

An Arduino and Ethernet shield with SD card are used as a web server to host a page that allows a user to select hour and minute values from two HTML drop-down select boxes. The time sent to the Arduino can be used to set a real-time clock from a web page or for other time related purposes.

To demonstrate that the Arduino is getting the time values from the web page, they are displayed in the Serial Monitor window of the Arduino IDE. JavaScript in the hosted HTML web page is used to send the hour and minute time values to the Arduino periodically. This allows the code to easily be integrated with the Arduino Ajax web server code. The code could also be adapted to send the time only when a button is clicked.

This video shows the sketch running and the selected time values from the web page being sent to the Serial Monitor window:

 

Web Server Hardware

An Arduino Uno, Ethernet shield and 2GB micro SD card were used for testing the code. Any Arduino board that is compatible with the Ethernet shield should work.

Setting up the Web Server

The Arduino sketch below must be loaded to the Arduino with Ethernet shield. The HTML web page from below must be copied to a file called index.htm on the micro SD card. Insert the micro SD card into the socket on the Ethernet shield.

Arduino Web Server Sketch

Copy this code and paste it to the Arduino IDE for loading to the Arduino board with Ethernet shield and SD card. Change the MAC and IP address to suit your own system.

/*--------------------------------------------------------------
  Program:      drop_down_select

  Description:  Arduino web server that gets hour and
                minute from two drop-down select boxes on an
                HTML page.
                The web page is stored on the micro SD card.
  
  Date:         22 June 2015
 
  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   60

// 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(115200);       // 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()
{
    byte hour;
    byte minute;
    
    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
                // limit the size of the stored received HTTP request
                // 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();
                        // print the received hour and minute to the Serial Monitor window
                        // if received with the incoming HTTP GET string
                        if (GetTime(&hour, &minute)) {
                          Serial.print("Hour: ");
                          Serial.println(hour);
                          Serial.print("Minute: ");
                          Serial.println(minute);
                        }
                    }
                    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();
                        }
                    }
                    // 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)
}

// extract hour and minute from the incoming HTTP GET data string
// returns true only if both the hour and minute have been received
boolean GetTime(byte *hr, byte *mn)
{
  boolean valid_time = false;  // hour and minute received flag
  char *str_part;              // pointer to part of the HTTP_req string
  char str_time[3] = {0};      // used to extract the times from HTTP_req string
  
  // get pointer to the beginning of hour data in string
  str_part = strstr(HTTP_req, "&h=");
  if (str_part != NULL) {
    // get the hour from the string
    str_time[0] = str_part[3];
    str_time[1] = str_part[4];
    *hr = atoi(str_time);
    // get pointer to the beginning of minute data in string
    str_part = strstr(HTTP_req, "&m=");
    if (str_part != NULL) {
      // get the minute from the string
      str_time[0] = str_part[3];
      str_time[1] = str_part[4];
      *mn = atoi(str_time);
      // got the hour and the minute
      valid_time = true;
    }
  }

  return valid_time;
}

// 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;
}


Arduino Hosted HTML Page

This code gets copied to the index.htm file on the micro SD card.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Drop-Down Select Box Example</title>
        <script>
        strHour = "";
        strMin = "";
        function GetArduinoIO()
        {
            nocache = "&nocache=" + Math.random() * 1000000;
            var request = new XMLHttpRequest();
            
            // get the values from the drop-down select boxes
            var sel_hour = document.getElementById("selHour");
            if (sel_hour.selectedIndex > 0) {
                strHour = "&h=" + sel_hour.options[sel_hour.selectedIndex].text;
            }
            else {
                // the first item in the drop-down box is invalid text, so clear the string
                strHour = "";
            }
            
            var sel_min = document.getElementById("selMin");
            if (sel_min.selectedIndex > 0) {
                strMin = "&m=" + sel_min.options[sel_min.selectedIndex].text;
            }
            else {
                strMin = "";
            }

            // send HTTP GET request with LEDs to switch on/off if any
            request.open("GET", "ajax_inputs" + strHour + strMin + nocache, true);
            request.send(null);
            setTimeout('GetArduinoIO()', 3000);
        }
    </script>
    </head>

    <body onload="GetArduinoIO()">
        <select id="selHour">
            <option selected="selected" value="">Select Hour</option>
            <option value="00">00</option>
            <option value="01">01</option>
            <option value="02">02</option>
            <option value="03">03</option>
            <option value="04">04</option>
            <option value="05">05</option>
            <option value="06">06</option>
            <option value="07">07</option>
            <option value="08">08</option>
            <option value="09">09</option>
            <option value="10">10</option>
            <option value="11">11</option>
            <option value="12">12</option>
        </select>
        <select id="selMin">
            <option selected="selected" value="">Select Minute</option>
            <option value="00">00</option>
            <option value="01">01</option>
            <option value="02">02</option>
            <option value="03">03</option>
            <option value="04">04</option>
            <option value="05">05</option>
            <option value="06">06</option>
            <option value="07">07</option>
            <option value="08">08</option>
            <option value="09">09</option>
            <option value="10">10</option>
            <option value="11">11</option>
            <option value="12">12</option>
            <option value="13">13</option>
            <option value="14">14</option>
            <option value="15">15</option>
            <option value="16">16</option>
            <option value="17">17</option>
            <option value="18">18</option>
            <option value="19">19</option>
            <option value="20">20</option>
            <option value="21">21</option>
            <option value="22">22</option>
            <option value="23">23</option>
            <option value="24">24</option>
            <option value="25">25</option>
            <option value="26">26</option>
            <option value="27">27</option>
            <option value="28">28</option>
            <option value="29">29</option>
            <option value="30">30</option>
            <option value="31">31</option>
            <option value="32">32</option>
            <option value="33">33</option>
            <option value="34">34</option>
            <option value="35">35</option>
            <option value="36">36</option>
            <option value="37">37</option>
            <option value="38">38</option>
            <option value="39">39</option>
            <option value="40">40</option>
            <option value="41">41</option>
            <option value="42">42</option>
            <option value="43">43</option>
            <option value="44">44</option>
            <option value="45">45</option>
            <option value="46">46</option>
            <option value="47">47</option>
            <option value="48">48</option>
            <option value="49">49</option>
            <option value="50">50</option>
            <option value="51">51</option>
            <option value="52">52</option>
            <option value="53">53</option>
            <option value="54">54</option>
            <option value="55">55</option>
            <option value="56">56</option>
            <option value="57">57</option>
            <option value="58">58</option>
            <option value="59">59</option>
        </select>
    </body>

</html>

Running the Web Server Drop-down Select Box Project

With the index.htm file on the SD card and the sketch loaded to the Arduino, open the Serial Monitor window and then use a web browser to surf to the IP address that is set in the sketch.

Change the hour and minute values in the drop-down boxes to valid time values to see the hour and minute displayed in the Serial Monitor window. Both the hour and minute must be set to valid values before anything is displayed.

Improved Arduino Live Cricket Score Ticker

The new Arduino live cricket score ticker code improves on the previous version of the ticker by saving the XML live cricket results to a file on an SD card. This allows the cricket score data to be randomly accessed for the desired data. A micro SD card inserted into the micro SD card socket on the Arduino Ethernet shield is used for saving the XML file.

Parsing XML using Arduino

XML parsing functions used in this project can be used with similar Arduino projects that need to parse XML files. The functions are used to search for specified tags in the XML file and if found can then be used to find child tags in the parent tags. The functions are used to drill down to the desired child tag in order to extract the required data from these tags.

With the XML file saved to SD card, it is possible for a sketch to reliably parse the file even if the order of the tag attributes is changed. The previous ticker code tried to parse the XML file on the fly as it gets sent to the Arduino and therefore relies on the tags and attributes being in a specific order.

Memory Limitations

An Arduino MEGA is needed for the new ticker because the Arduino Uno does not have enough memory to run the sketch. The blog post that compares the amount of memory used by various sketches shows some example sketches and how much of the Arduino Uno memory they use. From this comparison, it can be seen that the Arduino Uno memory can get used up fairly quickly as sketches start to use more libraries and get slightly more complex than some of the example sketches.

Go to the Improved Arduino Cricket Score Ticker Code →