ESP8266 - Response from server gets cut - arduino

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;
}
}

Related

Arduino MEGA, LCD and SSR is frozen after 24 hours

I'm going to tell you my problem with arduino.
I am making an access rfdi system to enable a water pump, the procedure is as follows: I bring the rfid keyring closer to the reader, I make a sql query to the server and if it returns the data, I enable the pump and later register that user is served water.
Everything works fine for 18-24 hours, after that time the screen freezes and the arduino doesn't respond in any way or run the program. To get it to work again I have to restart it.
Maybe I thought it was a memory problem, but I don't know. On build I have Sketch (18%) and memory (22%).
I don't know where the problem is.
#include <U8glib.h>
#include <SPI.h>
#include <EthernetENC.h>
#include <Wiegand.h> //PROTOCOLO P/ RFDI
#include <ArduinoJson.h>
U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7); //LCD Enable, RW, RS, RESET
#define FALSE 0
#define TRUE 1
long int rawToken;
char c;
char pageAdd[64];
char user[64];
int totalCount = 0;
String ID = "";
String readString = "";
String clientegraba = "";
String terrenograba = "";
bool inicio = true;
bool errorbit = false;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// CONFIG IP ARDUINO
IPAddress ip(192,168,0,210);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
// IP Y PUERTO SERVIDOR
IPAddress server(192,168,0,104);
char serverName[] = "192.168.0.104";
int serverPort = 80;
EthernetClient client;
WIEGAND wg;
void setup() {
Serial.begin(9600);
pinMode(34,OUTPUT); //OUT PUMP
digitalWrite(34,LOW);
welcome(); //PANTALLA BIENVENIDA
//GATE A
wg.D0PinA =2;
wg.D1PinA =3;
//GATE B
wg.D0PinB =18;
wg.D1PinB =19;
//GATE C
wg.D0PinC =20;
wg.D1PinC =21;
// Reader enable
wg.begin(TRUE, FALSE, FALSE); // wg.begin(GateA , GateB, GateC)
// disable SD SPI
pinMode(4,OUTPUT);
digitalWrite(4,HIGH);
// Start ethernet
Serial.println(F("Iniciando ethernet..."));
Ethernet.begin(mac, ip, gateway, gateway, subnet);
Serial.println(Ethernet.localIP());
delay(2000);
Serial.println(F("Listo"));
ingresellave();
}
void loop()
{
if(wg.available()){
errorbit = false;
espere(); //WAITING SCREEN
ID = String(wg.getCode()); //OBTIENE ID DE TARJETA
String data = "/test.php?cliente=" + ID; //CONCAT ID
sprintf(pageAdd,data.c_str(),totalCount);
Serial.println(pageAdd);
if(!getPage(server,serverPort,pageAdd)){
Serial.print(F("Falla "));
}else{
Serial.print(F("Paso "));
}
totalCount++;
Serial.println(totalCount,DEC);
}
if(ID != ""){
if(clientegraba != ""){
grabacarga(clientegraba,terrenograba);
}else{
if(errorbit == false){
noexiste();
delay(3000);
ID = "";
ingresellave();
}
}
}
delay(200);
}
byte getPage(IPAddress ipBuf,int thisPort, char *page)
{
int inChar;
char outBuf[128];
Serial.print(F("Conectando..."));
if(client.connect(ipBuf,thisPort) == 1){
Serial.println(F("Conectado"));
sprintf(outBuf,"GET %s HTTP/1.1",page);
client.println(outBuf);
sprintf(outBuf,"Host: %s",serverName);
client.println(outBuf);
client.println(F("Connection: close\r\n"));
}else{
error();
errorbit = true;
Serial.println(F("Error en servidor"));
return 0;
}
// connectLoop controls the hardware fail timeout
int connectLoop = 0;
boolean reader = false;
while(client.connected())
{
while(client.available())
{
String line = client.readStringUntil('\n');
if(reader){
StaticJsonBuffer<200> jsonBuffer;
JsonObject& datos = jsonBuffer.parseObject(line);
String apellido = datos["name"];
String cliente = datos["cliente"];
clientegraba = cliente;
long total = datos["total"];
long libres = datos["libres"];
String terreno = datos["terreno"];
terrenograba = terreno;
String costo = datos["costo"];
float price = costo.toFloat();
usuario(apellido,total,libres,price);
Serial.println("User: " + apellido);
Serial.println("Cliente: " + cliente);
Serial.println("Tarjeta: " + ID);
Serial.println("Terreno: " + terreno);
Serial.println("Costo: " + String(costo));
Serial.println("Total: " + String(total));
Serial.println("Libres: " + String(libres));
if(apellido != ""){
digitalWrite(34,HIGH); //PUMP START
delay(1000);
digitalWrite(34,LOW); //PUMP STOP
}
}
if(line == "\r") {
reader = true;
break;
}
// set connectLoop to zero if a packet arrives
connectLoop = 0;
}
connectLoop++;
// if more than 10000 milliseconds since the last packet
if(connectLoop > 10000)
{
// then close the connection from this end.
Serial.println();
Serial.println(F("Timeout"));
client.stop();
}
// this is a delay for the connectLoop timing
delay(1);
}
Serial.println();
Serial.println(F("Desconectando."));
// close client end
client.stop();
delay(100);
return 1;
}
void grabacarga(String cliente, String terreno){
String data = "/graba.php?cliente=" + cliente + "&tarjeta=" + ID + "&terreno='" + terreno + "'";
sprintf(pageAdd,data.c_str(),totalCount);
Serial.println(pageAdd);
if(!getPage(server,serverPort,pageAdd)) Serial.print(F("Falla "));
else Serial.print(F("Paso "));
totalCount++;
Serial.println(totalCount,DEC);
ID = "";
terrenograba = "";
clientegraba = "";
inicio = true;
delay(9000);
ingresellave();
}
void welcome() {
u8g.setRot180();
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(18,22,"SISTEMA");
u8g.drawStr(15,50,"ACCESO RFID");
} while( u8g.nextPage() );
}
void ingresellave() {
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(0,10,"COLOQUE EL BIDON");
u8g.drawStr(2,35,"Y LUEGO INGRESE");
u8g.drawStr(25,60,"UNA LLAVE");
} while( u8g.nextPage() );
}
void error() {
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(40,10,"ERROR");
u8g.drawStr(33,35,"INTENTE");
u8g.drawStr(22,60,"NUEVAMENTE");
} while( u8g.nextPage() );
}
void espere() {
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(25,35,"ESPERE...");
} while( u8g.nextPage() );
}
void usuario(String user, long total, long libres, float costo) {
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10);
u8g.drawStr(0,10,user.c_str());
String carga = "Carga:" + String(total) + "/" + String(libres);
u8g.setFont(u8g_font_unifont);
u8g.drawStr(15,33,carga.c_str());
if(total > libres){
long precio = total - libres;
float costototal = precio * costo;
Serial.println(costototal);
String valor = "Costo:$" + String(costototal);
u8g.drawStr(0,60,valor.c_str());
}
} while( u8g.nextPage() );
}
void noexiste(){
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(34,22,"USUARIO");
u8g.drawStr(12,50,"NO REGISTRADO");
} while( u8g.nextPage() );
}
The system power is from a 12V 4.5A source and the Arduino Mega along with the screen(LCD12864A) are powered from the 5V pin through an external LM2596 regulator.
The screen data pins are connected to pins 4,5,6 and 7, the rfid reader to pins 2 and 3 and the water pump output is pin 34 which has a 2222a pnp transistor connected with a 1K base resistor, emitter to ground and collector to an SSR-24DA solid state relay.
Thank you.
After reading your comment mentioning wiegand malfunction, and the fact that it only malfunctioned after several hours of running well, I would try and see if it's overheating somehow, or try and reduce EMI by using EMI filter on the power supply and shielding the circuit board with aluminium box or the like.
Water pump can cause high EMI and voltage spike in the mains upon turning on or off.

