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 →

A Comparison of Arduino Sketch Sizes in Memory

A comparison of several Arduino sketches from the Arduino code examples, as well as some code that uses a combination of library functions, shows how much memory is used in an Arduino Uno. This gives a rough idea of what the Arduino Uno is capable of handling in terms of memory usage / sketch size before having to move up to an Arduino that has more memory such as the Arduino MEGA.

Memory Usage in the Arduino IDE

Older versions of the Arduino IDE only showed the amount of Flash memory (non-volatile memory) used by an Arduino sketch at compile time i.e. when the Verify icon is clicked on the toolbar.

Newer versions of the Arduino IDE now show both the amount of Flash memory and SRAM memory that a sketch will use after compiling. The amount of SRAM memory used does not include local variables, however the compiler message shows the amount of SRAM left for local variables.

Arduino IDE Showing Sketch Memory Usage

Arduino IDE Showing Sketch Memory Usage

 

 

 

 

 

 

 

 

 

 

 

The above image shows the Arduino IDE after compiling. The area below the sketch shows the messages from the compiler that displays the sketch memory usage.

Arduino Sketch Memory Usage Examples

The examples below show the memory usage reported by the Arduino IDE compiler. Arduino IDE version 1.6.4 compiling for an Arduino Uno is used for all the examples.

Most of the sketches can be found in the Arduino IDE examples under File –> Examples as shown below, a link is given to sketches that are not found in with the IDE examples. The SRAM usage does not include SRAM used by local variables. The Flash memory maximum size of 32,256 bytes is the Arduino Uno Flash memory size of 32,768 bytes, minus 0.5kB used for the boot loader program.

Blinking An LED

File –> Examples –> 01.Basics –> Blink
This simple sketch blinks the on-board LED on and off at a set interval.

Flash usage: 1,030 bytes (3%) of 32,256
SRAM usage: 9 bytes of 2,048

Reading Analog Input

File –> Examples –> 01.Basics –> AnalogReadSerial
Reads a single analog value and prints it to the serial port.

Flash usage: 2,382 bytes (7%) of 32,256
SRAM usage: 184 bytes (8%) of 2,048

Reading Digital Input

File –> Examples –> 01.Basics –> DigitalReadSerial
Reads the state of a single digital input and prints the result to the serial port.

Flash usage: 2,704 bytes (8%) of 32,256
SRAM usage: 184 bytes (8%) of 2,048

Using the String Object

File –> Examples –> 08.Strings –> StringLength
Measures the length of a string sent over the serial port using a String object.

Flash usage: 3,966 bytes (12%) of 32,256
SRAM usage: 300 bytes (14%) of 2,048

Getting SD Card Information

File –> Examples –> SD –> CardInfo
Used for testing a SD card.

Flash usage: 1,502 bytes (35%) of 32,256
SRAM usage: 1,348 bytes (65%) of 2,048

Writing To and Reading From the SD Card

File –> Examples –> SD –> ReadWrite
Writes text to a file on an SD card and then reads the text back from the file.

Flash usage: 12,930 bytes (40%) of 32,256
SRAM usage: 992 bytes (48%) of 2,048

A Simple Web Server

File –> Examples –> Ethernet –> WebServer
A simple web server that hosts a web page displaying values read from analog pins. Does not used the SD card.

Flash usage: 12,612 bytes (39%) of 32,256
SRAM usage: 552 bytes (26%) of 2,048

A Simple Web Client

File –> Examples –> Ethernet –> WebClient
A web client that fetches a web page from the Internet.

Flash usage: 14,568 bytes (45%) of 32,256
SRAM usage: 673 bytes (32%) of 2,048

Printing Text to a LCD

File –> Examples –> LiquidCrystal –> HelloWorld
Prints a message to an LCD.

Flash usage: 2,328 bytes (7%) of 32,256
SRAM usage: 55 bytes (2%) of 2,048

Displaying Text from the Serial Port on the LCD

File –> Examples –> LiquidCrystal –> SerialDisplay
Display text sent over the serial port to the Arduino.

Flash usage: 3,182 bytes (9%) of 32,256
SRAM usage: 214 bytes (10%) of 2,048

Web Server that Uses the SD Card

Basic web server that hosts a web page on the SD card from the Arduino Ethernet tutorial.

