I am using ESP8266 & Firebase to control my fan speed. I want to get analog input from a potentiometer and send data to firebase realtime database. But when I analogRead in loop, firebase stream gives error
"Set string...
FAILED
REASON: connection lost".
When analogRead is removed code works perfectly.
void loop()
{
sensorValue = analogRead(A0);
if (Firebase.ready() && (millis() - sendDataPrevMillis > 150000 || sendDataPrevMillis == 0))
{
sendDataPrevMillis = millis();
count++;
String Path = path + "/String";
String Value = "Hello World! " + String(count);
Serial.println("------------------------------------");
Serial.println("Set string...");
if (Firebase.setString(fbdo, Path.c_str(), Value.c_str()))
{
Serial.println("PASSED");
Serial.println("PATH: " + fbdo.dataPath());
Serial.println("TYPE: " + fbdo.dataType());
Serial.print("VALUE: ");
printResult(fbdo); //see addons/RTDBHelper.h
Serial.println("------------------------------------");
Serial.println();
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + fbdo.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
}
if (Firebase.ready())
{
if (!Firebase.readStream(fbdo))
{
Serial.println("------------------------------------");
Serial.println("Can't read stream data...");
Serial.println("REASON: " + fbdo.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
if (fbdo.streamTimeout())
{
Serial.println("Stream timeout, resume streaming...");
Serial.println();
}
if (fbdo.streamAvailable())
{
Serial.println("------------------------------------");
Serial.println("Stream Data available...");
Serial.println("STREAM PATH: " + fbdo.streamPath());
Serial.println("EVENT PATH: " + fbdo.dataPath());
Serial.println("DATA TYPE: " + fbdo.dataType());
Serial.println("EVENT TYPE: " + fbdo.eventType());
Serial.print("VALUE: ");
printResult(fbdo); //see addons/RTDBHelper.h
Serial.println("------------------------------------");
Serial.println();
}
}
}
Related
#include <WiFiClient.h>
#include <WebServer.h>
#include <WiFi.h>
#include <ESPmDNS.h>
#include <SPI.h>
#include <SD.h>
String serverIndex = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Upload'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
" $.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!')"
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";
const char* ssid = "Entrib-Main";
const char* password = "shopWorx110T";
WebServer server(80);
File root;
bool opened = false;
String printDirectory(File dir, int numTabs) {
String response = "";
dir.rewindDirectory();
while(true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
//Serial.println("**nomorefiles**");
break;
}
for (uint8_t i=0; i<numTabs; i++) {
Serial.print('\t'); // we'll have a nice indentation
}
// Recurse for directories, otherwise print the file size
if (entry.isDirectory()) {
printDirectory(entry, numTabs+1);
} else {
response += String("<a href='") + String(entry.name()) + String("'>") + String(entry.name()) + String("</a>") + String("</br>");
}
entry.close();
}
return String("List files:</br>") + response + String("</br></br> Upload file:") + serverIndex;
}
void handleRoot() {
root = SD.open("/");
String res = printDirectory(root, 0);
server.send(200, "text/html", res);
}
bool loadFromSDCARD(String path){
path.toLowerCase();
String dataType = "text/plain";
if(path.endsWith("/")) path += "index.htm";
if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
else if(path.endsWith(".jpg")) dataType = "image/jpeg";
else if(path.endsWith(".txt")) dataType = "text/plain";
else if(path.endsWith(".zip")) dataType = "application/zip";
else if(path.endsWith(".bin")) dataType = "text/plain";
Serial.println(dataType);
File dataFile = SD.open(path.c_str());
if (!dataFile)
return false;
if (server.streamFile(dataFile, dataType) != dataFile.size()) {
Serial.println("Sent less data than expected!");
}
dataFile.close();
return true;
}
void handleNotFound(){
if(loadFromSDCARD(server.uri())) return;
String message = "SDCARD Not Detected\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 += " NAME:"+server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
Serial.println(message);
}
void setup(void){
SPI.begin(14, 2, 15, 13);
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());
//use IP or iotsharing.local to access webserver
if (MDNS.begin("iotsharing")) {
Serial.println("MDNS responder started");
}
if (!SD.begin()) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
//handle uri
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
/*handling uploading file */
server.on("/update", HTTP_POST, [](){
server.sendHeader("Connection", "close");
},[](){
HTTPUpload& upload = server.upload();
if(opened == false){
opened = true;
root = SD.open((String("/") + upload.filename).c_str(), FILE_WRITE);
if(!root){
Serial.println("- failed to open file for writing");
return;
}
}
if(upload.status == UPLOAD_FILE_WRITE){
if(root.write(upload.buf, upload.currentSize) != upload.currentSize){
Serial.println("- failed to write");
return;
}
} else if(upload.status == UPLOAD_FILE_END){
root.close();
Serial.println("UPLOAD_FILE_END");
opened = false;
}
});
server.begin();
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient();
}
This is a working code to obtain the sd card data from ESP32 TTGO T1 module on to the web server and will display all the files on the sd card directory and would download the file once you click on the file name.
However, when I tried to modify the code to enable the server to download the SD card file automatically without having to click on the file name it was not working. I tried the same by replacing SPIFFS in the async web server code with SD but it was not giving any output on the server
I have attached the code for AsyncWebServer below which was working perfectly with SPIFFS however didn't work with SD.
#include "WiFi.h"
#include "SPIFFS.h"
#include "ESPAsyncWebServer.h"
#include "SPI.h"
#include "SD.h"
const char* ssid = "Entrib-Main";
const char* password = "shopWorx110T";
AsyncWebServer server(80);
File root;
String serverIndex = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Upload'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
" $.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!')"
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";
String printDirectory(File dir, int numTabs) {
String response = "";
dir.rewindDirectory();
while(true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
//Serial.println("**nomorefiles**");
break;
}
for (uint8_t i=0; i<numTabs; i++) {
Serial.print('\t'); // we'll have a nice indentation
}
// Recurse for directories, otherwise print the file size
if (entry.isDirectory()) {
printDirectory(entry, numTabs+1);
} else {
response += String("<a href='") + String(entry.name()) + String("'>") + String(entry.name()) + String("</a>") + String("</br>");
}
entry.close();
}
return String("List files:</br>") + response + String("</br></br> Upload file:") + serverIndex;
}
void setup(){
Serial.begin(115200);
SPI.begin(14, 2, 15, 13);
if(!SPIFFS.begin()){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP());
server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){
SPI.begin(14, 2, 15, 13);
root = SD.open("/");
String res = printDirectory(root, 0);
request->send(SD, "/data/sample.bin", "text/html", true);
});
root = SD.open("/");
String res = printDirectory(root, 0);
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
root = SD.open("/");
String res = printDirectory(root, 0);
request->send(200, "text/html", res);
});
server.begin();
}
void loop(){}
Could anyone please suggest any changes to be made to this code to enable it to work for SD card files to auto download from a server or if you have any other working code for the same issue it would be appreciated. Thank You :)
I'm not sure it solves shalom-daniel's problem.
I just wanted to show how i am downloading a file named data.txt from sd card connected to esp32 to client.
CS is connected to io 5 on Esp32.
SCK is connected to io 18 on Esp32.
MOSI is connected to io 23 on Esp32.
MISO is connected to io 19 on Esp32.
It might look a little strange to start with SD.end,
but that's the only way i can make it work right.
server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){
SD.end();
SD.begin(SD_CS);
File file = SD.open("/data.txt");
if(!SD.begin(SD_CS)) {
Serial.println("Card Mount Failed");
request->send (200, "text/html", "<H1>Card Mount Failed</h1>");
}
else if(!file){
Serial.println("Failed to open file for reading");
request->send (200, "text/html", "<H1>Failed to open file for reading</h1>");
}
else{
request->send(file, "/data.txt", "text/xhr", true);
Serial.print("Recieved data.txt request from client IP ");
Serial.println(request->client()->remoteIP());
}
});
// Define CS pin for the SD card module
#define SD_CS 5
server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){
SD.begin(SD_CS);
if(!SD.begin(SD_CS)) {
Serial.println("Card Mount Failed");
logmessage = "Card Mount Failed";
return;
}
File file = SD.open("/data.txt");
if(!file){
//Serial.println(" Failed to open file for reading");
return;
}
request->send(file, "/data.txt", "text/xhr", true);
Serial.print("Recieved data.txt request from client IP ");
Serial.println(request->client()->remoteIP());
});
I have an ESP8266 and want to send messages to a MS-Teams channel. In the future I want to send temperature data but for now I am okay with whatever.
Right now I can connect to the host but it will not send any data to the team and it gives no error.
It works without any problems from Postman and the webhook also works from Python.
Here is my code:
#include "ESP8266HTTPClient.h"
#include "ESP8266WiFi.h"
#include <ArduinoJson.h>
#include <WiFiClientSecure.h>
void setup() {
Serial.begin(9600); //Serial connection
WiFi.begin("", ""); //WiFi connection
while (WiFi.status() != WL_CONNECTED) { //Wait for the WiFI connection completion
delay(500);
Serial.println("Waiting for connection");
}
}
void MicrosoftTeams() {
char host[] = "outlook.office.com"; //Specify request destination";
WiFiClient client;
if (client.connect(host, 443)) {
Serial.println("connected");
String url = "/webhook/Webhookcode";
char json[] = "{ \"#context\":
\"https://schema.org/extensions\",\"#type\":
\"MessageCard\",\"themeColor\": \"0072C6\",\"title\":
\"meddelande\",\"text\": \"Hello!!\"}";
int len = strlen(json);
String Output = "POST " + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Content-Type: application/json\r\n" +
"User-Agent: arduino/1.0\r\n" +
"Content-Length: " + len + "\r\n" +
"\r\n" +
json + "\n";
client.print(Output);
while (client.available()) {
String line = client.readStringUntil('\r');
Serial.print(line);
}
}
}
void loop() {
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
MicrosoftTeams();
} else {
Serial.println("Error in WiFi connection");
}
delay(30000); //Send a request every 30 seconds
}
Update:
Ive tested the following function and it works in this test example but not the real case. If i change the WiFiClient to WiFiClientSecure everything stops working.
void WifiCliwaySecure()
{
//Work
WiFiClient client;
const int httpPort = 80;
// //Doenst work
// WiFiClientSecure client;
// const int httpPort = 443;
char host[] = "ptsv2.com";
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
String url = "/t/erzs7-1555484154/post";
Serial.print("Requesting POST: ");
// Send request to the server:
String data = "{ \"title\": \"meddelande\",\"text\": \"Hallå alla bk!!\"}";
client.print(String("POST ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"User-Agent: BuildFailureDetectorESP8266\r\n" +
"Content-Length: " + data.length() + "\r\n" +
"Content-Type: application/json\r\n" +
"\r\n" +
data +
"\r\n");
Serial.print("url Send");
delay(500); // Can be changed
if (client.connected()) {
client.stop(); // DISCONNECT FROM THE SERVER
}
Serial.println();
Serial.println("closing connection");
}
By 2021, you should do the following:
#include <WiFi.h>
#include <HTTPClient.h>
void notifyTeams() {
// === Check WiFi connection status
if (WiFi.status()== WL_CONNECTED) {
HTTPClient http;
// == The incoming webhooks as given by Microsoft Teams
String url = "https://XXXXX.webhook.office.com/webhookb2/YYYYY/IncomingWebhook/ZZZZ/AAAA";
http.begin(url);
http.addHeader("Content-Type", "application/json");
// Send request to the server:
String data = "{ \"title\": \"Slug’s here!\", \"text\": \"Quickly go catch her!\"}";
int httpResponseCode = http.POST(data);
if(httpResponseCode>0) {
// === Get the response to the request
String response = http.getString();
Serial.println(httpResponseCode);
Serial.println(response);
}
else {
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
}
http.end();
}
else {
Serial.println("Error in WiFi connection");
}
}
I am using the following code which sends and receives a HTTP request to the custom website with no problem. However when I try to change the host to following I get a failure message. You can simply put this address into browser to see the actual response.
I need to change const char* host = "djxmmx.net"; to const char* host = "https://script.google.com/macros/s/AKfycby72HRgl874tst5e0FBHDa_VR6luqofn-ojiYF8KUBPmC2E3aiB/exec";
#include <ESP8266WiFi.h>
const char* ssid = "Phone";
const char* password = "aa";
const char* host = "djxmmx.net";
const uint16_t port = 17;
void setup() {
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi networkre
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
/* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
would try to act as both a client and an access-point and could cause
network-issues with your other WiFi-devices on your WiFi-network. */
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
Serial.print("connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);
// Use WiFiClient class to create TCP connections
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("connection failed");
delay(5000);
return;
}
// This will send a string to the server
Serial.println("sending data to server");
client.println("hello from ESP8266");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
delay(60000);
return;
}
}
// Read all the lines of the reply from server and print them to Serial
Serial.println("receiving from remote server");
while (client.available()) {
char ch = static_cast<char>(client.read());
Serial.print(ch);
}
// Close the connection
//Serial.println();
//Serial.println("closing connection");
// client.stop();
//delay(300000); // execute once every 5 minutes, don't flood remote service
}
You can do it this way using some help as mentioned. This requires a data server setup in Google app in this link GoogleSheetScript. Note how "name=Amir" transfer your data.
/* HTTPS on ESP8266 with follow redirects, chunked encoding support
* Version 2.1
* Author: Sujay Phadke
* Github: #electronicsguy
* Copyright (C) 2017 Sujay Phadke <electronicsguy123#gmail.com>
* All rights reserved.
*
* Example Arduino program
*/
#include <ESP8266WiFi.h>
#include "HTTPSRedirect.h"
#include "DebugMacros.h"
// Fill ssid and password with your network credentials
const char* ssid = "AmirPhone";
const char* password = "aa112233";
const char* host = "script.google.com";
// Replace with your own script id to make server side changes
const char *GScriptId = "AKfycby72HRgl874tst5e0FBHDa_VR6luqofn-ojiYF8KUBPmC2E3aiB";
const int httpsPort = 443;
// echo | openssl s_client -connect script.google.com:443 |& openssl x509 -fingerprint -noout
const char* fingerprint = "";
// Write to Google Spreadsheet
String url = String("/macros/s/") + GScriptId + "/exec?name=Amir";
// Fetch Google Calendar events for 1 week ahead
String url2 = String("/macros/s/") + GScriptId + "/exec?cal";
// Read from Google Spreadsheet
String url3 = String("/macros/s/") + GScriptId + "/exec?read";
String payload_base = "";
String payload = "";
HTTPSRedirect* client = nullptr;
// used to store the values of free stack and heap
// before the HTTPSRedirect object is instantiated
// so that they can be written to Google sheets
// upon instantiation
unsigned int free_heap_before = 0;
unsigned int free_stack_before = 0;
void setup() {
Serial.begin(115200);
Serial.flush();
//free_heap_before = ESP.getFreeHeap();
//free_stack_before = cont_get_free_stack(&g_cont);
Serial.printf("Free heap before: %u\n", free_heap_before);
Serial.printf("unmodified stack = %4d\n", free_stack_before);
Serial.println();
Serial.print("Connecting to wifi: ");
Serial.println(ssid);
// flush() is needed to print the above (connecting...) message reliably,
// in case the wireless connection doesn't go through
Serial.flush();
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Use HTTPSRedirect class to create a new TLS connection
client = new HTTPSRedirect(httpsPort);
client->setPrintResponseBody(true);
client->setContentTypeHeader("application/json");
Serial.print("Connecting to ");
Serial.println(host);
// Try to connect for a maximum of 5 times
bool flag = false;
for (int i=0; i<5; i++){
int retval = client->connect(host, httpsPort);
if (retval == 1) {
flag = true;
break;
}
else
Serial.println("Connection failed. Retrying...");
}
if (!flag){
Serial.print("Could not connect to server: ");
Serial.println(host);
Serial.println("Exiting...");
return;
}
if (client->verify(fingerprint, host)) {
Serial.println("Certificate match.");
} else {
Serial.println("Certificate mis-match");
}
// Send memory data to Google Sheets
payload = payload_base + "\"" + free_heap_before + "," + free_stack_before + "\"}";
client->POST(url2, host, payload, false);
payload = payload_base;// + "\"" + ESP.getFreeHeap() + "," + cont_get_free_stack(&g_cont) + "\"}";
client->POST(url2, host, payload, false);
// Note: setup() must finish within approx. 1s, or the the watchdog timer
// will reset the chip. Hence don't put too many requests in setup()
// ref: https://github.com/esp8266/Arduino/issues/34
Serial.println("\nGET: Write into cell 'A1'");
Serial.println("=========================");
// fetch spreadsheet data
client->GET(url, host);
// Send memory data to Google Sheets
payload = payload_base;// + "\"" + ESP.getFreeHeap() + "," + cont_get_free_stack(&g_cont) + "\"}";
client->POST(url2, host, payload, false);
Serial.println("\nGET: Fetch Google Calendar Data:");
Serial.println("================================");
// fetch spreadsheet data
client->GET(url2, host);
// Send memory data to Google Sheets
payload = payload_base;// + "\"" + ESP.getFreeHeap() + "," + cont_get_free_stack(&g_cont) + "\"}";
client->POST(url2, host, payload, false);
Serial.println("\nSeries of GET and POST requests");
Serial.println("===============================");
Serial.printf("Free heap: %u\n", ESP.getFreeHeap());
Serial.printf("unmodified stack = %4d\n");//, cont_get_free_stack(&g_cont));
// delete HTTPSRedirect object
delete client;
client = nullptr;
}
void loop() {
static int error_count = 0;
static int connect_count = 0;
const unsigned int MAX_CONNECT = 20;
static bool flag = false;
//Serial.printf("Free heap: %u\n", ESP.getFreeHeap());
//Serial.printf("unmodified stack = %4d\n", cont_get_free_stack(&g_cont));
if (!flag){
//free_heap_before = ESP.getFreeHeap();
// free_stack_before = cont_get_free_stack(&g_cont);
client = new HTTPSRedirect(httpsPort);
flag = true;
client->setPrintResponseBody(true);
client->setContentTypeHeader("application/json");
}
if (client != nullptr){
if (!client->connected()){
client->connect(host, httpsPort);
payload = payload_base + "\"" + free_heap_before + "," + free_stack_before + "\"}";
client->POST(url2, host, payload, false);
}
}
else{
DPRINTLN("Error creating client object!");
error_count = 5;
}
if (connect_count > MAX_CONNECT){
//error_count = 5;
connect_count = 0;
flag = false;
delete client;
return;
}
Serial.println("GET Data from cell 'A1':");
if (client->GET(url3, host)){
++connect_count;
}
else{
++error_count;
DPRINT("Error-count while connecting: ");
DPRINTLN(error_count);
}
Serial.println("POST append memory data to spreadsheet:");
payload = payload_base;// + "\"" + ESP.getFreeHeap() + "," + cont_get_free_stack(&g_cont) + "\"}";
if(client->POST(url2, host, payload)){
;
}
else{
++error_count;
DPRINT("Error-count while connecting: ");
DPRINTLN(error_count);
}
/*
if (!(client.reConnectFinalEndpoint())){
++error_count;
DPRINT("Error-count while connecting: ");
DPRINTLN(error_count);
}
else
error_count = 0;
*/
if (error_count > 3){
Serial.println("Halting processor...");
delete client;
client = nullptr;
Serial.printf("Final free heap: %u\n", ESP.getFreeHeap());
Serial.printf("Final unmodified stack = %4d\n");//, cont_get_free_stack(&g_cont));
Serial.flush();
ESP.deepSleep(0);
}
// In my testing on a ESP-01, a delay of less than 1500 resulted
// in a crash and reboot after about 50 loop runs.
delay(4000);
}
[1]: https://github.com/electronicsguy/ESP8266/blob/master/HTTPSRedirect/GoogleScript.gs
I am sending GET request to my website via the ESP8266 through Arduino AT commands.
I have searched a lot on Google but couldn't come up with a good solution.
For the first loop the code works fine but for next loop the code gives errors.
Different type
Here is my code:
#include <SoftwareSerial.h>
SoftwareSerial esp(2, 3); // Arduino RX:2, TX:3
String WIFI_SSID = "wifi_ssid"; //your network SSID
String WIFI_PWD = "wifi_pass"; //your network password
String Domain = "www.example.com";
void setup() {
Serial.begin(9600);
Serial.println("Started....");
esp.begin(9600);
//esp.setTimeout(500);
espAT("AT\r\n", 1000);
espAT("AT+CWMODE=1\r\n", 1000);
espAT("AT+CWJAP=\"" + WIFI_SSID + "\",\"" + WIFI_PWD + "\"\r\n", 5000);
espAT("AT+CIPSTATUS\r\n", 1000);
espAT("AT+CIPSTART=\"TCP\",\"" + Domain + "\",80\r\n", 5000);
}
void loop() {
int val = rand() % 255;
String request = "GET /iot/ HTTP/1.1\r\nHost: " + Domain + "\r\n\r\n";
espAT("AT\r\n", 1000);
espAT("AT+CIPSEND=" + String(request.length()+2) + "\r\n", 500);
espAT(request, 200);
String response = "";
while (esp.available()) {
response = esp.readStringUntil('0');
}
Serial.println(response);
espAT("AT+CIPCLOSE\r\n", 0);
delay(5000);
}
void espAT(String command, int waitFor)
{
esp.print(command);
int timeMillis = millis() + waitFor;
while (timeMillis > millis()) {
if (esp.available()) {
Serial.write(esp.read());
}
}
}
This code here in this instructable works for me quiet efficiently.
#include <SoftwareSerial.h>
String ssid ="yourSSID";
String password="yourPassword";
SoftwareSerial esp(6, 7);// RX, TX
String data;
String server = "yourServer"; // www.example.com
String uri = "yourURI";// our example is /esppost.php
int DHpin = 8;//sensor pin
byte dat [5];
String temp ,hum;
void setup() {
pinMode (DHpin, OUTPUT);
esp.begin(9600);
Serial.begin(9600);
reset();
connectWifi();
}
//reset the esp8266 module
void reset() {
esp.println("AT+RST");
delay(1000);
if(esp.find("OK") ) Serial.println("Module Reset");
}
//connect to your wifi network
void connectWifi() {
String cmd = "AT+CWJAP=\"" +ssid+"\",\"" + password + "\"";
esp.println(cmd);
delay(4000);
if(esp.find("OK")) {
Serial.println("Connected!");
}
else {
connectWifi();
Serial.println("Cannot connect to wifi"); }
}
byte read_data () {
byte data;
for (int i = 0; i < 8; i ++) {
if (digitalRead (DHpin) == LOW) {
while (digitalRead (DHpin) == LOW); // wait for 50us
delayMicroseconds (30); // determine the duration of the high level to determine the data is '0 'or '1'
if (digitalRead (DHpin) == HIGH)
data |= (1 << (7-i)); // high front and low in the post
while (digitalRead (DHpin) == HIGH);
// data '1 ', wait for the next one receiver
}
} return data; }
void start_test () {
digitalWrite (DHpin, LOW); // bus down, send start signal
delay (30); // delay greater than 18ms, so DHT11 start signal can be detected
digitalWrite (DHpin, HIGH);
delayMicroseconds (40); // Wait for DHT11 response
pinMode (DHpin, INPUT);
while (digitalRead (DHpin) == HIGH);
delayMicroseconds (80);
// DHT11 response, pulled the bus 80us
if (digitalRead (DHpin) == LOW);
delayMicroseconds (80);
// DHT11 80us after the bus pulled to start sending data
for (int i = 0; i < 4; i ++)
// receive temperature and humidity data, the parity bit is not considered
dat[i] = read_data ();
pinMode (DHpin, OUTPUT);
digitalWrite (DHpin, HIGH);
// send data once after releasing the bus, wait for the host to open the next Start signal
}
void loop () {
start_test ();
// convert the bit data to string form
hum = String(dat[0]);
temp= String(dat[2]);
data = "temperature=" + temp + "&humidity=" + hum;// data sent must be under this form //name1=value1&name2=value2.
httppost();
delay(1000);
}
void httppost () {
esp.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");//start a TCP connection.
if( esp.find("OK")) {
Serial.println("TCP connection ready");
} delay(1000);
String postRequest =
"POST " + uri + " HTTP/1.0\r\n" +
"Host: " + server + "\r\n" +
"Accept: *" + "/" + "*\r\n" +
"Content-Length: " + data.length() + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"\r\n" + data;
String sendCmd = "AT+CIPSEND=";//determine the number of caracters to be sent.
esp.print(sendCmd);
esp.println(postRequest.length() );
delay(500);
if(esp.find(">")) { Serial.println("Sending.."); esp.print(postRequest);
if( esp.find("SEND OK")) { Serial.println("Packet sent");
while (esp.available()) {
String tmpResp = esp.readString();
Serial.println(tmpResp);
}
// close the connection
esp.println("AT+CIPCLOSE");
}
}}
ESP8266 using the Arduino community firmware is as good as an Arduino. I propose to use the ESP8266 and should you need the Arduino, have them communicate using serial. It seems neater.
Best,
Odysseas
I'm using an ESP8266 connected to an Arduino one via SoftwareSerial to make a post request to a node web server. The ESP8266 sends some data to the server and it should get back other data. The data arrives at the server correctly, but the response from the server is incomplete (it gets cut each time in a different way) and I can't access the body of the response from my Arduino sketch. The server sends the response correctly, as i've checked with hurl.
This is my code:
#include "SoftwareSerial.h"
String ssid ="ssid";
String password="pwd";
SoftwareSerial esp(3, 2);// RX, TX
ESP8266_Simple wifi(3,2);
String data;
String server = "server";
String uri = "uri";
String token = "token";
float temp_set = 15; //standard values
float temp_rec = 15;
String temp_set_s;
String temp_rec_s;
int activate = LED_BUILTIN; //pin for relay
int button_up = 4;
int button_down = 5;
unsigned long time;
//LCD
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// DHT11
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 6
#define DHTTYPE DHT22
DHT_Unified dht(DHTPIN, DHTTYPE);
void setup() {
esp.begin(9600);
Serial.begin(9600);
delay(10);
reset();
connectWifi();
pinMode(activate, OUTPUT);
pinMode(button_up, INPUT);
pinMode(button_down, INPUT);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
//DHT setup
dht.begin();
sensor_t sensor;
delay(500);
}
//reset the esp8266 module
void reset() {
esp.println("AT+RST");
delay(1000);
if(esp.find("OK") ) Serial.println("Module Reset");
}
//connect to your wifi network
void connectWifi() {
String cmd = "AT+CWJAP=\"" +ssid+"\",\"" + password + "\"";
esp.println(cmd);
delay(4000);
if(esp.find("OK")) {
Serial.println("Connected!");
time = millis();
} else {
connectWifi();
Serial.println("Cannot connect to wifi");
}
}
void loop () {
//temp_rec_s = String(temp_rec);
//temp_set_s = String(temp_set);
//data = "tempRec=" + temp_rec_s + "&tempSet=" + temp_set_s;
//httppost();
// dht data
sensors_event_t event;
dht.temperature().getEvent(&event);
temp_rec = event.temperature;
//temp_rec_s = String(temp_rec);
//temp_set_s = String(temp_set);
//data = "tempRec=" + temp_rec_s + "&tempSet" + temp_set_s;
// to activate
if(temp_set < temp_rec){
digitalWrite(activate, LOW);
} else{
digitalWrite(activate, HIGH);
}
//function for physical buttons
if((digitalRead(button_up)) == HIGH){
temp_set = temp_set + 0.5;
delay(100);
}
if((digitalRead(button_down)) == HIGH){
temp_set = temp_set - 0.5;
delay(100);
}
//shows temperature on display
lcd.setCursor(0, 0);
lcd.print("T rec " + String(temp_rec));
//shows temperature on display
lcd.setCursor(0, 1);
lcd.print("T set " + String(temp_set));
temp_rec_s = String(temp_rec);
temp_set_s = String(temp_set);
data = "tempRec=" + temp_rec_s + "&tempSet=" + temp_set_s + "&token=" + token;
//Serial.println(data);
if((millis() - time) >= 10000){
httppost();
}
delay(200);
}
void httppost () {
esp.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");//start a TCP connection.
if(esp.find("OK")) {
Serial.println("TCP connection ready");
}
delay(1000);
String postRequest =
"POST " + uri + " HTTP/1.0\r\n" +
"Host: " + server + "\r\n" +
"Accept: *" + "/" + "*\r\n" +
"Content-Length: " + data.length() + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"\r\n" + data;
String sendCmd = "AT+CIPSEND="; //determine the number of caracters to be sent.
esp.print(sendCmd);
esp.println(postRequest.length());
Serial.println(postRequest);
delay(500);
if(esp.find(">")) {
Serial.println("Sending..");
esp.print(postRequest);
String tmpResp = esp.readString();
Serial.println(tmpResp);
if(esp.find("SEND OK")) {
Serial.println("Packet sent");
while(esp.available()) {
String line = esp.readString();
Serial.print(line);
}
// close the connection
esp.println("AT+CIPCLOSE");
}
}
}
Put a delay(1) under the esp.readString() and use .read() instead with char like this:
while(esp.available())
{
char line = esp.read(); // read one char at a time
delay(1); // prevent freezing
Serial.print(line);
if (line == '\0') continue; // terminate the `while` when end of the data
}
The .readString() method as pointed out by #gre_gor reads until there is no incoming data for 1 second.
So the better method is to use read() and char since you can test the char to see if you have reached the end of data character \0.
When using .read() consider using a custom timeout, because data can be delivered with delays so you might want to keep trying for a certain period of time if you haven't yet reached the end of data character \0, like this:
long int time = millis(); // current time
long int wait = 1000 * 10; // wait 10 seconds before terminating the read process
while ((time + wait) > millis())
{
while (esp.available())
{
char line = esp.read();
delay(1);
Serial.print(line);
if (line == '\0') continue;
}
}