Browse Source

tasks

pull/2568/head
Christos Themelis 5 months ago
parent
commit
aae6113940
  1. 1
      .gitignore
  2. 36
      examples/simple_secure_chat_ui/main.cpp
  3. 46
      examples/simple_secure_chat_ui/task_clock.cpp
  4. 11
      examples/simple_secure_chat_ui/task_lvgl.cpp
  5. 32
      examples/simple_secure_chat_ui/task_openWeather.cpp
  6. 5
      examples/simple_secure_chat_ui/uiManager.cpp
  7. 33
      examples/simple_secure_chat_ui/uiTasks.cpp
  8. 60
      include/openWeather.h
  9. 24
      include/structs.h
  10. 15
      include/uiConfiguration.h
  11. 11
      include/uiDefines.h
  12. 6
      include/uiExternals.h
  13. 2
      include/uiManager.h
  14. 6
      include/uiTasks.h
  15. 0
      include/uiTouch.h
  16. 28
      include/uiVars.h
  17. 21
      include/vars.h
  18. 4
      lib/lvgl/lv_conf.h
  19. 51
      src/helpers/wifi/MyWiFi.h
  20. 191
      src/helpers/wifi/myWiFi.cpp
  21. 9
      variants/elecrow_espnow/platformio.ini

1
.gitignore

@ -14,3 +14,4 @@ cmake-*
.cache
.ccls
compile_commands.json
**/user_setup.h

36
examples/simple_secure_chat_ui/main.cpp

