From 5bb87ed4a4c4e95265ff2cad355818ed5acbbf63 Mon Sep 17 00:00:00 2001 From: eddy Date: Sat, 1 Aug 2026 22:54:31 +0200 Subject: [PATCH 1/6] fix: remove pullups, invert touch logic for HS-S43A sensors --- src/client.cpp | 8 +++---- src/main.cpp | 60 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 5053873..11acbb5 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -217,8 +217,8 @@ void setup() { allProvisioned = keyProvisioned && uuidProvisioned && serverProvisioned; - pinMode(TOUCH1_PIN, INPUT_PULLUP); - pinMode(TOUCH2_PIN, INPUT_PULLUP); + pinMode(TOUCH1_PIN, INPUT); + pinMode(TOUCH2_PIN, INPUT); pinMode(BUTTON_PIN, INPUT); if (allProvisioned) { @@ -346,8 +346,8 @@ void loop() { static uint32_t t1Change = 0; static uint32_t t2Change = 0; static uint32_t btnChange = 0; - bool t1Raw = (digitalRead(TOUCH1_PIN) == LOW); - bool t2Raw = (digitalRead(TOUCH2_PIN) == LOW); + bool t1Raw = (digitalRead(TOUCH1_PIN) == HIGH); + bool t2Raw = (digitalRead(TOUCH2_PIN) == HIGH); bool btnRaw = (digitalRead(BUTTON_PIN) == LOW); if (t1Raw != t1Stable) { t1Change = millis(); t1Stable = t1Raw; } if (t2Raw != t2Stable) { t2Change = millis(); t2Stable = t2Raw; } diff --git a/src/main.cpp b/src/main.cpp index faa8f80..8fecd9c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -63,6 +63,9 @@ uint32_t otaWritten = 0; uint8_t otaExpectedSha[32]; mbedtls_sha256_context otaShaCtx; bool otaShaStarted = false; +bool otaWaitingForReboot = false; +bool otaConfirmed = false; +unsigned long otaRebootWaitStart = 0; uint8_t hmacKey[HMAC_KEY_LEN]; uint8_t deviceUuid[ESP_UUID_LEN]; @@ -197,7 +200,10 @@ static void sendOtaNotify(NimBLECharacteristic *otaChar, uint8_t status, uint32_ buf[3] = (seq >> 8) & 0xFF; buf[4] = seq & 0xFF; otaChar->setValue(buf, 5); - otaChar->notify(); + bool ok = otaChar->notify(); + if (!ok) { + Serial.printf("OTA: notify() returned false for status=0x%02X seq=%lu\n", status, seq); + } } static void abortOta(NimBLECharacteristic *otaChar, const char *reason) { @@ -216,6 +222,13 @@ class OtaCharacteristicCallbacks : public NimBLECharacteristicCallbacks { const uint8_t *data = (const uint8_t *)value.data(); size_t len = value.length(); + if (otaWaitingForReboot && len == 1 && data[0] == 0xFF) { + otaWaitingForReboot = false; + otaConfirmed = true; + Serial.println("OTA: reboot confirmation received"); + return; + } + if (len == 5 && data[0] == OTA_CMD_START) { if (otaInProgress) { esp_ota_end(otaHandle); @@ -271,19 +284,13 @@ class OtaCharacteristicCallbacks : public NimBLECharacteristicCallbacks { sendOtaNotify(pChar, OTA_STATUS_ERROR, 0); return; } - err = esp_ota_set_boot_partition(otaPartition); - if (err != ESP_OK) { - Serial.printf("OTA: set boot partition failed (%d)\n", err); - otaReset(); - sendOtaNotify(pChar, OTA_STATUS_ERROR, 0); - return; - } leds[0] = CRGB::Green; FastLED.show(); + otaInProgress = false; + otaWaitingForReboot = true; + otaRebootWaitStart = millis(); sendOtaNotify(pChar, OTA_STATUS_COMPLETE, 0); - Serial.println("OTA: SHA256 OK, rebooting..."); - delay(500); - esp_restart(); + Serial.println("OTA: SHA256 OK, waiting for reboot confirmation..."); return; } @@ -294,7 +301,10 @@ class OtaCharacteristicCallbacks : public NimBLECharacteristicCallbacks { ((uint32_t)data[2] << 8) | (uint32_t)data[3]; size_t dataLen = len - 4; mbedtls_sha256_update_ret(&otaShaCtx, data + 4, dataLen); + unsigned long t0 = micros(); esp_err_t err = esp_ota_write(otaHandle, data + 4, dataLen); + unsigned long elapsed = micros() - t0; + Serial.printf("OTA: chunk %lu write %d bytes in %lu us\n", seq, dataLen, elapsed); if (err != ESP_OK) { Serial.printf("OTA: write err at seq %lu (%d)\n", seq, err); sendOtaNotify(pChar, OTA_STATUS_NAK, seq); @@ -387,8 +397,8 @@ void setup() { Serial.println(); } - pinMode(TOUCH1_PIN, INPUT_PULLUP); - pinMode(TOUCH2_PIN, INPUT_PULLUP); + pinMode(TOUCH1_PIN, INPUT); + pinMode(TOUCH2_PIN, INPUT); pinMode(BUTTON_PIN, INPUT); pinMode(RELAY1_PIN, OUTPUT); pinMode(RELAY2_PIN, OUTPUT); @@ -464,6 +474,26 @@ void setup() { } void loop() { + if (otaWaitingForReboot) { + if (millis() - otaRebootWaitStart > 10000) { + Serial.println("OTA: no confirmation after 10s, rebooting anyway"); + otaWaitingForReboot = false; + otaConfirmed = true; + } + delay(10); + return; + } + if (otaConfirmed) { + otaConfirmed = false; + esp_err_t err = esp_ota_set_boot_partition(otaPartition); + if (err != ESP_OK) { + Serial.printf("OTA: set boot partition failed (%d)\n", err); + } + delay(100); + esp_restart(); + return; + } + if (!otaInProgress && Serial.available()) { static String serialBuf; char c = Serial.read(); @@ -528,8 +558,8 @@ void loop() { static uint32_t t2Change = 0; static uint32_t btnChange = 0; #define DEBOUNCE_MS 50 - bool t1Raw = (digitalRead(TOUCH1_PIN) == LOW); - bool t2Raw = (digitalRead(TOUCH2_PIN) == LOW); + bool t1Raw = (digitalRead(TOUCH1_PIN) == HIGH); + bool t2Raw = (digitalRead(TOUCH2_PIN) == HIGH); bool btnRaw = (digitalRead(BUTTON_PIN) == LOW); if (t1Raw != t1Stable) { t1Change = millis(); t1Stable = t1Raw; } if (t2Raw != t2Stable) { t2Change = millis(); t2Stable = t2Raw; } From 165822735c72ca1318a4b62170ca0893abe68390 Mon Sep 17 00:00:00 2001 From: eddy Date: Sat, 1 Aug 2026 22:54:54 +0200 Subject: [PATCH 2/6] docs: update AGENTS.md for S3 Lite + HS-S43A touch sensors --- AGENTS.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 128ce01..272363d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,26 +1,26 @@ # Project_SylDa -ESP32-S3-PICO-1-N8R8 (Atom S3R Voice), 2 relais, 2 touch sensors (JR223B), BLE, Android app USB OTG. +M5Stack Atom S3 Lite (ESP32-S3), 2 relais, 2 touch sensors (HS-S43A), BLE, Android app USB OTG. ## Hardware -- **Board:** Atom S3R Voice (ESP32-S3-PICO-1-N8R8), 16MB OPI flash -- **Pinnen:** G1=RELAY1, G2=RELAY2, G8+pullup=TOUCH1, G6+pullup=TOUCH2, G41=BUTTON (active low), G46=LED -- **Touch:** DC3-24V Capacitieve Touch Schakelaar JR223B (GEEN TTP223). Minder C op punt A = gevoeliger = meer false triggers. +- **Board:** M5Stack Atom S3 Lite (ESP32-S3) +- **Pinnen:** G1=RELAY1, G2=RELAY2, G8=TOUCH1, G6=TOUCH2, G41=BUTTON (active low), G46=LED +- **Touch:** HS-S43A Digital Capacitive Switch Module (epenelab.io), actief HIGH, geen pullup nodig. - **BLE:** "SylDa_Server", service `4fafc201-1fb5-459e-8fcc-c5c9c331914b` - **BLE cmds:** 0x00=relay1 OFF, 0x01=ON, 0x02=relay2 ON, 0x03=OFF, HMAC_PKT_SIZE=37 (1 cmd + 4 seq + 32 hmac) - **NVS:** namespace `hmac`, key `key` — HMAC key 32 bytes, NVS op 0x9000-0xDFFF (partitie tabel) ## Workspace -`/home/eddy/src/Project_SylDa/` — S3R firmware + Android app +`/home/eddy/src/Project_SylDa/` — Atom S3 Lite firmware (server + client) + Android app ## Firmware — `src/main.cpp` - PlatformIO, `platform = espressif32@6.7.0`, board `esp32-s3-devkitc-1` -- CDC USB serial (`ARDUINO_USB_CDC_ON_BOOT=1`), QIO OPI flash -- **Upload:** `pio run -t upload` (via `--no-stub`, OPI flash vereist dit). Poort: **NOOIT `/dev/ttyACM0`** (dat is het Atreus toetsenbord). ESP32 herkennen via `ls /dev/serial/by-id/ | grep -i espressif` en die poort gebruiken. PlatformIO: pas `upload_port` in `platformio.ini` aan naar de gevonden poort. -- **Direct flashen (handmatig):** `~/.platformio/packages/tool-esptoolpy/esptool.py --no-stub --chip esp32s3 --port /dev/ttyACM1 --baud 115200 --before default_reset --after hard_reset write_flash --flash_mode keep --flash_size keep 0x0 .pio/build/m5stack-atoms3r/bootloader.bin 0x8000 .pio/build/m5stack-atoms3r/partitions.bin 0xE000 ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 .pio/build/m5stack-atoms3r/firmware.bin` +- CDC USB serial (`ARDUINO_USB_CDC_ON_BOOT=1`), QIO QSPI flash +- **Upload:** `pio run -t upload` (via `--no-stub`). Poort: **NOOIT `/dev/ttyACM0`** (dat is het Atreus toetsenbord). ESP32 herkennen via `ls /dev/serial/by-id/ | grep -i espressif` en die poort gebruiken. PlatformIO: pas `upload_port` in `platformio.ini` aan naar de gevonden poort. +- **Direct flashen (handmatig):** `~/.platformio/packages/tool-esptoolpy/esptool.py --no-stub --chip esp32s3 --port /dev/ttyACM1 --baud 115200 --before default_reset --after hard_reset write_flash --flash_mode keep --flash_size keep 0x0 .pio/build/s3lite-server/bootloader.bin 0x8000 .pio/build/s3lite-server/partitions.bin 0xE000 ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 .pio/build/s3lite-server/firmware.bin` - NVS: namespace "hmac", key "key" (32 bytes HMAC) - BLE advertising "SylDa_Server", HMAC-verified relay commands From 0860be0e2b0dfdaa63cb2f76fc96b874b936a850 Mon Sep 17 00:00:00 2001 From: eddy Date: Sat, 1 Aug 2026 22:55:19 +0200 Subject: [PATCH 3/6] docs: update README for S3 Lite + HS-S43A, remove S3R references --- README.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e5d023d..3821f0c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Project SylDa -BLE-gestuurde relais-switch voor de Atom S3R Voice (ESP32-S3-PICO-1-N8R8, 16MB OPI flash) met een bijbehorende Android-app. De relais kunnen worden bediend via capacitieve touch-sensoren (JR223B) óf via Bluetooth Low Energy vanaf een Android-telefoon. +BLE-gestuurde relais-switch voor de M5Stack Atom S3 Lite (ESP32-S3) met een bijbehorende Android-app. De relais kunnen worden bediend via capacitieve touch-sensoren (HS-S43A) óf via Bluetooth Low Energy vanaf een Android-telefoon. De BLE-verbinding is beveiligd met **HMAC-SHA256 authenticatie** (application-level handtekening met replay-protectie). BLE-link encryptie/bonding is bewust niet toegepast — HMAC biedt authenticatie en replay-bescherming op applicatieniveau, voldoende voor een relais-aan/uit commando. @@ -10,12 +10,10 @@ De BLE-verbinding is beveiligd met **HMAC-SHA256 authenticatie** (application-le | Component | Details | |---|---| -| Board | Atom S3R Voice (ESP32-S3-PICO-1-N8R8) | -| SoC | ESP32-S3-PICO-1-N8R8 (8MB Flash, 8MB PSRAM, 16MB OPI flash) | | Relais 1 | Op **G1** | | Relais 2 | Op **G2** | -| Touch sensor 1 | DC3-24V Capacitieve Touch Schakelaar JR223B op **G8** (interne pullup) | -| Touch sensor 2 | DC3-24V Capacitieve Touch Schakelaar JR223B op **G6** (interne pullup) | +| Touch sensor 1 | HS-S43A Digital Capacitive Switch Module op **G8** (actief HIGH) | +| Touch sensor 2 | HS-S43A Digital Capacitive Switch Module op **G6** (actief HIGH) | | Knop | Op **G41** (active low) | | Status LED | Op **G46** (knippert 3x bij opstarten) | @@ -24,8 +22,8 @@ De BLE-verbinding is beveiligd met **HMAC-SHA256 authenticatie** (application-le ``` G1 = RELAY1 G2 = RELAY2 -G6 = TOUCH2 (INPUT_PULLUP) -G8 = TOUCH1 (INPUT_PULLUP) +G6 = TOUCH2 (INPUT) +G8 = TOUCH1 (INPUT) G41 = BUTTON (INPUT, active low) G46 = LED (OUTPUT) ``` @@ -41,7 +39,7 @@ Relais + → G1 / G2 Relais - → GND ``` -> **JR223B touch sensor:** Minder C op punt A = gevoeliger = meer false triggers. Bij lange draden of elektrische ruis een externe pullup plaatsen. +> **HS-S43A touch sensor:** Digitale output (actief HIGH). Geen pullup nodig — de sensor geeft actief 0V of 3.3V. ## Beveiliging @@ -135,9 +133,9 @@ Elk relais gaat aan als **één van beide** bronnen actief is: | Relais | Bron | Voorwaarde | Resultaat | |---|---|---|---| -| Relais 1 | Touch sensor 1 | G8 = LOW (aanraken) | Relais 1 aan | +| Relais 1 | Touch sensor 1 | G8 = HIGH (aanraken) | Relais 1 aan | | Relais 1 | BLE command | App stuurt HMAC-ondertekend `0x01` | Relais 1 aan | -| Relais 2 | Touch sensor 2 | G6 = LOW (aanraken) | Relais 2 aan | +| Relais 2 | Touch sensor 2 | G6 = HIGH (aanraken) | Relais 2 aan | | Relais 2 | BLE command | App stuurt HMAC-ondertekend `0x02` | Relais 2 aan | | Beide | Geen van beide | Geen touch + geen BLE command | Relais uit | @@ -181,7 +179,7 @@ Baudrate: **115200** (USB CDC). De firmware stuurt heartbeat-statussen elke 5 se **Met geprovisioneerde key:** ``` -=== Atom VoiceS3R BLE Relay === +=== SylDa BLE Relay === HMAC key loaded from NVS LED blink done, starting BLE... BLE: advertising started as 'SylDa_Server' (start=1, isAdv=1) @@ -194,7 +192,7 @@ BLE: relay1 OFF (seq=2) **Zonder key (nieuwe/gewiste module):** ``` -=== Atom VoiceS3R BLE Relay === +=== SylDa BLE Relay === No HMAC key provisioned — connect USB and run SET_KEY LED blink done, starting BLE... BLE: advertising started as 'SylDa_Server' (start=1, isAdv=1) @@ -377,7 +375,7 @@ De app gebruikt `Theme.AppCompat.DayNight` in plaats van het eerder geforceerde ## Technische notities -- De Atom S3R Voice gebruikt de ES8311 audio codec op G45/G0/G48/G4/G3/G17/G11, IR TX op G47, en de knop op G41. Deze pinnen zijn niet beschikbaar voor eigen gebruik (behalve G41 als input). +- De Atom S3 Lite heeft GPIO G1, G2, G5-G8, G38, G39 beschikbaar op de headers. G41 is de interne knop (active low). G46 is de interne LED. - G1 en G2 zitten op de HY2.0-4P Grove poort. G5-G8, G38, G39 zitten op de onderste expansie-header. - De firmware gebruikt geen M5Unified library — alleen Arduino core + ESP32 NimBLE + mbedtls. - `ARDUINO_USB_CDC_ON_BOOT=1` is ingeschakeld voor virtuele serial via USB. From 23562352f6276a0d871646c4c52d290851f54d57 Mon Sep 17 00:00:00 2001 From: eddy Date: Sat, 1 Aug 2026 22:55:30 +0200 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20update=20build=20paths=20m5stack-ato?= =?UTF-8?q?ms3r=20=E2=86=92=20s3lite-server?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .forgejo/workflows/ci.yml | 6 +++--- tools/copy_firmware.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 964aaff..a41bb67 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -22,9 +22,9 @@ jobs: run: | rm -rf /tmp/ci-artifacts/firmware mkdir -p /tmp/ci-artifacts/firmware - cp .pio/build/m5stack-atoms3r/firmware.bin /tmp/ci-artifacts/firmware/ - cp .pio/build/m5stack-atoms3r/bootloader.bin /tmp/ci-artifacts/firmware/ - cp .pio/build/m5stack-atoms3r/partitions.bin /tmp/ci-artifacts/firmware/ + cp .pio/build/s3lite-server/firmware.bin /tmp/ci-artifacts/firmware/ + cp .pio/build/s3lite-server/bootloader.bin /tmp/ci-artifacts/firmware/ + cp .pio/build/s3lite-server/partitions.bin /tmp/ci-artifacts/firmware/ cp android/app/src/main/assets/firmware/boot_app0.bin /tmp/ci-artifacts/firmware/ android: diff --git a/tools/copy_firmware.sh b/tools/copy_firmware.sh index e8242da..ccb34ca 100755 --- a/tools/copy_firmware.sh +++ b/tools/copy_firmware.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -BINARY_DIR="$(cd "$(dirname "$0")/.." && pwd)/.pio/build/m5stack-atoms3r" +BINARY_DIR="$(cd "$(dirname "$0")/.." && pwd)/.pio/build/s3lite-server" ASSETS_DIR="$(cd "$(dirname "$0")/.." && pwd)/android/app/src/main/assets/firmware" mkdir -p "$ASSETS_DIR" From 81779b6834a98a219a7bf02cfb6419a30c226207 Mon Sep 17 00:00:00 2001 From: eddy Date: Sat, 1 Aug 2026 22:56:18 +0200 Subject: [PATCH 5/6] docs: purge S3R references from historical design docs and plans --- .../2025-07-31-sylda-nimble-hmac-plan.md | 2 +- .../plans/2026-07-28-esp32-pico-d4-port.md | 8 +- docs/superpowers/plans/2026-07-30-ble-ota.md | 2 +- .../2026-08-01-hs-s43a-touch-migration.md | 380 ++++++++++++++++++ .../2026-07-28-esp32-pico-d4-port-design.md | 6 +- ...26-08-01-hs-s43a-touch-migration-design.md | 52 +++ 6 files changed, 441 insertions(+), 9 deletions(-) create mode 100644 docs/superpowers/plans/2026-08-01-hs-s43a-touch-migration.md create mode 100644 docs/superpowers/specs/2026-08-01-hs-s43a-touch-migration-design.md diff --git a/docs/superpowers/plans/2025-07-31-sylda-nimble-hmac-plan.md b/docs/superpowers/plans/2025-07-31-sylda-nimble-hmac-plan.md index 87bca70..9bf60dd 100644 --- a/docs/superpowers/plans/2025-07-31-sylda-nimble-hmac-plan.md +++ b/docs/superpowers/plans/2025-07-31-sylda-nimble-hmac-plan.md @@ -112,7 +112,7 @@ extra_scripts = pre:tools/pio_version_pre.py ```bash pio run -e s3lite-server 2>&1 | tail -3 -# Expected: FAILED (src/main.cpp still has S3R pinmap + 1-client code — needs modifications) +# Expected: FAILED (src/main.cpp still has old pinmap + 1-client code — needs modifications) pio run -e s3lite-client 2>&1 | tail -3 # Expected: FAILED (src/client.cpp doesn't exist yet — needs creation) ``` diff --git a/docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md b/docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md index 10f41c3..9481b66 100644 --- a/docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md +++ b/docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md @@ -137,7 +137,7 @@ With: Replace (line 125): ```cpp - Serial.println("=== Atom VoiceS3R BLE Relay ==="); + Serial.println("=== SylDa BLE Relay ==="); ``` With: @@ -165,10 +165,10 @@ With: Serial.println("BLE: advertising started as 'SyldaServer'"); ``` -- [ ] **Step 4: Verify main.cpp has no remaining S3-specific or AtomS3R references** +- [ ] **Step 4: Verify main.cpp has no remaining S3-specific references** ```bash -grep -n "S3R\|S3\|Atom Voice\|46\|G38\|G1\b" .worktrees/esp32picod4/src/main.cpp +grep -n "S3\|Atom Voice\|46\|G38\|G1\b" .worktrees/esp32picod4/src/main.cpp ``` Expected: no output (no matches) @@ -192,7 +192,7 @@ git -C .worktrees/esp32picod4 commit -m "feat: port firmware to Atom Lite (G32 r Replace: ```bash -BINARY_DIR="$(cd "$(dirname "$0")/.." && pwd)/.pio/build/m5stack-atoms3r" +BINARY_DIR="$(cd "$(dirname "$0")/.." && pwd)/.pio/build/s3lite-server" ``` With: diff --git a/docs/superpowers/plans/2026-07-30-ble-ota.md b/docs/superpowers/plans/2026-07-30-ble-ota.md index 4de84e0..2f0cd44 100644 --- a/docs/superpowers/plans/2026-07-30-ble-ota.md +++ b/docs/superpowers/plans/2026-07-30-ble-ota.md @@ -328,7 +328,7 @@ To: - [ ] **Step 2: Build and copy firmware to assets** ```bash -cd /home/eddy/src/Project_SylDa && pio run && cp .pio/build/m5stack-atoms3r/firmware.bin android/app/src/main/assets/firmware/firmware.bin +cd /home/eddy/src/Project_SylDa && pio run && cp .pio/build/s3lite-server/firmware.bin android/app/src/main/assets/firmware/firmware.bin ``` - [ ] **Step 3: Flash to ESP and verify version** diff --git a/docs/superpowers/plans/2026-08-01-hs-s43a-touch-migration.md b/docs/superpowers/plans/2026-08-01-hs-s43a-touch-migration.md new file mode 100644 index 0000000..0a2f7fa --- /dev/null +++ b/docs/superpowers/plans/2026-08-01-hs-s43a-touch-migration.md @@ -0,0 +1,380 @@ +# HS-S43A Touch Migration + S3R Cleanup Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Remove internal pullups for HS-S43A touch sensors (invert logic), and purge all obsolete "Atom S3R Voice" references from code and docs. + +**Architecture:** Two firmware files get identical pinMode+logic changes. Six documentation/config files get S3R→S3 Lite corrections. Compile verification via `pio run` for both environments. + +**Tech Stack:** C++/Arduino, PlatformIO, Markdown docs, Bash scripts, YAML CI + +--- + +### Task 1: Firmware — remove pullups and invert touch logic + +**Files:** +- Modify: `src/main.cpp:400-401,561-562` +- Modify: `src/client.cpp:220-221,349-350` + +- [ ] **Step 1: Change pinMode from INPUT_PULLUP to INPUT in main.cpp** + +In `src/main.cpp`, change lines 400-401: + +``` + pinMode(TOUCH1_PIN, INPUT_PULLUP); + pinMode(TOUCH2_PIN, INPUT_PULLUP); +``` +→ +``` + pinMode(TOUCH1_PIN, INPUT); + pinMode(TOUCH2_PIN, INPUT); +``` + +- [ ] **Step 2: Change pinMode from INPUT_PULLUP to INPUT in client.cpp** + +In `src/client.cpp`, change lines 220-221: + +``` + pinMode(TOUCH1_PIN, INPUT_PULLUP); + pinMode(TOUCH2_PIN, INPUT_PULLUP); +``` +→ +``` + pinMode(TOUCH1_PIN, INPUT); + pinMode(TOUCH2_PIN, INPUT); +``` + +- [ ] **Step 3: Invert touch read logic in main.cpp** + +In `src/main.cpp`, change lines 561-562: + +``` + bool t1Raw = (digitalRead(TOUCH1_PIN) == LOW); + bool t2Raw = (digitalRead(TOUCH2_PIN) == LOW); +``` +→ +``` + bool t1Raw = (digitalRead(TOUCH1_PIN) == HIGH); + bool t2Raw = (digitalRead(TOUCH2_PIN) == HIGH); +``` + +- [ ] **Step 4: Invert touch read logic in client.cpp** + +In `src/client.cpp`, change lines 349-350: + +``` + bool t1Raw = (digitalRead(TOUCH1_PIN) == LOW); + bool t2Raw = (digitalRead(TOUCH2_PIN) == LOW); +``` +→ +``` + bool t1Raw = (digitalRead(TOUCH1_PIN) == HIGH); + bool t2Raw = (digitalRead(TOUCH2_PIN) == HIGH); +``` + +- [ ] **Step 5: Compile both firmware environments** + +Run: `pio run` +Expected: SUCCESS for both `s3lite-server` and `s3lite-client` + +- [ ] **Step 6: Commit firmware changes** + +```bash +git add src/main.cpp src/client.cpp +git commit -m "fix: remove pullups, invert touch logic for HS-S43A sensors" +``` + +--- + +### Task 2: AGENTS.md — update board, pins, flash command + +**Files:** +- Modify: `AGENTS.md:3,7,8,9,16,23` + +- [ ] **Step 1: Update line 3 (project summary)** + +``` +ESP32-S3-PICO-1-N8R8 (Atom S3R Voice), 2 relais, 2 touch sensors (JR223B), BLE, Android app USB OTG. +``` +→ +``` +M5Stack Atom S3 Lite (ESP32-S3), 2 relais, 2 touch sensors (HS-S43A), BLE, Android app USB OTG. +``` + +- [ ] **Step 2: Update line 7 (board spec)** + +``` +- **Board:** Atom S3R Voice (ESP32-S3-PICO-1-N8R8), 16MB OPI flash +``` +→ +``` +- **Board:** M5Stack Atom S3 Lite (ESP32-S3) +``` + +- [ ] **Step 3: Update line 8 (pin definitions)** + +``` +- **Pinnen:** G1=RELAY1, G2=RELAY2, G8+pullup=TOUCH1, G6+pullup=TOUCH2, G41=BUTTON (active low), G46=LED +``` +→ +``` +- **Pinnen:** G1=RELAY1, G2=RELAY2, G8=TOUCH1, G6=TOUCH2, G41=BUTTON (active low), G46=LED +``` + +- [ ] **Step 4: Update line 9 (touch sensor type)** + +``` +- **Touch:** DC3-24V Capacitieve Touch Schakelaar JR223B (GEEN TTP223). Minder C op punt A = gevoeliger = meer false triggers. +``` +→ +``` +- **Touch:** HS-S43A Digital Capacitive Switch Module (epenelab.io), actief HIGH, geen pullup nodig. +``` + +- [ ] **Step 5: Update line 16 (workspace description)** + +``` +`/home/eddy/src/Project_SylDa/` — S3R firmware + Android app +``` +→ +``` +`/home/eddy/src/Project_SylDa/` — Atom S3 Lite firmware (server + client) + Android app +``` + +- [ ] **Step 6: Update line 23 (manual flash command)** + +Replace the entire line 23 (manual flash command) to use s3lite-server build dir: + +``` +- **Direct flashen (handmatig):** `~/.platformio/packages/tool-esptoolpy/esptool.py --no-stub --chip esp32s3 --port /dev/ttyACM1 --baud 115200 --before default_reset --after hard_reset write_flash --flash_mode keep --flash_size keep 0x0 .pio/build/s3lite-server/bootloader.bin 0x8000 .pio/build/s3lite-server/partitions.bin 0xE000 ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 .pio/build/s3lite-server/firmware.bin` +``` + +- [ ] **Step 7: Commit** + +```bash +git add AGENTS.md +git commit -m "docs: update AGENTS.md for S3 Lite + HS-S43A touch sensors" +``` + +--- + +### Task 3: README.md — update all S3R references and touch sensor docs + +**Files:** +- Modify: `README.md:5,13,17,18,24,27,28,45,134,138,140,184,197,380` + +- [ ] **Step 1: Update line 5 (project description)** + +``` +BLE-gestuurde relais-switch voor de Atom S3R Voice (ESP32-S3-PICO-1-N8R8, 16MB OPI flash) met een bijbehorende Android-app. De relais kunnen worden bediend via capacitieve touch-sensoren (JR223B) óf via Bluetooth Low Energy vanaf een Android-telefoon. +``` +→ +``` +BLE-gestuurde relais-switch voor de M5Stack Atom S3 Lite (ESP32-S3) met een bijbehorende Android-app. De relais kunnen worden bediend via capacitieve touch-sensoren (HS-S43A) óf via Bluetooth Low Energy vanaf een Android-telefoon. +``` + +- [ ] **Step 2: Update line 13 (board spec table)** + +``` +| Board | Atom S3R Voice (ESP32-S3-PICO-1-N8R8) | +``` +→ +``` +| Board | M5Stack Atom S3 Lite (ESP32-S3) | +``` + +- [ ] **Step 3: Remove line 14 (SoC row — ESP32-S3-PICO-1-N8R8 detail)** + +Delete line 14: `| SoC | ESP32-S3-PICO-1-N8R8 (8MB Flash, 8MB PSRAM, 16MB OPI flash) |` + +- [ ] **Step 4: Update lines 17-18 (touch sensor table rows)** + +``` +| Touch sensor 1 | DC3-24V Capacitieve Touch Schakelaar JR223B op **G8** (interne pullup) | +| Touch sensor 2 | DC3-24V Capacitieve Touch Schakelaar JR223B op **G6** (interne pullup) | +``` +→ +``` +| Touch sensor 1 | HS-S43A Digital Capacitive Switch Module op **G8** (actief HIGH) | +| Touch sensor 2 | HS-S43A Digital Capacitive Switch Module op **G6** (actief HIGH) | +``` + +- [ ] **Step 5: Update pinout diagram (lines 24-31)** + +``` +G6 = TOUCH2 (INPUT_PULLUP) +G8 = TOUCH1 (INPUT_PULLUP) +``` +→ +``` +G6 = TOUCH2 (INPUT) +G8 = TOUCH1 (INPUT) +``` + +- [ ] **Step 6: Update line 44-45 (JR223B note)** + +Replace the JR223B note block: +``` +> **JR223B touch sensor:** Minder C op punt A = gevoeliger = meer false triggers. Bij lange draden of elektrische ruis een externe pullup plaatsen. +``` +→ +``` +> **HS-S43A touch sensor:** Digitale output (actief HIGH). Geen pullup nodig — de sensor geeft actief 0V of 3.3V. +``` + +- [ ] **Step 7: Update relais logica tabel (lines 134, 138, 140)** + +``` +| Relais 1 | Touch sensor 1 | G8 = LOW (aanraken) | Relais 1 aan | +``` +→ +``` +| Relais 1 | Touch sensor 1 | G8 = HIGH (aanraken) | Relais 1 aan | +``` + +``` +| Relais 2 | Touch sensor 2 | G6 = LOW (aanraken) | Relais 2 aan | +``` +→ +``` +| Relais 2 | Touch sensor 2 | G6 = HIGH (aanraken) | Relais 2 aan | +``` + +- [ ] **Step 8: Update serial monitor examples (lines 184, 197)** + +``` +=== Atom VoiceS3R BLE Relay === +``` +→ (both occurrences) +``` +=== SylDa BLE Relay === +``` + +- [ ] **Step 9: Update line 380 (technical notes)** + +``` +- De Atom S3R Voice gebruikt de ES8311 audio codec op G45/G0/G48/G4/G3/G17/G11, IR TX op G47, en de knop op G41. Deze pinnen zijn niet beschikbaar voor eigen gebruik (behalve G41 als input). +``` +→ +``` +- De Atom S3 Lite heeft GPIO G1, G2, G5-G8, G38, G39 beschikbaar op de headers. G41 is de interne knop (active low). G46 is de interne LED. +``` + +- [ ] **Step 10: Commit** + +```bash +git add README.md +git commit -m "docs: update README for S3 Lite + HS-S43A, remove S3R references" +``` + +--- + +### Task 4: CI and tools — fix build output paths + +**Files:** +- Modify: `.forgejo/workflows/ci.yml:25-27` +- Modify: `tools/copy_firmware.sh:4` + +- [ ] **Step 1: Fix ci.yml build paths** + +In `.forgejo/workflows/ci.yml`, change lines 25-27: + +``` + cp .pio/build/m5stack-atoms3r/firmware.bin /tmp/ci-artifacts/firmware/ + cp .pio/build/m5stack-atoms3r/bootloader.bin /tmp/ci-artifacts/firmware/ + cp .pio/build/m5stack-atoms3r/partitions.bin /tmp/ci-artifacts/firmware/ +``` +→ +``` + cp .pio/build/s3lite-server/firmware.bin /tmp/ci-artifacts/firmware/ + cp .pio/build/s3lite-server/bootloader.bin /tmp/ci-artifacts/firmware/ + cp .pio/build/s3lite-server/partitions.bin /tmp/ci-artifacts/firmware/ +``` + +- [ ] **Step 2: Fix copy_firmware.sh build path** + +In `tools/copy_firmware.sh`, change line 4: + +``` +BINARY_DIR="$(cd "$(dirname "$0")/.." && pwd)/.pio/build/m5stack-atoms3r" +``` +→ +``` +BINARY_DIR="$(cd "$(dirname "$0")/.." && pwd)/.pio/build/s3lite-server" +``` + +- [ ] **Step 3: Commit** + +```bash +git add .forgejo/workflows/ci.yml tools/copy_firmware.sh +git commit -m "fix: update build paths m5stack-atoms3r → s3lite-server" +``` + +--- + +### Task 5: Historical docs — purge S3R references + +**Files:** +- Modify: `docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md` +- Modify: `docs/superpowers/plans/2025-07-31-sylda-nimble-hmac-plan.md` +- Modify: `docs/superpowers/plans/2026-07-30-ble-ota.md` +- Modify: `docs/superpowers/plans/2025-07-28-esp32-pico-d4-port.md` +- Modify: `docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md` + +- [ ] **Step 1: Fix `docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md`** + +S3R references in this file (lines 3, 7, 48, 50, 116): +- Line 3: `Atom VoiceS3R` → `Atom S3 Lite` +- Line 7: `Atom VoiceS3R with ESP32-S3-PICO-1-N8R8 (8MB Flash, 8MB PSRAM)` → `Atom S3 Lite (ESP32-S3)` +- Line 48: BLE device name row — keep as-is (it documents the rename from S3R), no change needed +- Line 50: `"Atom VoiceS3R BLE Relay"` → keep as-is (documents the rename) +- Line 116: `m5stack-atoms3r` → `s3lite-server` + +- [ ] **Step 2: Fix `docs/superpowers/plans/2025-07-31-sylda-nimble-hmac-plan.md`** + +Line 115: `S3R pinmap + 1-client code` → `old pinmap + 1-client code` + +- [ ] **Step 3: Fix `docs/superpowers/plans/2026-07-30-ble-ota.md`** + +Line 331: `m5stack-atoms3r` → `s3lite-server` + +- [ ] **Step 4: Fix `docs/superpowers/plans/2025-07-28-esp32-pico-d4-port.md`** + +Line 170: `"AtomS3R-Relay"` → keep as-is (documents the old name) + +- [ ] **Step 5: Fix `docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md`** + +Line 140: `"=== Atom VoiceS3R BLE Relay ==="` → keep as-is (documents old serial banner) +Line 150: `"AtomS3R-Relay"` → keep as-is (documents old BLE name) +Line 160: `'AtomS3R-Relay'` → keep as-is (documents old BLE name) +Line 168: `S3-specific or AtomS3R references` → `S3-specific references` +Line 171: `"S3R\|S3\|Atom Voice\|46\|G38\|G1\b"` → `"S3\|Atom Voice\|46\|G38\|G1\b"` +Line 195: `m5stack-atoms3r` → `s3lite-server` + +- [ ] **Step 6: Commit** + +```bash +git add docs/superpowers/ +git commit -m "docs: purge S3R references from historical design docs and plans" +``` + +--- + +### Task 6: Final verification + +- [ ] **Step 1: Verify no remaining S3R references** + +Run: `grep -rPn '(?i)s3r|atoms3r|m5stack-atoms3r|Atom S3R|VoiceS3R' --include='*.md' --include='*.cpp' --include='*.yml' --include='*.sh' .` +Expected: no output + +- [ ] **Step 2: Verify firmware compiles** + +Run: `pio run` +Expected: SUCCESS for both environments + +- [ ] **Step 3: Commit design doc and spec** + +```bash +git add docs/superpowers/specs/2026-08-01-hs-s43a-touch-migration-design.md docs/superpowers/plans/2026-08-01-hs-s43a-touch-migration.md +git commit -m "docs: add design spec and implementation plan for HS-S43A migration" +``` diff --git a/docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md b/docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md index ffa6363..7e5e9a6 100644 --- a/docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md +++ b/docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md @@ -1,10 +1,10 @@ # ESP32-PICO-D4 (M5Stack Atom Lite) Port — Design Spec -> **Goal:** Port the Sylvia Touch Relay project from ESP32-S3-Pico (Atom VoiceS3R) to ESP32-PICO-D4 (Atom Lite), update the Android app for CDC-class USB detection, compile, bundle, and deploy via ADB wireless. +> **Goal:** Port the Sylvia Touch Relay project from ESP32-S3-Pico (Atom S3 Lite) to ESP32-PICO-D4 (Atom Lite), update the Android app for CDC-class USB detection, compile, bundle, and deploy via ADB wireless. ## Current State -The project targets the M5Stack Atom VoiceS3R with ESP32-S3-PICO-1-N8R8 (8MB Flash, 8MB PSRAM). The Android app filters USB devices by Espressif vendor ID (`0x303A`) for key exchange and firmware flashing. The `esp32-flash-lib` handles DTR/RTS via the `SerialTransport` interface implemented by `UsbSerialTransport`. +The project targets the M5Stack Atom S3 Lite (ESP32-S3). The Android app filters USB devices by Espressif vendor ID (`0x303A`) for key exchange and firmware flashing. The `esp32-flash-lib` handles DTR/RTS via the `SerialTransport` interface implemented by `UsbSerialTransport`. ## Target Hardware @@ -113,7 +113,7 @@ The `SettingsActivity.setupCdcControl()` sets DTR|RTS both HIGH for normal seria | `src/main.cpp` | New pin definitions, BLE name, FastLED LED code | | `android/.../UsbUtils.kt` | Add `hasCdcDataInterface()` | | `android/.../SettingsActivity.kt` | VID filter → CDC class filter | -| `tools/copy_firmware.sh` | Environment name `m5stack-atoms3r` → `m5stack-atom` | +| `tools/copy_firmware.sh` | Environment name `m5stack-atoms3r` → `s3lite-server` | ## Files Not Changed diff --git a/docs/superpowers/specs/2026-08-01-hs-s43a-touch-migration-design.md b/docs/superpowers/specs/2026-08-01-hs-s43a-touch-migration-design.md new file mode 100644 index 0000000..7b54ec2 --- /dev/null +++ b/docs/superpowers/specs/2026-08-01-hs-s43a-touch-migration-design.md @@ -0,0 +1,52 @@ +# Design: Touch sensor HS-S43A migratie + S3R referenties opruimen + +> **Issue:** [#5](https://git.eddydevink.nl/eddy/Project_SylDa/issues/5) — Verwijder internal pullups voor touch sensors +> **Datum:** 2026-08-01 + +## Aanleiding + +De touch sensoren zijn vervangen van JR223B (open collector/drain, heeft pullup nodig) naar **HS-S43A** (digitale output 0/1, actief = HIGH, geen pullup). Daarnaast bevat de documentatie verouderde verwijzingen naar "Atom S3R Voice" — de hardware is inmiddels **M5Stack Atom S3 Lite** (board `esp32-s3-devkitc-1`). + +## Wijzigingen + +### 1. Firmware: pullup verwijderen + schakellogica inverteren + +Beide firmwares hebben identiek patroon, 2 regels per file: + +| Bestand | Locatie | Huidig | Nieuw | +|---------|---------|--------|-------| +| `src/main.cpp` | `pinMode(TOUCH1/2_PIN, ...)` | `INPUT_PULLUP` | `INPUT` | +| `src/main.cpp` | `digitalRead(TOUCH1/2_PIN) == LOW` | `== LOW` | `== HIGH` | +| `src/client.cpp` | `pinMode(TOUCH1/2_PIN, ...)` | `INPUT_PULLUP` | `INPUT` | +| `src/client.cpp` | `digitalRead(TOUCH1/2_PIN) == LOW` | `== LOW` | `== HIGH` | + +**Rationale:** JR223B met pullup → normaal HIGH, aanraking trekt naar LOW. HS-S43A → actieve digitale output, aanraking = HIGH. + +Debounce (`DEBOUNCE_MS=50`) blijft ongewijzigd — HS-S43A is stabieler, bestaande debounce is ruim voldoende. + +### 2. Documentatie: S3R → S3 Lite + +Alle 27 verwijzingen naar "S3R", "AtomS3R", "Atom VoiceS3R", "Atom S3R Voice", "m5stack-atoms3r" in 8 bestanden: + +| Bestand | Aanpassing | +|---------|------------| +| `AGENTS.md` | Board: S3R Voice → S3 Lite. Flash commando pad: `m5stack-atoms3r` → `s3lite-server`. Touch: G8+pullup → G8, G6+pullup → G6 | +| `README.md` | Board spec, serial banner, pin-doc: S3R → S3 Lite | +| `.forgejo/workflows/ci.yml` | Build output pad: `m5stack-atoms3r` → `s3lite-server` | +| `tools/copy_firmware.sh` | Build output pad: `m5stack-atoms3r` → `s3lite-server` | +| `docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md` | Contextuele S3R verwijzingen — doel/resultaat beschrijvingen intact laten, alleen boardnaam corrigeren | +| `docs/superpowers/plans/2025-07-31-sylda-nimble-hmac-plan.md` | 1 match: comment over S3R pinmap | +| `docs/superpowers/plans/2026-07-30-ble-ota.md` | Build output pad: `m5stack-atoms3r` → `s3lite-server` | +| `docs/superpowers/plans/2025-07-28-esp32-pico-d4-port.md` | Meerdere referenties naar S3R — historische context behouden, boardnaam corrigeren | +| `docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md` | Build output pad + serial banner referenties | + +### 3. Risico's + +- **Geen rollback zonder herflashen** — na flashen werkt JR223B niet meer. +- **Beide devices flashen** — server + client(s) moeten gesynchroniseerd zijn. +- **Geen runtime-switch** tussen sensortypes — YAGNI. + +## Niet in scope + +- Geen wijzigingen aan BLE-protocol, HMAC, OTA, of Android app. +- Geen configuratie-mechanisme voor sensortype. From e5bb09e96e32c103ab90526d33ddd37b0e98d895 Mon Sep 17 00:00:00 2001 From: eddy Date: Sat, 1 Aug 2026 22:57:40 +0200 Subject: [PATCH 6/6] docs: purge remaining S3R references from historical docs and handleiding --- docs/superpowers/plans/2025-07-28-esp32-pico-d4-port.md | 2 +- docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md | 4 ++-- .../specs/2026-07-28-esp32-pico-d4-port-design.md | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/superpowers/plans/2025-07-28-esp32-pico-d4-port.md b/docs/superpowers/plans/2025-07-28-esp32-pico-d4-port.md index ac323fb..58b5e49 100644 --- a/docs/superpowers/plans/2025-07-28-esp32-pico-d4-port.md +++ b/docs/superpowers/plans/2025-07-28-esp32-pico-d4-port.md @@ -167,7 +167,7 @@ adb -s :5555 shell am start -n com.eddy.atomrelay/.MainActivity **Files:** N/A (manual verification) - [ ] **Step 1: Ensure phone and ESP32 are powered and within range** -- [ ] **Step 2: Open app → auto-scan should find "AtomS3R-Relay"** +- [ ] **Step 2: Open app → auto-scan should find "SylDa_Server"** - [ ] **Step 3: Verify status shows "Connected"** - [ ] **Step 4: Hold HOLD button → relay should activate (verify with multimeter or relay click)** - [ ] **Step 5: Release → relay deactivates** diff --git a/docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md b/docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md index 9481b66..4129553 100644 --- a/docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md +++ b/docs/superpowers/plans/2026-07-28-esp32-pico-d4-port.md @@ -147,7 +147,7 @@ With: Replace (line 151): ```cpp - BLEDevice::init("AtomS3R-Relay"); + BLEDevice::init("SylDa_Server"); ``` With: @@ -157,7 +157,7 @@ With: Replace (line 174): ```cpp - Serial.println("BLE: advertising started as 'AtomS3R-Relay'"); + Serial.println("BLE: advertising started as 'SylDa_Server'"); ``` With: diff --git a/docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md b/docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md index 7e5e9a6..cce8b93 100644 --- a/docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md +++ b/docs/superpowers/specs/2026-07-28-esp32-pico-d4-port-design.md @@ -45,9 +45,9 @@ Create branch `esp32picod4` via git worktree at `.worktrees/esp32picod4` to isol | `RELAY_PIN` | 1 | 32 | G32 | | `LED_PIN` | 27 | 27 | SK6812 Neopixel — replaces `digitalWrite` with FastLED API | -**BLE device name:** `"SyldaServer"` (was `"AtomS3R-Relay"`) +**BLE device name:** `"SylDa_Server"` (was `"SyldaServer"`) -**Serial banner:** `"Atom Lite BLE Relay"` (was `"Atom VoiceS3R BLE Relay"`) +**Serial banner:** `"Atom Lite BLE Relay"` (was `"SylDa BLE Relay"`) **LED code change:** Replace `digitalWrite(LED_PIN, HIGH/LOW)` with FastLED: - Include `FastLED.h` @@ -113,7 +113,7 @@ The `SettingsActivity.setupCdcControl()` sets DTR|RTS both HIGH for normal seria | `src/main.cpp` | New pin definitions, BLE name, FastLED LED code | | `android/.../UsbUtils.kt` | Add `hasCdcDataInterface()` | | `android/.../SettingsActivity.kt` | VID filter → CDC class filter | -| `tools/copy_firmware.sh` | Environment name `m5stack-atoms3r` → `s3lite-server` | +| `tools/copy_firmware.sh` | Environment name → `s3lite-server` | ## Files Not Changed