Extending LED Output Range on Arduino MEGA 2560 Web Server

This is a solution to the problem that users found when using an Arduino MEGA 2560 with the Switching LEDs on from a Web Page tutorial. The problem is when outputs (or LEDs connected to outputs) greater than 9 are used, they will not switch on. This is the case with the Arduino MEGA 2560 which increases the number of input/output pins above the range of the Arduino Uno by I/O from 14 to 53.

The Problem

The problem is that in the original sketch, the CheckLEDs() function only checks for output (or LED) numbers from 0 to 9. It actually checks for the ASCII characters ‘0’ to ‘9’ as shown below:

// get the state of the LED checkboxes from the HTTP request
void CheckLEDs()
{
    for (byte led_num = 0; led_num < sizeof(LED_pins); led_num++) {
        if ((HTTP_req.charAt(9) == (LED_pins[led_num] + '0')) &&
                    (HTTP_req.charAt(16) == (LED_pins[led_num] + '0'))) {  // LED box is checked
            LED[led_num] = 1;
        }
        else if (HTTP_req.charAt(9) == (LED_pins[led_num] + '0')) {        // LED box is unchecked
            LED[led_num] = 0;
        }
    }
}

 

The Solution

The solution is to check for numbers that are greater than 9 i.e. 2 digit numbers. To do this, first a check is done to determine whether the output being switched on is a single or two digit number. The ASCII numbers are then converted to integers (although they are stored in char variables).

The full sketch is shown below:

/*--------------------------------------------------------------
  Program:      eth_websrv_LED2_MEGA

  Description:  Arduino web server that serves up a web page
                allowing the user to control LEDs
  
  Hardware:     - Arduino MEGA 2560 and official Arduino
                  Ethernet shield. Should work with other
                  Arduinos and compatible Ethernet shields.
                - LED and resistor in series connected between
                  Arduino pin 2 and GND. Second LED connected
                  to pin 30. Third LED connected to pin 53.
                
  Software:     Developed using Arduino 1.0.6 software
                Should be compatible with Arduino 1.0 +
  
  References:   - WebServer example by David A. Mellis and 
                  modified by Tom Igoe
                - Ethernet library documentation:
                  http://arduino.cc/en/Reference/Ethernet
                - Derived from eth_websrv_LED2 at:
                  http://blog.startingelectronics.com/?p=598

  Date:         25 February 2014
 
  Author:       W.A. Smith, http://startingelectronics.org
--------------------------------------------------------------*/

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

byte mac[] = { 0x90, 0xA2, 0x00, 0x00, 0x00, 0x01 };    // MAC address
IPAddress ip(192,168,0, 20);                               // IP address

EthernetServer server(80);

char char_in = 0;    // used to store a character from the Ethernet port
String HTTP_req;     // stores the received HTTP request

// add your LED outputs to be switched here
const byte LED_pins[] = {2, 30, 53};     // Arduino pins used as ouputs for LEDs
byte LED[sizeof(LED_pins)] = {0};        // the state of each LED

void setup()
{
//    Serial.begin(9600); ////////////debug
  
    Ethernet.begin(mac, ip);
    server.begin();
    
    // set up the LED pins as outputs
    for (byte index = 0; index < sizeof(LED_pins); index++) {
        pinMode(LED_pins[index], OUTPUT);
    }
}

void loop()
{
    EthernetClient client = server.available();

    if (client) {
        while (client.connected()) {
            if (client.available()) {
                char_in = client.read();  // get a single character from the Ethernet port
                HTTP_req += char_in;      // build a string out of the received characters

                // answer first HTTP request immediately
                if (char_in == '\n') {
                    // respond to HTTP request
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println();
                    CheckLEDs();              // get state of LED checkboxes from web page
                    DisplayLEDs(&client);     // display checkboxes on web & write to LEDs
                    HTTP_req = "";      // delete string contents
                    client.stop();
                } // end if (char_in == '\n')
            } // end if (client.available()
        } // end while (client.connected())
    } // end if (client)
}