Error using thingspeak talk back to control arduino led

The error I'm facing is about using talkback function of thingspeak to control my Arduino LED. it cannot execute the talkback command to off the led. The error is in my void get talkback. Please help me
#include "ThingSpeak.h"
#include <Ethernet.h>
#define redLED 8
byte mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x40, 0x4F};
const String channelsAPIKey = "";
const String talkBackAPIKey = "";
const String talkBackID = "";
const String talkCommandID = "";
const unsigned int getTalkBackInterval = 10 * 1000;
const unsigned int updateChannelsInterval = 15 * 1000;
String talkBackCommand;
long lastConnectionTimeChannels = 0;
boolean lastConnectedChannels = false;
int failedCounterChannels = 0;
long lastConnectionTimeTalkBack = 0;
boolean lastConnectedTalkBack = false;
int failedCounterTalkBack = 0;
char charIn;
// Arduino Ethernet Client is initialized
EthernetClient client;
void setup()
{
Ethernet.init(10); // Most Arduino Ethernet hardware
Serial.begin(9600); //Initialize serial
// start the Ethernet connection:
pinMode(redLED, OUTPUT);
digitalWrite(redLED, HIGH);
}
void loop()
{
getTalkBack();
}
void getTalkBack()
{
String tsData;
tsData = talkBackID + "/commands/execute?api_key=" + talkBackAPIKey;
if ((!client.connected() && (millis() - lastConnectionTimeTalkBack > getTalkBackInterval)))
{
if (client.connect("api.thingspeak.com", 80))
{
client.println("GET /talkbacks/" + tsData + " HTTP/1.0");
client.println();
lastConnectionTimeTalkBack = millis();
if (client.connected())
{
Serial.println("---------------------------------------");
Serial.println("GET TalkBack command");
Serial.println();
Serial.println("Connecting to ThingSpeak");
Serial.println();
Serial.println();
Serial.println("Server response");
Serial.println();
failedCounterTalkBack = 0;
while (client.connected() && !client.available()) delay(2000); //waits for data
while (client.connected() || client.available())
{
charIn = client.read();
talkBackCommand += charIn;
Serial.print(charIn);
if (talkBackCommand == "LED_ON")
{
digitalWrite(redLED, HIGH);
}
if (talkBackCommand == "LED_OFF")
{
digitalWrite(redLED, LOW);
}
}
if (talkBackCommand = talkBackCommand.substring(talkBackCommand.indexOf("_CMD_") + 5));
{
Serial.println();
Serial.println();
Serial.println("Disconnected");
Serial.println();
Serial.println("--------");
Serial.println();
Serial.println("talkback command was");
Serial.println();
Serial.println("--------");
Serial.println();
Serial.println(talkBackCommand);
Serial.println("--------");
Serial.println();
}
}
else
{
failedCounterTalkBack++;
Serial.println("Connection to ThingSpeak failed (" + String(failedCounterTalkBack, DEC) + ")");
Serial.println();
lastConnectionTimeChannels = millis();
}
}
}
if (failedCounterTalkBack > 3 )
{
startEthernet();
}
client.stop();
Serial.flush();
}
The below is a image from my serial monitor. It shows that I can capture the command but couldn't execute it.
Looks like you are reading and appending all the received bytes to talkBackCommand. So, talkBackCommand is "HTTP/1.1 200 OK Date...." and if (talkBackCommand == "LED_ON") would never be true.
I think you wanted to see if the received data contain your commands LED_ON or LED_OFF. You can do something like this:
if (talkBackCommand.indexOf("LED_ON") != -1)
indexOf() locates a String in a String and returns index or -1 if not found.
See more info about indexOf() here: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/indexof/

