Sending a proper Post request from Arduino - http

I am trying to send a Post request from my Arduino Mega using the Ethernet shield, I tried already many many codes all over the internet but I haven't done yet
Also did it already from a NodeMCU-ESP8266 but I don't know why with the mega is getting so tricky
From this code everything goes well except that I never get the POST request, I am using this website 'requestcatcher' to test the POST request
#include <Ethernet.h>
#include <SPI.h>
// Conf. mac
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Server to Post
char server[] = "http://abc.requestcatcher.com/test";
// Starting Ethernet client
EthernetClient client;
// =============== Connecting to internet =============== //
void setup() {
// Open serial communications and wait for port to open:
// wait for serial port to connect. Needed for native USB port only
Serial.begin(9600);
while (!Serial) {
;
}
// Connecting to internet
if (Ethernet.begin (mac) == 0) {
Serial.println("Can’t connect via DHCP");
}
// Give the Ethernet shield a second to initialize
delay(1000);
// Printing the IP Adress
Serial.print ("IP Address: ");
Serial.println(Ethernet.localIP());
}
/////============= Sending Post request ============= ////
void loop() {
Serial.println(" - Post request in process - ");
if (client.connect(server, 80) {
Serial.print(" Sending Post request ");
client.println("POST /test HTTP/1.1");
client.println("Host: abc.requestcatcher.com/");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: ");
client.println();
}
else {
Serial.println("Can’t reach the server");
}
// Wait 10 secs
delay(10000);
}
Arduino prints via serial something like this
IP Adress: 192.168.100.40
- Post request in process -
Sending Post request
- Post request in process -
Sending Post request
- Post request in process -
Sending Post request
So I think that means that the Arduino connects successfully to the internet and also 'client.connect(server, 80)' goes true since it prints 'Sending Post request', but I don't know why request catcher never gets any of the post requests, I tested 'requestcatcher' with online apps and as well with the NodeMCU and it gets the post request from all except the Arduino so I think something must be wrong around here:
client.println("POST /test HTTP/1.1");
client.println("Host: abc.requestcatcher.com/");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: ");
client.println();
Please help, any hint would be very helpful

You must to delete ; and close bracket in this part of code if (client.connect(server, 80); { => if (client.connect(server, 80)) {...}

I checked the protocol for the headers so here it's how finally worked
if (client.connect(server, 80)) {
Serial.print(" Sending Post request ");
client.println("POST /test HTTP/1.0");
client.println("Host: abc.requestcatcher.com");
client.println("Connection: close");
client.println("Content-Length: 0"); //------- I missed 0
client.println("Content-Type: application/x-www-form-urlencoded");
client.println(""); //------- I missed ""
Serial.println("Server response");
char c = client.read();
Serial.println(c);
client.stop();
}
Too bad that form the server response I get "⸮" when requestcatcher actually sends "request caught"I not very sure about the lines after the http request, Could you give a little push with that?.
but also and THIS IS VERY IMPORTANT I made a mistake right on the top, I didn't know that this would count as a typo but it does the server must be written this way otherwise the server will never get the POST request
char server[] = "abc.requestcatcher.com";
Avoid setting your server like this
char server[] ="http://abc.requestcatcher.com/test";
char server[] ="abc.requestcatcher.com/";

Related

How to send data from Arduino to Odoo?

I have set up an Arduino with some sensor and I am reading those data. Now I want to send it to odoo. My best guess is that I did something wrong with this,
client.connect(server, 4404)
My current arduino code,
#include <SPI.h>
#include <Ethernet.h>
// all vars are dummy
byte mac[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
IPAddress server(198, 11, 11, 11);
IPAddress ip(192, 11, 11, 11);
char HOST_NAME[] = "https://xyz-test200.odoo.com";
EthernetClient client;
String PostData = "https://xyz-test200.odoo.com/xmlrpc/2/common/POST/'x_1'='5.00'&'x_2'='myfvrtstring'";
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect.
}
Ethernet.begin(mac, ip);
delay(1000);
Serial.println("connecting...");
// we need server and port
// in odoo doc the server is mentioned, but I am not sure about port number
// I put 4404 as it should be the default for xmlrpc
if (client.connect(server, 4404)) {
Serial.println("connected");
client.println("POST /xmlrpc/common HTTP/1.1");
client.println("Host: 192.168.1.2:8169");
client.println("User-Agent: Arduino/1.0");
client.println("Connection: close");
client.print("Content-Length: ");
client.println(PostData.length());
client.println();
client.println(PostData);
client.println();
} else {
Serial.println("connection failed");
}
}
Here is the documentation for Odoo Rest API if anyone is interested and I tried it with python script, it works like a charm!
When connecting to an HTTPS server, you need an HTTPS-ready client.
HTTPS has port 443. You are currently using 4404.
If you host odoo yourself, you could create an HTTP endpoint for internal use. And then, I would also recommend creating a custom controller for more uncomplicated communication because RPC is a bit hard to do in a microcontroller.
https://forum.arduino.cc/t/ethernet-post-data-via-https/584139/3

POST request with ESP32 returns 301

I have a NGINX server on a raspberry pi. I want to send JSON file from my ESP32 board to the NGINX web-server.
In a first step, I have followed this tutorial :
https://techtutorialsx.com/2017/05/20/esp32-http-post-requests/
It gives this code :
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void setup() {
Serial.begin(115200);
delay(4000); //Delay needed before calling the WiFi.begin
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { //Check for the connection
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
}
void loop() {
if(WiFi.status()== WL_CONNECTED){ //Check WiFi connection status
HTTPClient http;
http.begin("http://jsonplaceholder.typicode.com/posts"); //Specify destination for HTTP request
http.addHeader("Content-Type", "text/plain"); //Specify content-type header
int httpResponseCode = http.POST("POSTING from ESP32"); //Send the actual POST request
if(httpResponseCode>0){
String response = http.getString(); //Get the response to the request
Serial.println(httpResponseCode); //Print return code
Serial.println(response); //Print request answer
}else{
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
}
http.end(); //Free resources
}else{
Serial.println("Error in WiFi connection");
}
delay(10000); //Send a request every 10 seconds
}
No problem if I use this code with the following line
http.begin("http://jsonplaceholder.typicode.com/posts");
My serial monitor of the ARDUINO's IDE returns :
201
{
"id": 101
}
But, when I only replace the previous line by
http.begin("http://82.145.56.62:151/postfile");
I get on my serial monitor this :
301
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>
Would you have an idea of my problem ?
Thank you ,
EDIT
I have gone ahead a little more. I have created a php file in the directory posts. Now I get the HTTP code 200, so my webserver receive the POST request.
New problem : I cannot figure out how to display the POST content on my php file. Would you have an idea ?
Thank you,
I have solved my problem by replacing :
http.addHeader("Content-Type", "text/plain");
by
http.addHeader("Content-Type", "application/x-www-form-urlencoded");

Unstable Arduino Web Server

I have been trying to setup a web server using Arduino. I have an UNO and a HanRun HR91105A I got off the internet, and I am using a modified version of the WebServer example to test my code. It did in fact work at first. But after setting up port forwarding, the connection suddenly became unstable. It connects and works for a few minutes, then suddenly I can't even ping it. Trying to ping the Arduino results in request time out. Research online suggests 2 possibilities:
1.) All the RAM is used up
2.) Ethernet shield is faulty
Below is my code
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0x44, 0x00, 0x10, 0x20, 0x8C, 0x0A
};
IPAddress ip(192,168,1,90);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(8081);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
// listen for incoming clients
EthernetClient 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("Connection: close");
client.println("Refresh: 2");
client.println();
client.println("<!DOCTYPE HTML>");
//-----------------Type in outputs below-------------------------------------
client.println("<html>");
client.print("Hello World!");
client.print("<p id='Header'>");
client.print("Sensor Data");
client.println("</p>");
client.print("<p id='Pressure'>");
client.print("Pressure:");
client.println("</p>");
client.print("<p id='Acceleration'>");
client.print("Acceleration:");
client.println("</p>");
client.println("<br /)");
client.println("</html>");
break;
//-----------------End of outputs--------------------------------------------
}
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 disconnected");
}
}
Additionally, the arduino does have a static IP, so I'm pretty sure it is not an issue of DHCP lease expiry.
I highly suspect that the shield is faulty as it gets very hot while in operation. Plus it IS a knockoff. But I can't dismiss the possibility that my coding is just inefficient as I am not very experienced. Any help would be appreciated. Thanks.
Your Arduino will opperate unpredictably when RAM is not enough.
In this code, there are many constant string. you should store those strings in FLASH memory to save RAM. In order to to so, use F() macro. For example.
client.println(F("HTTP/1.1 200 OK"));
If your program is big, I recommend to use the shield that equips an embedded web sever (e.g PHPoC Shield)

