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.