How to get data from web by NodeMCU - c++

I'm using NodeMCU v3, and can already send some information on its server.
But how can I receive some information from other web pages, let say for beginning, a plain text?

You need a HttpClient to communicate with a web server.
Good way to start is to use the HttpClient sample -> ReuseConnection.
This will allow you to make more requests than one.
You can see in Serial Monitor in Arduino IDE to see the response from the request.
Sample code:
Note: replace " http://:/someroute " with the desired http page you want to get.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#define USE_SERIAL Serial
ESP8266WiFiMulti WiFiMulti;
HTTPClient http;
void setup() {
USE_SERIAL.begin(115200);
// USE_SERIAL.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFiMulti.addAP("SSID", "PASSWORD");
// allow reuse (if server supports it)
http.setReuse(true);
}
void loop() {
// wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) {
http.begin("http://<IP>:<Port>/someroute");
int httpCode = http.GET();
if(httpCode > 0) {
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(3000);
}

Related

WiFiClient.cpp socket error "Software caused connection abort - PlatformIo

For a project I am working on a mesh network on ESP32 (devkit).
I'm using the https://gitlab.com/painlessMesh/painlessMesh library for this to work.
The data received by the other ESP32's need to be sended to an REST API on Home Assistent with adres: http://192.168.1.4:8123/api/states/sensor.mesh.
To to this I am using the https://www.arduino.cc/reference/en/libraries/http/ library to send these HTTP requests.
This is my code:
#include <painlessMesh.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino.h>
#include <ArduinoJson.h>
#define MESH_PREFIX "MeshNetwork"
#define MESH_PASSWORD "MeshPassword"
#define MESH_PORT 5555
const char* ssid_wifi = "<wifissid>";
const char* password_wifi = "<wifipassword>";
painlessMesh mesh;
Scheduler userScheduler;
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("Received from %u msg=%s\n", from, msg.c_str());
// Send To Home Assistent
Serial.printf("Node %u sends to HA....\n", from);
WiFiClient client;
HTTPClient http;
String serverName = "http://192.168.1.4:8123/api/states/sensor.mesh";
http.begin(client, serverName);
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer <TOKEN>");
String httpRequestData = "{\"state\":"+ String(random(0,30));
Serial.println(httpRequestData + ", \"attributes\": {\"unit_of_measurement\": \"°C\"}}");
int httpResponseCode = http.POST(httpRequestData + ", \"attributes\": {\"unit_of_measurement\": \"°C\"}}");
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
http.end();
}
void newConnectionCallback(uint32_t nodeId) {
Serial.printf("startHere: New Connection found!, nodeId = %u\n", nodeId);
}
void changedConnectionCallback() {
Serial.printf("Changed connections\n");
}
void nodeTimeAdjustedCallback(int32_t offset) {
Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset);
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid_wifi, password_wifi);
Serial.printf("\n Connecting to Wifi: %s", ssid_wifi);
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n Connected to Wifi! \n ");
// start Mesh Network
mesh.setDebugMsgTypes(ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE );
mesh.init( MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
// Set Root Node
mesh.setContainsRoot(true);
// Mesh Events
mesh.onReceive(&receivedCallback);
mesh.onNewConnection(&newConnectionCallback);
mesh.onChangedConnections(&changedConnectionCallback);
mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);
}
void loop() {
mesh.update();
}
When the data is sending it gives me the following error
[E][WiFiClient.cpp:258] connect(): socket error on fd 61, errno: 113, "Software caused connection abort"
HTTP Response code: -1
I don't know what to do know,I have tried a lot of things.
Can anybody help me?
Thanks!
Update: When requesting the HTTP POST in the setup() it works. Not in the loop()

How to get multiple responses per second with Get Request using ESP32

