wifi in a thread and indicator on display

This commit is contained in:
Dejvino 2026-02-12 23:33:58 +01:00
parent f0714e352f
commit afad096e34

View File

@ -4,12 +4,15 @@
// Feature Configuration - Comment out to disable
#define ENABLE_SENSORS
#define ENABLE_DISPLAY
//#define ENABLE_WIFI
//#define ENABLE_NOTIFICATIONS
#define ENABLE_WIFI
#define ENABLE_NOTIFICATIONS
#ifdef ENABLE_WIFI
#include <WiFi.h>
#include <HTTPClient.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#endif
#ifdef ENABLE_SENSORS
@ -57,6 +60,7 @@ const float LIGHT_DEACTIVATION_THRESHOLD = 20.0;
const unsigned long VIBRATION_STATE_CHANGE_INTERVAL = 5000; // 5 seconds
const unsigned long VIBRATION_ACTIVE_THRESHOLD = 10000;
const int VIBRATION_WINDOW_SIZE = 4; // X * 5s seconds window
const unsigned long WARMUP_DURATION = 20000; // 20 seconds warmup
// Device state
bool isVibrationActive = false;
@ -77,14 +81,14 @@ const int displayTextLines = 4;
int displayDataLines = displayTextLines;
#endif
// Notification queue
String queuedMessage1 = "";
String queuedTitle1 = "";
String queuedPriority1 = "";
String queuedMessage2 = "";
String queuedTitle2 = "";
String queuedPriority2 = "";
// Network Task & Queue
struct NotificationMessage {
char message[64];
char title[32];
char priority[10];
};
QueueHandle_t notificationQueue;
volatile bool isNetworkActive = false;
#ifdef ENABLE_SENSORS
unsigned long vibrationHistory[VIBRATION_WINDOW_SIZE];
@ -110,8 +114,66 @@ void IRAM_ATTR onChange() {
}
#endif
#ifdef ENABLE_WIFI
void networkTask(void *parameter) {
NotificationMessage msg;
unsigned long lastWifiCheckTime = 0;
const unsigned long WIFI_CHECK_INTERVAL = 30000;
while (true) {
unsigned long currentTime = millis();
if (currentTime - lastWifiCheckTime >= WIFI_CHECK_INTERVAL) {
lastWifiCheckTime = currentTime;
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected. Attempting to reconnect...");
WiFi.reconnect();
}
}
if (xQueueReceive(notificationQueue, &msg, 1000 / portTICK_PERIOD_MS) == pdTRUE) {
isNetworkActive = true;
bool sent = false;
while (!sent) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = "http://ntfy.sh/" + String(NTFY_TOPIC);
http.begin(url);
http.addHeader("Content-Type", "text/plain");
http.addHeader("Title", msg.title);
http.addHeader("Priority", msg.priority);
int httpResponseCode = http.POST(msg.message);
http.end();
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
sent = true;
} else {
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
} else {
unsigned long now = millis();
if (now - lastWifiCheckTime >= WIFI_CHECK_INTERVAL) {
lastWifiCheckTime = now;
Serial.println("WiFi disconnected. Attempting to reconnect...");
WiFi.reconnect();
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
isNetworkActive = false;
}
}
}
#endif
void setup() {
delay(500);
Serial.begin(9600);
delay(100);
Serial.println("Setup started.");
#if defined(ENABLE_SENSORS) || defined(ENABLE_DISPLAY)
@ -120,7 +182,7 @@ void setup() {
#ifdef ENABLE_SENSORS
// Initialize vibration sensor pin
pinMode(VIBRATION_PIN, INPUT);
pinMode(VIBRATION_PIN, INPUT_PULLUP);
lastChangeTime = micros();
attachInterrupt(digitalPinToInterrupt(VIBRATION_PIN), onChange, CHANGE);
@ -161,6 +223,11 @@ void setup() {
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
#ifdef ENABLE_NOTIFICATIONS
notificationQueue = xQueueCreate(10, sizeof(NotificationMessage));
xTaskCreatePinnedToCore(networkTask, "NetworkTask", 8192, NULL, 1, NULL, 0);
#endif
#endif
#if defined(ENABLE_DISPLAY) && defined(ENABLE_WIFI)
@ -175,30 +242,9 @@ void setup() {
Serial.println("Setup finished.");
}
bool sendNotification(String message, String title, String priority);
void updateDisplay();
void loop() {
#ifdef ENABLE_NOTIFICATIONS
// Try to send any queued notification
if (queuedMessage1 != "") {
if (sendNotification(queuedMessage1, queuedTitle1, queuedPriority1)) {
Serial.println("Successfully sent queued notification 1.");
queuedMessage1 = ""; // Clear queue
queuedTitle1 = "";
queuedPriority1 = "";
}
}
if (queuedMessage2 != "") {
if (sendNotification(queuedMessage2, queuedTitle2, queuedPriority2)) {
Serial.println("Successfully sent queued notification 2.");
queuedMessage2 = ""; // Clear queue
queuedTitle2 = "";
queuedPriority2 = "";
}
}
#endif
unsigned long currentTime = millis();
// Sensor readings
@ -237,7 +283,7 @@ void loop() {
vibrationWindowTotal += vibrationTotalLow;
vibrationHistoryIdx = (vibrationHistoryIdx + 1) % VIBRATION_WINDOW_SIZE;
if (vibrationWindowTotal > VIBRATION_ACTIVE_THRESHOLD) {
if (vibrationWindowTotal > VIBRATION_ACTIVE_THRESHOLD && currentTime > WARMUP_DURATION) {
isVibrationActive = true;
} else {
isVibrationActive = false;
@ -250,7 +296,7 @@ void loop() {
if (lightHighStartTime == 0) {
lightHighStartTime = currentTime;
}
if (currentTime - lightHighStartTime >= VIBRATION_STATE_CHANGE_INTERVAL) {
if (currentTime - lightHighStartTime >= VIBRATION_STATE_CHANGE_INTERVAL && currentTime > WARMUP_DURATION) {
isLightActive = true;
}
lightLowStartTime = 0;
@ -284,11 +330,18 @@ void loop() {
}
#ifdef ENABLE_NOTIFICATIONS
if (!sendNotification(message, title, priority)) {
queuedMessage1 = message;
queuedTitle1 = title;
queuedPriority1 = priority;
}
#ifdef ENABLE_WIFI
NotificationMessage msg;
strncpy(msg.message, message.c_str(), sizeof(msg.message) - 1);
msg.message[sizeof(msg.message) - 1] = 0;
strncpy(msg.title, title.c_str(), sizeof(msg.title) - 1);
msg.title[sizeof(msg.title) - 1] = 0;
strncpy(msg.priority, priority.c_str(), sizeof(msg.priority) - 1);
msg.priority[sizeof(msg.priority) - 1] = 0;
xQueueSend(notificationQueue, &msg, 0);
#else
Serial.println("WiFi Disabled. Notification skipped: " + message);
#endif
#else
Serial.println("Notification (Disabled): " + title + " - " + message);
#endif
@ -310,11 +363,18 @@ void loop() {
}
#ifdef ENABLE_NOTIFICATIONS
if (!sendNotification(message, title, priority)) {
queuedMessage2 = message;
queuedTitle2 = title;
queuedPriority2 = priority;
}
#ifdef ENABLE_WIFI
NotificationMessage msg;
strncpy(msg.message, message.c_str(), sizeof(msg.message) - 1);
msg.message[sizeof(msg.message) - 1] = 0;
strncpy(msg.title, title.c_str(), sizeof(msg.title) - 1);
msg.title[sizeof(msg.title) - 1] = 0;
strncpy(msg.priority, priority.c_str(), sizeof(msg.priority) - 1);
msg.priority[sizeof(msg.priority) - 1] = 0;
xQueueSend(notificationQueue, &msg, 0);
#else
Serial.println("WiFi Disabled. Notification skipped: " + message);
#endif
#else
Serial.println("Notification (Disabled): " + title + " - " + message);
#endif
@ -333,38 +393,6 @@ void loop() {
#endif
}
bool sendNotification(String message, String title, String priority) {
#ifdef ENABLE_WIFI
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = "http://ntfy.sh/" + String(NTFY_TOPIC);
http.begin(url);
http.addHeader("Content-Type", "text/plain");
http.addHeader("Title", title);
http.addHeader("Priority", priority);
int httpResponseCode = http.POST(message);
http.end();
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
return true;
} else {
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
return false;
}
} else {
Serial.println("WiFi Disconnected. Cannot send notification.");
return false;
}
#else
Serial.println("WiFi Disabled. Notification skipped.");
return true;
#endif
}
void updateDisplay() {
#ifdef ENABLE_DISPLAY
unsigned long currentTime = millis();
@ -410,6 +438,38 @@ void updateDisplay() {
display.fillRect(rectX + 2, rectY2 + 2, step, rectHeight - 4, WHITE);
}
// Network Status Indicator
#ifdef ENABLE_WIFI
int r = 8;
int cx = SCREEN_WIDTH - r - 2;
int cy = SCREEN_HEIGHT / 2;
if (WiFi.status() != WL_CONNECTED) {
display.drawLine(cx - r, cy - r, cx + r, cy + r, WHITE);
display.drawLine(cx - r, cy + r, cx + r, cy - r, WHITE);
} else if (isNetworkActive) {
display.fillCircle(cx, cy, r, WHITE);
} else {
display.drawCircle(cx, cy, r, WHITE);
}
#ifdef ENABLE_NOTIFICATIONS
if (notificationQueue != NULL) {
int waiting = (int)uxQueueMessagesWaiting(notificationQueue);
int startY = cy + r + 2;
int h = SCREEN_HEIGHT - startY;
for (int i = 0; i < waiting; i++) {
int x = (cx - r) + (i * 2);
if (x < SCREEN_WIDTH && h > 0) display.drawFastVLine(x, startY, h, WHITE);
}
}
#endif
#endif
// Warmup Indicator
if (currentTime < WARMUP_DURATION) {
display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE);
}
display.display();
#endif
}