Sending a HTTP request to Google Script in Arduino

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 having trouble sending data to website from ESP8266 (ESP-01) via Arduino with AT commands

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

Alarm.alarmRepeat repeats only twice then stops working

I'm using an arduino uno with a CC3000 WiFi Shield. The ardunio counts people using a light barrier and then reports the countings to the xievly site. It seems to work fine for an hour or two but then nothing happens. Any ideas?
// Libraries
#include <Adafruit_CC3000.h>
#include <SPI.h>
#include <Time.h>
#include <TimeAlarms.h>
// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ 3
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIV2); // you can change this clock speed
// WLAN parameters
#define WLAN_SSID "XX"
#define WLAN_PASS "XX"
#define WLAN_SECURITY WLAN_SEC_WPA2
// Xively parameters
#define WEBSITE "https://xively.com/feeds/XX"
#define API_key "XXX"
#define feedID "XXXX``"
uint32_t ip;
Adafruit_CC3000_Client client;
const unsigned long
connectTimeout = 15L * 1000L, // Max time to wait for server connection
responseTimeout = 15L * 1000L; // Max time to wait for data from server
// Visitor Counter
int anzahl =0;
int lastState=LOW;
const int inputPin = 2;
void setup()
{
// Initialize
attachInterrupt(0, count, RISING);
Serial.begin(115200);
if (!cc3000.begin())
{
while(1);
}
// Connect to WiFi network
cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
/* Wait for DHCP to complete */
while (!cc3000.checkDHCP())
{
delay(100);
}
unsigned long t = getTime();
cc3000.disconnect();
setTime(hour(t)+2,minute(t),second(t),month(t),day(t),year(t));
Alarm.alarmRepeat(9,59,59, Messung);
Alarm.alarmRepeat(10,59,59, Messung);
Alarm.alarmRepeat(11,59,59, Messung);
Alarm.alarmRepeat(12,59,59, Messung);
Alarm.alarmRepeat(13,59,59, Messung);
Alarm.alarmRepeat(14,59,59, Messung);
Alarm.alarmRepeat(15,59,59, Messung);
Alarm.alarmRepeat(16,59,59, Messung);
Alarm.alarmRepeat(17,59,59, Messung);
Alarm.alarmRepeat(18,59,59, Messung);
Alarm.alarmRepeat(19,59,59, Messung);
Alarm.alarmRepeat(22,59,59, Zeitkorrektur);
}
void count()
{
delay(10);
int val = digitalRead(inputPin);
if (val == HIGH && lastState==LOW)
{
anzahl++;
lastState=val;
}
else
{
lastState=val;
}
}
void Zeitkorrektur()
{
getTime();
}
void Messung()
{
datalog();
}
void loop()
{
Alarm.delay(1000);
}
// Minimalist time server query; adapted from Adafruit Gutenbird sketch,
// which in turn has roots in Arduino UdpNTPClient tutorial.
unsigned long getTime()
{
uint8_t buf[48];
unsigned long ip, startTime, t = 0L;
// Hostname to IP lookup; use NTP pool (rotates through servers)
if(cc3000.getHostByName("pool.ntp.org", &ip)) {
static const char PROGMEM
timeReqA[] = { 227, 0, 6, 236 },
timeReqB[] = { 49, 78, 49, 52 };
Serial.println(F("\r\nAttempting connection..."));
startTime = millis();
do {
client = cc3000.connectUDP(ip, 123);
} while((!client.connected()) &&
((millis() - startTime) < connectTimeout));
if(client.connected()) {
Serial.print(F("connected!\r\nIssuing request..."));
// Assemble and issue request packet
memset(buf, 0, sizeof(buf));
memcpy_P( buf , timeReqA, sizeof(timeReqA));
memcpy_P(&buf[12], timeReqB, sizeof(timeReqB));
client.write(buf, sizeof(buf));
Serial.print(F("\r\nAwaiting response..."));
memset(buf, 0, sizeof(buf));
startTime = millis();
while((!client.available()) &&
((millis() - startTime) < responseTimeout));
if(client.available()) {
client.read(buf, sizeof(buf));
t = (((unsigned long)buf[40] << 24) |
((unsigned long)buf[41] << 16) |
((unsigned long)buf[42] << 8) |
(unsigned long)buf[43]) - 2208988800UL;
Serial.print(F("OK\r\n"));
}
client.close();
}
}
if(!t) Serial.println(F("error"));
return t;
}
void datalog()
{
//noInterrupts();
// Connect to WiFi network
cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
/* Wait for DHCP to complete */
while (!cc3000.checkDHCP())
{
delay(100);
}
// Set the website IP
uint32_t ip = cc3000.IP2U32(216,52,233,120);
cc3000.printIPdotsRev(ip);
// Get data & transform to integers
int visitors = (int) anzahl/2; //Visitors going in and out therefore divided by 2
// Prepare JSON for Xively & get length
int length = 0;
String data = "";
data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"Visitors\",\"current_value\" : \"" + String(visitors) + "\"}]}";
length = data.length();
// Send request
Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
if (client.connected()) {
Serial.println("Connected!");
client.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
client.println("Host: api.xively.com");
client.println("X-ApiKey: " + String(API_key));
client.println("Content-Length: " + String(length));
client.print("Connection: close");
client.println();
client.print(data);
client.println();
} else {
Serial.println(F("Connection failed"));
return;
}
Serial.println(F("-------------------------------------"));
while (client.connected()) {
while (client.available()) {
char c = client.read();
Serial.print(c);
}
}
client.close();
Serial.println(F("-------------------------------------"));
Serial.println(F("\n\nDisconnecting"));
cc3000.disconnect();
anzahl =0;
//interrupts();
}
In setup() you configured interrupt with RISING. That means that it fires when the pin goes from low state to high state. But in interrupt handler - count() you have strange logic which looks excessive since you already configured interrupt to fire only once on event.
Let's see what happens in count(). val will always be HIGH (well, considering only normal case, not glitches).. When the first interrupt comes lastState is LOW as initial value and we increment, but all successive calls will not because lastState is HIGH and never becomes LOW again.
So, to fix problem, we simply need to drop lastState because it's not needed
void count()
{
delay(10);
// avoiding glitches - check if it's still high
int val = digitalRead(inputPin);
if (val == HIGH)
anzahl++;
}

Resources