I'm using an ESP32 controller to send Get requests to a page. I can get 1 response per second using the http protocol and one response every three seconds using HTTPS. I would like to get as many as 3 responses per second if possible. Is there a faster way to get these responses and is the problem with my ESP32, the code, or the server itself? I'm not sure if it helps but my ESP32 is sending the Get request to an ASP.NET application running on a Windows server through an Amazon Web Services EC2 instance. My API is simply returning true or false.
Here is the code running on the ESP32:
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#define USE_SERIAL Serial
WiFiMulti wifiMulti;
//Certificate when using HTTPS
/*
const char* ca = \
"-----BEGIN CERTIFICATE-----\n" \
"examplecertificate\n" \
"-----END CERTIFICATE-----\n" \
*/
void setup() {
USE_SERIAL.begin(115200);
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
wifiMulti.addAP("ssid", "password");
}
void loop() {
// wait for WiFi connection
if((wifiMulti.run() == WL_CONNECTED)) {
HTTPClient http;
//USE_SERIAL.print("[HTTP] begin...\n");
//http.begin("https://example.com/webapi/controller/getstatus/0", ca); //Using HTTPS takes 3 seconds
http.begin("http://example.com/webapi/controller/getstatus/0"); //Using HTTP takes 1 second
//USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0) {
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
}

esp32 BLE device scan doesn't work second time it loops

I am trying to connect to a BLE device, and once the callback is received it sends an ACK to a server and then reconnects the BLE device, the BLE device doesn't want to reconnect the second time round though and just skips over that line. I tried disabling and enabling Wi-Fi but that results in a http error code of -1.
My code:
#include "BLEDevice.h"
#include "WiFi.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Arduino_JSON.h>
//WiFi variables
//HTTPClient http;
bool wifiConnect = 0;
bool scanned = 0;
const char* ssid = "SSID";
const char* password = "Password";
char* serverName = "generic server name";
String serverPath;
String httpRequestData;
int Connection = 0;
int httpResponseCode;
String Data = "";
String externalID = "";
//BLE Device
BLEScan* pBLEScan;
float Temp=0;
// The remote service we wish to connect to.
static BLEUUID serviceUUID("0000fff0-0000-1000-8000-00805f9b34fb");
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("0000fff1-0000-1000-8000-00805f9b34fb");
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
ESP_LOG_BUFFER_HEX("my value", pData, length);//NEW, used to neatly show data
Serial.println("");
Serial.print("The ");
if (pData[3] == 0)
Serial.print("object ");
else if (pData[3] == 1)
Serial.print("body ");
Serial.print("temperature is: ");
Temp = (float(pData[4] * 256 + pData[5])) / 10;
Serial.print(Temp);
Serial.print("*C");
Serial.println("");
Connection = 1;
scanned = 1;
}
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
}
void onDisconnect(BLEClient* pclient) {
connected = false;
wifiConnect = 0;
Serial.println("onDisconnect");
}
};
bool connectToServer() {
Serial.print("Forming a connection to ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEClient* pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristic");
// Read the value of the characteristic.
if (pRemoteCharacteristic->canRead()) {
std::string value = pRemoteCharacteristic->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if (pRemoteCharacteristic->canNotify())
pRemoteCharacteristic->registerForNotify(notifyCallback);
connected = true;
return true;
}
/**
Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
/**
Called for each advertising BLE server.
*/
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());
// We have found a device, let us now see if it contains the service we are looking for.
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application..."); \
//WiFi setup
Serial.println();
Serial.printf("Connecting to %s\n", ssid);
WiFi.begin(ssid, password);
//WiFi.config(staticIP, gateway, subnet);
while (WiFi.status() != WL_CONNECTED)
{
Serial.println("Connecting to WiFi...");
delay(1000);
}//end while
Serial.print("Connected, IP address: ");
Serial.println(WiFi.localIP());
HTTPClient http;
serverPath = serverName;
if (WiFi.status() == WL_CONNECTED) {
// Your Domain name with URL path or IP address with path
http.begin(serverPath.c_str());
// Data to send with HTTP POST
JSONVar json_test;
json_test["id"] = WiFi.macAddress();
httpRequestData = JSON.stringify(json_test);
// If you need an HTTP request with a content type: application/json, use the following:
http.addHeader("Content-Type", "application/json");
httpResponseCode = http.POST(httpRequestData);
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
Serial.println("This is the response code");
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
Serial.println("This is the setup");
}
// Free resources
Serial.println("IS this done?");
http.end();
} else
{
Serial.println("WiFi disconnected");
}
} // End of setup.
// This is the Arduino main loop function.
void loop() {
if ((!wifiConnect))
{
//BLE
BLEDevice::init("");
// Retrieve a Scanner and set the callback we want to use to be informed when we
// have detected a new device. Specify that we want active scanning and start the
// scan to run for 5 seconds.
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
Serial.println("Done");
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true) {
if (connectToServer()) {
Serial.println("We are now connected to the BLE Server.");
} else {
Serial.println("We have failed to connect to the server; there is nothin more we will do.");
}
doConnect = false;
}
// If we are connected to a peer BLE Server, update the characteristic each time we are reached
// with the current time since boot.
/* if ((!connected) && (doScan)) {
BLEDevice::getScan()->start(5); // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino
}*/
if (connected)
{ wifiConnect = 1;
}
} else if (scanned)
{
scanned=0;
wifiConnect=0;
BLEDevice::getScan()->clearResults();
BLEDevice::deinit(true);
HTTPClient http;
serverPath = serverName;
if (WiFi.status() == WL_CONNECTED) {
// Your Domain name with URL path or IP address with path
http.begin(serverPath.c_str());
// Data to send with HTTP POST
JSONVar json_test;
json_test["id"] = WiFi.macAddress();
httpRequestData = JSON.stringify(json_test);
// If you need an HTTP request with a content type: application/json, use the following:
http.addHeader("Content-Type", "application/json");
httpResponseCode = http.POST(httpRequestData);
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
Serial.println("This is the response code");
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
} else
{
Serial.println("WiFi disconnected");
}
Connection = 0;
doConnect=0;
doScan=0;
connected=0;
}
Serial.println(".");
delay(1000); // Delay a second between loops.
} // End of loop