// get the state of the LED checkboxes from the HTTP request
void CheckLEDs()
{
    char num1, num2, num3, num4;
    
    num1 = HTTP_req.charAt(9);
    num2 = HTTP_req.charAt(10);
//    Serial.println(HTTP_req);///////////////debug
    
    // is it a 2 LED digit number?
    if ((num2 >= '0') && (num2 <= '9')) {
        // it is a 2 digit number, now get the 2nd 2 digit number
        num3 = HTTP_req.charAt(17);
        num4 = HTTP_req.charAt(18);
        // convert the two 2 digit ASCII numbers to integers
        num1 -= '0';
        num1 *= 10;
        num2 -= '0';
        num3 -= '0';
        num3 *= 10;
        num4 -= '0';
        num1 += num2;  // first number stored in num1
        num3 += num4;  // second number stored in num3
        
    }
    else {
        // single digit LED number
        // get the 2nd 1 digit number
        num3 = HTTP_req.charAt(16);
        // convert the numbers from ASCII to integer
        num1 -= '0';  // first number
        num3 -= '0';  // second number
    }
    for (byte led_num = 0; led_num < sizeof(LED_pins); led_num++) {
        if ((num1 == LED_pins[led_num]) && (num3 == LED_pins[led_num])) {  // LED box is checked
            LED[led_num] = 1;
        }
        else if (num1 == LED_pins[led_num]) {        // LED box is unchecked
            LED[led_num] = 0;
        }
    }
}

// write the HTML that includes the state of the LED checkboxes for displaying on the web browser
void DisplayLEDs(Client *client)
{
    // some CSS in the HTML to change colours and position of the box containing the LED checkboxes
    client->print("<div style=\"background:white; color:green; position: absolute; margin:20px; border: grey solid 2px; padding:0 10px 4px 10px;\">");
    client->print("<h1 style=\"font: normal 20px/150% Verdana, Arial, Sans-serif;\">LED Outputs</h1>");
    // send each LED checkbox in turn
    for (byte led_num = 0; led_num < sizeof(LED_pins); led_num++) {
        // use hidden checkbox so that unchecking a checkbox sends a value to the Arduino
        // if only a normal checkbox is used, nothing is sent when it is unchecked
        // both hidden and normal checkboxes are produced here for each LED
        client->print("<form> <input type=\"hidden\" name=\"LED");
        client->print(LED_pins[led_num], DEC);
        client->print("\" value=\"0\"> <input type=\"checkbox\" name=\"LED");
        client->print(LED_pins[led_num], DEC);
        client->print("\" value=\"");
        client->print(LED_pins[led_num], DEC);
        client->print("\"");
        // write to the LED connected to the Arduino board
        if (LED[led_num]) {
            client->print(" checked ");             // part of HTML if checkbox is to be displayed checked
            digitalWrite(LED_pins[led_num], HIGH);  // switch LED on
        }
        else {
            digitalWrite(LED_pins[led_num], LOW);  // switch LED off
        }
        client->print(" onclick=\"submit();\">LED");
        client->print(LED_pins[led_num], DEC);
        client->print(" </form>");                 // end of HTML for 1 LED's form
    }
    client->print("</div>");                       // end of box containing LEDs
}

The images below show the hardware used to test the sketch as well as the web page that the sketch generates.

Arduino MEGA 2560 Web Server

Arduino MEGA 2560 Web Server

 

Arduino MEGA 2560 Web Page

Arduino MEGA 2560 Web Page

How to Access your Arduino from the Internet

If you have built an Arduino web server (e.g. by following the Arduino web server tutorial), you will be able to access your web server on your local network, probably through your ADSL router. But what must be done if you want to access the Arduino server from outside of your home network?

The tutorial on connecting your Arduino web server to the Internet describes how to set up and access your Arduino web server from the Internet via any Internet connected device such as a PC, tablet or smart-phone. This allows you to remotely view and interact with your Arduino web server pages.

An external service such as no-ip can be used as a solution to the dynamic IP address that is usually assigned to the router. This is also explained in the tutorial.

Go to the tutorial now →

Basic Test for the GT-511C3 Fingerprint Scanner Module

The article on testing the GT-511C3 fingerprint module uses an Arduino Uno to test that basic communications are working on the module. This can be used to test that the module is correctly wired and also that it is working.

Sending a character from the Serial Monitor window of the Arduino IDE starts the test by sending a “open” command packet to the fingerprint module. If the fingerprint module is working, it should send back an acknowledge packet and an information packet that are both displayed as hexadecimal bytes in the Serial Monitor window.

Go to article and Arduino sketch →