Add a lock mechanism to improve the OTA chances of success with ESP32 and BLE (#634)
* Add a lock mechanism to improve the OTA chances of success change TimeBeforeMQTTconnect to InitialMQTTConnectionTimeout move delay(BLEinterval); after the scan so the first scan will always be done at start now remove non relevant delay add stopProcessing and startProcessing functions
This commit is contained in:
1 parent
eb5fff7fba
commit
9bba730e84
4 files changed
+90
-41
No files matched your search
+23
-1
@@ -75,6 +75,28 @@ home/OpenMQTTGateway/LWT Online
|
|||||||
home/OpenMQTTGateway/version
|
home/OpenMQTTGateway/version
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# OTA
|
||||||
|
With PIO you can also upload the firmware through Over the Air, so as to do that you can add the upload options flags used below, `upload_port` is the IP adress of your ESP:
|
||||||
|
|
||||||
|
``` ini
|
||||||
|
[env:esp32-ble]
|
||||||
|
platform = ${com.esp32_platform}
|
||||||
|
board = esp32dev
|
||||||
|
board_build.partitions = min_spiffs.csv
|
||||||
|
lib_deps =
|
||||||
|
${com-esp.lib_deps}
|
||||||
|
${libraries.ble}
|
||||||
|
build_flags =
|
||||||
|
${com-esp.build_flags}
|
||||||
|
'-DZgatewayBT="BT"'
|
||||||
|
'-DGateway_Name="OpenMQTTGateway_ESP32"'
|
||||||
|
upload_protocol = espota
|
||||||
|
upload_port = 192.168.1.22
|
||||||
|
upload_flags =
|
||||||
|
--auth=OTAPASSWORD
|
||||||
|
--port=8266
|
||||||
|
```
|
||||||
|
|
||||||
# API
|
# API
|
||||||
With the V0.9 we added the support of json for receiving and publishing.
|
With the V0.9 we added the support of json for receiving and publishing.
|
||||||
Per default Json reception and Json publication is activated, the previous simple reception mode is also activated to avoid regression on commands.
|
Per default Json reception and Json publication is activated, the previous simple reception mode is also activated to avoid regression on commands.
|
||||||
@@ -100,7 +122,7 @@ If you are using platformio you can also comment the definitions above and defin
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note that depending on the environment the default platformio.ini has common option defined see sections:
|
Note that depending on the environment the default platformio.ini has common option defined see sections:
|
||||||
```
|
``` ini
|
||||||
[com-arduino]
|
[com-arduino]
|
||||||
[com-esp]
|
[com-esp]
|
||||||
```
|
```
|
||||||
|
|||||||
+4
-4
@@ -279,10 +279,10 @@ uint8_t wifiProtocol = 0; // default mode, automatic selection
|
|||||||
# define JSON_MSG_BUFFER 64 // Json message max buffer size, don't put 1024 or higher it is causing unexpected behaviour on ESP8266
|
# define JSON_MSG_BUFFER 64 // Json message max buffer size, don't put 1024 or higher it is causing unexpected behaviour on ESP8266
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TimeBetweenReadingSYS 120 // time between (s) system readings (like memory)
|
#define TimeBetweenReadingSYS 120 // time between (s) system readings (like memory)
|
||||||
#define TimeBeforeMQTTconnect 10 // time estimated (s) before the board is connected to MQTT
|
#define InitialMQTTConnectionTimeout 10 // time estimated (s) before the board is connected to MQTT
|
||||||
#define subjectSYStoMQTT "/SYStoMQTT"
|
#define subjectSYStoMQTT "/SYStoMQTT"
|
||||||
#define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config"
|
#define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config"
|
||||||
|
|
||||||
/*-------------------DEFINE LOG LEVEL----------------------*/
|
/*-------------------DEFINE LOG LEVEL----------------------*/
|
||||||
#define LOG_LEVEL LOG_LEVEL_NOTICE
|
#define LOG_LEVEL LOG_LEVEL_NOTICE
|
||||||
|
|||||||
+44
-30
@@ -30,17 +30,17 @@ Thanks to wolass https://github.com/wolass for suggesting me HM 10 and dinosd ht
|
|||||||
*/
|
*/
|
||||||
#include "User_config.h"
|
#include "User_config.h"
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ZgatewayBT
|
||||||
# include "FreeRTOS.h"
|
|
||||||
|
# ifdef ESP32
|
||||||
|
# include "FreeRTOS.h"
|
||||||
FreeRTOS::Semaphore semaphoreCreateOrUpdateDevice = FreeRTOS::Semaphore("createOrUpdateDevice");
|
FreeRTOS::Semaphore semaphoreCreateOrUpdateDevice = FreeRTOS::Semaphore("createOrUpdateDevice");
|
||||||
// Headers used for deep sleep functions
|
// Headers used for deep sleep functions
|
||||||
# include <driver/adc.h>
|
# include <driver/adc.h>
|
||||||
# include <esp_bt.h>
|
# include <esp_bt.h>
|
||||||
# include <esp_bt_main.h>
|
# include <esp_bt_main.h>
|
||||||
# include <esp_wifi.h>
|
# include <esp_wifi.h>
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#ifdef ZgatewayBT
|
|
||||||
|
|
||||||
# include <vector>
|
# include <vector>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -299,6 +299,8 @@ void MiBandDiscovery(char* mac) {}
|
|||||||
|
|
||||||
//core on which the BLE detection task will run
|
//core on which the BLE detection task will run
|
||||||
static int taskCore = 0;
|
static int taskCore = 0;
|
||||||
|
// Process lock when we want to use a critical function like OTA for example
|
||||||
|
bool ProcessLock = false;
|
||||||
|
|
||||||
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
|
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
|
||||||
void onResult(BLEAdvertisedDevice advertisedDevice) {
|
void onResult(BLEAdvertisedDevice advertisedDevice) {
|
||||||
@@ -381,31 +383,43 @@ void BLEscan() {
|
|||||||
esp_bt_controller_deinit();
|
esp_bt_controller_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stopProcessing() {
|
||||||
|
Log.notice(F("Stop BLE processing" CR));
|
||||||
|
ProcessLock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void startProcessing() {
|
||||||
|
Log.notice(F("Start BLE processing" CR));
|
||||||
|
ProcessLock = false;
|
||||||
|
}
|
||||||
|
|
||||||
void coreTask(void* pvParameters) {
|
void coreTask(void* pvParameters) {
|
||||||
while (true) {
|
while (true) {
|
||||||
Log.trace(F("BT Task running on core: %d" CR), xPortGetCoreID());
|
Log.trace(F("BT Task running on core: %d" CR), xPortGetCoreID());
|
||||||
if (!low_power_mode)
|
if (!ProcessLock) {
|
||||||
delay(BLEinterval);
|
int n = 0;
|
||||||
int n = 0;
|
while (client.state() != 0 && n <= InitialMQTTConnectionTimeout) {
|
||||||
while (client.state() != 0 && n <= TimeBeforeMQTTconnect) {
|
n++;
|
||||||
n++;
|
Log.trace(F("Wait for MQTT on core: %d attempt: %d" CR), xPortGetCoreID(), n);
|
||||||
Log.trace(F("Wait for MQTT on core: %d attempt: %d" CR), xPortGetCoreID(), n);
|
delay(1000);
|
||||||
delay(1000);
|
}
|
||||||
|
if (client.state() != 0) {
|
||||||
|
Log.warning(F("MQTT client disconnected no BLE scan" CR));
|
||||||
|
} else {
|
||||||
|
pinMode(LOW_POWER_LED, OUTPUT);
|
||||||
|
if (low_power_mode == 2)
|
||||||
|
digitalWrite(LOW_POWER_LED, 1 - LOW_POWER_LED_OFF);
|
||||||
|
BLEscan();
|
||||||
|
//only change LOW_POWER_LED if low power mode is enabled
|
||||||
|
if (low_power_mode)
|
||||||
|
digitalWrite(LOW_POWER_LED, LOW_POWER_LED_OFF);
|
||||||
|
}
|
||||||
|
if (low_power_mode) {
|
||||||
|
lowPowerESP32();
|
||||||
|
} else {
|
||||||
|
delay(BLEinterval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (client.state() != 0) {
|
|
||||||
Log.warning(F("MQTT client disconnected no BLE scan" CR));
|
|
||||||
delay(1000);
|
|
||||||
} else {
|
|
||||||
pinMode(LOW_POWER_LED, OUTPUT);
|
|
||||||
if (low_power_mode == 2)
|
|
||||||
digitalWrite(LOW_POWER_LED, 1 - LOW_POWER_LED_OFF);
|
|
||||||
BLEscan();
|
|
||||||
//only change LOW_POWER_LED if low power mode is enabled
|
|
||||||
if (low_power_mode)
|
|
||||||
digitalWrite(LOW_POWER_LED, LOW_POWER_LED_OFF);
|
|
||||||
}
|
|
||||||
if (low_power_mode)
|
|
||||||
lowPowerESP32();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-6
@@ -699,15 +699,30 @@ void setOTA() {
|
|||||||
ArduinoOTA.setPassword(ota_password);
|
ArduinoOTA.setPassword(ota_password);
|
||||||
|
|
||||||
ArduinoOTA.onStart([]() {
|
ArduinoOTA.onStart([]() {
|
||||||
Log.trace(F("Start OTA" CR));
|
Log.trace(F("Start OTA, lock other functions" CR));
|
||||||
|
# if defined(ZgatewayBT) && defined(ESP32)
|
||||||
|
stopProcessing();
|
||||||
|
# endif
|
||||||
|
# if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
|
||||||
|
M5Display("OTA in progress", "", "");
|
||||||
|
# endif
|
||||||
});
|
});
|
||||||
ArduinoOTA.onEnd([]() {
|
ArduinoOTA.onEnd([]() {
|
||||||
Log.trace(F("\nEnd OTA" CR));
|
# if defined(ZgatewayBT) && defined(ESP32)
|
||||||
|
startProcessing();
|
||||||
|
# endif
|
||||||
|
Log.trace(F("\nOTA done" CR));
|
||||||
|
# if defined(ZboardM5STICKC) || defined(ZboardM5STACK)
|
||||||
|
M5Display("OTA done", "", "");
|
||||||
|
# endif
|
||||||
});
|
});
|
||||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||||
Log.trace(F("Progress: %u%%\r" CR), (progress / (total / 100)));
|
Log.trace(F("Progress: %u%%\r" CR), (progress / (total / 100)));
|
||||||
});
|
});
|
||||||
ArduinoOTA.onError([](ota_error_t error) {
|
ArduinoOTA.onError([](ota_error_t error) {
|
||||||
|
# if defined(ZgatewayBT) && defined(ESP32)
|
||||||
|
startProcessing();
|
||||||
|
# endif
|
||||||
Serial.printf("Error[%u]: ", error);
|
Serial.printf("Error[%u]: ", error);
|
||||||
if (error == OTA_AUTH_ERROR)
|
if (error == OTA_AUTH_ERROR)
|
||||||
Log.error(F("Auth Failed" CR));
|
Log.error(F("Auth Failed" CR));
|
||||||
@@ -1034,6 +1049,7 @@ void loop() {
|
|||||||
|
|
||||||
#if defined(ESP8266) || defined(ESP32)
|
#if defined(ESP8266) || defined(ESP32)
|
||||||
if (WiFi.status() == WL_CONNECTED) {
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
|
ArduinoOTA.handle();
|
||||||
#else
|
#else
|
||||||
if ((Ethernet.hardwareStatus() != EthernetW5100 && Ethernet.linkStatus() == LinkON) || (Ethernet.hardwareStatus() == EthernetW5100)) { //we are able to detect disconnection only on w5200 and w5500
|
if ((Ethernet.hardwareStatus() != EthernetW5100 && Ethernet.linkStatus() == LinkON) || (Ethernet.hardwareStatus() == EthernetW5100)) { //we are able to detect disconnection only on w5200 and w5500
|
||||||
#endif
|
#endif
|
||||||
@@ -1048,10 +1064,6 @@ void loop() {
|
|||||||
|
|
||||||
client.loop();
|
client.loop();
|
||||||
|
|
||||||
#if defined(ESP8266) || defined(ESP32)
|
|
||||||
ArduinoOTA.handle();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
||||||
if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)) || !timer_sys_measures) {
|
if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)) || !timer_sys_measures) {
|
||||||
timer_sys_measures = millis();
|
timer_sys_measures = millis();
|
||||||
@@ -1228,6 +1240,7 @@ void stateMeasures() {
|
|||||||
# ifdef ESP32
|
# ifdef ESP32
|
||||||
SYSdata["lowpowermode"] = (int)low_power_mode;
|
SYSdata["lowpowermode"] = (int)low_power_mode;
|
||||||
# endif
|
# endif
|
||||||
|
SYSdata["interval"] = BLEinterval;
|
||||||
# endif
|
# endif
|
||||||
# ifdef ZgatewayRFM69
|
# ifdef ZgatewayRFM69
|
||||||
modules = modules + ZgatewayRFM69;
|
modules = modules + ZgatewayRFM69;
|
||||||
|
|||||||
Reference in new issue
Block a user