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:
Florian authored and GitHub committed 2020-06-19 12:44:53 -05:00
1 parent eb5fff7fba
commit 9bba730e84
4 files changed
+90 -41

No files matched your search

+23 -1
View File
@@ -75,6 +75,28 @@ home/OpenMQTTGateway/LWT Online
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
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.
@@ -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:
```
``` ini
[com-arduino]
[com-esp]
```
+4 -4
View File
@@ -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
#endif
#define TimeBetweenReadingSYS 120 // time between (s) system readings (like memory)
#define TimeBeforeMQTTconnect 10 // time estimated (s) before the board is connected to MQTT
#define subjectSYStoMQTT "/SYStoMQTT"
#define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config"
#define TimeBetweenReadingSYS 120 // time between (s) system readings (like memory)
#define InitialMQTTConnectionTimeout 10 // time estimated (s) before the board is connected to MQTT
#define subjectSYStoMQTT "/SYStoMQTT"
#define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config"
/*-------------------DEFINE LOG LEVEL----------------------*/
#define LOG_LEVEL LOG_LEVEL_NOTICE
+44 -30
View File
@@ -30,17 +30,17 @@ Thanks to wolass https://github.com/wolass for suggesting me HM 10 and dinosd ht
*/
#include "User_config.h"
#ifdef ESP32
# include "FreeRTOS.h"
#ifdef ZgatewayBT
# ifdef ESP32
# include "FreeRTOS.h"
FreeRTOS::Semaphore semaphoreCreateOrUpdateDevice = FreeRTOS::Semaphore("createOrUpdateDevice");
// Headers used for deep sleep functions
# include <driver/adc.h>
# include <esp_bt.h>
# include <esp_bt_main.h>
# include <esp_wifi.h>
#endif
#ifdef ZgatewayBT
# include <driver/adc.h>
# include <esp_bt.h>
# include <esp_bt_main.h>
# include <esp_wifi.h>
# endif
# include <vector>
using namespace std;
@@ -299,6 +299,8 @@ void MiBandDiscovery(char* mac) {}
//core on which the BLE detection task will run
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 {
void onResult(BLEAdvertisedDevice advertisedDevice) {
@@ -381,31 +383,43 @@ void BLEscan() {
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) {
while (true) {
Log.trace(F("BT Task running on core: %d" CR), xPortGetCoreID());
if (!low_power_mode)
delay(BLEinterval);
int n = 0;
while (client.state() != 0 && n <= TimeBeforeMQTTconnect) {
n++;
Log.trace(F("Wait for MQTT on core: %d attempt: %d" CR), xPortGetCoreID(), n);
delay(1000);
if (!ProcessLock) {
int n = 0;
while (client.state() != 0 && n <= InitialMQTTConnectionTimeout) {
n++;
Log.trace(F("Wait for MQTT on core: %d attempt: %d" CR), xPortGetCoreID(), n);
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
View File
@@ -699,15 +699,30 @@ void setOTA() {
ArduinoOTA.setPassword(ota_password);
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([]() {
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) {
Log.trace(F("Progress: %u%%\r" CR), (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
# if defined(ZgatewayBT) && defined(ESP32)
startProcessing();
# endif
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR)
Log.error(F("Auth Failed" CR));
@@ -1034,6 +1049,7 @@ void loop() {
#if defined(ESP8266) || defined(ESP32)
if (WiFi.status() == WL_CONNECTED) {
ArduinoOTA.handle();
#else
if ((Ethernet.hardwareStatus() != EthernetW5100 && Ethernet.linkStatus() == LinkON) || (Ethernet.hardwareStatus() == EthernetW5100)) { //we are able to detect disconnection only on w5200 and w5500
#endif
@@ -1048,10 +1064,6 @@ void loop() {
client.loop();
#if defined(ESP8266) || defined(ESP32)
ArduinoOTA.handle();
#endif
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)) || !timer_sys_measures) {
timer_sys_measures = millis();
@@ -1228,6 +1240,7 @@ void stateMeasures() {
# ifdef ESP32
SYSdata["lowpowermode"] = (int)low_power_mode;
# endif
SYSdata["interval"] = BLEinterval;
# endif
# ifdef ZgatewayRFM69
modules = modules + ZgatewayRFM69;