What would be the easiest approach for receiving data on an Arduino from a Webpage ?
Basically I want to send 'button-press' events and perhaps a 'textbox-value' to the Arduino.
PS.
Arduino is connected to the internet through WiFi Shield.
Im able to run client / cerver code.
What would be the easiest approach for receiving data on an Arduino from a Webpage ?
If the web page is not served by the Arduino, it is going to be a lot more challenging to make the action events make requests to the Arduino-as-server.
If the Arduino is the server, then the process should be pretty obvious. The Arduino is already (or should be) determining what the client requested. Adding some if-the-client-request-includes blocks is trivial.
If the Arduino is the server, and you are blindly serving up the same page regardless of what the client asked for, then you need to stop that.
One of the requirements for posting in the Programming section is to post your code. You failed to do that.
Well, if I know the ip address of the Arduino (and I do), and the Arduino is listening for clients, wouldn't it then be possible to send simple data directly to it ?
Well "ace" - that's the point - I have no code, if I had I would ask "why doesn't this work" !?
Instead I'm asking how is it done, that would somehow indicate that im on "thin ice", or ... ?
But here is a piece of code, are you happy now ?
// listen for incoming clients
WiFiClient w_client = w_server.available();
if (w_client)
{
if (w_client.connected())
{
while(w_client.available() > 0)
{
char c = client.read();
Serial.write(c);
}
Serial.println("Connected to client");
}
// close the connection:
Serial.println("Disconnected");
w_client.flush();
w_client.stop();
}
Well, if I know the ip address of the Arduino (and I do), and the Arduino is listening for clients, wouldn't it then be possible to send simple data directly to it ?
Yes. Bottom is some simple server test that has a submit box where you can enter values. You use the serial monitor to see what is being received by the server. Below is how you would incorporate sending the submit request to an arduino IP address different from where the page itself is served from.
client.println("<FORM ACTION='http://192.168.1.102:84/' method=get >"); //uses IP/port of the arduino server
//zoomkat 12-08-12
//get submit box code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html or use a '
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84);; //server port
String readString;
//////////////////////
void setup(){
pinMode(5, OUTPUT); //pin selected to control
//start Ethernet
Ethernet.begin(mac, ip, gateway, gateway, subnet);
server.begin();
//enable serial data print
Serial.begin(9600);
Serial.println("server text box test1"); // so I can keep track of what is loaded
}
void loop(){
// Create a client connection
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += c;
//Serial.print(c);
}
//if HTTP request has ended
if (c == '\n') {
///////////////
Serial.println(readString); //see what was captured
//now output HTML data header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<HTML>");
client.println("<HEAD>");
client.println("<TITLE>Arduino GET test page</TITLE>");
client.println("</HEAD>");
client.println("<BODY>");
client.println("<H1>HTML form GET example</H1>");
client.println("<FORM ACTION='/' method=get >"); //uses IP/port of web page
client.println("Pin 5 'on5' or 'off5': <INPUT TYPE=TEXT NAME='LED' VALUE='' SIZE='25' MAXLENGTH='50'>
");
client.println("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Change Pin 5!'>");
client.println("</FORM>");
client.println("
");
client.println("</BODY>");
client.println("</HTML>");
delay(1);
//stopping client
client.stop();
/////////////////////
if(readString.indexOf("on5") >0)//checks for on
{
digitalWrite(5, HIGH); // set pin 5 high
Serial.println("Led On");
}
if(readString.indexOf("off5") >0)//checks for off
{
digitalWrite(5, LOW); // set pin 5 low
Serial.println("Led Off");
}
//clearing string for next read
readString="";
}
}
}
}
}
What I have is a webpage where some data are displayed. The arduino sends these data to the webserver, and data are read / displayed by a php script.
What I would like was, to be able to push a button on the webpage and based on that, send some command to the arduino. Eg. Stop / Start logging.
Can this be done in a very simple way ?, or do I need to pars the html code sent to the arduino, and search for specific chars in a string. To me that sound a little unreliable ?
Also - I dont really want the arduino to send back all this html stuff, as this is already handled by the webserver.
Does the webserver expect and answer, and what is the bare minimum I can return to satisfy it ?
What I have is a webpage where some data are displayed. The arduino sends these data to the webserver, and data are read / displayed by a php script.
That is NOT what the code you posted does.
Either post your real code or go away.
A client, as you are describing the Arduino above, can NOT be contacted by another client (the web browser) under any circumstances. The server that is in between can NOT push data to a client.
In response to a pull request (a GET, PUT, or POST), the server generates a response which is sent back to the client, and then the server looses all ability to remember that that client ever even existed, and has no way to get in touch with that client again.
All connections to a server that appear to be persistent, like online shopping carts, are because the client remembers where the server is, how to get in touch with it, and the credentials needed by the server to make it appear to be a persistent connection (like session ID).
Dont tell me to go away !
I dont know you, you dont know me. Just because you're behind a screen, doesn't mean you can behave like this. If this is as constructive as you can get - well then shut up. And you go away.
Nevertheless I'm not quite sure you're right. I have seen examples where arduino is running both as server and client. So somehow it must be possible.
I have seen examples where arduino is running both as server and client. So somehow it must be possible.
It is possible for a machine to be both client and server. It is not possible for one client to talk to another client. It is not possible for a server to initiate communications with a client.
So, there is no way for a web browser to PUSH information to another client. The web browser can make GET requests that cause a server to do something. If the server is the Arduino, the Arduino can respond to those requests by returning data, or by turning LEDs on.
However, it is VERY unusual for a server to serve up pages containing forms with submit buttons where the submit button causes a GET request to be made to a different server.
Why is it so difficult for the Arduino to be a server in your case?
4 analogue channels are read every 5 sec. Values are transmitted to webserver.
The "arduino_update_data.php" script grabs the data and saves them in a .csv file.
Asynch to this, when a user opens the webpage, a second .php script generates a graph, reads data from .csv files and shows them in the graph. Buttons for clearing data etc. are also generated and shown.
Everything works like a charm
Now what I would like to have, was a button where I could trigger functionality in the Arduino, like Start / Stop the logging etc.
Now what I would like to have, was a button where I could trigger functionality in the Arduino, like Start / Stop the logging etc.
Below is some simple server code that serves a web page with simple click commands. The GET request from the client is evaluated by the server and actions performed based on the command contents. The server return to the client includes the status: 204 code telling the client to not refresh the web page.
//zoomkat 10-6-13
//simple button GET with iframe code
//open serial monitor to see what the arduino receives
//use the ' instead of " in html ilnes
//address will look like http://192.168.1.102:84/ when submited
//for use with W5100 based ethernet shields
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //ethernet shield mac address
byte ip[] = { 192, 168, 1, 102 }; // arduino IP in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
String readString;
//////////////////////
void setup(){
pinMode(4, OUTPUT); //pin selected to control
//start Ethernet
Ethernet.begin(mac, ip, gateway, gateway, subnet);
server.begin();
//enable serial data print
Serial.begin(9600);
Serial.println("servertest1"); // so I can keep track of what is loaded
}
void loop(){
// Create a client connection
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += c;
//Serial.print(c);
}
//if HTTP request has ended
if (c == '\n') {
///////////////
Serial.println(readString); //print to serial monitor for debuging
//now output HTML data header
if(readString.indexOf('?') >=0) { //don't send new page
client.println("HTTP/1.1 204 Zoomkat");
client.println();
client.println();
}
else {
client.println("HTTP/1.1 200 OK"); //send new page
client.println("Content-Type: text/html");
client.println();
client.println("<HTML>");
client.println("<HEAD>");
client.println("<TITLE>Arduino GET test page</TITLE>");
client.println("</HEAD>");
client.println("<BODY>");
client.println("<H1>Zoomkat's simple Arduino button</H1>");
client.println("<a href='/?on1' target='inlineframe'>ON</a>");
client.println("<a href='/?off' target='inlineframe'>OFF</a>");
client.println("<IFRAME name=inlineframe style='display:none'>");
client.println("</IFRAME>");
client.println("</BODY>");
client.println("</HTML>");
}
delay(1);
//stopping client
client.stop();
///////////////////// control arduino pin
if(readString.indexOf("on1") >0)//checks for on
{
digitalWrite(4, HIGH); // set pin 4 high
Serial.println("Led On");
}
if(readString.indexOf("off") >0)//checks for off
{
digitalWrite(4, LOW); // set pin 4 low
Serial.println("Led Off");
}
//clearing string for next read
readString="";
}
}
}
}
}