POST request on a webserver using Arduino Wifi shield

Hello.

I try to program a security button that sends a Boolean true value when pressed to a web server. I am a little stuck in the HTTP POST code to get it to send the value to my web server. I guess It Is an easy fix, but I have not very good experience with HTTP and need some help! :slight_smile:

The code works in chrome or an browser and will change from “Everything is ok” to “Door has been open!” If the button is pressed. This was just to get the button to work and test, but now I need the Arduino board to send the information to a web server. Please help!

#include <SPI.h>
#include <WiFi.h>

char ssid[] = "";     //  your network SSID (name) 
char pass[] = "";    // your network password


// byte mac[] = {0x, 0x, 0x, 0x, 0x, 0x};
// byte ip[] = {xxx,xxx,x,x};
// byte gateway[] = {x,x,x,x};

//WifiShield MAC 

int status = WL_IDLE_STATUS;

boolean btnpressed = false;

WiFiServer server(80);

void setup() {
 // start serial port for debugging purposes
 Serial.begin(9600);
 
 // Attach interrupt to pin 2
 attachInterrupt(0, AlarmPressed, RISING);

 // attempt to connect to Wifi network:
 while ( status != WL_CONNECTED) { 
   Serial.print("Attempting to connect to SSID: ");
   Serial.println(ssid);
   status = WiFi.begin(ssid, pass);
   // wait 10 seconds for connection:
   delay(10000);
 } 
 server.begin();
 // you're connected now, so print out the status:
 printWifiStatus();
}


void loop() {
           
 // listen for incoming clients
 WiFiClient client = server.available();
 if (client) {
   Serial.println("new client");
   // an http request ends with a blank line
   boolean currentLineIsBlank = true;
   while (client.connected()) {
     if (client.available()) {
       char c = client.read();
       Serial.write(c);
       // if you've gotten to the end of the line (received a newline
       // character) and the line is blank, the http request has ended,
       // so you can send a reply
       if (c == '\n' && currentLineIsBlank) {
         // send a standard http response header
         client.println("HTTP/1.1 200 OK");
         client.println("Content-Type: text/html");
         client.println("Connnection: close");
         client.println();
         client.println("<!DOCTYPE HTML>");
         client.println("<html>");
         client.println("<meta http-equiv=\"refresh\" content=\"5\">");
         
           if (btnpressed == false){
             client.print("Everything is ok");
             btnpressed = false;
           }
           else {
              client.print("Alert ! The door has been opened");
           }       
         client.println("
");
         client.println("</html>");
          
          
          break;
       }
       if (c == '\n') {
         // you're starting a new line
         currentLineIsBlank = true;
       } 
       else if (c != '\r') {
         // you've gotten a character on the current line
         currentLineIsBlank = false;
       }
     }
   }
   // give the web browser time to receive the data
   delay(1);
     // close the connection:
     client.stop();
     Serial.println("client disonnected");
 }
}


void printWifiStatus() {
 // print the SSID of the network you're attached to:
 Serial.print("SSID: ");
 Serial.println(WiFi.SSID());

 // print your WiFi shield's IP address:
 IPAddress ip = WiFi.localIP();
 Serial.print("IP Address: ");
 Serial.println(ip);

 // print the received signal strength:
 long rssi = WiFi.RSSI();
 Serial.print("signal strength (RSSI):");
 Serial.print(rssi);
 Serial.println(" dBm");
}

void AlarmPressed() {
 btnpressed = true;
}

Why do you need the obfuscation offered by POST, to send 0 or 1?

Variables use by interrupt handlers and other functions MUST be volatile.

GET and POST are commands that a client uses to communicate with a server. Your code is NOT a client, so talk of GET or POST is irrelevant.

If you use the client example in the Ethernet library, it shows how to make a GET request. A GET request can contain information, like when you ask google to find stuff. You say something like GET /?topicIs="Arduino" and the server knows that you want information where the topic is Arduino.

Thanks for the reply.

But I do not want to get any information from the web server. I simply want my arduino to send TRUE to the webserver when the button is pressed. Say I have 10 buttons like this. I want the buttons to send "Alarm has been triggered" to the web server. Can you please help me with the code?

But I do not want to get any information from the web server.

What you want, and what you can get are two different things. You don’t need to do anything with the data you get from the server, if any, but you must plan for the server to send a reply.

I simply want my arduino to send TRUE to the webserver when the button is pressed.

That’s what a GET request is for.

Say I have 10 buttons like this.

OK. “I have to buttons like this”. I can’t see that that helped, but I did what you said.

Can you please help me with the code?

No. I have no idea what the IP address of your server is. I have no idea what port it is listening on. I have no idea what script on the server you want to run.

But, those are the only substantive changes you need to make the client example. The other change you need to make is to change the information in the GET request to match what the script is expecting.

It seems to me that sending WHICH switch was pressed would be interesting information.

Finally, since the Arduino won’t be busy processing client requests, an interrupt is not appropriate for reading the switch states.

But, those are the only substantive changes you need to make the client example. The other change you need to make is to change the information in the GET request to match what the script is expecting.

It seems to me that sending WHICH switch was pressed would be interesting information.

Yes. But that is the reason I ask for help here, because I do not know what to change and to what in the HTTP code to the server. The server doesn't run any script for now, its only a homemade server that I made in Labview. But can anyone please just give some specific help to the code, and maybe I can understand better? :)

But can anyone please just give some specific help to the code, and maybe I can understand better?

You can't get from point A to point B if you are not at point A. Point A would be some code you are having trouble understanding/modifying. That could be the client example or something that you have written. If you are at point A, prove it by posting your code.

The server doesn't run any script for now, its only a homemade server that I made in Labview.

I don't think that is going to work. The ethernet shield is expecting something to be listening to some port, and for that something to understand the http protocol. Usually, that something is httpd, which does understand the http protocol.

Test whether your "server" is working be making a web browser send your "server" the same kind of information that the Arduino will eventually send it.

Describe exactly what you did that actually resulted in some data being saved/used somewhere.

Yes. But that is the reason I ask for help here, because I do not know what to change and to what in the HTTP code to the server. The server doesn’t run any script for now, its only a homemade server that I made in Labview. But can anyone please just give some specific help to the code, and maybe I can understand better?

To send something to a web server use client code, with the GET type of request being the simplest. Below is some client test code made for a non-wifi ethernet shield (the wifi shields are somewhat sketchy in operation, so I never got one). Note that you will need to write your button code such that only one request is sent per button press, otherwise you may create a flood of request while the button remains depressed.

//zoomkat 11-04-13
//simple client test
//for use with IDE 1.0.1
//with DNS, DHCP, and Host
//open serial monitor and send an e to test client GET
//for use with W5100 based ethernet shields
//remove SD card if inserted
//data from myIP server captured in readString 

#include <SPI.h>
#include <Ethernet.h>
String readString;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address

char serverName[] = "checkip.dyndns.com"; // myIP server test web page server
EthernetClient client;

//////////////////////

void setup(){

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }

  Serial.begin(9600); 
  Serial.println("client readString test 11/04/13"); // so I can keep track of what is loaded
  Serial.println("Send an e in serial monitor to test"); // what to do to test
  Serial.println();
}