Guru Meditation Error Core 0 panic'ed (LoadProhibited). Exception was unhandled

error project
Guru Meditation Error in project
Core 0 panic'ed (LoadProhibited). Exception was unhandled.
I have project using pulsesensor with ESP32, Data from ESP32 is saved in database.
I tried many times but could not
help me
#include <ssl_client.h>
#include <WiFiClientSecure.h>
#include <WiFi.h>
#include <SPI.h>
#include <WiFiClient.h>
#include <HTTPClient.h>
#define USE_SERIAL Serial
/* Konfigurasi pada SSID dan Password Wifi */
const char* ssid = "berdikari";
const char* password = "alfian24";
/* Konfigurasi koneksi ke server */
char server[] = "192.168.43.108"; // Ganti dengan IP Address komputer aplikasi
int port = 81;
/*konfigurasi*/
int PulseSensorPurplePin = 34; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0
int LED21 = 21; // The on-board Arduion LED
int Signal; // holds the incoming raw data. Signal value can range from 0-102
float pulse=0;
WiFiClient client;
void setup() {
USE_SERIAL.begin(115200); // Baudrate/kec. komunikasi pengiriman data ke serial terminal
delay(10);
Serial.println('\n');
WiFi.begin(ssid, password);
USE_SERIAL.print("Terhubung ke ");
USE_SERIAL.print(ssid);
// WiFi.config(local_IP, gateway, subnet, dns);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
USE_SERIAL.print('.');
}
USE_SERIAL.print('\n');
USE_SERIAL.println("Identitas ESP-32");
USE_SERIAL.print("IP Address:\t");
USE_SERIAL.println(WiFi.localIP()); // IP Address ESP-32
USE_SERIAL.print('\n');
USE_SERIAL.println("Identitas Web Server");
USE_SERIAL.println("IP Address:");
USE_SERIAL.print(server);
USE_SERIAL.print("\tport:\t");
USE_SERIAL.print(port);
}
void loop() {
Signal = analogRead(PulseSensorPurplePin); // Read the PulseSensor’s value.
// Send the Signal value to Serial Plotter.
delay(1000);
pulse = Signal;
USE_SERIAL.println(pulse);
if(WiFi.status() == WL_CONNECTED){
//URL target untuk menyimpan data sensor Pulse ke database
String url = "http://192.168.43.108:81/";
url += "sistem_monitoring/Monitoring/simpan/";
url += String(pulse);
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
http.begin(url);
USE_SERIAL.print("[HTTP] GET...\n");
int httpCode = http.GET();
if(httpCode > 0) {
USE_SERIAL.printf("[HTTP] GET... code: %d\n",
httpCode);
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n",
http.errorToString(httpCode).c_str());
}
http.end();
}
}
please help me.
What should I do??
I've seen this question asked a few times but never got a good answer.

