Hello friends,
I have built several Arduino webservers, with the use of this great tutorial:
https://startingelectronics.org/tutorials/arduino/ethernet-shield-web-server-tutorial/SD-card-IO/
They work fine, and I can read temperatures, read binary inputs and analog values like temperature, voltages and so on. However, they all have their own IP adress, like 192.168.1.10, 192.168.1.11 and so on. So, on order to read analog values, I need to connect to each server.
What I simply want, is a "main" webserver, polling data from each arduino webservers. This main webserver is to be located in may NAS and it got the speed and processing power.
Programming C++ in arduino is OK. But my challenge is html, CSS and java. I searched google and found a result that maybe linked me to a possiblee path, but it only show example how to direct a switch/button. What about binary inputs and analog inputs? status request for binary inputs, outputs? Can I use this? It would be great if someone would help me out. ![]()
My google find:
No need to add any library / framework to accomplish what you need. Even you can achieve it without javascript at all. Simply add an invisible IFRAME in your HTML file with name attribute set. In following example we'll use "Arduino" as the IFRAME's name, but you can use any valid element name you'd like.
IFRAME name="Arduino" style="display:none"></IFRAME
Next, add target attribute on your link element (the 'A' tags) with value specified as the IFRAME's name, i.e.:
A href="http://192.168.0.88/?sol_on" target="Arduino">Turn On Solenoid
When you click on the link, request sent to your Arduino and resulting response will be directed to the the invisible IFRAME without navigating away from currently viewed page.
For the button element, prefix location.href in onclick handler with the IFRAME's name:
BUTTON onclick="Arduino.location.href='//192.168.0.88?sol_on';">On</BUTTON
This is the Arduiono webserver code:
/*--------------------------------------------------------------
Program: eth_websrv_SD_Ajax_in_out
Description: Arduino web server that displays 4 analog inputs,
the state of 3 switches and controls 4 outputs,
2 using checkboxes and 2 using buttons.
The web page is stored on the micro SD card.
Hardware: Arduino Uno and official Arduino Ethernet
shield. Should work with other Arduinos and
compatible Ethernet shields.
2Gb micro SD card formatted FAT16.
A2 to A4 analog inputs, pins 2, 3 and 5 for
the switches, pins 6 to 9 as outputs (LEDs).
Software: Developed using Arduino 1.0.5 software
Should be compatible with Arduino 1.0 +
SD card contains web page called index.htm
References: - WebServer example by David A. Mellis and
modified by Tom Igoe
- SD card examples by David A. Mellis and
Tom Igoe
- Ethernet library documentation:
http://arduino.cc/en/Reference/Ethernet
- SD Card library documentation:
http://arduino.cc/en/Reference/SD
Date: 4 April 2013
Modified: 19 June 2013
- removed use of the String class
Author: W.A. Smith, http://startingelectronics.com
--------------------------------------------------------------*/
#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
boolean LED_state[4] = {0}; // stores the states of the LEDs
void setup()
{
// disable Ethernet chip
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
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.");
// switches on pins 2, 3 and 5
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(5, INPUT);
// LEDs
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
Ethernet.begin(mac, ip); // initialize Ethernet device
server.begin(); // start to listen for clients
}
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
// 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();
SetLEDs();
// send XML file containing input states
XML_response(client);
}
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();
}
}
// display received HTTP request on serial port
Serial.print(HTTP_req);
// 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)
}
// checks if received HTTP request is switching on/off LEDs
// also saves the state of the LEDs
void SetLEDs(void)
{
// LED 1 (pin 6)
if (StrContains(HTTP_req, "LED1=1")) {
LED_state[0] = 1; // save LED state
digitalWrite(6, HIGH);
}
else if (StrContains(HTTP_req, "LED1=0")) {
LED_state[0] = 0; // save LED state
digitalWrite(6, LOW);
}
// LED 2 (pin 7)
if (StrContains(HTTP_req, "LED2=1")) {
LED_state[1] = 1; // save LED state
digitalWrite(7, HIGH);
}
else if (StrContains(HTTP_req, "LED2=0")) {
LED_state[1] = 0; // save LED state
digitalWrite(7, LOW);
}
// LED 3 (pin 8)
if (StrContains(HTTP_req, "LED3=1")) {
LED_state[2] = 1; // save LED state
digitalWrite(8, HIGH);
}
else if (StrContains(HTTP_req, "LED3=0")) {
LED_state[2] = 0; // save LED state
digitalWrite(8, LOW);
}
// LED 4 (pin 9)
if (StrContains(HTTP_req, "LED4=1")) {
LED_state[3] = 1; // save LED state
digitalWrite(9, HIGH);
}
else if (StrContains(HTTP_req, "LED4=0")) {
LED_state[3] = 0; // save LED state
digitalWrite(9, LOW);
}
}
// send the XML file with analog values, switch status
// and LED status
void XML_response(EthernetClient cl)
{
int analog_val; // stores value read from analog inputs
int count; // used by 'for' loops
int sw_arr[] = {2, 3, 5}; // pins interfaced to switches
cl.print("<?xml version = \"1.0\" ?>");
cl.print("<inputs>");
// read analog inputs
for (count = 2; count <= 5; count++) { // A2 to A5
analog_val = analogRead(count);
cl.print("<analog>");
cl.print(analog_val);
cl.println("</analog>");
}
// read switches
for (count = 0; count < 3; count++) {
cl.print("<switch>");
if (digitalRead(sw_arr[count])) {
cl.print("ON");
}
else {
cl.print("OFF");
}
cl.println("</switch>");
}
// checkbox LED states
// LED1
cl.print("<LED>");
if (LED_state[0]) {
cl.print("checked");
}
else {
cl.print("unchecked");
}
cl.println("</LED>");
// LED2
cl.print("<LED>");
if (LED_state[1]) {
cl.print("checked");
}
else {
cl.print("unchecked");
}
cl.println("</LED>");
// button LED states
// LED3
cl.print("<LED>");
if (LED_state[2]) {
cl.print("on");
}
else {
cl.print("off");
}
cl.println("</LED>");
// LED4
cl.print("<LED>");
if (LED_state[3]) {
cl.print("on");
}
else {
cl.print("off");
}
cl.println("</LED>");
cl.print("</inputs>");
}
// 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;
}
This the webserver html code:
<!DOCTYPE html>
<html>
<head>
<title>Arduino Ajax I/O</title>
<script>
strLED1 = "";
strLED2 = "";
strLED3 = "";
strLED4 = "";
var LED3_state = 0;
var LED4_state = 0;
function GetArduinoIO()
{
nocache = "&nocache=" + Math.random() * 1000000;
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (this.readyState == 4) {
if (this.status == 200) {
if (this.responseXML != null) {
// XML file received - contains analog values, switch values and LED states
var count;
// get analog inputs
var num_an = this.responseXML.getElementsByTagName('analog').length;
for (count = 0; count < num_an; count++) {
document.getElementsByClassName("analog")[count].innerHTML =
this.responseXML.getElementsByTagName('analog')[count].childNodes[0].nodeValue;
}
// get switch inputs
var num_an = this.responseXML.getElementsByTagName('switch').length;
for (count = 0; count < num_an; count++) {
document.getElementsByClassName("switches")[count].innerHTML =
this.responseXML.getElementsByTagName('switch')[count].childNodes[0].nodeValue;
}
// LED 1
if (this.responseXML.getElementsByTagName('LED')[0].childNodes[0].nodeValue === "checked") {
document.LED_form.LED1.checked = true;
}
else {
document.LED_form.LED1.checked = false;
}
// LED 2
if (this.responseXML.getElementsByTagName('LED')[1].childNodes[0].nodeValue === "checked") {
document.LED_form.LED2.checked = true;
}
else {
document.LED_form.LED2.checked = false;
}
// LED 3
if (this.responseXML.getElementsByTagName('LED')[2].childNodes[0].nodeValue === "on") {
document.getElementById("LED3").innerHTML = "LED 3 is ON (D8)";
LED3_state = 1;
}
else {
document.getElementById("LED3").innerHTML = "LED 3 is OFF (D8)";
LED3_state = 0;
}
// LED 4
if (this.responseXML.getElementsByTagName('LED')[3].childNodes[0].nodeValue === "on") {
document.getElementById("LED4").innerHTML = "LED 4 is ON (D9)";
LED4_state = 1;
}
else {
document.getElementById("LED4").innerHTML = "LED 4 is OFF (D9)";
LED4_state = 0;
}
}
}
}
}
// send HTTP GET request with LEDs to switch on/off if any
request.open("GET", "ajax_inputs" + strLED1 + strLED2 + strLED3 + strLED4 + nocache, true);
request.send(null);
setTimeout('GetArduinoIO()', 1000);
strLED1 = "";
strLED2 = "";
strLED3 = "";
strLED4 = "";
}
// service LEDs when checkbox checked/unchecked
function GetCheck()
{
if (LED_form.LED1.checked) {
strLED1 = "&LED1=1";
}
else {
strLED1 = "&LED1=0";
}
if (LED_form.LED2.checked) {
strLED2 = "&LED2=1";
}
else {
strLED2 = "&LED2=0";
}
}
function GetButton1()
{
if (LED3_state === 1) {
LED3_state = 0;
strLED3 = "&LED3=0";
}
else {
LED3_state = 1;
strLED3 = "&LED3=1";
}
}
function GetButton2()
{
if (LED4_state === 1) {
LED4_state = 0;
strLED4 = "&LED4=0";
}
else {
LED4_state = 1;
strLED4 = "&LED4=1";
}
}
</script>
<style>
.IO_box {
float: left;
margin: 0 20px 20px 0;
border: 1px solid blue;
padding: 0 5px 0 5px;
width: 120px;
}
h1 {
font-size: 120%;
color: blue;
margin: 0 0 10px 0;
}
h2 {
font-size: 85%;
color: #5734E6;
margin: 5px 0 5px 0;
}
p, form, button {
font-size: 80%;
color: #252525;
}
.small_text {
font-size: 70%;
color: #737373;
}
</style>
</head>
<body onload="GetArduinoIO()">
<h1>Arduino Ajax I/O</h1>
<div class="IO_box">
<h2>Analog Inputs</h2>
<p class="small_text">A0 used by Ethernet shield</p>
<p class="small_text">A1 used by Ethernet shield</p>
<p>A2: <span class="analog">...</span></p>
<p>A3: <span class="analog">...</span></p>
<p>A4: <span class="analog">...</span></p>
<p>A5: <span class="analog">...</span></p>
</div>
<div class="IO_box">
<h2>Switch Inputs</h2>
<p class="small_text">D0: used by serial RX</p>
<p class="small_text">D1: used by serial TX</p>
<p>Switch 1 (D2): <span class="switches">...</span></p>
<p>Switch 2 (D3): <span class="switches">...</span></p>
<p class="small_text">D4: used by Ethernet shield</p>
<p>Switch 3 (D5): <span class="switches">...</span></p>
</div>
<div class="IO_box">
<h2>LEDs Using Checkboxes</h2>
<form id="check_LEDs" name="LED_form">
<input type="checkbox" name="LED1" value="0" onclick="GetCheck()" />LED 1 (D6)<br /><br />
<input type="checkbox" name="LED2" value="0" onclick="GetCheck()" />LED 2 (D7)<br /><br />
</form>
</div>
<div class="IO_box">
<h2>LEDs Using Buttons</h2>
<button type="button" id="LED3" onclick="GetButton1()">LED 3 is OFF (D8)</button><br /><br />
<button type="button" id="LED4" onclick="GetButton2()">LED 4 is OFF (D9)</button><br /><br />
<p class="small_text">D10 to D13 used by Ethernet shield</p>
</div>
</body>
</html>