Closed Merlin-33 closed 3 years ago
Hello,
Which ESP board do you use?
hello, so I'm using the Wemos D1 mini ESP card. I'm trying to see how I can work around my problem, I had a solution with delay (); but it blocks me all, even the OTA update.
Hello, i have tested OTA update with two diferent librarys (ArduinoOTA and ESP8266httpUpdate), both work fine for me. Here is my test code. It include both librarys and mqtt
#include <ESP8266WiFi.h>
#include <ESP8266httpUpdate.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include "WeatherStationDataRx.h"
#ifdef ESP8266
#define DATA_PIN D5
#define BATT_PIN A0
#else
#define DATA_PIN 2
#define BATT_PIN A0
#endif
const String hostName = "WeatherStation";
const char* version = "0.0.7";
const char* wifi_ssid = "your SSID";
const char* wifi_pass = "your password";
const char* ota_url = "http://your-update-server/WeatherStation.bin";
const char* mqtt_server = "your mqtt server ip";
const char* mqtt_user = "mqtt usr";
const char* mqtt_pass = "mqtt password";
const unsigned long reconnectInterval = 5000; // reconnect interval if mqtt disconnected
const unsigned long battReadInterval = 60000; // battery read interval
unsigned long lastReconnect = 0;
unsigned long lastBattRead = 0;
WiFiClient espClient;
PubSubClient client(espClient);
WeatherStationDataRx wsdr(DATA_PIN, true);
void PubSubCallback(char* topic, byte* payload, unsigned int length) {
String sTopic((const __FlashStringHelper*)topic);
Serial.print("Message arrived [" + sTopic + "]");
String sVal((const __FlashStringHelper*)payload);
sVal = sVal.substring(0, length);
Serial.println(sVal);
}
void PairedDeviceAdded(byte newID)
{
#if defined(ESP8266) || defined(ESP32)
Serial.printf("New device paired %d\r\n", newID);
#else
Serial.print("New device paired ");
Serial.println(newID, DEC);
#endif
wsdr.pair(NULL, PairedDeviceAdded);
}
void setup()
{
Serial.begin(115200);
delay(5000);
Serial.println(String("Init ") + hostName + "@" + version);
Serial.println(hostName);
Serial.print("Connecting to ");
Serial.println(wifi_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.hostname(hostName);
WiFi.begin(wifi_ssid, wifi_pass);
int retrys = 30;
while ((WiFi.status() != WL_CONNECTED) && (retrys > 0)) {
delay(1000);
Serial.print(".");
retrys--;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("get firmware");
t_httpUpdate_return ret = ESPhttpUpdate.update(ota_url, version);
switch(ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
Serial.println("");
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
break;
}
} else {
Serial.println("WiFi not connected");
}
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_SPIFFS
type = "filesystem";
}
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
Serial.println("End Failed");
}
});
ArduinoOTA.begin();
client.setServer(mqtt_server, 1883);
client.setCallback(PubSubCallback);
wsdr.begin();
wsdr.pair(NULL, PairedDeviceAdded);
}
void reconnect()
{
// Loop until we're reconnected
if (!client.connected())
{
Serial.print("Attempting MQTT connection...");
// Attempt to connect
//if you MQTT broker has clientID,username and password
//please change following line to if (client.connect(clientId,userName,passWord))
if (client.connect(hostName.c_str(), mqtt_user, mqtt_pass))
{
Serial.println("connected");
//once connected to MQTT broker, subscribe command if any
client.publish((hostName + "/Version").c_str(), version);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
}
}
}
void loop()
{
unsigned long now = millis();
if (!client.connected() && (now - lastReconnect > reconnectInterval)) {
reconnect();
lastReconnect = now;
now = millis();
}
ArduinoOTA.handle();
if (now - lastBattRead > battReadInterval) {
int battValueSum = 0;
for (int i=0; i<10; i++) {
battValueSum += analogRead(BATT_PIN);
delay(10);
}
battValueSum = battValueSum / 10;
float battValue = (float)battValueSum / 10;
Serial.print("Battery state: ");
Serial.print(battValue);
Serial.println("V");
client.publish((hostName + "/Battery").c_str(), String(battValue).c_str());
lastBattRead = now;
}
String sensorID = String(wsdr.sensorID());
bool batteryLow = bitRead(wsdr.batteryStatus(), 0) != 0;
client.loop();
char newData = wsdr.readData();
switch (newData)
{
case 'T': {
String temperature = String(wsdr.readTemperature());
String humidity = String(wsdr.readHumidity());
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("°");
Serial.println("C");
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.println("%");
Serial.print("Battery: ");
Serial.println(batteryLow ? "Low" : "OK");
Serial.print("Sensor ID: ");
Serial.println(sensorID);
client.publish((hostName + "/" + wsdr.sensorID() + "/Temperature").c_str(), temperature.c_str());
client.publish((hostName + "/" + wsdr.sensorID() + "/Humidity").c_str(), humidity.c_str());
client.publish((hostName + "/" + wsdr.sensorID() + "/BatteryLow").c_str(), String(batteryLow).c_str());
break;
}
case 'S': {
String windSpeed = String(wsdr.readWindSpeed());
Serial.print("Wind speed: ");
Serial.print(windSpeed);
Serial.println("m/s");
Serial.print("Battery: ");
Serial.println(batteryLow ? "Low" : "OK");
Serial.print("Sensor ID: ");
Serial.println(sensorID);
client.publish((hostName + "/" + wsdr.sensorID() + "/WindSpeed").c_str(), windSpeed.c_str());
client.publish((hostName + "/" + wsdr.sensorID() + "/BatteryLow").c_str(), String(batteryLow).c_str());
break;
}
case 'G': {
String windDirection = String(wsdr.readWindDirection());
String windGust = String(wsdr.readWindGust());
Serial.print("Wind direction: ");
Serial.print(windDirection);
Serial.println("°");
Serial.print("Wind gust: ");
Serial.print(windGust);
Serial.println("m/s");
Serial.print("Battery: ");
Serial.println(batteryLow ? "Low" : "OK");
Serial.print("Sensor ID: ");
Serial.println(sensorID);
client.publish((hostName + "/" + wsdr.sensorID() + "/WindDirection").c_str(), windDirection.c_str());
client.publish((hostName + "/" + wsdr.sensorID() + "/WindGust").c_str(), windGust.c_str());
client.publish((hostName + "/" + wsdr.sensorID() + "/BatteryLow").c_str(), String(batteryLow).c_str());
break;
}
case 'R': {
String rainVolume = String(wsdr.readRainVolume());
Serial.print("Rain volume: ");
Serial.print(rainVolume);
Serial.println("mm");
Serial.print("Battery: ");
Serial.println(batteryLow ? "Low" : "OK");
Serial.print("Sensor ID: ");
Serial.println(sensorID);
client.publish((hostName + "/" + wsdr.sensorID() + "/RainVolume").c_str(), rainVolume.c_str());
client.publish((hostName + "/" + wsdr.sensorID() + "/BatteryLow").c_str(), String(batteryLow).c_str());
break;
}
default:
break;
}
}
Ok thank you, my code is not quite the same, but a priori it is a loop which pisses off at the level of the wifi which takes back the hand according to certain people ... Suddenly it does not even work with the solution of your code. So I sought to develop an update system through a button to block the launch of wsdr.begin () and let the OTA update be done. It's not yet finished but I'm almost there, if it works I could say how to do it here, if it's possible :)
I have implemented end() function. I hope it helps you with your problem.
Ok thanks, so if I do wsdr.end (); this will therefore stop me from all the functions that have been launched by wsdr.begin (); ?
Yes exactly.
Hello,
I signed up on github because I don't know how to ask you for help with your arduino library. I am putting OTA support but I am having upload problems due to wsdr.begin (); which causes me errors every time. A priori this blocks me the OTA update and I do not know how to stop this function because the wsdr.end (); does not exist according to my IDE compiler ... How can I do? I hope I put it in the right place because I have no idea how Github works ... Thank you