Serial communication between esp8266 and atmega328p

I have a web server running on the esp8266.
The code is here:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include "index.h"
#include "login.h"
ESP8266WiFiMulti wifiMulti; // Create an instance of the ESP8266WiFiMulti class, called 'wifiMulti'
ESP8266WebServer server(80); // Create a webserver object that listens for HTTP request on port 80
void handleRoot(); // function prototypes for HTTP handlers
void handleLogin();
void handleNotFound();
void setup(void){
Serial.begin(115200); // Start the Serial communication to send messages to the computer
delay(100);
wifiMulti.addAP("DIGISOL", "edot2017"); // add Wi-Fi networks you want to connect to
Serial.println("Connecting ...");
while (wifiMulti.run() != WL_CONNECTED) { // Wait for the Wi-Fi to connect: scan for Wi-Fi networks, and connect to the strongest of the networks above
delay(250);
Serial.print('.');
}
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // Tell us what network we're connected to
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer
server.on("/", HTTP_GET, handleRoot); // Call the 'handleRoot' function when a client requests URI "/"
server.on("/login", HTTP_POST, handleLogin); // Call the 'handleLogin' function when a POST request is made to URI "/login"
server.on("/back",HTTP_POST,handleRoot);
server.onNotFound(handleNotFound); // When a client requests an unknown URI (i.e. something other than "/"), call function "handleNotFound"
server.begin(); // Actually start the server
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient(); // Listen for HTTP requests from clients
}
void handleRoot() { // When URI / is requested, send a web page
String indexPage = MAIN_page;
server.send(200, "text/html",indexPage);
}
void handleLogin() { // If a POST request is made to URI /login
String message = "";
if( ! server.hasArg("data") || server.arg("data") == NULL ){ // If the POST request doesn't have username and password data
server.send(400, "text/plain", "400: Invalid Request"); // The request is invalid, so send HTTP status 400
return;
}
else
{
message += server.arg("data"); //Get the name of the parameter
Serial.println(message);
String loginpage = LOGIN_PAGE;
server.send(200, "text/html",loginpage);
}
}
void handleNotFound(){
server.send(404, "text/plain", "404: Not found"); // Send HTTP status 404 (Not Found) when there's no handler for the URI in the request
}
Then I have a sketch to display a message on to the ledp10 display which is working fine.
ledp10 display message code:
#include <SPI.h>
#include <DMD2.h>
#include <fonts/SystemFont5x7.h>
#include <fonts/Arial14.h>
#include <fonts/Droid_Sans_24.h>
#include <fonts/Droid_Sans_16.h>
// Set Width to the number of displays wide you have
const int WIDTH = 1;
const int COUNTDOWN_FROM = 0;
int counter = COUNTDOWN_FROM;
// You can change to a smaller font (two lines) by commenting this line,
// and uncommenting the line after it:
const uint8_t *FONT = SystemFont5x7;
const uint8_t *FONT2 = SystemFont5x7;
const char *MESSAGE = "GOA";
SoftDMD dmd(WIDTH,1); // DMD controls the entire display
DMD_TextBox box(dmd, 0, 1);
DMD_TextBox box1(dmd,11,1); // "box" provides a text box to automatically write to/scroll the display
// the setup routine runs once when you press reset:
void setup() {
Serial.begin(9600);
dmd.setBrightness(255);
//dmd.selectFont(FONT);
dmd.begin();
}
// the loop routine runs over and over again forever:
void loop() {
dmd.selectFont(FONT);
box.print(counter);
dmd.selectFont(FONT2);
const char *next = MESSAGE;
while(*next) {
Serial.print(*next);
box1.print(*next);
delay(500);
next++;
}
box.println(F(""));
counter++;
if(counter == 60) {
dmd.clearScreen();
counter = 0;
}
}
Now I need to communicate between the esp8266 and atmega328p. I.e the message sent on the web page needs to be displayed on to the ledp10 display.
How should I do it?
Please help only in serial communication between esp8266 and atmega328p.
modify the lcd Atmega sketch to receive a text from Serial Monitor.
Then connect the esp8266 to Serial of Atmega and the Atmega sketch will receive the text you print to Serial in the esp sketch