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

Simple Raspberry PI Serial Port and Breakout Board

Add a RS232 serial port and GPIO breakout to your Raspberry PI using this simple single-sided circuit board that you can build at home.

To keep the design simple and easy to lay out on a single sided board, only 5 GPIO pins were connected to a socket strip – this is fine for initial experimentation. The serial port allows the Raspberry PI to be connected to a PC without the need to connect a keyboard and screen to the Raspberry PI.

Go to the article on the Raspberry PI serial port and breakout board to see the circuit diagram and source files in KiCad format.

Switching LEDs on from a Web Page using Arduino

The Arduino and Ethernet shield are set up as a web server. The web page that the server hosts allows two LEDs to be controlled by clicking checkboxes on the web page.

This video shows the Arduino and web page in action:

The LEDs are interfaced to pin 2 and pin 3 of the Arduino.

This is an answer to a question from the Arduino web server blog entry relating to the article on Arduino Web Server LED Control. The question is on how to control two LEDs from a web page.

The Arduino sketch for this solution:
eth_websrv_LED2.zip
This code is a hack from some previous code that I wrote and so does not look exactly like the code from the sketch that the question is related to.