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.