void loop(){
  // check for serial input
  if (Serial.available() > 0) //if something in serial buffer
  {
    byte inChar; // sets inChar as a byte
    inChar = Serial.read(); //gets byte from buffer
    if(inChar == 'e') // checks to see byte is an e
    {
      sendGET(); // call sendGET function below when byte is an e
    }
  }  
} 

//////////////////////////

void sendGET() //client function to send/receive GET request data.
{
  if (client.connect(serverName, 80)) {  //starts client connection, checks for connection
    Serial.println("connected");
    client.println("GET / HTTP/1.1"); //download text
    client.println("Host: checkip.dyndns.com");
    client.println("Connection: close");  //close 1.1 persistent connection  
    client.println(); //end of get request
  } 
  else {
    Serial.println("connection failed"); //error message if no client connect
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read(); //gets byte from ethernet buffer
    readString += c; //places captured byte in readString
  }

  //Serial.println();
  client.stop(); //stop client
  Serial.println("client disconnected.");
  Serial.println("Data from server captured in readString:");
  Serial.println();
  Serial.print(readString); //prints readString to serial monitor 
  Serial.println();  
  Serial.println();
  Serial.println("End of readString");
  Serial.println("==================");
  Serial.println();
  readString=""; //clear readString variable

}

If you are sending information to a web server with a POST request, you require a post body is a suitable format.

This is governed by the Content-Type header in the post.

eg

POST /doorPressAction HTTP/1.1
Content-Type: application/json
Content-Length: **whatever the length of the body is**

{ "door_open": true }

or to simulate a HTML form submission

POST /doorPressAction HTTP/1.1
Content-Type: application/x-www-form-urlencoded 
Content-Length: **whatever the length of the body is**

door_open=true

or if your web server wants an XML document (ie, ajax) :

POST /doorPressAction HTTP/1.1
Content-Type: application/xml 
Content-Length: **whatever the length of the body is**

<?xml version="1.0"?>
<openmessage door_open="true"/>

Or whatever the particular format of the xml document it expects might be.