Merge pull request #164 from cyberman54/development

v1.5.3
This commit is contained in:
Verkehrsrot 2018-09-23 15:24:59 +02:00 committed by GitHub
commit 215149d479
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 241 additions and 197 deletions

View File

@ -26,7 +26,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
[common] [common]
; for release_version use max. 10 chars total, use any decimal format like "a.b.c" ; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
release_version = 1.5.2 release_version = 1.5.3
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
debug_level = 0 debug_level = 0

View File

@ -4,7 +4,7 @@
// Basic config // Basic config
#include "globals.h" #include "globals.h"
#include "senddata.h" #include "senddata.h"
#include "OTA.h" #include "ota.h"
// Local logging tag // Local logging tag
static const char TAG[] = "main"; static const char TAG[] = "main";

View File

@ -21,6 +21,25 @@ NOTICE:
Parts of the source files in this repository are made available under different Parts of the source files in this repository are made available under different
licenses. Refer to LICENSE.txt file in repository for more details. licenses. Refer to LICENSE.txt file in repository for more details.
//////////////////////// ESP32-Paxcounter \\\\\\\\\\\\\\\\\\\\\\\\\\
Uused tasks and timers:
Task Core Prio Purpose
====================================================================
IDLE 0 0 ESP32 arduino scheduler
gpsloop 0 2 read data from GPS over serial or i2c
IDLE 1 0 Arduino loop() -> used for LED switching
loraloop 1 1 runs the LMIC stack
statemachine 1 3 switches application process logic
ESP32 hardware timers
==========================
0 Display-Refresh
1 Wifi Channel Switch
2 Send Cycle
3 Housekeeping
*/ */
// Basic Config // Basic Config
@ -90,39 +109,66 @@ void setup() {
esp_log_set_vprintf(redirect_log); esp_log_set_vprintf(redirect_log);
#endif #endif
ESP_LOGI(TAG, "Starting %s v%s", PRODUCTNAME, PROGVERSION); // read (and initialize on first run) runtime settings from NVRAM
// initialize system event handler for wifi task, needed for
// wifi_sniffer_init()
// esp_event_loop_init(NULL, NULL);
// ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
// print chip information on startup if in verbose mode
#ifdef VERBOSE
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
ESP_LOGI(TAG,
"This is ESP32 chip with %d CPU cores, WiFi%s%s, silicon revision "
"%d, %dMB %s Flash",
chip_info.cores, (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "",
chip_info.revision, spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded"
: "external");
ESP_LOGI(TAG, "ESP32 SDK: %s", ESP.getSdkVersion());
ESP_LOGI(TAG, "Free RAM: %d bytes", ESP.getFreeHeap());
#ifdef HAS_GPS
ESP_LOGI(TAG, "TinyGPS+ v%s", TinyGPSPlus::libraryVersion());
#endif
#endif // verbose
// read settings from NVRAM
loadConfig(); // includes initialize if necessary loadConfig(); // includes initialize if necessary
#ifdef VENDORFILTER // initialize leds
strcat_P(features, " OUIFLT"); #if (HAS_LED != NOT_A_PIN)
pinMode(HAS_LED, OUTPUT);
strcat_P(features, " LED");
#endif
#ifdef HAS_RGB_LED
rgb_set_color(COLOR_PINK);
strcat_P(features, " RGB");
#endif
// initialize wifi antenna
#ifdef HAS_ANTENNA_SWITCH
strcat_P(features, " ANT");
antenna_init();
antenna_select(cfg.wifiant);
#endif
// switch off bluetooth, if not compiled
#ifdef BLECOUNTER
strcat_P(features, " BLE");
#else
bool btstop = btStop();
#endif
// initialize battery status
#ifdef HAS_BATTERY_PROBE
strcat_P(features, " BATT");
calibrate_voltage();
batt_voltage = read_voltage();
#endif
// reboot to firmware update mode if ota trigger switch is set
if (cfg.runmode == 1) {
cfg.runmode = 0;
saveConfig();
start_ota_update();
}
// initialize button
#ifdef HAS_BUTTON
strcat_P(features, " BTN_");
#ifdef BUTTON_PULLUP
strcat_P(features, "PU");
// install button interrupt (pullup mode)
pinMode(HAS_BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, RISING);
#else
strcat_P(features, "PD");
// install button interrupt (pulldown mode)
pinMode(HAS_BUTTON, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, FALLING);
#endif // BUTTON_PULLUP
#endif // HAS_BUTTON
// initialize gps
#ifdef HAS_GPS
strcat_P(features, " GPS");
#endif #endif
// initialize LoRa // initialize LoRa
@ -149,58 +195,32 @@ void setup() {
SEND_QUEUE_SIZE * PAYLOAD_BUFFER_SIZE); SEND_QUEUE_SIZE * PAYLOAD_BUFFER_SIZE);
#endif #endif
// initialize led #ifdef VENDORFILTER
#if (HAS_LED != NOT_A_PIN) strcat_P(features, " OUIFLT");
pinMode(HAS_LED, OUTPUT);
strcat_P(features, " LED");
#endif #endif
#ifdef HAS_RGB_LED ESP_LOGI(TAG, "Starting %s v%s", PRODUCTNAME, PROGVERSION);
rgb_set_color(COLOR_PINK);
strcat_P(features, " RGB");
#endif
// initialize button // print chip information on startup if in verbose mode
#ifdef HAS_BUTTON #ifdef VERBOSE
strcat_P(features, " BTN_"); esp_chip_info_t chip_info;
#ifdef BUTTON_PULLUP esp_chip_info(&chip_info);
strcat_P(features, "PU"); ESP_LOGI(TAG,
// install button interrupt (pullup mode) "This is ESP32 chip with %d CPU cores, WiFi%s%s, silicon revision "
pinMode(HAS_BUTTON, INPUT_PULLUP); "%d, %dMB %s Flash",
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, RISING); chip_info.cores, (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
#else (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "",
strcat_P(features, "PD"); chip_info.revision, spi_flash_get_chip_size() / (1024 * 1024),
// install button interrupt (pulldown mode) (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded"
pinMode(HAS_BUTTON, INPUT_PULLDOWN); : "external");
attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, FALLING); ESP_LOGI(TAG, "ESP32 SDK: %s", ESP.getSdkVersion());
#endif // BUTTON_PULLUP ESP_LOGI(TAG, "Free RAM: %d bytes", ESP.getFreeHeap());
#endif // HAS_BUTTON
// initialize wifi antenna
#ifdef HAS_ANTENNA_SWITCH
strcat_P(features, " ANT");
antenna_init();
antenna_select(cfg.wifiant);
#endif
// switch off bluetooth on esp32 module, if not compiled
#ifdef BLECOUNTER
strcat_P(features, " BLE");
#else
bool btstop = btStop();
#endif
// initialize gps
#ifdef HAS_GPS #ifdef HAS_GPS
strcat_P(features, " GPS"); ESP_LOGI(TAG, "TinyGPS+ v%s", TinyGPSPlus::libraryVersion());
#endif #endif
// initialize battery status #endif // verbose
#ifdef HAS_BATTERY_PROBE
strcat_P(features, " BATT");
calibrate_voltage();
batt_voltage = read_voltage();
#endif
// initialize display // initialize display
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
@ -208,16 +228,6 @@ void setup() {
DisplayState = cfg.screenon; DisplayState = cfg.screenon;
init_display(PRODUCTNAME, PROGVERSION); init_display(PRODUCTNAME, PROGVERSION);
/*
Usage of ESP32 hardware timers
==============================
0 Display-Refresh
1 Wifi Channel Switch
2 Send Cycle
3 Housekeeping
*/
// setup display refresh trigger IRQ using esp32 hardware timer // setup display refresh trigger IRQ using esp32 hardware timer
// https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/ // https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
@ -232,13 +242,6 @@ void setup() {
timerAlarmEnable(displaytimer); timerAlarmEnable(displaytimer);
#endif #endif
// reboot to firmware update mode if ota trigger switch is set
if (cfg.runmode == 1) {
cfg.runmode = 0;
saveConfig();
start_ota_update();
}
// setup channel rotation trigger IRQ using esp32 hardware timer 1 // setup channel rotation trigger IRQ using esp32 hardware timer 1
channelSwitch = timerBegin(1, 800, true); channelSwitch = timerBegin(1, 800, true);
timerAttachInterrupt(channelSwitch, &ChannelSwitchIRQ, true); timerAttachInterrupt(channelSwitch, &ChannelSwitchIRQ, true);
@ -293,18 +296,6 @@ void setup() {
// join network // join network
LMIC_startJoining(); LMIC_startJoining();
/*
Task Core Prio Purpose
====================================================================
IDLE 0 0 ESP32 arduino scheduler
gpsloop 0 2 read data from GPS over serial or i2c
IDLE 1 0 Arduino loop() -> used for LED switching
loraloop 1 1 runs the LMIC stack
statemachine 1 3 switches application process logic
*/
// start lmic runloop in rtos task on core 1 // start lmic runloop in rtos task on core 1
// (note: arduino main loop runs on core 1, too) // (note: arduino main loop runs on core 1, too)
// https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/ // https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/
@ -332,6 +323,8 @@ void setup() {
// start wifi in monitor mode and start channel rotation task on core 0 // start wifi in monitor mode and start channel rotation task on core 0
ESP_LOGI(TAG, "Starting Wifi..."); ESP_LOGI(TAG, "Starting Wifi...");
// esp_event_loop_init(NULL, NULL);
// ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_sniffer_init(); wifi_sniffer_init();
// initialize salt value using esp_random() called by random() in // initialize salt value using esp_random() called by random() in
// arduino-esp32 core. Note: do this *after* wifi has started, since // arduino-esp32 core. Note: do this *after* wifi has started, since
@ -345,40 +338,9 @@ void setup() {
} // setup() } // setup()
void stateMachine(void *pvParameters) {
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
while (1) {
#ifdef HAS_BUTTON
readButton();
#endif
#ifdef HAS_DISPLAY
updateDisplay();
#endif
// check wifi scan cycle and if due rotate channel
if (ChannelTimerIRQ)
switchWifiChannel(channel);
// check housekeeping cycle and if due do the work
if (HomeCycleIRQ)
doHousekeeping();
// check send queue and process it
enqueuePayload();
// check send cycle and if due enqueue payload to send
if (SendCycleTimerIRQ)
sendPayload();
// give yield to CPU
vTaskDelay(2 / portTICK_PERIOD_MS);
}
}
void loop() { void loop() {
// switch LED states if device has a LED // switch LED state if device has LED(s)
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
led_loop(); led_loop();
#endif #endif

View File

@ -1,20 +1,17 @@
#ifndef _MAIN_H #ifndef _MAIN_H
#define _MAIN_H #define _MAIN_H
#include "globals.h"
#include "led.h"
#include "macsniff.h"
#include "wifiscan.h"
#include "configmanager.h"
#include "senddata.h"
#include "cyclic.h"
#include "beacon_array.h"
#include "OTA.h"
#include <esp_spi_flash.h> // needed for reading ESP32 chip attributes #include <esp_spi_flash.h> // needed for reading ESP32 chip attributes
#include <esp_event_loop.h> // needed for Wifi event handler #include <esp_event_loop.h> // needed for Wifi event handler
#include <esp32-hal-timer.h> // needed for timers #include <esp32-hal-timer.h> // needed for timers
void stateMachine(void *pvParameters); #include "globals.h"
#include "led.h"
#include "wifiscan.h"
#include "configmanager.h"
#include "cyclic.h"
#include "beacon_array.h"
#include "ota.h"
#include "statemachine.h"
#endif #endif

View File

@ -35,15 +35,36 @@ volatile bool isValidContentType = false;
// Local logging tag // Local logging tag
static const char TAG[] = "main"; static const char TAG[] = "main";
void display(const uint8_t x, const uint8_t y, char* text) { void display(const uint8_t row, std::string status, std::string msg) {
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
u8x8.setCursor(x, y); u8x8.setCursor(14, row);
u8x8.print(text); u8x8.print((status.substr(0, 2)).c_str());
if (!msg.empty()) {
u8x8.clearLine(7);
u8x8.setCursor(0, 7);
u8x8.print(msg.substr(0, 16).c_str());
}
#endif #endif
} }
// callback function to show download progress while streaming data
void show_progress(size_t current, size_t size) {
char buf[17];
snprintf(buf, 17, "%-9lu (%3lu%%)", current, current*100 / size);
display(4, "**", buf);
}
void start_ota_update() { void start_ota_update() {
// turn on LED
#if (HAS_LED != NOT_A_PIN)
#ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, LOW);
#else
digitalWrite(HAS_LED, HIGH);
#endif
#endif
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
u8x8.begin(); u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r); u8x8.setFont(u8x8_font_chroma48medium8_r);
@ -51,67 +72,80 @@ void start_ota_update() {
#ifdef DISPLAY_FLIP #ifdef DISPLAY_FLIP
u8x8.setFlipMode(1); u8x8.setFlipMode(1);
#endif #endif
u8x8.draw2x2String(0, 0, "UPDATING"); u8x8.setInverseFont(1);
u8x8.setCursor(0, 3); u8x8.print("SOFTWARE UPDATE \n");
u8x8.print("Wifi connect ..\n"); u8x8.setInverseFont(0);
u8x8.print("Get Update? ..\n"); u8x8.print("WiFi connect ..\n");
u8x8.print("Has Update? ..\n");
u8x8.print("Downloading ..\n"); u8x8.print("Downloading ..\n");
u8x8.print("Flashing ..\n"); u8x8.print("Flashing ..\n");
u8x8.print("Rebooting .."); u8x8.print("Rebooting ..");
#endif #endif
ESP_LOGI(TAG, "Starting Wifi OTA update"); ESP_LOGI(TAG, "Starting Wifi OTA update");
display(14, 3, "**"); display(1, "**", WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS); WiFi.begin(WIFI_SSID, WIFI_PASS);
int i = WIFI_MAX_TRY; int i = WIFI_MAX_TRY;
while (i--) { while (i--) {
ESP_LOGI(TAG, "trying to connect to %s", WIFI_SSID); ESP_LOGI(TAG, "Trying to connect to %s", WIFI_SSID);
if (WiFi.status() == WL_CONNECTED) if (WiFi.status() == WL_CONNECTED)
break; break;
vTaskDelay(5000 / portTICK_PERIOD_MS); vTaskDelay(5000 / portTICK_PERIOD_MS);
} }
if (i >= 0) { if (i >= 0) {
ESP_LOGI(TAG, "connected to %s", WIFI_SSID); ESP_LOGI(TAG, "Connected to %s", WIFI_SSID);
display(14, 3, "OK"); display(1, "OK", "WiFi connected");
checkFirmwareUpdates(); // gets and flashes new firmware and restarts checkFirmwareUpdates(); // gets and flashes new firmware
} else { } else {
ESP_LOGI(TAG, "could not connect to %s, rebooting.", WIFI_SSID); ESP_LOGI(TAG, "Could not connect to %s, rebooting.", WIFI_SSID);
display(14, 3, " E"); display(1, " E", "no WiFi connect");
} }
display(14, 7, "**"); display(5, "**", ""); // mark line rebooting
delay(5000);
ESP.restart(); // reached only if update was not successful or no wifi connect // turn off LED
#if (HAS_LED != NOT_A_PIN)
#ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, HIGH);
#else
digitalWrite(HAS_LED, LOW);
#endif
#endif
vTaskDelay(5000 / portTICK_PERIOD_MS);
ESP.restart();
} // start_ota_update } // start_ota_update
void checkFirmwareUpdates() { void checkFirmwareUpdates() {
// Fetch the latest firmware version // Fetch the latest firmware version
ESP_LOGI(TAG, "OTA mode, checking latest firmware version on server..."); ESP_LOGI(TAG, "Checking latest firmware version on server...");
display(14, 4, "**"); display(2, "**", "checking version");
const String latest = bintray.getLatestVersion(); const String latest = bintray.getLatestVersion();
if (latest.length() == 0) { if (latest.length() == 0) {
ESP_LOGI( ESP_LOGI(
TAG, TAG,
"Could not load info about the latest firmware. Rebooting to runmode."); "Could not load info about the latest firmware. Rebooting to runmode.");
display(14, 4, " E"); display(2, " E", "file not found");
return; return;
} else if (version_compare(latest, cfg.version) <= 0) { } else if (version_compare(latest, cfg.version) <= 0) {
ESP_LOGI(TAG, "Current firmware is up to date. Rebooting to runmode."); ESP_LOGI(TAG, "Current firmware is up to date. Rebooting to runmode.");
display(14, 4, "NO"); display(2, "NO", "no update found");
return; return;
} }
ESP_LOGI(TAG, "New firmware version v%s available. Downloading...", ESP_LOGI(TAG, "New firmware version v%s available. Downloading...",
latest.c_str()); latest.c_str());
display(14, 4, "OK"); display(2, "OK", "");
processOTAUpdate(latest); processOTAUpdate(latest);
} }
// A helper function to extract header value from header // helper function to extract header value from header
inline String getHeaderValue(String header, String headerName) { inline String getHeaderValue(String header, String headerName) {
return header.substring(strlen(headerName.c_str())); return header.substring(strlen(headerName.c_str()));
} }
@ -120,11 +154,13 @@ inline String getHeaderValue(String header, String headerName) {
* OTA update processing * OTA update processing
*/ */
void processOTAUpdate(const String &version) { void processOTAUpdate(const String &version) {
display(14, 5, "**");
char buf[17];
display(3, "**", "requesting file");
String firmwarePath = bintray.getBinaryPath(version); String firmwarePath = bintray.getBinaryPath(version);
if (!firmwarePath.endsWith(".bin")) { if (!firmwarePath.endsWith(".bin")) {
ESP_LOGI(TAG, "Unsupported binary format, OTA update cancelled."); ESP_LOGI(TAG, "Unsupported binary format, OTA update cancelled.");
display(14, 5, " E"); display(3, " E", "file type error");
return; return;
} }
@ -136,7 +172,7 @@ void processOTAUpdate(const String &version) {
if (!client.connect(currentHost.c_str(), port)) { if (!client.connect(currentHost.c_str(), port)) {
ESP_LOGI(TAG, "Cannot connect to %s", currentHost.c_str()); ESP_LOGI(TAG, "Cannot connect to %s", currentHost.c_str());
display(14, 5, " E"); display(3, " E", "connection lost");
return; return;
} }
@ -148,7 +184,7 @@ void processOTAUpdate(const String &version) {
if (!client.connect(currentHost.c_str(), port)) { if (!client.connect(currentHost.c_str(), port)) {
ESP_LOGI(TAG, "Redirect detected, but cannot connect to %s", ESP_LOGI(TAG, "Redirect detected, but cannot connect to %s",
currentHost.c_str()); currentHost.c_str());
display(14, 5, " E"); display(3, " E", "server error");
return; return;
} }
} }
@ -164,7 +200,7 @@ void processOTAUpdate(const String &version) {
while (client.available() == 0) { while (client.available() == 0) {
if (millis() - timeout > RESPONSE_TIMEOUT_MS) { if (millis() - timeout > RESPONSE_TIMEOUT_MS) {
ESP_LOGI(TAG, "Client Timeout."); ESP_LOGI(TAG, "Client Timeout.");
display(14, 5, " E"); display(3, " E", "client timeout");
client.stop(); client.stop();
return; return;
} }
@ -224,35 +260,38 @@ void processOTAUpdate(const String &version) {
} }
} }
display(14, 5, "OK"); display(3, "OK", ""); // line download
// check whether we have everything for OTA update // check whether we have everything for OTA update
if (contentLength && isValidContentType) { if (contentLength && isValidContentType) {
size_t written; size_t written, current, size;
if (Update.begin(contentLength)) { if (Update.begin(contentLength)) {
// register callback function for showing progress while streaming data
Update.onProgress(&show_progress);
int i = FLASH_MAX_TRY; int i = FLASH_MAX_TRY;
while ((i--) && (written != contentLength)) { while ((i--) && (written != contentLength)) {
ESP_LOGI(TAG, ESP_LOGI(TAG,
"Starting OTA update, attempt %d of %d. This will take some " "Starting OTA update, attempt %u of %u. This will take some "
"time to complete...", "time to complete...",
FLASH_MAX_TRY - i, FLASH_MAX_TRY); FLASH_MAX_TRY - i, FLASH_MAX_TRY);
display(14, 6, "**"); display(4, "**", "writing...");
written = Update.writeStream(client); written = Update.writeStream(client);
if (written == contentLength) { if (written == contentLength) {
ESP_LOGI(TAG, "Written %d bytes successfully", written); ESP_LOGI(TAG, "Written %u bytes successfully", written);
display(14, 6, "**"); snprintf(buf, 17, "%u kB Done!", (uint16_t)(written / 1024));
display(4, "OK", buf);
break; break;
} else { } else {
ESP_LOGI(TAG, ESP_LOGI(TAG,
"Written only %d of %d bytes, OTA update attempt cancelled.", "Written only %u of %u bytes, OTA update attempt cancelled.",
written, contentLength); written, contentLength);
display(14, 6, " E");
} }
} }
@ -262,33 +301,31 @@ void processOTAUpdate(const String &version) {
ESP_LOGI( ESP_LOGI(
TAG, TAG,
"OTA update completed. Rebooting to runmode with new version."); "OTA update completed. Rebooting to runmode with new version.");
display(14, 7, "OK");
client.stop(); client.stop();
return; return;
} else { } else {
ESP_LOGI(TAG, "Something went wrong! OTA update hasn't been finished " ESP_LOGI(TAG, "Something went wrong! OTA update hasn't been finished "
"properly."); "properly.");
display(14, 7, " E");
} }
} else { } else {
ESP_LOGI(TAG, "An error occurred. Error #: %d", Update.getError()); ESP_LOGI(TAG, "An error occurred. Error #: %d", Update.getError());
display(14, 7, " E"); snprintf(buf, 17, "Error #: %d", Update.getError());
display(4, " E", buf);
} }
} else { } else {
ESP_LOGI(TAG, "There isn't enough space to start OTA update"); ESP_LOGI(TAG, "There isn't enough space to start OTA update");
display(14, 7, " E"); display(4, " E", "disk full");
client.flush(); client.flush();
} }
} else { } else {
ESP_LOGI(TAG, ESP_LOGI(TAG,
"There was no valid content in the response from the OTA server!"); "There was no valid content in the response from the OTA server!");
display(14, 7, " E"); display(4, " E", "response error");
client.flush(); client.flush();
} }
ESP_LOGI(TAG, ESP_LOGI(TAG,
"OTA update failed. Rebooting to runmode with current version."); "OTA update failed. Rebooting to runmode with current version.");
display(14, 7, " E");
client.stop(); client.stop();
} }

View File

@ -13,5 +13,6 @@ void checkFirmwareUpdates();
void processOTAUpdate(const String &version); void processOTAUpdate(const String &version);
void start_ota_update(); void start_ota_update();
int version_compare(const String v1, const String v2); int version_compare(const String v1, const String v2);
void show_progress(size_t current, size_t size);
#endif // OTA_H #endif // OTA_H

View File

@ -73,8 +73,8 @@ void IRAM_ATTR SendCycleIRQ() {
portEXIT_CRITICAL(&timerMux); portEXIT_CRITICAL(&timerMux);
} }
// interrupt triggered function to eat data from RTos send queues and transmit it // interrupt triggered function to eat data from send queues and transmit it
void enqueuePayload() { void checkSendQueues() {
MessageBuffer_t SendBuffer; MessageBuffer_t SendBuffer;
#ifdef HAS_LORA #ifdef HAS_LORA
@ -98,7 +98,7 @@ void enqueuePayload() {
} }
#endif #endif
} // enqueuePayload } // checkSendQueues
void flushQueues() { void flushQueues() {
#ifdef HAS_LORA #ifdef HAS_LORA

View File

@ -4,7 +4,7 @@
void SendData(uint8_t port); void SendData(uint8_t port);
void sendPayload(void); void sendPayload(void);
void SendCycleIRQ(void); void SendCycleIRQ(void);
void enqueuePayload(void); void checkSendQueues(void);
void flushQueues(); void flushQueues();
#endif // _SENDDATA_H_ #endif // _SENDDATA_H_

35
src/statemachine.cpp Normal file
View File

@ -0,0 +1,35 @@
#include "statemachine.h"
// Local logging tag
static const char TAG[] = "main";
void stateMachine(void *pvParameters) {
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
while (1) {
#ifdef HAS_BUTTON
readButton();
#endif
#ifdef HAS_DISPLAY
updateDisplay();
#endif
// check wifi scan cycle and if due rotate channel
if (ChannelTimerIRQ)
switchWifiChannel(channel);
// check housekeeping cycle and if due do the work
if (HomeCycleIRQ)
doHousekeeping();
// check send cycle and if due enqueue payload to send
if (SendCycleTimerIRQ)
sendPayload();
// check send queues and process due payload to send
checkSendQueues();
// give yield to CPU
vTaskDelay(2 / portTICK_PERIOD_MS);
}
}

12
src/statemachine.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _STATEMACHINE_H
#define _STATEMACHINE_H
#include "globals.h"
#include "led.h"
#include "wifiscan.h"
#include "senddata.h"
#include "cyclic.h"
void stateMachine(void *pvParameters);
#endif

View File

@ -310,7 +310,7 @@ size_t UpdateClass::write(uint8_t *data, size_t len) {
} }
size_t UpdateClass::writeStream(Stream &data) { size_t UpdateClass::writeStream(Stream &data) {
data.setTimeout(10000); data.setTimeout(20000);
size_t written = 0; size_t written = 0;
size_t toRead = 0; size_t toRead = 0;
if(hasError() || !isRunning()) if(hasError() || !isRunning())