From 6a617ef3861627eb539684c6c7e6a4ec49562d9b Mon Sep 17 00:00:00 2001 From: Bota Date: Sat, 22 Nov 2025 15:22:35 +0100 Subject: [PATCH 1/4] Config and OTA update via WiFiManager Configs moved from SPIFFS to NVS to survive firmware update Added support for PlatformIO Fixed blink led on connection and when the relay is active --- .gitignore | 2 + bitcoinSwitch/100_config.cpp | 147 +++++++++++ bitcoinSwitch/100_config.h | 24 ++ bitcoinSwitch/100_config.ino | 186 -------------- bitcoinSwitch/101_serial_config.cpp | 120 +++++++++ bitcoinSwitch/101_serial_config.h | 14 ++ bitcoinSwitch/102_portal_config.cpp | 49 ++++ bitcoinSwitch/102_portal_config.h | 13 + bitcoinSwitch/200_wifi.cpp | 33 +++ bitcoinSwitch/200_wifi.h | 11 + bitcoinSwitch/200_wifi.ino | 26 -- bitcoinSwitch/{300_tft.ino => 300_tft.cpp} | 45 ++-- bitcoinSwitch/300_tft.h | 12 + ..._split_string.ino => 400_split_string.cpp} | 11 +- bitcoinSwitch/400_split_string.h | 5 + bitcoinSwitch/bitcoinSwitch.ino | 236 ++++++++---------- platformio.ini | 58 +++++ 17 files changed, 631 insertions(+), 361 deletions(-) create mode 100644 bitcoinSwitch/100_config.cpp create mode 100644 bitcoinSwitch/100_config.h delete mode 100644 bitcoinSwitch/100_config.ino create mode 100644 bitcoinSwitch/101_serial_config.cpp create mode 100644 bitcoinSwitch/101_serial_config.h create mode 100644 bitcoinSwitch/102_portal_config.cpp create mode 100644 bitcoinSwitch/102_portal_config.h create mode 100644 bitcoinSwitch/200_wifi.cpp create mode 100644 bitcoinSwitch/200_wifi.h delete mode 100644 bitcoinSwitch/200_wifi.ino rename bitcoinSwitch/{300_tft.ino => 300_tft.cpp} (80%) create mode 100644 bitcoinSwitch/300_tft.h rename bitcoinSwitch/{101_split_string.ino => 400_split_string.cpp} (79%) create mode 100644 bitcoinSwitch/400_split_string.h create mode 100644 platformio.ini diff --git a/.gitignore b/.gitignore index 0cbe9cd..3685678 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ installer/firmware dist build firmware.zip +bitcoinSwitch/config-*.h +bitcoinSwitch/bitcoinSwitch.ino.cpp diff --git a/bitcoinSwitch/100_config.cpp b/bitcoinSwitch/100_config.cpp new file mode 100644 index 0000000..8471b28 --- /dev/null +++ b/bitcoinSwitch/100_config.cpp @@ -0,0 +1,147 @@ +#include "100_config.h" + +#define VERSION "v1.0.1" + +#define BOOTUP_TIMEOUT 2 // seconds +#define CONFIG_NAME "config" + +String config_ssid; +String config_password; +String config_device_string; + +// uncomment if you dont want to use the configuration file +// #define HARDCODED + +// device specific configuration / defaults +#define CONFIG_SSID "mywifi" +#define CONFIG_PASSWORD "mypw" +#define CONFIG_DEVICE_STRING "" + +#ifdef HARDCODED +void setupConfig() +{ + Serial.println("Setting hardcoded values..."); + config_ssid = CONFIG_SSID; + Serial.println("SSID: " + config_ssid); + config_password = CONFIG_PASSWORD; + Serial.println("SSID password: " + config_password); + config_device_string = CONFIG_DEVICE_STRING; + Serial.println("Device string: " + config_device_string); + + showWelcomeScreen(); +} +#else +void setupConfig() +{ + // first give the installer a chance to delete configuration file + executeConfigBoot(); + + showWelcomeScreen(); + + if (!readConfig()) + { + // file does not exist, so we will enter endless config mode + Serial.println("Config file does not exist."); + executeSerialConfigForever(); + } +} + +bool readConfig() +{ + Preferences preferences; + preferences.begin(CONFIG_NAME, true); + + if (!preferences.isKey("ssid")) + { + config_ssid = CONFIG_SSID; + config_password = CONFIG_PASSWORD; + config_device_string = CONFIG_DEVICE_STRING; + + preferences.end(); + return false; + } + + config_ssid = preferences.getString("ssid", CONFIG_SSID); + config_password = preferences.getString("password", CONFIG_PASSWORD); + config_device_string = preferences.getString("device_string", CONFIG_DEVICE_STRING); + + preferences.end(); + return true; +} + +void executeConfigBoot() +{ + Serial.println("Entering boot mode. Waiting for " + String(BOOTUP_TIMEOUT) + " seconds."); + clearTFT(); + printTFT("BOOT MODE", 21, 21); + + int counter = (BOOTUP_TIMEOUT + 1) * 10; + while (counter-- > 0) + { +#ifdef TOUCH_PIN + int val = touchRead(TOUCH_PIN); + Serial.println("Touch read value: " + String(val)); + if (val < 60) + { + Serial.println("Touch detected"); + executePortalConfig(); + return; + } +#endif + +#ifdef BT1_PIN + pinMode(BT1_PIN, INPUT_PULLUP); + if (digitalRead(BT1_PIN) == LOW) + { + Serial.println("Button pressed"); + executePortalConfig(); + return; + } +#endif + + if (Serial.available() == 0) + { + delay(100); + continue; + } + Serial.println(); + // if we get serial data in the first seconds, we will enter config mode + counter = 0; + executeSerialConfigForever(); + return; + } + + Serial.println("Exiting boot mode."); +} + +void clearConfig() +{ + Preferences preferences; + preferences.begin(CONFIG_NAME, false); + preferences.clear(); + preferences.end(); + + readConfig(); +} + +void saveConfig() +{ + Preferences preferences; + preferences.begin(CONFIG_NAME, false); + + preferences.putString("ssid", config_ssid); + preferences.putString("password", config_password); + preferences.putString("device_string", config_device_string); + + preferences.end(); +} +#endif + +void showWelcomeScreen() +{ + Serial.print("Welcome to BitcoinSwitch!"); + Serial.println(" (" + String(VERSION) + ")"); + clearTFT(); + printTFT("BitcoinSwitch", 21, 21); + printTFT(String(VERSION), 21, 42); +} \ No newline at end of file diff --git a/bitcoinSwitch/100_config.h b/bitcoinSwitch/100_config.h new file mode 100644 index 0000000..15d7d39 --- /dev/null +++ b/bitcoinSwitch/100_config.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "300_tft.h" +#ifndef HARDCODED +#include +#include "101_serial_config.h" +#include "102_portal_config.h" +#endif + +extern String config_ssid; +extern String config_password; +extern String config_device_string; + +void showWelcomeScreen(); +void setupConfig(); + +#ifndef HARDCODED +bool readConfig(); +void executeConfigBoot(); +void clearConfig(); +void saveConfig(); +#endif \ No newline at end of file diff --git a/bitcoinSwitch/100_config.ino b/bitcoinSwitch/100_config.ino deleted file mode 100644 index 77b9196..0000000 --- a/bitcoinSwitch/100_config.ino +++ /dev/null @@ -1,186 +0,0 @@ -#define VERSION "v1.0.1" - -#define BOOTUP_TIMEOUT 2 // seconds -#define CONFIG_FILE "/elements.json" - -// uncomment if you dont want to use the configuration file -// #define HARDCODED - -// device specific configuration / defaults -#define CONFIG_SSID "mywifi" -#define CONFIG_PASSWORD "mypw" -#define CONFIG_DEVICE_STRING "" -#define CONFIG_THRESHOLD_INKEY "" // Invoice/read key of LNbits wallet -#define CONFIG_THRESHOLD_AMOUNT "" // In sats -#define CONFIG_THRESHOLD_PIN "" // GPIO pin -#define CONFIG_THRESHOLD_TIME "" // Time to turn pin on - -#ifdef HARDCODED -void setupConfig(){ - Serial.println("Setting hardcoded values..."); - config_ssid = CONFIG_SSID; - Serial.println("SSID: " + config_ssid); - config_password = CONFIG_PASSWORD; - Serial.println("SSID password: " + config_password); - config_device_string = CONFIG_DEVICE_STRING; - Serial.println("Device string: " + config_device_string); - config_threshold_inkey = CONFIG_THRESHOLD_INKEY; - Serial.println("Threshold inkey: " + config_threshold_inkey); - String threshold_amount = String(CONFIG_THRESHOLD_AMOUNT); - if (threshold_amount == "") { - config_threshold_amount = 0; - } else { - config_threshold_amount = threshold_amount.toInt(); - } - Serial.println("Threshold amount: " + String(config_threshold_amount)); - String led_pin = String(CONFIG_THRESHOLD_PIN); - config_threshold_pin = led_pin.toInt(); - Serial.println("Threshold pin: " + String(config_threshold_pin)); - String led_time = String(CONFIG_THRESHOLD_TIME); - config_threshold_time = led_time.toInt(); - Serial.println("Threshold time: " + String(config_threshold_time)); -} -#else -#include -#include - -void setupConfig(){ - SPIFFS.begin(true); - // first give the installer a chance to delete configuration file - executeConfigBoot(); - String fileContent = readConfig(); - // file does not exist, so we will enter endless config mode - if (fileContent == "") { - Serial.println("Config file does not exist."); - executeConfigForever(); - } - JsonDocument doc; - DeserializationError error = deserializeJson(doc, fileContent); - if(error){ - Serial.print("deserializeJson() failed: "); - Serial.println(error.c_str()); - } - - config_ssid = getJsonValue(doc, "config_ssid", CONFIG_SSID); - config_password = getJsonValue(doc, "config_password", CONFIG_PASSWORD); - config_device_string = getJsonValue(doc, "config_device_string", CONFIG_DEVICE_STRING); - config_threshold_inkey = getJsonValue(doc, "config_threshold_inkey", CONFIG_THRESHOLD_INKEY); - String threshold_amount = getJsonValue(doc, "config_threshold_amount", CONFIG_THRESHOLD_AMOUNT); - if (threshold_amount == "") { - config_threshold_amount = 0; - } else { - config_threshold_amount = threshold_amount.toInt(); - } - String led_pin = getJsonValue(doc, "config_threshold_pin", CONFIG_THRESHOLD_PIN); - config_threshold_pin = led_pin.toInt(); - Serial.println("Threshold pin: " + String(config_threshold_pin)); - String led_time = getJsonValue(doc, "config_threshold_time", CONFIG_THRESHOLD_TIME); - config_threshold_time = led_time.toInt(); - Serial.println("Threshold time: " + String(config_threshold_time)); -} - -String readConfig() { - File paramFile = SPIFFS.open(CONFIG_FILE, FILE_READ); - if (!paramFile) { - return ""; - } - String fileContent = paramFile.readString(); - if (fileContent == "") { - return ""; - } - paramFile.close(); - return fileContent; -} - -String getJsonValue(JsonDocument &doc, const char* name, String defaultValue) -{ - String value = defaultValue; - for (JsonObject elem : doc.as()) { - if (strcmp(elem["name"], name) == 0) { - value = elem["value"].as(); - Serial.println(String(name) + ": " + value); - return value; - } - } - Serial.println(String(name) + " (using default): " + value); - return defaultValue; -} - -void executeConfigBoot() { - Serial.println("Entering boot mode. Waiting for " + String(BOOTUP_TIMEOUT) + " seconds."); - clearTFT(); - printTFT("BOOT MODE", 21, 21); - int counter = BOOTUP_TIMEOUT + 1; - while (counter-- > 0) { - if (Serial.available() == 0) { - delay(1000); - continue; - } - Serial.println(); - // if we get serial data in the first 5 seconds, we will enter config mode - counter = 0; - executeConfigForever(); - } - Serial.println("Exiting boot mode."); - Serial.print("Welcome to BitcoinSwitch!"); - Serial.println(" (" + String(VERSION) + ")"); - clearTFT(); - printTFT("BitcoinSwitch", 21, 21); - printTFT(String(VERSION), 21, 42); -} - -void executeConfigForever() { - Serial.println("Entering config mode. until we receive /config-done."); - clearTFT(); - printTFT("CONFIG", 21, 21); - bool done = false; - while (true) { - done = executeConfig(); - if (done) { - Serial.println("Exiting config mode."); - return; - } - } -} - -bool executeConfig() { - if (Serial.available() == 0) return false; - String data = Serial.readStringUntil('\n'); - Serial.println("received serial data: " + data); - if (data == "/config-done") { - delay(1000); - return true; - } - if (data == "/file-remove") { - SPIFFS.remove(CONFIG_FILE); - } - if (data.startsWith("/file-append")) { - File file = SPIFFS.open(CONFIG_FILE, FILE_APPEND); - if (!file) { - file = SPIFFS.open(CONFIG_FILE, FILE_WRITE); - } - if (!file) { - Serial.println("Failed to open file for writing."); - } - if (file) { - int pos = data.indexOf(" "); - String jsondata = data.substring(pos + 1); - file.println(jsondata); - file.close(); - } - } - if (data.startsWith("/file-read")) { - File file = SPIFFS.open(CONFIG_FILE, "r"); - if (file) { - while (file.available()) { - String line = file.readStringUntil('\n'); - Serial.println("/file-send " + line); - } - file.close(); - Serial.println("/file-done"); - } - return false; - } - return false; -} -#endif diff --git a/bitcoinSwitch/101_serial_config.cpp b/bitcoinSwitch/101_serial_config.cpp new file mode 100644 index 0000000..d5eee82 --- /dev/null +++ b/bitcoinSwitch/101_serial_config.cpp @@ -0,0 +1,120 @@ +#include "101_serial_config.h" + +String fileContent = ""; + +void executeSerialConfigForever() +{ + Serial.println("Entering config mode. until we receive /config-done."); + clearTFT(); + printTFT("SERIAL CONFIG", 21, 21); + bool done = false; + while (true) + { + done = executeSerialConfig(); + if (done) + { + Serial.println("Exiting config mode."); + return; + } + } +} + +bool executeSerialConfig() +{ + if (Serial.available() == 0) + return false; + String data = Serial.readStringUntil('\n'); + Serial.println("received serial data: " + data); + if (data == "/config-done") + { + if (fileContent.length() > 0) + saveConfigFromFile(); + + delay(1000); + return true; + } + if (data == "/file-remove") + { + clearConfig(); + fileContent = ""; + } + if (data.startsWith("/file-append")) + { + int pos = data.indexOf(" "); + String jsondata = data.substring(pos + 1); + fileContent += jsondata; + } + if (data.startsWith("/file-read")) + { + fileContent = readConfigToFile(); + + int start = 0; + while (start < fileContent.length()) + { + int end = fileContent.indexOf('\n', start); + if (end == -1) + end = fileContent.length(); + String line = fileContent.substring(start, end); + Serial.println("/file-send " + line); + start = end + 1; + } + + fileContent = ""; + Serial.println("/file-done"); + return false; + } + return false; +} + +String readConfigToFile() +{ + readConfig(); + + String content = ""; + + JsonDocument doc; + JsonArray arr = doc.to(); + + JsonObject ssidObj = arr.add(); + ssidObj["name"] = "config_ssid"; + ssidObj["value"] = config_ssid; + + JsonObject pwObj = arr.add(); + pwObj["name"] = "config_password"; + pwObj["value"] = config_password; + + JsonObject devStrObj = arr.add(); + devStrObj["name"] = "config_device_string"; + devStrObj["value"] = config_device_string; + + serializeJsonPretty(doc, content); + content += "\n"; + return content; +} + +void saveConfigFromFile() +{ + JsonDocument doc; + DeserializationError error = deserializeJson(doc, fileContent); + if (error) + { + Serial.print("deserializeJson() failed: "); + Serial.println(error.c_str()); + } + + for (JsonObject elem : doc.as()) + { + String key = elem["name"].as(); + + if (key == "config_ssid") + config_ssid = elem["value"].as(); + else if (key == "config_password") + config_password = elem["value"].as(); + else if (key == "config_device_string") + config_device_string = elem["value"].as(); + else + Serial.println("Unknown config key: " + key); + } + + saveConfig(); +} diff --git a/bitcoinSwitch/101_serial_config.h b/bitcoinSwitch/101_serial_config.h new file mode 100644 index 0000000..4e5afed --- /dev/null +++ b/bitcoinSwitch/101_serial_config.h @@ -0,0 +1,14 @@ +#pragma once + +#ifndef HARDCODED +#include +#include +#include "100_config.h" +#include "300_tft.h" + +void executeSerialConfigForever(); +bool executeSerialConfig(); +String readConfigToFile(); +void saveConfigFromFile(); +void executePortalConfig(); +#endif \ No newline at end of file diff --git a/bitcoinSwitch/102_portal_config.cpp b/bitcoinSwitch/102_portal_config.cpp new file mode 100644 index 0000000..87669d0 --- /dev/null +++ b/bitcoinSwitch/102_portal_config.cpp @@ -0,0 +1,49 @@ +#include "102_portal_config.h" + +#define AP_PASSWORD "111222333" + +void executePortalConfig() +{ + String apName = "BitcoinSwitch-" + String(WIFI_getChipId()); + + Serial.println("Entering portal config mode. Connect to AP: " + apName); + clearTFT(); + printTFT("PORTAL CONFIG", 21, 21); + printTFT("Connect to AP", 21, 51); + printTFT(apName, 21, 81); + + WiFiManager wm; + wm.setTitle("Bitcoin Switch"); + wm.setBreakAfterConfig(true); + wm.setParamsPage(true); + wm.setShowInfoUpdate(true); + wm.setDarkMode(true); + wm.setConfigPortalTimeout(0); + wm.setConnectTimeout(15); + + readConfig(); + WiFiManagerParameter device_string_field("config_device_string", "Device string", config_device_string.c_str(), 200, "placeholder=\"wss://\""); + wm.addParameter(&device_string_field); + wm.setSaveConfigCallback([&wm]() + { saveWiFi(wm); }); + wm.setSaveParamsCallback([&device_string_field]() + { saveParams(device_string_field); }); + + Serial.println("Starting config portal..."); + wm.startConfigPortal(apName.c_str(), AP_PASSWORD); +} + +void saveWiFi(WiFiManager &wm) +{ + Serial.println("Save WiFi settings"); + config_ssid = wm.getWiFiSSID(); + config_password = wm.getWiFiPass(); + saveConfig(); +} + +void saveParams(WiFiManagerParameter device_string_field) +{ + Serial.println("Save device string"); + config_device_string = String(device_string_field.getValue()); + saveConfig(); +} \ No newline at end of file diff --git a/bitcoinSwitch/102_portal_config.h b/bitcoinSwitch/102_portal_config.h new file mode 100644 index 0000000..7447609 --- /dev/null +++ b/bitcoinSwitch/102_portal_config.h @@ -0,0 +1,13 @@ +#pragma once + +#ifndef HARDCODED +#include +#include +#include +#include "100_config.h" +#include "300_tft.h" + +void executePortalConfig(); +void saveWiFi(WiFiManager &wm); +void saveParams(WiFiManagerParameter device_string_field); +#endif \ No newline at end of file diff --git a/bitcoinSwitch/200_wifi.cpp b/bitcoinSwitch/200_wifi.cpp new file mode 100644 index 0000000..4f35ce3 --- /dev/null +++ b/bitcoinSwitch/200_wifi.cpp @@ -0,0 +1,33 @@ +#include "200_wifi.h" + +void setupWifi() +{ + WiFi.begin(config_ssid.c_str(), config_password.c_str()); + Serial.print("Connecting to WiFi."); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(500); +#ifdef LED_BUILTIN + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); +#endif + } + #ifdef LED_BUILTIN + digitalWrite(LED_BUILTIN, !LED_ON); + #endif + + Serial.println(); + Serial.println("WiFi connection etablished!"); + printHome(true, false, false); +} + +void loopWifi() +{ + while (WiFi.status() != WL_CONNECTED) + { + Serial.println("WiFi disconnected!"); + printHome(false, false, false); + delay(500); + setupWifi(); + } +} diff --git a/bitcoinSwitch/200_wifi.h b/bitcoinSwitch/200_wifi.h new file mode 100644 index 0000000..480a627 --- /dev/null +++ b/bitcoinSwitch/200_wifi.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include + +#include "100_config.h" +#include "300_tft.h" + +void setupWifi(); +void loopWifi(); \ No newline at end of file diff --git a/bitcoinSwitch/200_wifi.ino b/bitcoinSwitch/200_wifi.ino deleted file mode 100644 index 4d63b71..0000000 --- a/bitcoinSwitch/200_wifi.ino +++ /dev/null @@ -1,26 +0,0 @@ -#include - -void setupWifi() { - WiFi.begin(config_ssid.c_str(), config_password.c_str()); - Serial.print("Connecting to WiFi."); - while (WiFi.status() != WL_CONNECTED) { - Serial.print("."); - delay(500); - digitalWrite(2, HIGH); - Serial.print("."); - delay(500); - digitalWrite(2, LOW); - } - Serial.println(); - Serial.println("WiFi connection etablished!"); - printHome(true, false, false); -} - -void loopWifi() { - while (WiFi.status() != WL_CONNECTED) { - Serial.println("WiFi disconnected!"); - printHome(false, false, false); - delay(500); - setupWifi(); - } -} diff --git a/bitcoinSwitch/300_tft.ino b/bitcoinSwitch/300_tft.cpp similarity index 80% rename from bitcoinSwitch/300_tft.ino rename to bitcoinSwitch/300_tft.cpp index 69d5e68..cc6697e 100644 --- a/bitcoinSwitch/300_tft.ino +++ b/bitcoinSwitch/300_tft.cpp @@ -1,7 +1,8 @@ +#include "300_tft.h" #ifdef TFT -#include TFT_eSPI tft = TFT_eSPI(TFT_WIDTH, TFT_HEIGHT); -void setupTFT() { +void setupTFT() +{ tft.init(); Serial.println("TFT: " + String(TFT_WIDTH) + "x" + String(TFT_HEIGHT)); Serial.println("TFT pin MISO: " + String(TFT_MISO)); @@ -15,54 +16,60 @@ void setupTFT() { tft.invertDisplay(true); tft.fillScreen(TFT_BLACK); } -void printTFT(String message, int x, int y) { +void printTFT(String message, int x, int y) +{ tft.setTextSize(2); tft.setTextColor(TFT_WHITE); tft.setCursor(x, y); tft.println(message); } -void printHome(bool wifi, bool ws, bool ping) { - if (ping) { +void printHome(bool wifi, bool ws, bool ping) +{ + if (ping) tft.fillScreen(TFT_BLUE); - } else { + else tft.fillScreen(TFT_BLACK); - } tft.setTextSize(2); tft.setTextColor(TFT_YELLOW); tft.setCursor(21, 21); tft.println("BitcoinSwitch"); tft.setTextSize(2); tft.setTextColor(TFT_WHITE); - if (wifi) { + if (wifi) + { tft.setCursor(21, 69); tft.println("WiFi connected!"); - } else { + } + else + { tft.setCursor(21, 69); tft.setTextColor(TFT_RED); tft.println("No WiFi!"); } tft.setCursor(21, 95); - if (ws) { - if (ping) { + if (ws) + { + if (ping) + { tft.setTextColor(TFT_WHITE); tft.println("WS ping!"); - } else { + } + else + { tft.setTextColor(TFT_GREEN); tft.println("WS connected!"); } } - else { + else + { tft.setTextColor(TFT_RED); tft.println("No WS!"); } } -void clearTFT() { - tft.fillScreen(TFT_BLACK); -} -void flashTFT() { - tft.fillScreen(TFT_GREEN); -} +void clearTFT() { tft.fillScreen(TFT_BLACK); } +void flashTFT() { tft.fillScreen(TFT_GREEN); } #else +void setupTFT() {} void printTFT(String message, int x, int y) {} void printHome(bool wifi, bool ws, bool ping) {} void clearTFT() {} diff --git a/bitcoinSwitch/300_tft.h b/bitcoinSwitch/300_tft.h new file mode 100644 index 0000000..59ccb16 --- /dev/null +++ b/bitcoinSwitch/300_tft.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#ifdef TFT +#include +#endif + +void setupTFT(); +void printTFT(String message, int x, int y); +void printHome(bool wifi, bool ws, bool ping); +void clearTFT(); +void flashTFT(); \ No newline at end of file diff --git a/bitcoinSwitch/101_split_string.ino b/bitcoinSwitch/400_split_string.cpp similarity index 79% rename from bitcoinSwitch/101_split_string.ino rename to bitcoinSwitch/400_split_string.cpp index ec16d0a..085d71b 100644 --- a/bitcoinSwitch/101_split_string.ino +++ b/bitcoinSwitch/400_split_string.cpp @@ -1,13 +1,18 @@ -int splitString(String input, char delimiter, String parts[], int maxParts) { +#include "400_split_string.h" + +int splitString(String input, char delimiter, String parts[], int maxParts) +{ int partIndex = 0; int startIndex = 0; int delimIndex; - while ((delimIndex = input.indexOf(delimiter, startIndex)) != -1 && partIndex < maxParts) { + while ((delimIndex = input.indexOf(delimiter, startIndex)) != -1 && partIndex < maxParts) + { parts[partIndex++] = input.substring(startIndex, delimIndex); startIndex = delimIndex + 1; } // Add the last part - if (partIndex < maxParts) { + if (partIndex < maxParts) + { parts[partIndex++] = input.substring(startIndex); } return partIndex; // number of parts found diff --git a/bitcoinSwitch/400_split_string.h b/bitcoinSwitch/400_split_string.h new file mode 100644 index 0000000..b626cdf --- /dev/null +++ b/bitcoinSwitch/400_split_string.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +int splitString(String input, char delimiter, String parts[], int maxParts); \ No newline at end of file diff --git a/bitcoinSwitch/bitcoinSwitch.ino b/bitcoinSwitch/bitcoinSwitch.ino index d48778b..534da9b 100644 --- a/bitcoinSwitch/bitcoinSwitch.ino +++ b/bitcoinSwitch/bitcoinSwitch.ino @@ -1,67 +1,68 @@ -#include #include -String config_ssid; -String config_password; -String config_device_string; -String config_threshold_inkey; -int config_threshold_amount; -int config_threshold_pin; -int config_threshold_time; +#include "100_config.h" +#include "400_split_string.h" +#include "200_wifi.h" +#include "300_tft.h" String apiUrl = "/api/v1/ws/"; WebSocketsClient webSocket; -void setup() { - Serial.begin(115200); - // Serial.setDebugOutput(true); - #ifdef TFT - setupTFT(); - printHome(false, false, false); - #endif - setupConfig(); - setupWifi(); - - pinMode(2, OUTPUT); // To blink on board LED - - if (config_device_string == "") { - Serial.println("No device string configured!"); - printTFT("No device string!", 21, 95); - return; - } - - if (!config_device_string.startsWith("wss://")) { - Serial.println("Device string does not start with wss://"); - printTFT("no wss://!", 21, 95); - return; - } - - String cleaned_device_string = config_device_string.substring(6); // Remove wss:// - String host = cleaned_device_string.substring(0, cleaned_device_string.indexOf('/')); - String apiPath = cleaned_device_string.substring(cleaned_device_string.indexOf('/')); - Serial.println("Websocket host: " + host); - Serial.println("Websocket API Path: " + apiPath); - - if (config_threshold_amount != 0) { // Use in threshold mode - Serial.println("Using THRESHOLD mode"); - Serial.println("Connecting to websocket: " + host + apiUrl + config_threshold_inkey); - webSocket.beginSSL(host, 443, apiUrl + config_threshold_inkey); - } else { // Use in normal mode - Serial.println("Using NORMAL mode"); - Serial.println("Connecting to websocket: " + host + apiPath); - webSocket.beginSSL(host, 443, apiPath); - } - webSocket.onEvent(webSocketEvent); - webSocket.setReconnectInterval(1000); +void setup() +{ + Serial.begin(115200); +// Serial.setDebugOutput(true); +#ifdef TFT + setupTFT(); + printHome(false, false, false); +#endif + +#ifdef LED_BUILTIN + pinMode(LED_BUILTIN, OUTPUT); // To blink on board LED + digitalWrite(LED_BUILTIN, !LED_ON); +#endif + + setupConfig(); + setupWifi(); + + if (config_device_string == "") + { + Serial.println("No device string configured!"); + printTFT("No device string!", 21, 95); + return; + } + + if (!config_device_string.startsWith("wss://")) + { + Serial.println("Device string does not start with wss://"); + printTFT("no wss://!", 21, 95); + return; + } + + String cleaned_device_string = config_device_string.substring(6); // Remove wss:// + String host = cleaned_device_string.substring(0, cleaned_device_string.indexOf('/')); + String apiPath = cleaned_device_string.substring(cleaned_device_string.indexOf('/')); + Serial.println("Websocket host: " + host); + Serial.println("Websocket API Path: " + apiPath); + + // Use in normal mode + Serial.println("Using NORMAL mode"); + Serial.println("Connecting to websocket: " + host + apiPath); + webSocket.beginSSL(host, 443, apiPath); + + webSocket.onEvent(webSocketEvent); + webSocket.setReconnectInterval(1000); } -void loop() { - loopWifi(); - webSocket.loop(); +void loop() +{ + loopWifi(); + webSocket.loop(); } -void executePayment(uint8_t *payload) { +void executePayment(uint8_t *payload) +{ printTFT("Payment received!", 21, 15); flashTFT(); @@ -77,92 +78,73 @@ void executePayment(uint8_t *payload) { printTFT("Time: " + String(time), 21, 55); String comment = ""; - if (numParts == 3) { - comment = parts[2]; - Serial.println("[WebSocket] received comment: " + comment); - printTFT("Comment: " + comment, 21, 75); + if (numParts == 3) + { + comment = parts[2]; + Serial.println("[WebSocket] received comment: " + comment); + printTFT("Comment: " + comment, 21, 75); } Serial.println("[WebSocket] received pin: " + String(pin) + ", duration: " + String(time)); - if (config_threshold_amount != 0) { - // If in threshold mode we check the "balance" pushed by the - // websocket and use the pin/time preset - // executeThreshold(); - return; // Threshold mode not implemented yet - } - // the magic happens here pinMode(pin, OUTPUT); digitalWrite(pin, HIGH); +#ifdef LED_BUILTIN + digitalWrite(LED_BUILTIN, LED_ON); +#endif delay(time); digitalWrite(pin, LOW); +#ifdef LED_BUILTIN + digitalWrite(LED_BUILTIN, !LED_ON); +#endif printHome(true, true, false); - } -// long thresholdSum = 0; -// void executeThreshold() { -// StaticJsonDocument<1900> doc; -// DeserializationError error = deserializeJson(doc, payloadStr); -// if (error) { -// Serial.print("deserializeJson() failed: "); -// Serial.println(error.c_str()); -// return; -// } -// thresholdSum = thresholdSum + doc["payment"]["amount"].toInt(); -// Serial.println("thresholdSum: " + String(thresholdSum)); -// if (thresholdSum >= (config_threshold_amount * 1000)) { -// pinMode(config_threshold_pin, OUTPUT); -// digitalWrite(config_threshold_pin, HIGH); -// delay(config_threshold_time); -// digitalWrite(config_threshold_pin, LOW); -// thresholdSum = 0; -// } -// } - //////////////////WEBSOCKET/////////////////// bool ping_toggle = false; -void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) { - switch (type) { - case WStype_ERROR: - Serial.printf("[WebSocket] Error: %s\n", payload); - printHome(true, false, false); - break; - case WStype_DISCONNECTED: - Serial.println("[WebSocket] Disconnected!\n"); - printHome(true, false, false); - break; - case WStype_CONNECTED: - Serial.printf("[WebSocket] Connected to url: %s\n", payload); - // send message to server when Connected - webSocket.sendTXT("Connected"); - printHome(true, true, false); - break; - case WStype_TEXT: - executePayment(payload); - break; - case WStype_BIN: - Serial.printf("[WebSocket] Received binary data: %s\n", payload); - break; - case WStype_FRAGMENT_TEXT_START: - break; - case WStype_FRAGMENT_BIN_START: - break; - case WStype_FRAGMENT: - break; - case WStype_FRAGMENT_FIN: - break; - case WStype_PING: - Serial.printf("[WebSocket] Ping!\n"); - ping_toggle = !ping_toggle; - printHome(true, true, ping_toggle); - // pong will be sent automatically - break; - case WStype_PONG: - // is not used - Serial.printf("[WebSocket] Pong!\n"); - printHome(true, true, true); - break; - } +void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) +{ + switch (type) + { + case WStype_ERROR: + Serial.printf("[WebSocket] Error: %s\n", payload); + printHome(true, false, false); + break; + case WStype_DISCONNECTED: + Serial.println("[WebSocket] Disconnected!\n"); + printHome(true, false, false); + break; + case WStype_CONNECTED: + Serial.printf("[WebSocket] Connected to url: %s\n", payload); + // send message to server when Connected + webSocket.sendTXT("Connected"); + printHome(true, true, false); + break; + case WStype_TEXT: + executePayment(payload); + break; + case WStype_BIN: + Serial.printf("[WebSocket] Received binary data: %s\n", payload); + break; + case WStype_FRAGMENT_TEXT_START: + break; + case WStype_FRAGMENT_BIN_START: + break; + case WStype_FRAGMENT: + break; + case WStype_FRAGMENT_FIN: + break; + case WStype_PING: + Serial.printf("[WebSocket] Ping!\n"); + ping_toggle = !ping_toggle; + printHome(true, true, ping_toggle); + // pong will be sent automatically + break; + case WStype_PONG: + // is not used + Serial.printf("[WebSocket] Pong!\n"); + printHome(true, true, true); + break; + } } diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..3a13bfb --- /dev/null +++ b/platformio.ini @@ -0,0 +1,58 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +src_dir = bitcoinSwitch +;default_envs = esp-wrover-kit + +[env] +platform = espressif32 +framework = arduino +monitor_speed = 115200 +board_build.partitions = min_spiffs.csv +lib_deps = + WebSockets@^2.6.1 + ArduinoJson@^7.3.1 + WiFiManager + +[env:esp32dev] +board = esp32dev +build_flags = + -D TOUCH_PIN=T9 ; GPIO32 + -D LED_BUILTIN=22 + -D LED_ON=LOW + +[env:lilygo-t-display] +board = lilygo-t-display +lib_deps = + ${env.lib_deps} + TFT_eSPI +build_flags = + -D TOUCH_PIN=T5 ; GPIO12 + -D BT1_PIN=35 + -D TFT + -D USER_SETUP_LOADED=1 + -include $PROJECT_LIBDEPS_DIR/$PIOENV/TFT_eSPI/User_Setups/Setup25_TTGO_T_Display.h + -D TOUCH_CS=-1 + +[env:esp-wrover-kit] +board = esp-wrover-kit +build_flags = + -D LED_BUILTIN=2 + -D LED_ON=LOW + +[env:esp32-s3] +board = esp32-s3-devkitc-1 + +[env:esp32-c3] +board = esp32-c3-devkitm-1 + +[env:esp32-s2] +board = esp32-s2-saola-1 \ No newline at end of file From 7159aaf06b3ba6c37c71e644b0d2a18257e6adb0 Mon Sep 17 00:00:00 2001 From: Bota Date: Mon, 24 Nov 2025 00:38:55 +0100 Subject: [PATCH 2/4] hardcoded fix --- bitcoinSwitch/100_config.cpp | 13 ------------- bitcoinSwitch/100_config.h | 13 +++++++++++++ bitcoinSwitch/101_serial_config.cpp | 2 ++ bitcoinSwitch/102_portal_config.cpp | 4 +++- bitcoinSwitch/200_wifi.h | 1 - 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/bitcoinSwitch/100_config.cpp b/bitcoinSwitch/100_config.cpp index 8471b28..a36d0e0 100644 --- a/bitcoinSwitch/100_config.cpp +++ b/bitcoinSwitch/100_config.cpp @@ -1,22 +1,9 @@ #include "100_config.h" -#define VERSION "v1.0.1" - -#define BOOTUP_TIMEOUT 2 // seconds -#define CONFIG_NAME "config" - String config_ssid; String config_password; String config_device_string; -// uncomment if you dont want to use the configuration file -// #define HARDCODED - -// device specific configuration / defaults -#define CONFIG_SSID "mywifi" -#define CONFIG_PASSWORD "mypw" -#define CONFIG_DEVICE_STRING "" - #ifdef HARDCODED void setupConfig() { diff --git a/bitcoinSwitch/100_config.h b/bitcoinSwitch/100_config.h index 15d7d39..cbb35b3 100644 --- a/bitcoinSwitch/100_config.h +++ b/bitcoinSwitch/100_config.h @@ -1,5 +1,18 @@ #pragma once +#define VERSION "v1.0.1" + +#define BOOTUP_TIMEOUT 2 // seconds +#define CONFIG_NAME "config" + +// uncomment if you dont want to use the configuration file +// #define HARDCODED + +// device specific configuration / defaults +#define CONFIG_SSID "mywifi" +#define CONFIG_PASSWORD "mypw" +#define CONFIG_DEVICE_STRING "" + #include #include "300_tft.h" diff --git a/bitcoinSwitch/101_serial_config.cpp b/bitcoinSwitch/101_serial_config.cpp index d5eee82..b067132 100644 --- a/bitcoinSwitch/101_serial_config.cpp +++ b/bitcoinSwitch/101_serial_config.cpp @@ -1,5 +1,6 @@ #include "101_serial_config.h" +#ifndef HARDCODED String fileContent = ""; void executeSerialConfigForever() @@ -118,3 +119,4 @@ void saveConfigFromFile() saveConfig(); } +#endif \ No newline at end of file diff --git a/bitcoinSwitch/102_portal_config.cpp b/bitcoinSwitch/102_portal_config.cpp index 87669d0..762053a 100644 --- a/bitcoinSwitch/102_portal_config.cpp +++ b/bitcoinSwitch/102_portal_config.cpp @@ -1,5 +1,6 @@ #include "102_portal_config.h" +#ifndef HARDCODED #define AP_PASSWORD "111222333" void executePortalConfig() @@ -46,4 +47,5 @@ void saveParams(WiFiManagerParameter device_string_field) Serial.println("Save device string"); config_device_string = String(device_string_field.getValue()); saveConfig(); -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/bitcoinSwitch/200_wifi.h b/bitcoinSwitch/200_wifi.h index 480a627..75fe0df 100644 --- a/bitcoinSwitch/200_wifi.h +++ b/bitcoinSwitch/200_wifi.h @@ -2,7 +2,6 @@ #include #include -#include #include "100_config.h" #include "300_tft.h" From aa19d45e68b1e6b7a3ad13f9e2f443c195157785 Mon Sep 17 00:00:00 2001 From: Bota Date: Mon, 8 Dec 2025 16:39:48 +0100 Subject: [PATCH 3/4] refactor web socket --- bitcoinSwitch/200_wifi.cpp | 6 +- bitcoinSwitch/201_web_socket.cpp | 126 +++++++++++++++++++++++++++++ bitcoinSwitch/201_web_socket.h | 13 +++ bitcoinSwitch/bitcoinSwitch.ino | 132 ++----------------------------- platformio.ini | 15 +++- 5 files changed, 160 insertions(+), 132 deletions(-) create mode 100644 bitcoinSwitch/201_web_socket.cpp create mode 100644 bitcoinSwitch/201_web_socket.h diff --git a/bitcoinSwitch/200_wifi.cpp b/bitcoinSwitch/200_wifi.cpp index 4f35ce3..7df2879 100644 --- a/bitcoinSwitch/200_wifi.cpp +++ b/bitcoinSwitch/200_wifi.cpp @@ -12,9 +12,9 @@ void setupWifi() digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); #endif } - #ifdef LED_BUILTIN - digitalWrite(LED_BUILTIN, !LED_ON); - #endif +#if defined(LED_BUILTIN) && defined(LED_ON) + digitalWrite(LED_BUILTIN, !LED_ON); +#endif Serial.println(); Serial.println("WiFi connection etablished!"); diff --git a/bitcoinSwitch/201_web_socket.cpp b/bitcoinSwitch/201_web_socket.cpp new file mode 100644 index 0000000..8a7bf43 --- /dev/null +++ b/bitcoinSwitch/201_web_socket.cpp @@ -0,0 +1,126 @@ +#include "201_web_socket.h" + +WebSocketsClient webSocket; +bool ping_toggle = false; + +void setupWebSocket() +{ + if (config_device_string == "") + { + Serial.println("No device string configured!"); + printTFT("No device string!", 21, 95); + return; + } + + if (!config_device_string.startsWith("wss://")) + { + Serial.println("Device string does not start with wss://"); + printTFT("no wss://!", 21, 95); + return; + } + + String cleaned_device_string = config_device_string.substring(6); // Remove wss:// + String host = cleaned_device_string.substring(0, cleaned_device_string.indexOf('/')); + String apiPath = cleaned_device_string.substring(cleaned_device_string.indexOf('/')); + Serial.println("Websocket host: " + host); + Serial.println("Websocket API Path: " + apiPath); + + // Use in normal mode + Serial.println("Using NORMAL mode"); + Serial.println("Connecting to websocket: " + host + apiPath); + webSocket.beginSSL(host, 443, apiPath); + + webSocket.onEvent(webSocketEvent); + webSocket.setReconnectInterval(1000); +} + +void loopWebSocket() +{ + webSocket.loop(); +} + +void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) +{ + switch (type) + { + case WStype_ERROR: + Serial.printf("[WebSocket] Error: %s\n", payload); + printHome(true, false, false); + break; + case WStype_DISCONNECTED: + Serial.println("[WebSocket] Disconnected!\n"); + printHome(true, false, false); + break; + case WStype_CONNECTED: + Serial.printf("[WebSocket] Connected to url: %s\n", payload); + // send message to server when Connected + webSocket.sendTXT("Connected"); + printHome(true, true, false); + break; + case WStype_TEXT: + executePayment(payload); + break; + case WStype_BIN: + Serial.printf("[WebSocket] Received binary data: %s\n", payload); + break; + case WStype_FRAGMENT_TEXT_START: + break; + case WStype_FRAGMENT_BIN_START: + break; + case WStype_FRAGMENT: + break; + case WStype_FRAGMENT_FIN: + break; + case WStype_PING: + Serial.printf("[WebSocket] Ping!\n"); + ping_toggle = !ping_toggle; + printHome(true, true, ping_toggle); + // pong will be sent automatically + break; + case WStype_PONG: + // is not used + Serial.printf("[WebSocket] Pong!\n"); + printHome(true, true, true); + break; + } +} + +void executePayment(uint8_t *payload) +{ + printTFT("Payment received!", 21, 15); + flashTFT(); + + String parts[3]; // pin, time, comment + // format: {pin-time-comment} where comment is optional + String payloadStr = String((char *)payload); + int numParts = splitString(payloadStr, '-', parts, 3); + + int pin = parts[0].toInt(); + printTFT("Pin: " + String(pin), 21, 35); + + int time = parts[1].toInt(); + printTFT("Time: " + String(time), 21, 55); + + String comment = ""; + if (numParts == 3) + { + comment = parts[2]; + Serial.println("[WebSocket] received comment: " + comment); + printTFT("Comment: " + comment, 21, 75); + } + Serial.println("[WebSocket] received pin: " + String(pin) + ", duration: " + String(time)); + + // the magic happens here + pinMode(pin, OUTPUT); + digitalWrite(pin, HIGH); +#if defined(LED_BUILTIN) && defined(LED_ON) + digitalWrite(LED_BUILTIN, LED_ON); +#endif + delay(time); + digitalWrite(pin, LOW); +#if defined(LED_BUILTIN) && defined(LED_ON) + digitalWrite(LED_BUILTIN, !LED_ON); +#endif + + printHome(true, true, false); +} \ No newline at end of file diff --git a/bitcoinSwitch/201_web_socket.h b/bitcoinSwitch/201_web_socket.h new file mode 100644 index 0000000..f0c9eba --- /dev/null +++ b/bitcoinSwitch/201_web_socket.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +#include "100_config.h" +#include "300_tft.h" +#include "400_split_string.h" + +void setupWebSocket(); +void loopWebSocket(); +void webSocketEvent(WStype_t type, uint8_t *payload, size_t length); +void executePayment(uint8_t *payload); \ No newline at end of file diff --git a/bitcoinSwitch/bitcoinSwitch.ino b/bitcoinSwitch/bitcoinSwitch.ino index 534da9b..34d304a 100644 --- a/bitcoinSwitch/bitcoinSwitch.ino +++ b/bitcoinSwitch/bitcoinSwitch.ino @@ -1,14 +1,8 @@ -#include - #include "100_config.h" -#include "400_split_string.h" #include "200_wifi.h" +#include "201_web_socket.h" #include "300_tft.h" -String apiUrl = "/api/v1/ws/"; - -WebSocketsClient webSocket; - void setup() { Serial.begin(115200); @@ -18,133 +12,19 @@ void setup() printHome(false, false, false); #endif -#ifdef LED_BUILTIN +#if defined(LED_BUILTIN) && defined(LED_ON) pinMode(LED_BUILTIN, OUTPUT); // To blink on board LED digitalWrite(LED_BUILTIN, !LED_ON); #endif setupConfig(); setupWifi(); - - if (config_device_string == "") - { - Serial.println("No device string configured!"); - printTFT("No device string!", 21, 95); - return; - } - - if (!config_device_string.startsWith("wss://")) - { - Serial.println("Device string does not start with wss://"); - printTFT("no wss://!", 21, 95); - return; - } - - String cleaned_device_string = config_device_string.substring(6); // Remove wss:// - String host = cleaned_device_string.substring(0, cleaned_device_string.indexOf('/')); - String apiPath = cleaned_device_string.substring(cleaned_device_string.indexOf('/')); - Serial.println("Websocket host: " + host); - Serial.println("Websocket API Path: " + apiPath); - - // Use in normal mode - Serial.println("Using NORMAL mode"); - Serial.println("Connecting to websocket: " + host + apiPath); - webSocket.beginSSL(host, 443, apiPath); - - webSocket.onEvent(webSocketEvent); - webSocket.setReconnectInterval(1000); + setupWebSocket(); } void loop() { loopWifi(); - webSocket.loop(); -} - -void executePayment(uint8_t *payload) -{ - printTFT("Payment received!", 21, 15); - flashTFT(); - - String parts[3]; // pin, time, comment - // format: {pin-time-comment} where comment is optional - String payloadStr = String((char *)payload); - int numParts = splitString(payloadStr, '-', parts, 3); - - int pin = parts[0].toInt(); - printTFT("Pin: " + String(pin), 21, 35); - - int time = parts[1].toInt(); - printTFT("Time: " + String(time), 21, 55); - - String comment = ""; - if (numParts == 3) - { - comment = parts[2]; - Serial.println("[WebSocket] received comment: " + comment); - printTFT("Comment: " + comment, 21, 75); - } - Serial.println("[WebSocket] received pin: " + String(pin) + ", duration: " + String(time)); - - // the magic happens here - pinMode(pin, OUTPUT); - digitalWrite(pin, HIGH); -#ifdef LED_BUILTIN - digitalWrite(LED_BUILTIN, LED_ON); -#endif - delay(time); - digitalWrite(pin, LOW); -#ifdef LED_BUILTIN - digitalWrite(LED_BUILTIN, !LED_ON); -#endif - - printHome(true, true, false); -} - -//////////////////WEBSOCKET/////////////////// -bool ping_toggle = false; -void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) -{ - switch (type) - { - case WStype_ERROR: - Serial.printf("[WebSocket] Error: %s\n", payload); - printHome(true, false, false); - break; - case WStype_DISCONNECTED: - Serial.println("[WebSocket] Disconnected!\n"); - printHome(true, false, false); - break; - case WStype_CONNECTED: - Serial.printf("[WebSocket] Connected to url: %s\n", payload); - // send message to server when Connected - webSocket.sendTXT("Connected"); - printHome(true, true, false); - break; - case WStype_TEXT: - executePayment(payload); - break; - case WStype_BIN: - Serial.printf("[WebSocket] Received binary data: %s\n", payload); - break; - case WStype_FRAGMENT_TEXT_START: - break; - case WStype_FRAGMENT_BIN_START: - break; - case WStype_FRAGMENT: - break; - case WStype_FRAGMENT_FIN: - break; - case WStype_PING: - Serial.printf("[WebSocket] Ping!\n"); - ping_toggle = !ping_toggle; - printHome(true, true, ping_toggle); - // pong will be sent automatically - break; - case WStype_PONG: - // is not used - Serial.printf("[WebSocket] Pong!\n"); - printHome(true, true, true); - break; - } -} + loopWebSocket(); + delay(10); // to allow background processes +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 3a13bfb..1aacaef 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,7 +20,7 @@ board_build.partitions = min_spiffs.csv lib_deps = WebSockets@^2.6.1 ArduinoJson@^7.3.1 - WiFiManager + tzapu/WiFiManager@^2.0.17 [env:esp32dev] board = esp32dev @@ -49,10 +49,19 @@ build_flags = -D LED_ON=LOW [env:esp32-s3] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip board = esp32-s3-devkitc-1 -[env:esp32-c3] -board = esp32-c3-devkitm-1 +[env:esp32c3_super_mini] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip +board = nologo_esp32c3_super_mini +build_flags = + -D ARDUINO_USB_CDC_ON_BOOT=1 + -D ARDUINO_USB_MODE=1 +; -D LED_BUILTIN=8 + -D LED_ON=LOW + -D BT1_PIN=9 [env:esp32-s2] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip board = esp32-s2-saola-1 \ No newline at end of file From feb1932064017bad684eb8e8876920f3ac249b3a Mon Sep 17 00:00:00 2001 From: Bota Date: Sun, 30 Nov 2025 18:04:49 +0100 Subject: [PATCH 4/4] rimossi file github --- .github/workflows/arduino-report.yml | 12 ------- .github/workflows/arduino.yml | 54 ---------------------------- .github/workflows/release.yml | 43 ---------------------- .github/workflows/static.yml | 54 ---------------------------- .gitignore | 1 + 5 files changed, 1 insertion(+), 163 deletions(-) delete mode 100644 .github/workflows/arduino-report.yml delete mode 100644 .github/workflows/arduino.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/static.yml diff --git a/.github/workflows/arduino-report.yml b/.github/workflows/arduino-report.yml deleted file mode 100644 index a51cf64..0000000 --- a/.github/workflows/arduino-report.yml +++ /dev/null @@ -1,12 +0,0 @@ -on: - push: - branches: - - main - pull_request: - schedule: - - cron: '*/5 * * * *' -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: arduino/report-size-deltas@v1 diff --git a/.github/workflows/arduino.yml b/.github/workflows/arduino.yml deleted file mode 100644 index 383b19c..0000000 --- a/.github/workflows/arduino.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: arduino -on: - push: - branches: - - main - pull_request: - -jobs: - build-for-esp32: - runs-on: ubuntu-latest - strategy: - matrix: - fqbn: - - esp32:esp32:esp32 - steps: - - uses: actions/checkout@v4 - - uses: arduino/compile-sketches@v1 - with: - enable-deltas-report: true - github-token: ${{ secrets.GITHUB_TOKEN }} - fqbn: ${{ matrix.fqbn }} - platforms: | - - name: esp32:esp32 - source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - sketch-paths: | - - bitcoinSwitch - libraries: | - - name: WebSockets - - name: ArduinoJson - - name: TFT_eSPI - cli-compile-flags: | - - --warnings="none" - - - uses: actions/upload-artifact@v4 - with: - name: sketches-reports - path: sketches-reports - - - report: - needs: build-for-esp32 - if: github.event_name == 'pull_request' - runs-on: ubuntu-latest - steps: - # This step is needed to get the size data produced by the compile jobs - - name: Download sketches reports artifact - uses: actions/download-artifact@v4 - with: - name: sketches-reports - path: sketches-reports - - - uses: arduino/report-size-deltas@v1 - with: - sketches-reports-source: sketches-reports diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 07b6d92..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: release - -on: - push: - tags: - - "v[0-9]+.[0-9]+.[0-9]+" - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: write - pages: write - id-token: write - -jobs: - release: - runs-on: ubuntu-latest - steps: - - - uses: actions/checkout@v4 - with: - ref: main - - - name: Install Arduino CLI - uses: arduino/setup-arduino-cli@v1 - - - name: build, release and upload on github - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ github.ref_name }} - run: | - sh install.sh - devices=$(jq '.devices[]' versions.json -r) - uploads="" - for device in $devices; do - sh build.sh $device - mv build/bitcoinSwitch.ino.bin ./bitcoinSwitch-$device.ino.bin - uploads="$uploads ./bitcoinSwitch-$device.ino.bin" - mv build/bitcoinSwitch.ino.partitions.bin ./bitcoinSwitch-$device.ino.partitions.bin - uploads="$uploads ./bitcoinSwitch-$device.ino.partitions.bin" - mv build/bitcoinSwitch.ino.bootloader.bin ./bitcoinSwitch-$device.ino.bootloader.bin - uploads="$uploads ./bitcoinSwitch-$device.ino.bootloader.bin" - done - gh release create "$tag" --generate-notes $uploads diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml deleted file mode 100644 index d1e94e9..0000000 --- a/.github/workflows/static.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Simple workflow for deploying static content to GitHub Pages -name: Deploy static content to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - - # Allows you to run this workflow from other workflows - workflow_call: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: '22.x' - - name: build webinstaller - run: | - sh build-webinstaller.sh - cd hardware-installer - npm install - npm run build - - name: Setup Pages - uses: actions/configure-pages@v3 - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: "hardware-installer/dist" - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 3685678..fca82df 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ build firmware.zip bitcoinSwitch/config-*.h bitcoinSwitch/bitcoinSwitch.ino.cpp +.github \ No newline at end of file