I'm quite new to messing up with esp's, i've managed - USING ARDUINO IDE- to create a local page with buttons on it, one directs me to my local server and the other is the subject of my question, I need it to redirect me to a URI that is constantly changing, the URI is acquired from an arduino through serial connection any help would be much appreciated, thanks in advance
this is my code:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
const char* ssid = "SSID";
const char* password = "PASSWORD";
ESP8266WebServer server(80);
//Check if header is present and correct
bool is_authentified(){
Serial.println("Enter is_authentified");
if (server.hasHeader("Cookie")){
Serial.print("Found cookie: ");
String cookie = server.header("Cookie");
Serial.println(cookie);
if (cookie.indexOf("ESPSESSIONID=1") != -1) {
Serial.println("Authentification Successful");
return true;
}
}
Serial.println("Authentification Failed");
return false;
}
//login page, also called for disconnect
void handleLogin(){
String msg;
if (server.hasHeader("Cookie")){
Serial.print("Found cookie: ");
String cookie = server.header("Cookie");
Serial.println(cookie);
}
if (server.hasArg("DISCONNECT")){
Serial.println("Disconnection");
server.sendHeader("Location","/login");
server.sendHeader("Cache-Control","no-cache");
server.sendHeader("Set-Cookie","ESPSESSIONID=0");
server.send(301);
return;
}
if (server.hasArg("USERNAME") && server.hasArg("PASSWORD")){
if (server.arg("USERNAME") == "98710" && server.arg("PASSWORD") == "hussein" ){
server.sendHeader("Location","/");
server.sendHeader("Cache-Control","no-cache");
server.sendHeader("Set-Cookie","ESPSESSIONID=1");
server.send(301);
Serial.println("Log in Successful");
return;
}
msg = "invalid username/password please try again";
Serial.println("Log in Failed");
}
String content = "<center><div id=\"ucPageViewer_ctl00_TopHead\"><div id=\"ucPageViewer_ctl00_ctl03_dvBody\" class=\"\"><div id=\"ucPageViewer_ctl00_ctl03_ctl00_containerid\"><img border=\"0\" alt=\"main page\" src=\"http://www.ungift.org/images/knowledgehub/logos/usaid-logo.jpeg\" width=\"930\" height=\"110\"></div></div></div></center>";
content += "<center></center> ";
content += "<center></center>";
content += "<center><html><body><form action='/login' method='POST'>please enter your info to be able to login<br></center>";
content += "<center>Username:<input type='text' name='USERNAME' placeholder='Username'><br></center>";
content += "<center>Password:<input type='password' name='PASSWORD' placeholder='Password'><br></center>";
content += "<center><input type='submit' name='SUBMIT' value='sign in'> </form>" + msg + "<br></center>";
content += "<center>for more info<a href='/inline'>press here</a></body> </html></center>";
server.send(200, "text/html", content);
}
//root page can be accessed only if authentification is ok
void handleRoot(){
Serial.println("Enter handleRoot");
String header;
if (!is_authentified()){
server.sendHeader("Location","/login");
server.sendHeader("Cache-Control","no-cache");
server.send(301);
return;
}
String content = "<center><div id=\"ucPageViewer_ctl00_TopHead\"><div id=\"ucPageViewer_ctl00_ctl03_dvBody\" class=\"\"><div id=\"ucPageViewer_ctl00_ctl03_ctl00_containerid\"><img border=\"0\" alt=\"main page\" src=\"http://www.ungift.org/images/knowledgehub/logos/usaid-logo.jpeg\" width=\"930\" height=\"110\"></div></div></div></center>";
if (server.hasHeader("User-Agent")){
}
content += "<center><img crossorigin=\"anonymous\" src=\"https://upload.wikimedia.org/wikipedia/ar/b/bf/Yarmouk_University_Logo.png \"width=\"168\" height=\"250\"</center>";
content += "<h1><center>hi there</center></h1>";
content += "<center><p><button>go to link from serial </button></p></center>";
content += "<center><p>browse server <button>ON</button></p></center>";
content += "please sign out before leaving sign out</body></html>";
server.send(200, "text/html", content);
}
//no need authentification
void handleNotFound(){
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
void setup(void){
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.on("/login", handleLogin);
server.on("/inline", [](){
String MGS = "<h1><center>please enter valid username and password</center></h1>";
MGS += "to go back to login page please press `enter code here`here</body></html>";
server.send(200, "text/html", MGS );
});
server.on("/search", [](){
String T = "";
T = Serial.readString();
Serial.print(T);
server.send(200, "text/html", T );
});
server.onNotFound(handleNotFound);
//here the list of headers to be recorded
const char * headerkeys[] = {"User-Agent","Cookie"} ;
size_t headerkeyssize = sizeof(headerkeys)/sizeof(char*);
//ask server to track these headers
server.collectHeaders(headerkeys, headerkeyssize );
server.begin();
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient();
}
Related
I am trying to post a JSON object to a server deployed on Heroku from an ESP8266 board.
My problem is that I am not posting anything or I am posting a wrong JSON object, as Heroku logs show a 500 error and I am getting an empty object on the serial monitor.
My understanding is that I am hitting the server correctly, but either the format of the JSON object is wrong or I am missing something in my post method.
Could you please check my code and help me find a solution?
Here is my code:
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <WiFiClient.h>
const char *host = "appname.herokuapp.com";
const char* serverName = "https://appname.herokuapp.com";
const char* ssid = "*******";
const char* password = "*******";
void setup() {
Serial.begin(9600);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
}
void loop() {
if(WiFi.status()== WL_CONNECTED) {
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setInsecure();
HTTPClient https;
DynamicJsonDocument doc(512);
JsonObject object = doc.to<JsonObject>();
object["temperature"] = 30;
String data;
serializeJsonPretty(object, data);
Serial.println(data);
https.addHeader("Accept:", "application/json");
https.addHeader("Host:", host);
if (https.begin(*client, serverName)) {
Serial.print("[HTTPS] POST...\n");
int httpCode = https.POST(data);
if (httpCode > 0) {
Serial.printf("[HTTPS] POST... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload);
} else {
Serial.printf("[HTTPS] POST... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
} else {
Serial.printf("[HTTPS] POST... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
https.end();
} else {
Serial.printf("[HTTPS] Unable to connect\n");
}
}
delay(5000);
}
The problem was to have the post method nested inside the if statement instead of having it after adding the headers.
I have modified the code and now it works.
void loop() {
if(WiFi.status()== WL_CONNECTED) {
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setInsecure();
HTTPClient https;
DynamicJsonDocument doc(512);
JsonObject object = doc.to<JsonObject>();
object["temperature"] = 32;
String data;
serializeJsonPretty(object, data);
Serial.println(data);
https.begin(*client, serverName);
https.addHeader("Content-Type", "application/json; charset=UTF-8");
int httpCode = https.POST(data);
if (httpCode == 200) {
Serial.println("POST succeeded with code:");
Serial.println(httpCode);
} else if (httpCode != 200) {
Serial.println("POST failed with code:");
Serial.println(httpCode);
} else {
Serial.println("Unknown error");
}
String payload = https.getString();
Serial.println(payload);
https.end();
}
delay(10000);
}
Hi im currently doing Servo NodeMCU controlling. my plan is to create an Input Box where i can type, then whatever number i type will be use as servo angle using Webserver or 194.168.4.1 or so on. (ex: i type 90, servo angle will be 90) the problem i si do not know how to get it. here is the code:
#include<Servo.h>
Servo ServoPin;
int angle = 0;
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#define ServoPin 34; // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED
// Set these to your desired credentials.
const char *ssid = "XXXXXX";
const char *password = "XXXXXX";
WiFiServer server(80);
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");
pinMode(ServoPin,OUTPUT);
// You can remove the password parameter if you want the AP to be open.
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
Serial.println("Server started");
}
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("<!DOCTYPE html>");
client.print("<html>");
client.print("<body>");
client.print("<p>Change the text of the text field, and then click the button below.</p>"); //
client.print("INPUT NUMBER: <input type='number' id='servo'>"); //in this area, I WILL TYPE number 0-255.
client.print("<button type='button' '>Go</button>");
ServoPin.attach(number); //the area where i will assign the servo to the angle i type.
// 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
}
}
}
// close the connection:
client.stop();
Serial.println("Client Disconnected.");
}
}
So as you can see in client.print"INPUT NUMBER.... so on line, that is the place where my code will design an input box. the problem is it is inside a " " or double quotation mark. i wonder what should i do to get the 'number' input then use it on ServoPin.attach(number);
im very beginner on HTML(zero actually) because i dont have knowledge here yet. this code is mostly taken from internet w3school website then i modify it a bit to Servo controlling. so im really hoping that someone can tell me how to do it....
Board: Node32
actual Board: NodeMCU ESP 32
Here is web server code that parses two variables from a GET response of a HTML form, I suppose it should be no problem to adopt it for your needs: http://playground.arduino.cc/Code/WebServerST
Hey so this is the how I do this, I've made a form in your html that would take the input and send a get request to the server and can be dealt with there. this is the process:
input put into form, sent to server in get request.
the get request is send stored char by char in header variable.
if statement checks if the parameter is in the header. The string is searched for the value and the value is saved into a string.
good luck this should work.
#include<Servo.h>
Servo ServoPin;
int angle = 0;
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#define ServoPin 34; // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED
// Set these to your desired credentials.
const char *ssid = "XXXXXX";
const char *password = "";
WiFiServer server(80);
String header;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");
pinMode(ServoPin,OUTPUT);
// You can remove the password parameter if you want the AP to be open.
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
Serial.println("Server started");
}
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
header += c; //write request to the header
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();
if (header.indexOf("input1=") >= 0) { //if input1 is in the header then...
Serial.println(header);
String input_string = "";
int reqEnd = header.indexOf(" HTTP/1.1");
for (int n = 16; n < reqEnd; ++n) { //put the input value from the header to the variable
input_string += header[n];
}
Serial.println(input_string);
}
// the content of the HTTP response follows the header:
client.print("<!DOCTYPE html>");
client.print("<html>");
client.print("<body>");
client.print("<form action=\"/get\">"); //added a form to take a text input and send a get request.
client.print("input1: <input type=\"text\" name=\"input1\">");
client.print("<input type=\"submit\" value=\"Submit\">");
client.print("</form><br>");
ServoPin.attach(number); //the area where i will assign the servo to the angle i type.
// 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
}
}
}
// close the connection:
client.stop();
Serial.println("Client Disconnected.");
}
}
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPass";
AsyncWebServer server(80);
void setup(){
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
int paramsNr = request->params();
Serial.println(paramsNr);
for(int i=0;i<paramsNr;i++){
AsyncWebParameter* p = request->getParam(i);
Serial.print("Param name: ");
Serial.println(p->name());
Serial.print("Param value: ");
Serial.println(p->value());
Serial.println("------");
}
request->send(200, "text/plain", "message received");
});
server.begin();
}
void loop()
{}
Please help me. I did many and various way including changing flash firmware many versions but still it cannot request data from my website to display on Arduino LCD. I also try a few coding with wifiesp and without still it cannot read my Json file.
void loop() {
String payload = "";
bool parse_json = false;
char web_host[] = "putraelection.000webhostapp.com";
if (client.connect(web_host, 80)) {
Serial.println("CONNECT HOST");
String url = "/reqdatacalon.php";
client.print("GET " + url + "HTTP/1.0\r\n" +
"Host: " + web_host + "\r\n" +
//"Accept: application/json\r\n" +
//"Content-Type: text/html\r\n" +
"Connection: Keep-Alive\r\n" +
"\r\n");
while (client.connected() || client.available()) {
if (client.available()) {
//char c = client.read();
String b = client.readString();
Serial.println(b);
/*if (c == '{') {
parse_json = true;
}
if (parse_json) {
payload += c;
}*/
}
}
client.stop();
}
Serial.print("data");
Serial.println(payload);
payload.trim();
if (payload != "") {
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.println("ERROR JSON");
} else {
String can1 = doc["CANDIDATE 1"];
Serial.println ("calon 1:" +can1);
}
} else {
Serial.println("data kosong");
}
delay(5000);
}
I want to connect my NODEMCU wifi module to live server and then comunicate with rest API. While I was calling simple GET method with plain-text content then everything works fine, problem arises while calling POST and JSON data. Though my server API seems to work fine on ARC(Rest API testing Application).
Working With
Windows 10
Arduino IDE 1.8.12
Linux Live Server (hosted on BIGROCK)
Secure Domain (https://)
API directory permission is 755
LIVE SERVER
<?php
if (strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {
throw new Exception('Only POST requests are allowed');
}
$content_type = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '';
if (stripos($content_type, 'application/json') === false) {
throw new Exception('Content-Type must be application/json');
}
$body = file_get_contents("php://input");
$object = json_decode($body, true);
if (!is_array($object)) {
throw new Exception('Failed to decode JSON object');
}
print_r($object);
?>
Arduino IDE
#include <ESP8266WiFi.h>
const char* ssid = "**********";
const char* password = "**********";
const char* host = "www.ameyakrishi.com";
void setup()
{
Serial.begin(115200);
delay(2000);
Serial.print("[Connecting to "); Serial.print(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");delay(500);
}
Serial.println(" Connected]");delay(1000);
}
void loop()
{
WiFiClient client;
Serial.print("[Connecting to "); Serial.print(host);delay(500);
if (client.connect(host, 80))
{
Serial.println(" Connected]");delay(1000);
String postData = "{\"key\":\"papa\",\"val\":999}";
client.print(String("POST /automation/app.php") + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Content-Type: application/json \r\n" +
"Content-Length: " + postData.length() + "\r\n" +
"Connection: close\r\n" +
"\r\n"
);
while (client.connected() || client.available())
{
if (client.available())
{
String line = client.readStringUntil('\n');
Serial.println(line);
}
}
client.stop();
Serial.println("\n[Disconnected]");delay(1000);
}
else
{
Serial.println("connection failed!]");delay(1000);
client.stop();
}
delay(30000);
}
Serial Monitor Output
All connections are succeed and then print the 500 Internal Server Error response in format.
I am trying to upload data from an Aurdino to Xively. I can connect to Xively and even get the PUT request showing up on the Xively Request Log.
But i get the error 400 Bad Request
{"title":"JSON Parser Error","errors":"The feed is empty"}
I think the problem may be here
data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"Reading\",\"current_value\" : \"" + String(reading) + "\"}]}";
Any tips would be much appreciated.
Cheers and thanks
///////////////////////
// Saving to Xively ///
///////////////////////
int savetoxively(String reading, char* feedID) {
//getting the IP address for the xively website.
ip = 0;
Serial.print(WEBSITE); Serial.print(F(" -> "));
while (ip == 0) {
if (! cc3000.getHostByName(WEBSITE, &ip)) {
Serial.println(F("Couldn't resolve!"));
}
delay(500);
}
cc3000.printIPdotsRev(ip);
// formatting the data for the xively website.
int length = 0;
String data = ""; //the problem might be here, the serial monitor says the length is 0. should have something ing it.
data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"Reading\",\"current_value\" : \"" + String(reading) + "\"}]}";
length = data.length();
Serial.print("Data length");
Serial.println(length);
Serial.println();
// Print request for debug purposes
Serial.print("PUT /v2/feeds/");
Serial.print(feedID); //serial monitor shows the correct feedID here
Serial.println(".json HTTP/1.1");
Serial.println("Host: api.xively.com");
Serial.print("X-ApiKey: ");
Serial.println(API_key); //serial monitor shows the correct API key
Serial.print("Content-Length: ");
Serial.println(length, DEC);
Serial.print("Connection: close");
Serial.println();
Serial.print("Reading: ");
Serial.println(reading); //serial monitor shows the correct reading
Serial.println();
// connecting with the xively server
Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
if (client.connected()) {
Serial.println("Connected!");
Serial.print("feedID: ");
Serial.println(feedID);
client.print("PUT /v2/feeds/");
client.print(feedID);
client.println(".json HTTP/1.1");
client.println("Host: api.xively.com");
client.print("X-ApiKey: ");
client.println(API_key);
client.print("User-Agent: ");
client.println(USERAGENT);
client.print("Content-Length: ");
client.println(length);
client.print("Connection: close");
client.println();
client.print(data);
client.println();
Serial.println("data sent");
}
while (client.connected()) { //printing connection status
while (client.available()) { //HTTP/1.1 400 Bad Request
char c = client.read(); //Date: Sat, 15 Mar 2014 19:33:38 GMT
Serial.print(c); //Content-Type: application/json; charset=utf-8
//Content-Length: 58
//Connection: close
//X-Request-Id: f48494a26daa2a5f0979dc4460264d233103f0f5
//{"title":"JSON Parser Error","errors":"The feed is empty"}
}
}
client.close(); // closes the connection with xively
cc3000.disconnect(); //disconnects the Wifi network
return 1;
}