Flash usage: 22,806 bytes (70%) of 32,256
SRAM usage: 1,274 bytes (62%) of 2,048

Web Server that Uses the SD Card and LCD

This code is based on the above SD card web server, but also uses an LCD display to show some text during initialization and to display the amount of free SRAM.

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <LiquidCrystal.h>

// 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;
// have to change the pin numbers from the example defaults when using the Ethernet shield
LiquidCrystal lcd(3, 2, 8, 7, 6, 5);

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

void setup()
{
    // set up the LCD's number of columns and rows:
    lcd.begin(16, 2);
    // Print a message to the LCD.
    lcd.print("Initializing...");
  
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients
    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.");
    lcd.setCursor(0, 1);
    lcd.print("Done.");
}

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
                // 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");
                    client.println("Content-Type: text/html");
                    client.println("Connection: close");
                    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();
                    }
                    lcd.clear();
                    lcd.setCursor(0, 0);
                    lcd.print("Free RAM:");
                    lcd.setCursor(0, 1);
                    lcd.print(freeRam());
                    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)
}

Flash usage: 24,100 bytes (74%) of 32,256
SRAM usage: 1,338 bytes (65%) of 2,048

Finding the Amount of Available SRAM at Runtime

The above sketch uses the freeRam() function from the Arduino Playground article on available memory to display the amount of available SRAM at runtime (while the sketch is running as opposed to at compile time).

The compiler shows the amount of free memory as 710 bytes available for local variables. The amount of free memory shown by the freeRam() function is 657 bytes at the time that the web page has been sent to the client. This available SRAM now takes into account the local variables that are in use and this is the reason that the runtime RAM available is less than the compile time RAM.

Comparing the Memory Usage Results

From the above memory usage results, it can be seen that some of the simpler sketches use less than 15% of available Flash and less than 15% of available SRAM. These are very simple sketches that only demonstrate a single principle.

The SD card read / write example starts approaching the half way mark of the available memory resources with the web client and  simple web server using less than half the memory resources.

As soon as more libraries are used together, memory usage goes over the 50% mark as is the case with the SD card web server at 70% Flash memory usage and  62% SRAM usage. This is still a relatively simple web server hosting a single static web page, but now including the SD card library.

When the LCD is added to the SD card web server, memory usage goes up to 74% for Flash and 65% for SRAM.

From the above, we can see that a simple sketch that uses multiple libraries can quickly use up available memory resources on an Arduino Uno. There are some techniques for making more efficient use of memory. One of the simplest ways to free up RAM is to use the F() macro to keep text in Flash memory so that it does not get copied to RAM at all. The F() macro can be applied to strings that are constant and aren’t modified at runtime.

Freeing Up SRAM

The same sketch above can be modified using the F() macro to put the text strings that are sent from the Arduino over the serial port, to the LCD and to the Ethernet client into Flash memory. For example, the string in the following line of code:

Serial.println("Initializing SD card...");

can be put into Flash memory like this:

Serial.println(F("Initializing SD card..."));

by putting the string including the opening and closing quotation marks into the brackets of the F() macro.

The above sketch will then look like this:

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <LiquidCrystal.h>

// 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;
// have to change the pin numbers from the example defaults when using the Ethernet shield
LiquidCrystal lcd(3, 2, 8, 7, 6, 5);

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

void setup()
{
    // set up the LCD's number of columns and rows:
    lcd.begin(16, 2);
    // Print a message to the LCD.
    lcd.print(F("Initializing..."));
  
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients
    Serial.begin(9600);       // for debugging
    
    // initialize SD card
    Serial.println(F("Initializing SD card..."));
    if (!SD.begin(4)) {
        Serial.println(F("ERROR - SD card initialization failed!"));
        return;    // init failed
    }
    Serial.println(F("SUCCESS - SD card initialized."));
    // check for index.htm file
    if (!SD.exists("index.htm")) {
        Serial.println(F("ERROR - Can't find index.htm file!"));
        return;  // can't find index file
    }
    Serial.println(F("SUCCESS - Found index.htm file."));
    lcd.setCursor(0, 1);
    lcd.print(F("Done."));
}

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
                // 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(F("HTTP/1.1 200 OK"));
                    client.println(F("Content-Type: text/html"));
                    client.println(F("Connection: close"));
                    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();
                    }
                    lcd.clear();
                    lcd.setCursor(0, 0);
                    lcd.print(F("Free RAM:"));
                    lcd.setCursor(0, 1);
                    lcd.print(freeRam());
                    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)
}