@ -52,23 +52,19 @@
#include "../src/fonts/fonts.h"
#include "../lvgl/lvgl.h"
#include "../include/externals.h"
#include "../include/uiExternals.h"
#include "../include/lgfx.h"
#include "../include/defines.h"
#include "../include/structs.h"
#include "../include/uiDefines.h"
#include "../include/uiManager.h"
#ifdef USE_MULTI_THREAD
#include "../include/tasks.h"
#endif
#include "touch.h"
#include "../include/uiTasks.h"
#include "uiTouch.h"
#define SEND_TIMEOUT_BASE_MILLIS 500
#define FLOOD_SEND_TIMEOUT_FACTOR 16.0f
#define DIRECT_SEND_PERHOP_FACTOR 6.0f
#define DIRECT_SEND_PERHOP_EXTRA_MILLIS 250
#define PUBLIC_GROUP_PSK "izOH6cXN6mrJ5e26oRXNcg=="
#define PUBLIC_GROUP_PSK "izOH6cXN6mrJ5e26oRXNcg=="
#define MAX_CHAT_MESSAGES 50
@ -82,18 +78,8 @@ static lv_color_t disp_draw_buf[800 * 480 / 10];
//static lv_color_t disp_draw_buf;
static lv_disp_drv_t disp_drv;
s_espNow espNowPacket;
UIManager *uiManager;
#ifdef USE_MULTI_THREAD
// Tasks
#ifdef DISPLAY_AT_CORE1
TaskHandle_t t_core1_tft;
#endif
// Semaphores
SemaphoreHandle_t semaphoreData;
#endif
SemaphoreHandle_t semaphoreData;
TwoWire I2Cone = TwoWire(0);
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &I2Cone, OLED_RESET);
@ -412,10 +398,8 @@ void initializeLVGL() {
}
void createSemaphores() {
#ifdef USE_MULTI_THREAD
semaphoreData = xSemaphoreCreateMutex();
xSemaphoreGive(semaphoreData);
#endif
}
// Believe it or not, this std C function is busted on some platforms!
@ -679,8 +663,12 @@ public:
{
// defaults
memset(&_prefs, 0, sizeof(_prefs));
_prefs.airtime_factor = 2.0; // one third
strcpy(_prefs.node_name, "NONAME");
_prefs.airtime_factor = 2.0; // one third
#ifdef ADVERT_NAME
strcpy(_prefs.node_name, ADVERT_NAME);
#else
strcpy(_prefs.node_name, "NONAME");
#endif
_prefs.freq = LORA_FREQ;
_prefs.tx_power_dbm = LORA_TX_POWER;

46
examples/simple_secure_chat_ui/task_clock.cpp

@ -0,0 +1,46 @@
#include <Arduino.h>
#include "esp_log.h"
#include "uiDefines.h"
#include "uiVars.h"
void clock_task(void *pvParameters) {
vTaskSuspend(NULL);
ESP_LOGI("Clock manager: Task running on core %d", xPortGetCoreID());
bool ntpResult = false;
uiManager->clearDateTime();
while (!ntpResult) {
myWiFi->ensureConnection();
if (myWiFi->isConnected()) {
ntpResult = myClock->setTimeFromNTP();
if (!ntpResult) {
vTaskDelay(DELAY_NTP_TASK / portTICK_PERIOD_MS);
} else {
uiManager->updateInfo("", COLOR_WHITE);
}
} else {
ESP_LOGE("No internet connection");
vTaskDelay(DELAY_WIFI_RECONNECT_TASK / portTICK_PERIOD_MS);
}
}
#ifdef USE_OPEN_WEATHER
vTaskResume(t_core1_openWeather);
#endif
while (1) {
uiManager->updateDateTime(
myClock->getTimeStruct()
);
uiManager->updateValues();
vTaskDelay(DELAY_CLOCK_TASK / portTICK_PERIOD_MS);
}
}

11
examples/simple_secure_chat_ui/task_lvgl.cpp

@ -1,20 +1,17 @@
#include <Arduino.h>
#include "defines.h"
//#include <MyDebug.h>
#include "vars.h"
#include "esp_log.h"
#include "uiDefines.h"
#include "uiVars.h"
void lvgl_task(void *pvParameters) {
vTaskSuspend(NULL);
Serial.printf("UI manager: Task running on core %d", xPortGetCoreID());
Serial.println();
ESP_LOGI("UI manager: Task running on core %d", xPortGetCoreID());
while (1) {
lv_timer_handler();
vTaskDelay(DELAY_LVGL_TASK / portTICK_PERIOD_MS);
}
// myDebug->println(DEBUG_LEVEL_INFO, "Terminating UI manager");
// vTaskDelete(NULL);
}

32
examples/simple_secure_chat_ui/task_openWeather.cpp

@ -0,0 +1,32 @@
#include <Arduino.h>
#include "esp_log.h"
#include "uiDefines.h"
#ifdef USE_OPEN_WEATHER
#include "uiVars.h"
void openWeather_task(void *pvParameters) {
vTaskSuspend(NULL);
ESP_LOGI("openWeather manager: Task running on core %d", xPortGetCoreID());
int errors = 0;
for (;;) {
myWiFi->ensureConnection();
if (myWiFi->isConnected()) {
if (openWeather->fetchData()) {
vTaskDelay(DELAY_OPEN_WEATHER_TASK / portTICK_PERIOD_MS);
} else {
vTaskDelay(DELAY_OPEN_WEATHER_SHORT_TASK / portTICK_PERIOD_MS);
}
} else {
ESP_LOGE("No internet connection");
vTaskDelay(DELAY_WIFI_RECONNECT_TASK / portTICK_PERIOD_MS);
}
}
}
#endif

5
examples/simple_secure_chat_ui/uiManager.cpp

@ -1,10 +1,9 @@
#include <Arduino.h>
#include "UI/ui.h"
#include "defines.h"
#include "vars.h"
#include "uiDefines.h"
#include "uiVars.h"
//#include <MyDebug.h>
#include "uiManager.h"
#if defined(LANG_GR)

33
examples/simple_secure_chat_ui/tasks.cpp → examples/simple_secure_chat_ui/uiTasks.cpp

@ -1,12 +1,11 @@
#include <Arduino.h>
#include "defines.h"
#include "tasks.h"
//#include <MyDebug.h>
#include "vars.h"
#include "uiDefines.h"
#include "uiTasks.h"
#include "uiVars.h"
// Tasks
TaskHandle_t t_core1_lvgl;
//TaskHandle_t t_core1_clock;
TaskHandle_t t_core0_lvgl;
TaskHandle_t t_core1_clock;
#ifdef USE_OPEN_WEATHER
TaskHandle_t t_core1_openWeather;
#endif
@ -20,17 +19,17 @@ void createTasks() {
10000, // Stack size of task
NULL, // Parameter of the task
5, // Priority of the task
&t_core1_lvgl, // Task handle to keep track of created task
&t_core0_lvgl, // Task handle to keep track of created task
0); // Pin task to core 0
// xTaskCreatePinnedToCore(
// clock_task, // Task function.
// "CLOCK_Manager", // Name of task.
// 10000, // Stack size of task
// NULL, // Parameter of the task
// 4, // Priority of the task
// &t_core1_clock, // Task handle to keep track of created task
// 1); // Pin task to core 0
xTaskCreatePinnedToCore(
clock_task, // Task function.
"CLOCK_Manager", // Name of task.
10000, // Stack size of task
NULL, // Parameter of the task
4, // Priority of the task
&t_core1_clock, // Task handle to keep track of created task
1); // Pin task to core 0
#ifdef USE_OPEN_WEATHER
xTaskCreatePinnedToCore(
@ -46,7 +45,7 @@ void createTasks() {
Serial.println("All tasks created\nStarting tasks...");
vTaskResume(t_core1_lvgl);
//vTaskResume(t_core1_clock);
vTaskResume(t_core0_lvgl);
vTaskResume(t_core1_clock);
}

60
include/openWeather.h

@ -0,0 +1,60 @@
#ifndef OPEN_WEATHER_h
#define OPEN_WEATHER_h
#include <Arduino.h>
#include "uiDefines.h"
#ifdef USE_OPEN_WEATHER
#include <HttpClient.h>
#include <ArduinoJson.h>
#include <PNGdec.h>
#include "user_setup.h"
// Weather Image
#define IMG_WIDTH 200
#define IMG_HEIGHT 200
#define PNG_PIXELS_PER_LINE 2048
class OpenWeather {
private:
// functions
static int renderPNGToBuffer(PNGDRAW *pDraw); // static callback
int renderPNGToBufferImpl(PNGDRAW *pDraw); // normal method
void downloadImageToMemory(const char *url);
// User setup
String town = USER_WeatherTown;
String myAPI = USER_WeatherAPI;
String units = USER_WeatherUnits;
// vars
PNG png;
uint8_t *imageBuffer = nullptr;
uint16_t *rgb565_buffer = nullptr;
int bufferSize;
lv_img_dsc_t img_dsc;
String openWeatherServer;
s_openWeatherData data;
String oldIconUrl;
SemaphoreHandle_t semaphoreData;
bool dataUpdated;
String lastUpdate;
HTTPClient http;
char* tmp_buf;
public:
OpenWeather();
// functions
void init();
bool fetchData();
bool isDataUpdated();
void setDataUpdated(bool updated);
s_openWeatherData getData();
bool decodePngToRgb565(uint8_t *png_data, int png_size);
};
#endif
#endif

24
include/structs.h

@ -1,24 +0,0 @@
#ifndef structs_h
#define structs_h
#include <Arduino.h>
#include "../lvgl/lvgl.h"
typedef struct s_espNow {
uint8_t type;
uint8_t id;
int16_t value;
} s_espNow;
typedef struct s_espNowButtons {
bool enabled;
bool needsUpdate;
int16_t state;
lv_obj_t *obj;
uint32_t colorOn;
uint32_t colorOff;
lv_obj_t *uiLabel;
char *uiLabelText;
} s_espNowButtons;
#endif

15
include/configuration.h → include/uiConfiguration.h

@ -12,21 +12,6 @@
// Modules //
/////////////
//#define SHOW_TOP_BAR
#define USE_MODULE_CONTROLS
//////////////////
// Running mode //
//////////////////
// Debug
//#define MODE_DEBUG_FULL
#define MODE_DEBUG
//#define MODE_RELEASE_INFO
//#define MODE_RELEASE
// Multithread
#define USE_MULTI_THREAD
#define DISPLAY_AT_CORE1
// Language
//#define LANG_EN

11
include/defines.h → include/uiDefines.h

@ -1,10 +1,19 @@
#ifndef DEFINES_h
#define DEFINES_h
#include "configuration.h"
#include "uiConfiguration.h"
#define BUTTONS_ON_SCREEN 7
#define DELAY_LVGL_TASK 10
#define DELAY_MAIN_TASK 500
#define DELAY_CLOCK_TASK 1000
#define DELAY_NTP_TASK 30000
#define DELAY_WIFI_RECONNECT_TASK 5000
// every 5 minutes on success
#define DELAY_OPEN_WEATHER_TASK 300000
// every 1 minute on failure
#define DELAY_OPEN_WEATHER_SHORT_TASK 60000
#define STATE_OFF HIGH
#define STATE_ON LOW

6
include/externals.h → include/uiExternals.h

@ -3,11 +3,11 @@
#include <Arduino.h>
#include "configuration.h"
#include "uiConfiguration.h"
extern void createTasks();
extern TaskHandle_t t_core1_lvgl;
//TaskHandle_t t_core1_clock;
extern TaskHandle_t t_core0_lvgl;
extern TaskHandle_t t_core1_clock;
#ifdef USE_OPEN_WEATHER
extern TaskHandle_t t_core1_openWeather;
#endif

2
include/uiManager.h

@ -2,7 +2,7 @@
#define UI_MANAGER_h
#include <Arduino.h>
#include "defines.h"
#include "uiDefines.h"
class UIManager {
private:

6
include/tasks.h → include/uiTasks.h

@ -2,13 +2,13 @@
#define TASKS_h
#include <Arduino.h>
#include "defines.h"
#include "vars.h"
#include "uiDefines.h"
#include "uiVars.h"
void lvgl_task(void *pvParameters);
//void clock_task(void *pvParameters);
#ifdef USE_OPEN_WEATHER
void openWeather_task(void *pvParameters);
void openWeather_task(void *pvParameters);
#endif
#endif

0
include/touch.h → include/uiTouch.h

28
include/uiVars.h

@ -0,0 +1,28 @@
#ifndef VARS_h
#define VARS_h
#include <Arduino.h>
#include "openWeather.h"
#include "lvgl.h"
extern void createTasks();
extern TaskHandle_t t_core1_tft;
extern TaskHandle_t t_core0_lvgl;
extern TaskHandle_t t_core1_clock;
extern SemaphoreHandle_t semaphoreData;
extern UIManager *uiManager;
extern MyClock *myClock;
extern MyWiFi *myWiFi;
#ifdef USE_OPEN_WEATHER
extern OpenWeather *openWeather;
extern TaskHandle_t t_core1_openWeather;
#endif
#ifdef USE_MAIN_TAB_VIEW
extern lv_obj_t * ui_MainTabView;
#endif
#endif

21
include/vars.h

@ -1,21 +0,0 @@
#ifndef VARS_h
#define VARS_h
#include <Arduino.h>
#include "structs.h"
#ifdef USE_MULTI_THREAD
extern SemaphoreHandle_t semaphoreData;
// Tasks
#ifdef DISPLAY_AT_CORE1
extern TaskHandle_t t_core1_tft;
#endif
#ifdef USE_MAIN_TAB_VIEW
extern lv_obj_t * ui_MainTabView;
#endif
#endif
#endif

4
lib/lvgl/lv_conf.h

@ -540,7 +540,7 @@
#define LV_USE_IMGBTN 0
#define LV_USE_KEYBOARD 0
#define LV_USE_KEYBOARD 1
#define LV_USE_LED 0
@ -550,7 +550,7 @@
#define LV_USE_METER 0
#define LV_USE_MSGBOX 0
#define LV_USE_MSGBOX 1
#define LV_USE_SPAN 1
#if LV_USE_SPAN

51
src/helpers/wifi/MyWiFi.h

@ -0,0 +1,51 @@
#ifndef WIFI_h
#define WIFI_h
#include <Arduino.h>
#include <WiFi.h>
#include "esp_wifi.h"
#include <esp_now.h>
typedef struct s_espNow {
uint8_t type;
uint8_t id;
int16_t value;
} s_espNow;
class MyWiFi {
private:
// functions
void notInitialized();
using OnDataSentCallback = void (*)(const uint8_t *mac_addr, esp_now_send_status_t status);
using OnDataRecvCallback = void (*)(const uint8_t *mac_addr, const uint8_t *incomingData, int len);
//Vars
uint8_t WiFiChannel;
bool initDone;
esp_now_peer_info_t peerInfo;
s_espNow espNowPacket;
SemaphoreHandle_t semaphoreData;
char *tmp_buf;
char *savedSSID;
char *savedPassword;
public:
MyWiFi();
// functions
void init(wifi_mode_t mode, char *ssid, char *password);
void stop();
bool initESPNow(int channel, bool encrypted, OnDataSentCallback onSent, OnDataRecvCallback onRecv);
void addEspNowPeer(uint8_t address[6]);
esp_err_t sendEspNow(const uint8_t *peer_addr, uint8_t type, uint8_t id, uint16_t value);
void connect();
void disconnect();
void ensureConnection();
bool isConnected();
wl_status_t getStatus();
uint8_t getChannel();
};
#endif

191
src/helpers/wifi/myWiFi.cpp

@ -0,0 +1,191 @@
#include <Arduino.h>
#include <WiFi.h>
#include "esp_log.h"
#include "MyWiFi.h"
MyWiFi::MyWiFi() {
ESP_LOGD("[WiFi]");
initDone = false;
tmp_buf = (char*)malloc(128);
semaphoreData = xSemaphoreCreateMutex();
xSemaphoreGive(semaphoreData);
}
void MyWiFi::init(wifi_mode_t mode, char *ssid, char *password) {
ESP_LOGD("Initializing WiFi");
savedSSID = (char*)malloc(strlen(ssid) + 1);
strcpy(savedSSID, ssid);
savedPassword = (char*)malloc(strlen(password) + 1);
strcpy(savedPassword, password);
ESP_LOGD("SSID: '%s', password:'%s'", savedSSID, savedPassword);
WiFi.mode(mode);
ESP_LOGI("MAC Address: %s", WiFi.macAddress());
initDone = true;
}
void MyWiFi::stop() {
if (!initDone) {
notInitialized();
return;
}
disconnect();
initDone = false;
free(savedSSID);
free(savedPassword);
}
void MyWiFi::notInitialized() {
ESP_LOGE("WiFi not initialized");
}
void MyWiFi::connect() {
ESP_LOGI("WiFi disconnected, reconnecting...");
if (!initDone) {
notInitialized();
return;
}
xSemaphoreTake(semaphoreData, portMAX_DELAY);
WiFi.disconnect();
WiFi.begin(savedSSID, savedPassword);
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) {
delay(500);
}
wifi_ap_record_t ap_info;
if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) {
ESP_LOGD("WiFi connected");
WiFiChannel = ap_info.primary;
ESP_LOGD("WiFi channel: %d", WiFiChannel);
} else {
WiFiChannel = 0;
ESP_LOGD("Not connected to any WiFi network.");
}
xSemaphoreGive(semaphoreData);
}
void MyWiFi::ensureConnection() {
if (!initDone) {
notInitialized();
return;
}
if (!isConnected()) {
connect();
}
}
bool MyWiFi::isConnected() {
if (!initDone) {
notInitialized();
return false;
}
bool ret;
xSemaphoreTake(semaphoreData, portMAX_DELAY);
ret = WiFi.status() == WL_CONNECTED;
xSemaphoreGive(semaphoreData);
return ret;
}
void MyWiFi::disconnect() {
ESP_LOGD("WiFi disconnecting...");
if (!initDone) {
notInitialized();
return;
}
xSemaphoreTake(semaphoreData, portMAX_DELAY);
WiFi.disconnect();
xSemaphoreGive(semaphoreData);
}
wl_status_t MyWiFi::getStatus() {
if (!initDone) {
notInitialized();
return WL_DISCONNECTED;
}
wl_status_t ret;
xSemaphoreTake(semaphoreData, portMAX_DELAY);
ret = WiFi.status();
xSemaphoreGive(semaphoreData);
return ret;
}
uint8_t MyWiFi::getChannel() {
if (!initDone) {
notInitialized();
return 0;
}
uint8_t ret;
xSemaphoreTake(semaphoreData, portMAX_DELAY);
ret = WiFiChannel;
xSemaphoreGive(semaphoreData);
return ret;
}
////////////
// ESPNow //
////////////
void MyWiFi::addEspNowPeer(uint8_t address[6]) {
ESP_LOGD("Adding ESPNow peer");
memcpy(peerInfo.peer_addr, address, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
ESP_LOGE("Failed to add peer");
} else {
ESP_LOGD("ESPNow peer added");
}
}
bool MyWiFi::initESPNow(int channel, bool encrypted, OnDataSentCallback onSent, OnDataRecvCallback onRecv) {
ESP_LOGI("Initializing ESP-NOW...");
if (onRecv == nullptr) {
ESP_LOGE("register_recv_cb is null");
return false;
}
WiFi.mode(WIFI_STA);
ESP_LOGI("MAC Address: %s", WiFi.macAddress());
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
ESP_LOGE("Error initializing ESP-NOW");
return false;
} else {
ESP_LOGD("Initializing ESP-NOW ok");
}
// preper register peer
peerInfo.channel = channel;
peerInfo.encrypt = encrypted;
peerInfo.ifidx = WIFI_IF_STA;
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
if (onSent != nullptr) {
esp_now_register_send_cb(onSent);
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(onRecv);
return true;
}
esp_err_t MyWiFi::sendEspNow(const uint8_t *peer_addr, uint8_t type, uint8_t id, uint16_t value) {
espNowPacket.type = type;
espNowPacket.id = id;
espNowPacket.value = value;
return esp_now_send(peer_addr, (uint8_t *) &espNowPacket, sizeof(s_espNow));
}

9
variants/elecrow_espnow/platformio.ini

@ -23,19 +23,19 @@ build_flags =
${Elecrow_ESPNOW.build_flags}
-I./include
-D${PIOENV}
-D USE_MODULE_SWITCHES
-D CORE_DEBUG_LEVEL=2
-D CORE_DEBUG_LEVEL=4 ; 0: None, 1: Error, 2: Warn, 3: Info, 4: Debug, 5: Verbose
-D LV_CONF_PATH=lv_conf.h
-D ELECROW_DISPLAY_50
-D USE_MODULE_SWITCHES
-D CLIENT_WITHOUT_LORA
-D USE_OPEN_WEATHER
-D ADVERT_NAME='"Elecrow Terminal"'
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=8
-D MESH_DEBUG=1
-D BOARD_HAS_PSRAM=1
build_src_filter = ${Elecrow_ESPNOW.build_src_filter}
+<../examples/simple_secure_chat/*.cpp>
+<../examples/simple_secure_chat_ui/*.cpp>
+<helpers/wifi/myWiFi.cpp>
+<fonts/*.c>
+<UI/*.c>
lib_deps =
@ -43,5 +43,6 @@ lib_deps =
adafruit/Adafruit SSD1306 @ ^2.5.15
lvgl/[email protected]
lovyan03/LovyanGFX@^1.1.16
bitbank2/PNGdec@^1.1.6
tamctec/TAMC_GT911@^1.0.2
densaugeo/base64 @ ~1.4.0

Loading…
Cancel
Save