Arduino Getting Data From Web Page

I'm trying to connect my Arduino uno + Ethernet shield to a php script that gets a value from a database and then is sent back which then is displayed on a serial monitor. It works, it connects successfully and i get the value sent back however I'm having trouble displaying it on the serial monitor. It should just display what the server sends however it doesn't. Any one can help?
The Serial Output : It should just output "The Value", however there are numbers that shouldn't be there. If i output this to a LCD monitor i can't have them numbers present.
connecting...
connected
HTTP/1.1 200 OK
Server: cloudflare-nginx
Date: Sat, 04 Jan 2014 15:36:51 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close
Set-Cookie: __cfduid=dcef101052b82760c1a2de019e6b076141388849811461; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.linku.biz; HttpOnly
X-Powered-By: PHP/5.3.27
CF-RAY: e7901b6dec606e2
4
The
5
Value
0
disconnecting.
PHP Script
<?php
echo 'The Value';
?>
Arduino Script
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "www.linku.biz"; // name address for Google (using DNS)
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,0,177);
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected");
// Make a HTTP request:
client.println("GET /arduino.php HTTP/1.1");
client.println("Host: www.linku.biz");
client.println("Connection: close");
client.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed");
}
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
while(true);
}
}
Don't know if this helps, but notice that the numbers are the count of available chars which are read out. 4 "The " and 5 "value"
I would expect that client.available returns the 4 and 5 values just after those chars are received. How they got converted to ASCI "4" and "5" and printed, I have no idea.
I parse data by this code
String readString;
//gets byte from ethernet buffer
readString += client.read(); //places captured byte in
//parse readString for request
index = readString.indexOf("text"); //finds location of first "text"
data_want = readString.substring(index+some char, index+some char); //captures data String
Serial.println(data_wand);

