This demo code is working fine but mine does not.
It returns "HTTPC_ERROR_CONNECTION_REFUSED" (my debug work suggests that it fails to create a TCP connection)
The example code uses WiFiMulti but that is not the issue.
What am I missing ?
Please kindly assist.
Working Example:
/**
* BasicHTTPClient.ino
*
* Created on: 24.05.2015
*
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#define USE_SERIAL Serial
ESP8266WiFiMulti WiFiMulti;
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);
}
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("SSID", "PASSWORD");
}
void loop() {
// wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
http.begin("http://192.168.1.12/test.html"); //HTTP
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) {
// HTTP header has been send and Server response header has been handled
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(10000);
}
My code:
#include <string>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
//EEPROM
#include <EEPROM.h>
//Serial
#include <SoftwareSerial.h> // We need this even if we're not using a SoftwareSerial object
#include <SerialCommand.h>
//Timer
#include <Ticker.h>
//***************************************************
#include "generalDeclerations.h"
#include "serialSetup.h"
#include "EEPROMAnything.h"
#include "ioControl.h"
#include "webServer.h"
//***************************************************
void setup() {
Serial.begin(115200);
EEPROM.begin(100);
initIO();
checkFD(); //Factory default ?
initSerialSetup(); //Initelize serial setup interface
bootPause(); //give the user a chance to interupt using the serial interface
//***************************** Starting the flow from here
// loadEEPROM();
initConnection();
initWebServer();
ledControl(HB_LED_PIN, 0.5);
regData.attach(REG_DATA_INTERVAL, regData2DB);
}
void loop() {
webServer.handleClient();
SCmd.readSerial(); // We don't do much, just process serial commands
// collectData();
// regData();
if ( (wifiMode == WIFI_AP) && (millis() - apTimeStamp > WIFI_RETRY_TIME_MILI_SECONDS)) {
initConnection();
apTimeStamp = millis();
}
}
void regData2DB() {
if (wifiMode != WIFI_STA) {
Serial.println("no internet connection");
return;
}
if (WiFi.status() != WL_CONNECTED ) return;
// http.begin(msg); //HTTP
http.begin("http://google.com"); //HTTP
int httpCode = http.GET();
Serial.println(httpCode);
// http.returnError(httpCode);
// httpCode will be negative on error
if (httpCode > 0) {
Serial.print("got respond");
// HTTP header has been send and Server response header has been handled
// file found at server
if (httpCode == HTTP_CODE_OK) {
Serial.println("and it is a GOOD one !");
String payload = http.getString();
if (http.getString() == "ok") {
Serial.println(counter_in);
Serial.println(counter_out);
counter_in = 0;
counter_out = 0;
}
}
} else {
Serial.println("and it is a BAD one !");
Serial.println(counter_in);
Serial.println(counter_out);
// ledControl(WIFI_LED_PIN, 0.1); //need to return the toggle rate once ok
}
http.end();
}
void initConnection() {
loadEEPROM();
WiFi.disconnect(true); //disconect from any activity ==> Fresh Start
delay(3000);
if (strcmp(eeprom.ssid, "") == 0) {
//No SSID stored.. init as access point
Serial.println("No SSID found in eeprom Starting AP mode:");
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID, AP_PASS);
delay(5000);
Serial.print(WiFi.softAPIP());
apTimeStamp = millis();
wifiMode = WIFI_AP;
ledControl(WIFI_LED_PIN, 0.5);
} else {
Serial.print("Found SSID and PASS in eeprom, trying STA connect to: "); Serial.print(eeprom.ssid); Serial.print(" | "); Serial.println(eeprom.pass);
WiFi.mode(WIFI_STA);
WiFi.begin(eeprom.ssid, eeprom.pass);
delay(6000);
int i = 0;
while (WiFi.status() != WL_CONNECTED) {
Serial.print("Failed ==>");
if (i > 3) {
Serial.println("Starting AP mode:");
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID, AP_PASS);
apTimeStamp = millis();
wifiMode = WIFI_AP;
ledControl(WIFI_LED_PIN, 0.5);
return;
}
else {
Serial.println("Retrying..");
WiFi.mode(WIFI_STA);
WiFi.begin(eeprom.ssid, eeprom.pass);
delay(5000);
}
i++;
}
wifiMode = WIFI_STA;
Serial.print("Connected as STA:");
Serial.println(WiFi.localIP());
WiFi.setAutoReconnect(true);
ledControl(WIFI_LED_PIN, HIGH);
}
}
SOLVED.
I was calling the regData2DB() function by using timer...
When I called the regData2DB() function from main loop by using:
if ( (millis() - regDataTimeStamp) > DB_UPDATE_INTERVAL_MS) {
regData2DB();
regDataTimeStamp = millis();
}
It started to work.
No Idea what happened but it seems to be stable.. moving on :-)
Related
I am performing ESP32 OTA over the GSM. I have found some example code online, modified it slightly based on my board connections and was able to sucesfully perform a firmware update.
I use lilygo ESP32 GSM development board.
However, it frustrates me that I am not capable of understanding what really happens in the code at the low level. I really want to understand before I go any further with my project.
Full code for my OTA update:
#include <Update.h>
#define TINY_GSM_MODEM_SIM800
// Increase RX buffer
#define TINY_GSM_RX_BUFFER 1030
const char apn[] = "omnitel";
const char user[] = "omni";
const char pass[] = "omni";
#define MODEM_RST 5
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define LED_GPIO 13
#define LED_ON HIGH
#define LED_OFF LOW
#define SerialAT Serial1
#include <TinyGsmClient.h>
#include <CRC32.h>
#include "FS.h"
#include "SPIFFS.h"
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);
const char server[] = "myesptestserver.ddns.net";
const int port = 80;
const char resource[] = "/esp.bin"; //here de bin file
uint32_t knownCRC32 = 0x6f50d767;
uint32_t knownFileSize = 1024; // In case server does not send it
void setup()
{
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
// Set console baud rate
Serial.begin(115200);
setupModem();
delay(10);
if (!SPIFFS.begin(true))
{
Serial.println("SPIFFS Mount Failed");
return;
}
SPIFFS.format();
listDir(SPIFFS, "/", 0);
// Set GSM module baud rate
delay(3000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
modem.restart();
String modemInfo = modem.getModemInfo();
Serial.print("Modem: ");
Serial.println(modemInfo);
// Unlock your SIM card with a PIN
//modem.simUnlock("1234");
}
void loop()
{
Serial.print("Waiting for network...");
if (!modem.waitForNetwork())
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
Serial.print("Connecting to ");
Serial.print(apn);
if (!modem.gprsConnect(apn, user, pass))
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
Serial.print("Connecting to ");
Serial.print(server);
// if you get a connection, report back via serial:
if (!client.connect(server, port))
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
// Make a HTTP request:
client.print(String("GET ") + resource + " HTTP/1.0\r\n");
client.print(String("Host: ") + server + "\r\n");
client.print("Connection: close\r\n\r\n");
long timeout = millis();
while (client.available() == 0)
{
if (millis() - timeout > 5000L)
{
Serial.println(">>> Client Timeout !");
client.stop();
delay(10000L);
return;
}
}
Serial.println("Reading header");
uint32_t contentLength = knownFileSize;
File file = SPIFFS.open("/update.bin", FILE_APPEND);
while (client.available())
{
String line = client.readStringUntil('\n');
line.trim();
//Serial.println(line); // Uncomment this to show response header
line.toLowerCase();
if (line.startsWith("content-length:"))
{
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
}
else if (line.length() == 0)
{
break;
}
}
timeout = millis();
uint32_t readLength = 0;
CRC32 crc;
unsigned long timeElapsed = millis();
printPercent(readLength, contentLength);
while (readLength < contentLength && client.connected() && millis() - timeout < 10000L)
{
int i = 0;
while (client.available())
{
// read file data to spiffs
if (!file.print(char(client.read())))
{
Serial.println("Appending file");
}
//Serial.print((char)c); // Uncomment this to show data
//crc.update(c);
readLength++;
if (readLength % (contentLength / 13) == 0)
{
printPercent(readLength, contentLength);
}
timeout = millis();
}
}
file.close();
printPercent(readLength, contentLength);
timeElapsed = millis() - timeElapsed;
Serial.println();
client.stop();
Serial.println("stop client");
modem.gprsDisconnect();
Serial.println("gprs disconnect");
Serial.println();
float duration = float(timeElapsed) / 1000;
/*
Serial.print("Tamaño de Archivo: ");
Serial.println(contentLength);
Serial.print("Leido: ");
Serial.println(readLength);
Serial.print("Calculado. CRC32: 0x");
Serial.println(crc.finalize(), HEX);
Serial.print("Conocido CRC32: 0x");
Serial.println(knownCRC32, HEX);
Serial.print("Bajado en: ");
Serial.print(duration);
Serial.println("s");
Serial.println("Se genera una espera de 3 segundos");
for (int i = 0; i < 3; i++)
{
Serial.print(String(i) + "...");
delay(1000);
}
*/
//readFile(SPIFFS, "/update.bin");
updateFromFS();
// Do nothing forevermore
while (true)
{
delay(1000);
}
}
void appendFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if (!file)
{
Serial.println("Failed to open file for appending");
return;
}
if (file.print(message))
{
Serial.println("APOK");
}
else
{
Serial.println("APX");
}
}
void readFile(fs::FS &fs, const char *path)
{
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file || file.isDirectory())
{
Serial.println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while (file.available())
{
Serial.write(file.read());
delayMicroseconds(100);
}
}
void writeFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
Serial.println("Failed to open file for writing");
return;
}
if (file.print(message))
{
Serial.println("File written");
}
else
{
Serial.println("Write failed");
}
}
void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if (!root)
{
Serial.println("Failed to open directory");
return;
}
if (!root.isDirectory())
{
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while (file)
{
if (file.isDirectory())
{
Serial.print(" DIR : ");
Serial.println(file.name());
if (levels)
{
listDir(fs, file.name(), levels - 1);
}
}
else
{
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
void deleteFile(fs::FS &fs, const char *path)
{
Serial.printf("Deleting file: %s\n", path);
if (fs.remove(path))
{
Serial.println("File deleted");
}
else
{
Serial.println("Delete failed");
}
}
void updateFromFS()
{
File updateBin = SPIFFS.open("/update.bin");
if (updateBin)
{
if (updateBin.isDirectory())
{
Serial.println("Directory error");
updateBin.close();
return;
}
size_t updateSize = updateBin.size();
if (updateSize > 0)
{
Serial.println("Starting update");
performUpdate(updateBin, updateSize);
}
else
{
Serial.println("Error, archivo vacío");
}
updateBin.close();
// whe finished remove the binary from sd card to indicate end of the process
//fs.remove("/update.bin");
}
else
{
Serial.println("no such binary");
}
}
void performUpdate(Stream &updateSource, size_t updateSize)
{
if (Update.begin(updateSize))
{
size_t written = Update.writeStream(updateSource);
if (written == updateSize)
{
Serial.println("Writes : " + String(written) + " successfully");
}
else
{
Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
}
if (Update.end())
{
Serial.println("OTA finished!");
if (Update.isFinished())
{
Serial.println("Restart ESP device!");
ESP.restart();
}
else
{
Serial.println("OTA not fiished");
}
}
else
{
Serial.println("Error occured #: " + String(Update.getError()));
}
}
else
{
Serial.println("Cannot beggin update");
}
}
void printPercent(uint32_t readLength, uint32_t contentLength)
{
// If we know the total length
if (contentLength != -1)
{
Serial.print("\r ");
Serial.print((100.0 * readLength) / contentLength);
Serial.print('%');
}
else
{
Serial.println(readLength);
}
}
void setupModem()
{
#ifdef MODEM_RST
// Keep reset high
pinMode(MODEM_RST, OUTPUT);
digitalWrite(MODEM_RST, HIGH);
#endif
pinMode(MODEM_PWRKEY, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
// Turn on the Modem power first
digitalWrite(MODEM_POWER_ON, HIGH);
// Pull down PWRKEY for more than 1 second according to manual requirements
digitalWrite(MODEM_PWRKEY, HIGH);
delay(100);
digitalWrite(MODEM_PWRKEY, LOW);
delay(1000);
digitalWrite(MODEM_PWRKEY, HIGH);
// Initialize the indicator as an output
pinMode(LED_GPIO, OUTPUT);
digitalWrite(LED_GPIO, LED_OFF);
}
From what I understand, the following part of the code reads my binary file that is stored in the server and read it into SPIFFS memory:
while (readLength < contentLength && client.connected() && millis() - timeout < 10000L)
{
int i = 0;
while (client.available())
{
// read file data to spiffs
if (!file.print(char(client.read())))
{
Serial.println("Appending file");
}
//Serial.print((char)c); // Uncomment this to show data
//crc.update(c);
readLength++;
if (readLength % (contentLength / 13) == 0)
{
printPercent(readLength, contentLength);
}
timeout = millis();
}
}
Then the updateFromFS() function is executed, which checks whether the binary is all good and then calls another function performUpdate(updateBin, updateSize);
void updateFromFS()
{
File updateBin = SPIFFS.open("/update.bin");
if (updateBin)
{
if (updateBin.isDirectory())
{
Serial.println("Directory error");
updateBin.close();
return;
}
size_t updateSize = updateBin.size();
if (updateSize > 0)
{
Serial.println("Starting update");
performUpdate(updateBin, updateSize);
}
else
{
Serial.println("Error, archivo vacío");
}
updateBin.close();
// whe finished remove the binary from sd card to indicate end of the process
//fs.remove("/update.bin");
}
else
{
Serial.println("no such binary");
}
}
in the performUpdate(updateBin, updateSize), 2 functions from Arduino Update Library are being called ( Update.begin(updateSize) and Update.writeStream(updateSource) ) and that is where I cant follow anymore...
void performUpdate(Stream &updateSource, size_t updateSize)
{
if (Update.begin(updateSize))
{
size_t written = Update.writeStream(updateSource);
if (written == updateSize)
{
Serial.println("Writes : " + String(written) + " successfully");
}
else
{
Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
}
if (Update.end())
{
Serial.println("OTA finished!");
if (Update.isFinished())
{
Serial.println("Restart ESP device!");
ESP.restart();
}
else
{
Serial.println("OTA not fiished");
}
}
else
{
Serial.println("Error occured #: " + String(Update.getError()));
}
}
else
{
Serial.println("Cannot beggin update");
}
}
I have found this Update library source code :
https://github.com/espressif/arduino-esp32/blob/master/libraries/Update/src/Updater.cpp
But it seems that this is beyond my knowledge to understand what really is going on in this code.
First of all, we pass only 1 variable to .begin method, but the function prototype requires more than that:
bool UpdateClass::begin(size_t size, int command, int ledPin, uint8_t ledOn, const char *label)
And then I am trying to understand what happens in function Update.writeStream(updateSource) but cant..
If anyone could shed some light here I would appreciate a lot! Thanks in advance...
The algorithm downloads the new firmware (.bin) from the cloud to the device's local memory and makes the firmware change with the UpdateClass library
(I see the texts in Spanish if you want we speak in Spanish)
Check the .h (only one argument required)
https://github.com/espressif/arduino-esp32/blob/master/libraries/Update/src/Update.h
/*
Call this to check the space needed for the update
Will return false if there is not enough space
*/
bool begin(size_t size=UPDATE_SIZE_UNKNOWN, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW, const char *label = NULL);
You could use the OTAdrive library and use it for OTA updates.
Check here for the esp32 gsm modem OTA example.
I am trying to use this code:
https://github.com/jatocode/WifiConnect/blob/master/WifiConnect/WifiConnect.ino with my ESP32.
The problem is that my wifi network name is "y&t" and when I am trying to use it the progrem saves to the EEPROM "y&26t" insted, with other networks names in my area it dosn't have a problem.
I will be greatful if somebady knows how to solve this problem.
Thanks to #Juraj I solved the problem.
I used in this code a decoder from here: https://circuits4you.com/2019/03/21/esp8266-url-encode-decode-example/
/*
Configuration AP example
The example shows a very simple Configuration Access Point.
created in August 2019
by Juraj Andrassy https://github.com/jandrassy
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include <Arduino.h>
// #include <String.h>
String urldecode(String str);
unsigned char h2int(char c);
void setup() {
Serial.begin(115200);
delay(500);
// WiFi.disconnect(); // forget the persistent connection to test the Configuration AP
WiFi.persistent(true);
// waiting for connection to remembered Wifi network
Serial.println("Waiting for connection to WiFi");
WiFi.begin(); // use SSID and password stored by SDK
WiFi.waitForConnectResult();
if (WiFi.status() != WL_CONNECTED) {
Serial.println();
Serial.println("Could not connect to WiFi. Starting configuration AP...");
configAP();
} else {
Serial.println("WiFi connected");
}
}
void loop() {
}
void configAP() {
WiFiServer configWebServer(80);
WiFi.mode(WIFI_AP_STA); // starts the default AP (factory default or setup as persistent)
Serial.print("Connect your computer to the WiFi network ");
// Serial.print(WiFi.softAP());
Serial.println();
IPAddress ip = WiFi.softAPIP();
Serial.print("and enter http://");
Serial.print(ip);
Serial.println(" in a Web browser");
configWebServer.begin();
while (true) {
WiFiClient client = configWebServer.available();
if (client) {
char line[64];
int l = client.readBytesUntil('\n', line, sizeof(line));
line[l] = 0;
client.find((char*) "\r\n\r\n");
if (strncmp_P(line, PSTR("POST"), strlen("POST")) == 0) {
l = client.readBytes(line, sizeof(line));
line[l] = 0;
// parse the parameters sent by the html form
const char* delims = "=&";
strtok(line, delims);
const char* ssid = strtok(NULL, delims);
strtok(NULL, delims);
const char* pass = strtok(NULL, delims);
// decoding the ssid and the password for ASCII characters
String ssidS = String(ssid);
String ssidSdecode= urldecode(ssidS);
ssid=const_cast<char*>(ssidSdecode.c_str());
String passS = String(pass);
String passSdecode= urldecode(passS);
pass=const_cast<char*>(passSdecode.c_str());
// send a response before attemting to connect to the WiFi network
// because it will reset the SoftAP and disconnect the client station
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Connection: close"));
client.println(F("Refresh: 10")); // send a request after 10 seconds
client.println();
client.println(F("<html><body><h3>Configuration AP</h3><br>connecting...</body></html>"));
client.stop();
Serial.println();
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
WiFi.waitForConnectResult();
// configuration continues with the next request
} else {
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Connection: close"));
client.println();
client.println(F("<html><body><h3>Configuration AP</h3><br>"));
int status = WiFi.status();
if (status == WL_CONNECTED) {
client.println(F("Connection successful. Ending AP."));
} else {
client.println(F("<form action='/' method='POST'>WiFi connection failed. Enter valid parameters, please.<br><br>"));
client.println(F("SSID:<br><input type='text' name='i'><br>"));
client.println(F("Password:<br><input type='password' name='p'><br><br>"));
client.println(F("<input type='submit' value='Submit'></form>"));
}
client.println(F("</body></html>"));
client.stop();
if (status == WL_CONNECTED) {
delay(1000); // to let the SDK finish the communication
Serial.println("Connection successful. Ending AP.");
configWebServer.stop();
WiFi.mode(WIFI_STA);
}
}
}
}
}
String urldecode(String str) {
String encodedString="";
char c;
char code0;
char code1;
for (int i =0; i < str.length(); i++) {
c=str.charAt(i);
if (c == '+') {
encodedString+=' ';
} else if (c == '%') {
i++;
code0=str.charAt(i);
i++;
code1=str.charAt(i);
c = (h2int(code0) << 4) | h2int(code1);
encodedString+=c;
} else {
encodedString+=c;
}
yield();
}
return encodedString;
}
unsigned char h2int(char c) {
if (c >= '0' && c <='9') {
return((unsigned char)c - '0');
}
if (c >= 'a' && c <='f') {
return((unsigned char)c - 'a' + 10);
}
if (c >= 'A' && c <='F') {
return((unsigned char)c - 'A' + 10);
}
return(0);
}
This error shows in my serial monitor see the code below for ESP32
and please help me to solve
Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached
memory region accessed) Core 1 register dump: PC : 0x400d1580 PS
: 0x00060034 A0 : 0x400847fc A1 : 0x3ffbe7b0 A2 :
0x00000001 A3 : 0x00000002 A4 : 0x000000ff A5 :
0x4008b368 A6 : 0x00000000 A7 : 0x00000001 A8 :
0x80081348 A9 : 0x3ff5f024 A10 : 0x3ffbebfc A11 :
0x20000000 A12 : 0x00000400 A13 : 0x3ffb1b10 A14 :
0x00000026 A15 : 0x3ffc4598 SAR : 0x00000020 EXCCAUSE:
0x00000007 EXCVADDR: 0x00000000 LBEG : 0x40001609 LEND :
0x4000160d LCOUNT : 0x00000000 Core 1 was running in ISR context:
EPC1 : 0x40087157 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4
: 0x400d1580
Backtrace: 0x400d1580:0x3ffbe7b0 0x400847f9:0x3ffbe7d0
0x40087154:0x3ffb1b50 0x400e2aa9:0x3ffb1bc0 0x400e1379:0x3ffb1be0
0x400e17c7:0x3ffb1c00 0x400e015d:0x3ffb1c70 0x400e0c5f:0x3ffb1cc0
0x400df715:0x3ffb1d20 0x400dfc8d:0x3ffb1d60 0x4012d7e6:0x3ffb1d80
0x4012d9da:0x3ffb1dd0 0x4012da2d:0x3ffb1e00 0x400e2f57:0x3ffb1e20
0x400e30aa:0x3ffb1e40 0x400d70dd:0x3ffb1e60 0x400d2da9:0x3ffb1e80
0x400d1392:0x3ffb1f80 0x400d468b:0x3ffb1fb0 0x40088c05:0x3ffb1fd0
#include <esp_now.h>
#include <WiFi.h>
#include <IRremote.h>
int IR_Recv = 4;
#define CHANNEL 3
#define NUM_SLAVES 20 // ESP-Now can handle a maximum of 20 slaves
#define PRINTSCANRESULTS 0
IRrecv irrecv(IR_Recv);
decode_results results;
int slaveCount = 0; // Keeps count of no. of slaves with the defined prefix
esp_now_peer_info_t slaves[NUM_SLAVES]; // Stores the information of each of the slave that is added as a peer
void initESPNow();
void manageSlaves();
void scanForSlaves();
void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status);
void onDataRecv(const uint8_t *mac_add, const uint8_t *data, int data_len);
void sendData(uint8_t data);
void setup()
{
Serial.begin(115200);
irrecv.enableIRIn();
WiFi.mode(WIFI_MODE_STA);
initESPNow();
esp_now_register_send_cb(onDataSent);
esp_now_register_recv_cb(onDataRecv);
scanForSlaves();
manageSlaves();
}
void loop()
{
//Serial.println("Digital Read: " + String(digitalRead(IR_PIN)));
if(slaveCount > 0)
{
if (irrecv.decode(&results)){
long int decCode = results.value;
Serial.println(results.value);
switch (results.value){
case 2921: //when you press the 1 button
sendData(0);
break;
case 873: //when you press the 4 button
sendData(512);
break;
case 874: //when you press the 2 button
sendData(100);
break;
case 2922: //when you press the 5 button
sendData(300);
break;
default:
Serial.println('nothing to send');
break;
}
irrecv.resume(); // Receives the next value from the button you press
}
}
delay(3000);
}
// Init ESP Now with fallback
void initESPNow()
{
WiFi.disconnect();
if (esp_now_init() == ESP_OK)
{
Serial.println("ESPNow Init Success");
}
else
{
Serial.println("ESPNow Init Failed");
ESP.restart();
}
}
// Scan for slaves in AP mode
void scanForSlaves()
{
int8_t scanResults = WiFi.scanNetworks();
//reset slaves
memset(slaves, 0, sizeof(slaves));
slaveCount = 0;
Serial.println("");
if (scanResults == 0)
{
Serial.println("No WiFi devices in AP Mode found");
}
else
{
Serial.print("Found ");
Serial.print(scanResults);
Serial.println(" devices ");
for (int i = 0; i < scanResults; i++)
{
// Print SSID and RSSI for each device found
String SSID = WiFi.SSID(i);
int32_t RSSI = WiFi.RSSI(i);
String BSSIDstr = WiFi.BSSIDstr(i);
if (PRINTSCANRESULTS)
{
Serial.print(i + 1);
Serial.print(": ");
Serial.print(SSID);
Serial.print(" [");
Serial.print(BSSIDstr);
Serial.print("]");
Serial.print(" (");
Serial.print(RSSI);
Serial.print(")");
Serial.println("");
}
delay(10);
// Check if the current device starts with `Slave`
if (SSID.indexOf("Slave") == 0)
{
// SSID of interest
Serial.print(i + 1);
Serial.print(": ");
Serial.print(SSID);
Serial.print(" [");
Serial.print(BSSIDstr);
Serial.print("]");
Serial.print(" (");
Serial.print(RSSI);
Serial.print(")");
Serial.println("");
// Get BSSID => Mac Address of the Slave
int mac[6];
if(6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]))
{
for(int j = 0; j < 6; j++)
{
slaves[slaveCount].peer_addr[j] = (uint8_t)mac[j];
}
}
slaves[slaveCount].channel = CHANNEL; // pick a channel
slaves[slaveCount].encrypt = 0; // no encryption
slaveCount++;
}
}
}
if(slaveCount > 0)
{
Serial.print(slaveCount); Serial.println(" Slave(s) found, processing..");
}
else
{
Serial.println("No Slave Found, trying again.");
}
// clean up ram
WiFi.scanDelete();
}
// Check if the slave is already paired with the master.
// If not, pair the slave with master
void manageSlaves()
{
if(slaveCount > 0)
{
for(int i = 0; i < slaveCount; i++)
{
const esp_now_peer_info_t *peer = &slaves[i];
const uint8_t *peer_addr = slaves[i].peer_addr;
Serial.print("Processing: ");
for(int j = 0; j < 6; j++)
{
Serial.print((uint8_t) slaves[i].peer_addr[j], HEX);
if (j != 5)
{
Serial.print(":");
}
}
Serial.print(" Status: ");
// check if the peer exists
bool exists = esp_now_is_peer_exist(peer_addr);
if(exists)
{
// Slave already paired.
Serial.println("Already Paired");
}
else
{
// Slave not paired, attempt pair
esp_err_t addStatus = esp_now_add_peer(peer);
if(addStatus == ESP_OK)
{
// Pair success
Serial.println("Pair success");
}
else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT)
{
// How did we get so far!!
Serial.println("ESPNOW Not Init");
}
else if (addStatus == ESP_ERR_ESPNOW_ARG)
{
Serial.println("Add Peer - Invalid Argument");
}
else if (addStatus == ESP_ERR_ESPNOW_FULL)
{
Serial.println("Peer list full");
}
else if (addStatus == ESP_ERR_ESPNOW_NO_MEM)
{
Serial.println("Out of memory");
}
else if (addStatus == ESP_ERR_ESPNOW_EXIST)
{
Serial.println("Peer Exists");
}
else
{
Serial.println("Not sure what happened");
}
delay(1000);
}
}
}
else
{
// No slave found to process
Serial.println("No Slave found to process");
}
}
// send data
void sendData(uint8_t data)
{
for(int i = 0; i < slaveCount; i++)
{
const uint8_t *peer_addr = slaves[i].peer_addr;
if (i == 0)
{
// print only for first slave
Serial.print("Sending: ");
Serial.println(data);
}
esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data));
Serial.print("Send Status: ");
if (result == ESP_OK) {
Serial.println("Success");
} else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
// How did we get so far!!
Serial.println("ESPNOW not Init.");
} else if (result == ESP_ERR_ESPNOW_ARG) {
Serial.println("Invalid Argument");
} else if (result == ESP_ERR_ESPNOW_INTERNAL) {
Serial.println("Internal Error");
} else if (result == ESP_ERR_ESPNOW_NO_MEM) {
Serial.println("ESP_ERR_ESPNOW_NO_MEM");
} else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
Serial.println("Peer not found.");
} else {
Serial.println("Not sure what happened");
}
delay(100);
}
}
// callback when data is sent from Master to Slave
void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
char macStr[18];
// sendTime = millis();
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print("Last Packet Sent to: ");
Serial.println(macStr);
Serial.print("Last Packet Send Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
// callback when data is received from Slave to Master
void onDataRecv(const uint8_t *mac_add, const uint8_t *data, int data_len)
{
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]);
Serial.print("Last Packet Recv from: ");
Serial.println(macStr);
Serial.print("Last Packet Recv Data: ");
Serial.println(*data);
Serial.println("");
}```
Out of curiosity I tried your code and I can reproduced what you are facing. But I noticed that if I swap the line irrecv.enableIRIn(); with WiFi.mode(WIFI_MODE_STA); in setup(), the crash stop.
This will cause the sketch to crash
#include <WiFi.h>
#include <IRremote.h>
int IR_Recv = 4;
IRrecv irRecv(IR_Recv);
decode_results results;
void setup()
{
Serial.begin(115200);
irRecv.enableIRIn();
WiFi.mode(WIFI_MODE_STA);
}
void loop() {
}
This will work perfectly without crash
#include <WiFi.h>
#include <IRremote.h>
int IR_Recv = 4;
IRrecv irRecv(IR_Recv);
decode_results results;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_MODE_STA);
irRecv.enableIRIn();
}
void loop() {
}
I couldn't explain why, what irrecv.enableIRIn() does is to setup the interrupt and reset the timer2, but I couldn't see how this affect the WiFi.mode(WIFI_MODE_STA), maybe others could explain why this happen.
I'm trying to get GPS data and send it to the server via socket.
I'm using Arduino Uno and GPS/GSM module A7 Ai-Thinker.
And for Internet I use Ethernet shield connected to Wi-Fi router.
But I got trouble when I joined getting GPS data and sending it.
Separately that functions work fine. How I start A7, there is a loop where I type AT commands and send it to A7. About socket, I want to set connection at start function and keep it alive all the time.
But the problem is that when I initialized A7 and set socket connection, I go to the loop function and after first iteration there are no data at A7.
If I try to set connection with server first, and start A7 after it, A7 doesn't react to AT commands.
How can I keep connection with my server and don't lost connection with A7?
Code:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Ethernet.h>
//-------------------------------------------------------
static const int RXPin = 10, TXPin = 11;
static const uint32_t GPSBaud = 4800;
const String START_GPS = "START_GPS";
TinyGPSPlus gps;
SoftwareSerial gps_serial(RXPin, TXPin);
//-------------------------------------------------------
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "192.168.0.100";
int port = 8090;
IPAddress ip(192, 168, 0, 177);
EthernetClient client;
//-------------------------------------------------------
void initGpsConnection();
void startGps();
void initSocketConnection();
void sendData();
void setup()
{
Serial.begin(9600);
Serial.println();
initSocketConnection();
initGpsConnection();
sendData();
}
void loop()
{
while (gps_serial.available() > 0) {
if (gps.encode(gps_serial.read())) {
displayInfo();
//delay(1000);
}
}
if (millis() > 120000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
//while(true);
}
if (!client.connected()) {
Serial.println();
Serial.println("Socket connection has been lost.");
client.stop();
//while (true);
}
}
void displayInfo()
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" Date/Time: "));
if (gps.date.isValid()) {
Serial.print(gps.date.month() + "/" gps.date.day() + "/" + gps.date.year();
} else {
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid()) {
Serial.print(gps.time.hour() + ":" + gps.time.minute() + ":" + gps.time.second());
} else {
Serial.print(F("INVALID"));
}
Serial.println();
}
void initGpsConnection() {
Serial.println("In init gps");
gps_serial.begin(GPSBaud);
Serial.println("after gps begin");
delay(1000);
startGps();
Serial.println("GPS connection has been set");
}
void startGps() {
Serial.println("Enter at commands, after that enter `start_gps`");
String response = "";
while (true) {
if (gps_serial.available()) {
Serial.write(gps_serial.read());
}
if (Serial.available()) {
char c = Serial.read();
response += c;
if (response.indexOf(START_GPS) > 0)
break;
gps_serial.write(c);
}
}
}
void initSocketConnection() {
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
Ethernet.begin(mac, ip);
}
delay(1000);
Serial.println("connecting...");
if (client.connect(server, port)) {
Serial.println("Connection with server has been set");
} else {
Serial.println("Connection with server has been failed");
}
}
void sendData(){
client.print("TEst ard");
}
The problem was at A7 connection. It was connected via 10, 11 pins at Ethernet shield. But 10-13 pins are reserved by A7. It's just needed connect A7 vie 8, 9 or others pins.
Made some code for a NodeMCU in the Arduino IDE to push a button using MQTT. The code works perfectly fine for some time, but after a couple of hours it will not respond anymore.
The code is very frankenstein, since I am a mega rookie, and is as follows:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Servo.h>
const char* ssid = "ap_name"; //change
const char* password = "ap_pw"; //change
const char* mqttServer = "server_ip"; //change
const int mqttPort = 1883;
const char* mqttUser = "server_name"; //change
const char* mqttPassword = "server_pw"; //change
WiFiClient espClient;
PubSubClient client(espClient);
Servo servo;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
servo.attach(D4);
servo.write(70);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
client.publish("esp/test", "Hello from ESP8266");
client.subscribe("esp/test");
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
if(*payload == 49){
rotServo();
Serial.println();
Serial.print("Roterar servo");
delay(3000);
client.publish("esp/test", "0");
}
Serial.println();
Serial.println("-----------------------");
}
void rotServo(){
servo.attach(D4);
servo.write(70);
delay(1000);
servo.write(175);
delay(2000);
servo.write(70);
delay(3000);
servo.detach();
}
void loop() {
client.loop();
}
Anyone that would know what might be causing it to stop working?
It could be because, you never reconnect if your client ever gets disconnected.
See the example here for more details, but here is the reconnect function from the example and how it is called in the loop. You would need to tailor it to suite your application.
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
// ... and resubscribe
client.subscribe("inTopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
...
}
On another note, while I don't think it would cause your specific problem, in your callback, you just compare the contents of the payload to the number 49.
if(*payload == 49){
...
}
You should check that the topic is the actual topic you are interested in and that the length is also what you expect, before you start looking at the payload.