This changes the original sketch memory usage from:
Flash: 24,100 bytes (74%)
SRAM: 1,338 bytes (65%) — 710 bytes for local variables
Runtime SRAM available: 657 bytes

To:
Flash: 24,170 bytes (74%)
SRAM: 1,086 bytes (53%) — 962 bytes for local variables
Runtime SRAM available: 909 bytes

Which frees up 253 bytes of memory for local variables.

The image below shows the above sketch running and reporting back the number of free bytes of SRAM available from the freeRam() function.

Arduino SD Card Web Server with LCD

Arduino SD Card Web Server with LCD Displaying Free SRAM after using the F() Macro

From this comparison of sketches on the Arduino Uno, it can be seen that the main limiting factor on the Arduino Uno is the amount of available memory. A relatively short sketch that uses functions or objects from several libraries can quickly use up 70% of available memory. Any sketch that gets slightly more complex can start approaching the 100% memory usage mark.

When available RAM becomes limited, there is good chance that the sketch can start exhibiting unexpected behaviour and even crash as the unavailability of RAM results in variables being overwritten. One technique has been shown that can help to reduce the amount of RAM used by a sketch.

Using Arduino as a Sports Score Ticker to get Live Cricket Results

An Arduino with Ethernet shield can be configured as an Ethernet client to fetch live sports scores from the Internet. The scores can the be displayed on any display device connected to the Arduino or sent through the serial port.

In the Arduino live cricket score project, the Arduino fetches the live cricket scores from cricbuzz.com and displays them in the Arduino IDE serial monitor window. It gets the scores by accessing the XML scores feed and then extracting the desired information from the XML file.

Arduino cricket score ticker

Arduino Cricket Score Ticker

This is a very early version of cricket score code and will be improved on in the future. The code is susceptible to breaking if there are any unexpected changes to the XML file, but the code will be made more robust and will be updated to handle and recover from errors in the future.

Go to the Arduino live cricket score project →

Basic Multi-file Arduino Web Server

This basic Arduino web server hosts HTML web pages and various other files such as CSS, JavaScript, text and image files.

Web pages and other resource files are stored on the SD card inserted into the SD card socket on  Arduino Ethernet shield or Arduino Ethernet board.

The code for the web server can be copied from the project’s page which contains a form that allows parameters such as the MAC, IP and port numbers to be changed. After changes have been made to the settings, a button is clicked to update the Arduino web server sketch. The sketch can then be copied and pasted into the Arduino IDE for loading to the Arduino board with Ethernet shield. Some sample HTML files, JavaScript, CSS, text and image files are also available for download and demonstrate the web server capabilities.

This web server is a supplement to the Arduino Ethernet shield web server tutorial and provides a starting place to design your own web server.

Get the Arduino web server code →

How to Control an LED from an Arduino Web Page Button and an External Push Button

The article on how to control an LED with both a button on a web page from an Arduino web server and a physical hardware button includes the circuit diagram, HTML and JavaScript code and the Arduino code.

I wrote the article after being asked a question on how to control an LED from an HTML button on an Arduino hosted web page and a physical button connected to an Arduino pin.

The image below shows the final project.

Arduino LED Control from Web Page and Push Button Switch

Arduino LED Control from Web Page and Push Button Switch

An Arduino and Ethernet shield is used with a web page hosted on the micro SD card inserted into the Ethernet shield.

When the checkbox or button on the web page is clicked, the corresponding LED will switch on or off. When a push button is pressed, the corresponding LED will switch on or off and the state of the LED will be updated on the web page. Ajax is used to update the LED states on the web page so that there is no page refresh flicker.

Pressing the left push button causes the left LED to switch on and the checkbox on the page to get a check mark. Pushing the left push button again switches the LED off and the check is removed from the checkbox on the web page.

The button on the web page will initially display the text OFF as part of the button text. When the right push button is pressed, the LED will switch on and the HTML button text will be updated to display ON. Pressing the right push button again will switch the LED off and update the button text on the web page to display OFF again.

Go to the project article with video, circuit diagram and HTML, JavaScript and Arduino Code →