simple web server nort working with arduino wifi shield

I have recently bought an arduino wifi shield(Atmal chip 32UC3A1512-U), which I connected with
my Arduino Mega ADK R3 board)...It is getting connected to my wifi network, But when I run the
SimpleWebServer Example provided in the library to on/off the LED is not working. The code is given below...
#include <SPI.h>
#include <WiFi.h>
char ssid[] = "belkin.E33"; // your network SSID (name)
char pass[] = "abc123cde456"; // your network password
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
WiFiServer server(80);
void setup() {
Serial.begin(9600); // initialize serial communication
pinMode(9, OUTPUT); // set the LED pin mode
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
while(true); // don't continue
}
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid); // print the network name (SSID);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
server.begin(); // start the web server on port 80
printWifiStatus(); // you're connected now, so print out the status
}
void loop() {
WiFiClient client = server.available(); // listen for incoming clients
if (client) { // if you get a client,
Serial.println("new client"); // print a message out the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
// the content of the HTTP response follows the header:
client.print("Click here turn the LED on pin 9 on<br>");
client.print("Click here turn the LED on pin 9 off<br>");
// The HTTP response ends with another blank line:
client.println();
// break out of the while loop:
break;
}
else { // if you got a newline, then clear currentLine:
currentLine = "";
}
}
else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
// Check to see if the client request was "GET /H" or "GET /L":
if (currentLine.endsWith("GET /H")) {
digitalWrite(9, HIGH); // GET /H turns the LED on
}
if (currentLine.endsWith("GET /L")) {
digitalWrite(9, LOW); // GET /L turns the LED off
}
}
}
// 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");
// print where to go in a browser:
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip);
}
The result that I am getting in the serial monitor is
Attempting to connect to Network named: belkin.E33
SSID: belkin.E33
IP Address: 192.168.2.5
strength (RSSI):-56 dBm
To see this page in action, open a browser to http://192.168.2.5
But When I am opening the browser with the specified IP address, It is showing
Could not Connect to 192.168.2.5
I have tried this in mozilla and chrome from my ubuntu machine...also tried from some other machines in the same network but with the same result. But when I am pinging to 192.168.2.5 it is pinging...What went wrong??? . My friend adviced to change the firmware...Is it an issue,bcas as told earlier simple examples for establishing the connection are working...Please guide me
I've got the same problem after upgrading Arduino IDE to lastest version (v2) from v1.0.8 which is doing fine with the wifi shield tests (client and server).
Going to try the nightly build now and see if it's fixed.
Edit: Yeap, Nightly build solves this issue.

Resources