Compare commits
12 changed files with 39 additions and 502 deletions
|
|
@ -35,13 +35,6 @@ M5Stack Atom S3 Lite (ESP32-S3), 2 relais, 2 touch sensors (HS-S43A), BLE, Andro
|
||||||
- Bestanden: `MainActivity.kt`, `SettingsActivity.kt`, `EspFlasher.kt`, `UsbSerialTransport.kt`, `PrefsHelper.kt`, `UsbUtils.kt`
|
- Bestanden: `MainActivity.kt`, `SettingsActivity.kt`, `EspFlasher.kt`, `UsbSerialTransport.kt`, `PrefsHelper.kt`, `UsbUtils.kt`
|
||||||
- Assets: `firmware/bootloader.bin`, `partitions.bin`, `boot_app0.bin`, `firmware.bin`
|
- Assets: `firmware/bootloader.bin`, `partitions.bin`, `boot_app0.bin`, `firmware.bin`
|
||||||
|
|
||||||
## Versiebeheer
|
|
||||||
|
|
||||||
- **Single source of truth:** `version.txt` (regels `server=N` en `client=N`)
|
|
||||||
- `src/version.h` wordt **automatisch gegenereerd** uit `version.txt` door PlatformIO pre-build script
|
|
||||||
- Nooit `version.h` handmatig bewerken — altijd `version.txt` aanpassen en `pio run` laten regenereren
|
|
||||||
- Firmwareversie ophogen: bump het nummer in `version.txt`, commit, rebuild firmware, kopieer `.bin` naar Android assets
|
|
||||||
|
|
||||||
## ADB — telefoon
|
## ADB — telefoon
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ android {
|
||||||
applicationId "nl.eddydevink.sylda"
|
applicationId "nl.eddydevink.sylda"
|
||||||
minSdk 26
|
minSdk 26
|
||||||
targetSdk 34
|
targetSdk 34
|
||||||
versionCode 2
|
versionCode 1
|
||||||
versionName "1.1"
|
versionName "1.0"
|
||||||
buildConfigField "String", "BUILD_NUMBER", "\"${new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new Date())}\""
|
buildConfigField "String", "BUILD_NUMBER", "\"${new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new Date())}\""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -40,8 +40,9 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
|
||||||
statusText.text = getString(R.string.status_connected)
|
statusText.text = getString(R.string.status_connected)
|
||||||
setupRelayButton()
|
setupRelayButton()
|
||||||
setupRelay2Button()
|
setupRelay2Button()
|
||||||
relay1Button.isEnabled = true
|
val isServer = PrefsHelper.getDeviceMode(this@MainActivity) == "server"
|
||||||
relay2Button.isEnabled = true
|
relay1Button.isEnabled = isServer
|
||||||
|
relay2Button.isEnabled = isServer
|
||||||
}
|
}
|
||||||
BleStatus.Disconnected -> {
|
BleStatus.Disconnected -> {
|
||||||
statusText.text = getString(R.string.status_connecting)
|
statusText.text = getString(R.string.status_connecting)
|
||||||
|
|
@ -106,8 +107,9 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
|
||||||
}
|
}
|
||||||
setupRelayButton()
|
setupRelayButton()
|
||||||
setupRelay2Button()
|
setupRelay2Button()
|
||||||
relay1Button.isEnabled = true
|
val isServer = PrefsHelper.getDeviceMode(this) == "server"
|
||||||
relay2Button.isEnabled = true
|
relay1Button.isEnabled = isServer
|
||||||
|
relay2Button.isEnabled = isServer
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java")
|
@Deprecated("Deprecated in Java")
|
||||||
|
|
|
||||||
|
|
@ -1,292 +0,0 @@
|
||||||
# LED Stable Connection 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:** Uniform LED signaling for server and client — LED acts as debug indicator, turns off after 60s stable connection.
|
|
||||||
|
|
||||||
**Architecture:** Shared LED state machine: OTA overrides all, then relay-flash overlay, then connection-status base color (Red=disconnected, Yellow=connected<60s, Off=stable>=60s). Both firmwares use identical logic.
|
|
||||||
|
|
||||||
**Tech Stack:** C++/Arduino, FastLED, NimBLE, ESP32-S3 (PlatformIO)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## File Map
|
|
||||||
|
|
||||||
| File | Action | Purpose |
|
|
||||||
|------|--------|---------|
|
|
||||||
| `src/main.cpp` | Modify | Server LED logic, new globals, remove setup blinks |
|
|
||||||
| `src/client.cpp` | Modify | Client LED logic, new globals, OTA placeholders |
|
|
||||||
| `src/version.h` | Modify | Version bumps (server 15→16, client 1→2) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 1: Server LED logic
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `src/main.cpp`
|
|
||||||
|
|
||||||
- [ ] **Step 1: Add new global variables after line 56 (after `int connectedCount = 0;`)**
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define STABLE_LED_TIMEOUT_MS 60000
|
|
||||||
uint32_t connectionStableMs = 0;
|
|
||||||
uint32_t relayFlashUntil = 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 2: Remove `ledOtaBusy()` function (lines 181-183)**
|
|
||||||
|
|
||||||
Delete this function — it will be inlined in the new LED logic:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
static void ledOtaBusy() {
|
|
||||||
leds[0] = (millis() / 100) % 2 ? CRGB::Green : CRGB::Black;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Remove all 3 lines.
|
|
||||||
|
|
||||||
- [ ] **Step 3: Replace setup LED blinks (lines 414-422) with solid red**
|
|
||||||
|
|
||||||
Replace:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
leds[0] = CRGB::Green;
|
|
||||||
FastLED.show();
|
|
||||||
delay(200);
|
|
||||||
leds[0] = CRGB::Black;
|
|
||||||
FastLED.show();
|
|
||||||
delay(200);
|
|
||||||
}
|
|
||||||
Serial.println("LED blink done, starting BLE...");
|
|
||||||
```
|
|
||||||
|
|
||||||
With:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
leds[0] = CRGB::Red;
|
|
||||||
FastLED.show();
|
|
||||||
Serial.println("LED red (no connection), starting BLE...");
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 4: Remove `leds[0] = CRGB::Yellow;` from otaReady handler (line 553)**
|
|
||||||
|
|
||||||
In the otaReady block (lines 542-558), remove line 553 `leds[0] = CRGB::Yellow;`. The wait-for-confirm LED is now handled by the main LED logic checking `otaInProgress && otaEnded`.
|
|
||||||
|
|
||||||
- [ ] **Step 5: Replace the LED block in loop() (lines 599-615) with new logic**
|
|
||||||
|
|
||||||
Replace lines 599-615:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
if (!otaInProgress) {
|
|
||||||
relay1State = t1Active || btnActive ||
|
|
||||||
(connActive[0] && bleRelay1[0]) || (connActive[1] && bleRelay1[1]);
|
|
||||||
relay2State = t2Active ||
|
|
||||||
(connActive[0] && bleRelay2[0]) || (connActive[1] && bleRelay2[1]);
|
|
||||||
|
|
||||||
leds[0] = (connectedCount > 0) ? CRGB::Green : CRGB::Black;
|
|
||||||
} else {
|
|
||||||
relay1State = false;
|
|
||||||
relay2State = false;
|
|
||||||
ledOtaBusy();
|
|
||||||
}
|
|
||||||
|
|
||||||
digitalWrite(RELAY1_PIN, relay1State ? HIGH : LOW);
|
|
||||||
digitalWrite(RELAY2_PIN, relay2State ? HIGH : LOW);
|
|
||||||
|
|
||||||
FastLED.show();
|
|
||||||
```
|
|
||||||
|
|
||||||
With:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
if (!otaInProgress) {
|
|
||||||
relay1State = t1Active || btnActive ||
|
|
||||||
(connActive[0] && bleRelay1[0]) || (connActive[1] && bleRelay1[1]);
|
|
||||||
relay2State = t2Active ||
|
|
||||||
(connActive[0] && bleRelay2[0]) || (connActive[1] && bleRelay2[1]);
|
|
||||||
} else {
|
|
||||||
relay1State = false;
|
|
||||||
relay2State = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- LED logic ---
|
|
||||||
CRGB ledColor;
|
|
||||||
|
|
||||||
if (otaInProgress) {
|
|
||||||
ledColor = otaEnded
|
|
||||||
? CRGB::Yellow
|
|
||||||
: (((millis() / 100) % 2) ? CRGB::Green : CRGB::Black);
|
|
||||||
} else {
|
|
||||||
if (connectedCount > 0) {
|
|
||||||
if (connectionStableMs == 0) connectionStableMs = millis();
|
|
||||||
} else {
|
|
||||||
connectionStableMs = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectedCount > 0) {
|
|
||||||
ledColor = (millis() - connectionStableMs >= STABLE_LED_TIMEOUT_MS)
|
|
||||||
? CRGB::Black
|
|
||||||
: CRGB::Yellow;
|
|
||||||
} else {
|
|
||||||
ledColor = CRGB::Red;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool lastRelayActive = false;
|
|
||||||
bool relayActive = relay1State || relay2State;
|
|
||||||
if (relayActive != lastRelayActive) {
|
|
||||||
relayFlashUntil = millis() + 150;
|
|
||||||
}
|
|
||||||
lastRelayActive = relayActive;
|
|
||||||
|
|
||||||
if (millis() < relayFlashUntil) {
|
|
||||||
ledColor = CRGB::Green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
leds[0] = ledColor;
|
|
||||||
|
|
||||||
digitalWrite(RELAY1_PIN, relay1State ? HIGH : LOW);
|
|
||||||
digitalWrite(RELAY2_PIN, relay2State ? HIGH : LOW);
|
|
||||||
|
|
||||||
FastLED.show();
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 6: Commit server changes**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git add src/main.cpp
|
|
||||||
git commit -m "feat(server): uniform LED signaling — off after 60s stable connection"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 2: Client LED logic
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `src/client.cpp`
|
|
||||||
|
|
||||||
- [ ] **Step 1: Add new global variables after line 48 (after `static uint32_t seq = 0;`)**
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define STABLE_LED_TIMEOUT_MS 60000
|
|
||||||
uint32_t connectionStableMs = 0;
|
|
||||||
uint32_t relayFlashUntil = 0;
|
|
||||||
bool otaInProgress = false;
|
|
||||||
bool otaEnded = false;
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 2: Replace the LED block in loop() (lines 368-375) with new logic**
|
|
||||||
|
|
||||||
Replace lines 368-375:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
if (relay1State || relay2State) {
|
|
||||||
leds[0] = CRGB::Green;
|
|
||||||
} else if (connected) {
|
|
||||||
leds[0] = CRGB::Blue;
|
|
||||||
} else {
|
|
||||||
leds[0] = CRGB::Red;
|
|
||||||
}
|
|
||||||
FastLED.show();
|
|
||||||
```
|
|
||||||
|
|
||||||
With:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
// --- LED logic ---
|
|
||||||
CRGB ledColor;
|
|
||||||
|
|
||||||
if (otaInProgress) {
|
|
||||||
ledColor = otaEnded
|
|
||||||
? CRGB::Yellow
|
|
||||||
: (((millis() / 100) % 2) ? CRGB::Green : CRGB::Black);
|
|
||||||
} else {
|
|
||||||
if (connected) {
|
|
||||||
if (connectionStableMs == 0) connectionStableMs = millis();
|
|
||||||
} else {
|
|
||||||
connectionStableMs = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connected) {
|
|
||||||
ledColor = (millis() - connectionStableMs >= STABLE_LED_TIMEOUT_MS)
|
|
||||||
? CRGB::Black
|
|
||||||
: CRGB::Yellow;
|
|
||||||
} else {
|
|
||||||
ledColor = CRGB::Red;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool lastRelayActive = false;
|
|
||||||
bool relayActive = relay1State || relay2State;
|
|
||||||
if (relayActive != lastRelayActive) {
|
|
||||||
relayFlashUntil = millis() + 150;
|
|
||||||
}
|
|
||||||
lastRelayActive = relayActive;
|
|
||||||
|
|
||||||
if (millis() < relayFlashUntil) {
|
|
||||||
ledColor = CRGB::Green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
leds[0] = ledColor;
|
|
||||||
FastLED.show();
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 3: Commit client changes**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git add src/client.cpp
|
|
||||||
git commit -m "feat(client): uniform LED signaling — off after 60s stable connection"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 3: Version bumps
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `src/version.h`
|
|
||||||
|
|
||||||
- [ ] **Step 1: Bump versions**
|
|
||||||
|
|
||||||
Replace:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define FIRMWARE_VERSION_SERVER "15"
|
|
||||||
#define FIRMWARE_VERSION_CLIENT "1"
|
|
||||||
```
|
|
||||||
|
|
||||||
With:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#define FIRMWARE_VERSION_SERVER "16"
|
|
||||||
#define FIRMWARE_VERSION_CLIENT "2"
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 2: Commit version bump**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git add src/version.h
|
|
||||||
git commit -m "chore: bump server v16, client v2"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 4: Build verification
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- None (build only)
|
|
||||||
|
|
||||||
- [ ] **Step 1: Build server firmware**
|
|
||||||
|
|
||||||
Run: `pio run -e s3lite-server`
|
|
||||||
Expected: SUCCESS, no errors.
|
|
||||||
|
|
||||||
- [ ] **Step 2: Build client firmware**
|
|
||||||
|
|
||||||
Run: `pio run -e s3lite-client`
|
|
||||||
Expected: SUCCESS, no errors.
|
|
||||||
|
|
||||||
- [ ] **Step 3: Verify both targets compile cleanly**
|
|
||||||
|
|
||||||
Run: `pio run`
|
|
||||||
Expected: Both environments compile SUCCESS.
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
# LED-signalering: stabiele verbinding
|
|
||||||
|
|
||||||
**Issue:** [#4](https://git.eddydevink.nl/eddy/Project_SylDa/issues/4) — Leds mogen uit na een minuut stabiele verbinding
|
|
||||||
**Datum:** 2026-08-02
|
|
||||||
**Status:** goedgekeurd
|
|
||||||
|
|
||||||
## Doel
|
|
||||||
|
|
||||||
Uniforme LED-signalering voor zowel server als client. De LED dient als debug-indicator tijdens opstarten en bij verbindingsproblemen. Na 60 seconden continue stabiele verbinding schakelt de LED uit.
|
|
||||||
|
|
||||||
## Kleurenschema
|
|
||||||
|
|
||||||
Identiek voor server (`main.cpp`) en client (`client.cpp`):
|
|
||||||
|
|
||||||
| State | LED | Prioriteit |
|
|
||||||
|-------|-----|-----------|
|
|
||||||
| OTA in progress | Groen knipperend (100ms interval) | 1 (hoogst) |
|
|
||||||
| OTA completed, waiting confirm | Geel vast | 1 |
|
|
||||||
| Geen verbinding | Rood | 2 |
|
|
||||||
| Verbinding actief (< 60s) | Geel | 3 |
|
|
||||||
| Verbinding stabiel (>= 60s) | **Uit** | 4 (laagst) |
|
|
||||||
| Relais-flash (overlay) | Groen 150ms | overlay |
|
|
||||||
|
|
||||||
Relais-flash is een overlay: toont kort groen bij verandering in relais-status, daarna keert LED terug naar de kleur die hoort bij de huidige verbindingsstatus.
|
|
||||||
|
|
||||||
## Timer-logica
|
|
||||||
|
|
||||||
- Timer (`connectionStableMs`) start zodra de **eerste** verbinding tot stand komt
|
|
||||||
- `connectionStableMs` telt op zolang er minstens 1 verbinding is (connectedCount > 0 voor server, connected == true voor client)
|
|
||||||
- Nieuwe verbindingen die later bijkomen resetten de timer **niet**
|
|
||||||
- Bij disconnect van een verbinding terwijl er nog andere verbindingen zijn: timer loopt door
|
|
||||||
- Pas als **alle** verbindingen wegvallen: `connectionStableMs` = 0, LED direct rood
|
|
||||||
- Drempel: `STABLE_LED_TIMEOUT_MS = 60000`
|
|
||||||
|
|
||||||
### Server-specifiek
|
|
||||||
|
|
||||||
- `connectedCount`: aantal actieve BLE-clients (0-2)
|
|
||||||
- Timer loopt als `connectedCount > 0`
|
|
||||||
- Alle clients disconnect = reset
|
|
||||||
|
|
||||||
### Client-specifiek
|
|
||||||
|
|
||||||
- `connected`: boolean, of client verbonden is met server
|
|
||||||
- Timer loopt als `connected == true`
|
|
||||||
- Disconnect = reset
|
|
||||||
|
|
||||||
## Relais-flash mechanisme
|
|
||||||
|
|
||||||
- Detectie: vergelijk huidige relais-state met vorige loop-iteratie
|
|
||||||
- Bij verandering: zet `relayFlashUntil = millis() + 150`
|
|
||||||
- Zolang `millis() < relayFlashUntil`: LED groen (overschrijft verbindingskleur)
|
|
||||||
- Flash reset de 60s timer **niet**
|
|
||||||
- **Server:** detecteert verandering in `relay1State || relay2State` (combinatie van touch, button, en BLE-commands)
|
|
||||||
- **Client:** detecteert verandering in `relay1State || relay2State` (alleen touch/button)
|
|
||||||
|
|
||||||
## OTA (beide firmwares)
|
|
||||||
|
|
||||||
OTA heeft hoogste prioriteit en override alle andere LED-states:
|
|
||||||
|
|
||||||
- **OTA in progress** (`otaInProgress == true`): groen knipperend, 100ms interval
|
|
||||||
- **OTA completed, waiting confirm** (`otaEnded == true && !otaConfirmed`): geel vast
|
|
||||||
- **OTA confirm timeout** of **OTA error**: valt terug naar normale verbindings-LED
|
|
||||||
- **OTA success + reboot**: groen vast, dan reboot
|
|
||||||
|
|
||||||
Client heeft OTA-logica nog niet geïmplementeerd, maar de LED-code wordt alvast voorbereid met dezelfde OTA-override structuur zodat toekomstige OTA-implementatie direct past.
|
|
||||||
|
|
||||||
## LED-update volgorde in loop()
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Bepaal base-kleur op basis van verbindingsstatus (rood/geel/uit)
|
|
||||||
2. Controleer relais-flash: als actief -> groen
|
|
||||||
3. Controleer OTA-override: als actief -> OTA-kleur
|
|
||||||
4. FastLED.show()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Wijzigingen per bestand
|
|
||||||
|
|
||||||
### `src/main.cpp` (server)
|
|
||||||
|
|
||||||
- Toevoegen: `STABLE_LED_TIMEOUT_MS`, `connectionStableMs`, `relayFlashUntil`, `lastRelayActive`
|
|
||||||
- Aanpassen: LED-logica in `loop()` — base-kleur uit `connectionStableMs` i.p.v. `connectedCount > 0`
|
|
||||||
- Toevoegen: relais-flash detectie
|
|
||||||
- Behouden: OTA LED-override (werkt al, prioriteit blijft hoogst)
|
|
||||||
- Verwijderen: setup LED-blinks (drie groene knipperingen) — vervangen door rood (geen verbinding)
|
|
||||||
|
|
||||||
### `src/client.cpp` (client)
|
|
||||||
|
|
||||||
- Toevoegen: `STABLE_LED_TIMEOUT_MS`, `connectionStableMs`, `relayFlashUntil`, `lastRelayActive`
|
|
||||||
- Aanpassen: LED-logica in `loop()` — base-kleur uit `connectionStableMs`, geen aparte relais-kleur meer
|
|
||||||
- Toevoegen: relais-flash detectie
|
|
||||||
- Toevoegen: OTA-override structuur (placeholder, `otaInProgress` default `false`)
|
|
||||||
- Setup: LED rood i.p.v. direct rood (blijft rood, maar nu als onderdeel van uniform schema)
|
|
||||||
|
|
||||||
### `src/version.h`
|
|
||||||
|
|
||||||
- Server versie bump naar "16"
|
|
||||||
- Client versie bump naar "2"
|
|
||||||
|
|
@ -11,7 +11,7 @@ build_flags =
|
||||||
lib_deps =
|
lib_deps =
|
||||||
fastled/FastLED@^3
|
fastled/FastLED@^3
|
||||||
h2zero/NimBLE-Arduino@^2
|
h2zero/NimBLE-Arduino@^2
|
||||||
upload_port = /dev/serial/by-id/usb-Espressif_USB_JTAG_serial_debug_unit_44:1B:F6:F4:CF:14-if00
|
upload_port = /dev/ttyACM1
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
upload_flags = --no-stub
|
upload_flags = --no-stub
|
||||||
build_src_filter = +<main.cpp> -<client.cpp>
|
build_src_filter = +<main.cpp> -<client.cpp>
|
||||||
|
|
|
||||||
|
|
@ -47,12 +47,6 @@ static bool relay1SendState = false;
|
||||||
static bool relay2SendState = false;
|
static bool relay2SendState = false;
|
||||||
static uint32_t seq = 0;
|
static uint32_t seq = 0;
|
||||||
|
|
||||||
#define STABLE_LED_TIMEOUT_MS 60000
|
|
||||||
uint32_t connectionStableMs = 0;
|
|
||||||
uint32_t relayFlashUntil = 0;
|
|
||||||
bool otaInProgress = false;
|
|
||||||
bool otaEnded = false;
|
|
||||||
|
|
||||||
static bool bleReady = false;
|
static bool bleReady = false;
|
||||||
static bool serverFound = false;
|
static bool serverFound = false;
|
||||||
static NimBLEAddress serverAddress;
|
static NimBLEAddress serverAddress;
|
||||||
|
|
@ -368,43 +362,16 @@ void loop() {
|
||||||
}
|
}
|
||||||
prevBtnActive = btnActive;
|
prevBtnActive = btnActive;
|
||||||
|
|
||||||
bool relay1State = !t1Active || btnActive;
|
bool relay1State = t1Active || btnActive;
|
||||||
bool relay2State = !t2Active;
|
bool relay2State = t2Active;
|
||||||
|
|
||||||
CRGB ledColor;
|
if (relay1State || relay2State) {
|
||||||
|
leds[0] = CRGB::Green;
|
||||||
if (otaInProgress) {
|
} else if (connected) {
|
||||||
ledColor = otaEnded
|
leds[0] = CRGB::Blue;
|
||||||
? CRGB::Yellow
|
|
||||||
: (((millis() / 100) % 2) ? CRGB::Green : CRGB::Black);
|
|
||||||
} else {
|
} else {
|
||||||
if (connected) {
|
leds[0] = CRGB::Red;
|
||||||
if (connectionStableMs == 0) connectionStableMs = millis();
|
|
||||||
} else {
|
|
||||||
connectionStableMs = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connected) {
|
|
||||||
ledColor = (millis() - connectionStableMs >= STABLE_LED_TIMEOUT_MS)
|
|
||||||
? CRGB::Black
|
|
||||||
: CRGB::Yellow;
|
|
||||||
} else {
|
|
||||||
ledColor = CRGB::Red;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool lastRelayActive = false;
|
|
||||||
bool relayActive = relay1State || relay2State;
|
|
||||||
if (relayActive != lastRelayActive) {
|
|
||||||
relayFlashUntil = millis() + 150;
|
|
||||||
}
|
|
||||||
lastRelayActive = relayActive;
|
|
||||||
|
|
||||||
if (millis() < relayFlashUntil) {
|
|
||||||
ledColor = CRGB::Green;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
leds[0] = ledColor;
|
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
|
|
||||||
if (connected && pCmdChar != nullptr) {
|
if (connected && pCmdChar != nullptr) {
|
||||||
|
|
@ -459,8 +426,8 @@ void loop() {
|
||||||
static uint32_t heartbeat = 0;
|
static uint32_t heartbeat = 0;
|
||||||
if (millis() - heartbeat > 60000) {
|
if (millis() - heartbeat > 60000) {
|
||||||
Serial.printf("[heartbeat] t1=%s t2=%s btn=%s r1=%s r2=%s connected=%s\n",
|
Serial.printf("[heartbeat] t1=%s t2=%s btn=%s r1=%s r2=%s connected=%s\n",
|
||||||
!t1Active ? "YES" : "no",
|
t1Active ? "YES" : "no",
|
||||||
!t2Active ? "YES" : "no",
|
t2Active ? "YES" : "no",
|
||||||
btnActive ? "YES" : "no",
|
btnActive ? "YES" : "no",
|
||||||
relay1State ? "ON" : "OFF",
|
relay1State ? "ON" : "OFF",
|
||||||
relay2State ? "ON" : "OFF",
|
relay2State ? "ON" : "OFF",
|
||||||
|
|
|
||||||
71
src/main.cpp
71
src/main.cpp
|
|
@ -55,10 +55,6 @@ uint32_t lastSeq[MAX_CLIENTS] = {0, 0};
|
||||||
uint16_t connHandles[MAX_CLIENTS] = {0xFFFF, 0xFFFF};
|
uint16_t connHandles[MAX_CLIENTS] = {0xFFFF, 0xFFFF};
|
||||||
int connectedCount = 0;
|
int connectedCount = 0;
|
||||||
|
|
||||||
#define STABLE_LED_TIMEOUT_MS 60000
|
|
||||||
uint32_t connectionStableMs = 0;
|
|
||||||
uint32_t relayFlashUntil = 0;
|
|
||||||
|
|
||||||
bool otaInProgress = false;
|
bool otaInProgress = false;
|
||||||
esp_ota_handle_t otaHandle = 0;
|
esp_ota_handle_t otaHandle = 0;
|
||||||
const esp_partition_t *otaPartition = nullptr;
|
const esp_partition_t *otaPartition = nullptr;
|
||||||
|
|
@ -70,7 +66,6 @@ bool otaShaStarted = false;
|
||||||
bool otaReady = false;
|
bool otaReady = false;
|
||||||
bool otaEnded = false;
|
bool otaEnded = false;
|
||||||
bool otaConfirmed = false;
|
bool otaConfirmed = false;
|
||||||
bool otaEarlyConfirm = false;
|
|
||||||
uint32_t otaEndedAt = 0;
|
uint32_t otaEndedAt = 0;
|
||||||
#define OTA_CONFIRM_TIMEOUT_MS 10000
|
#define OTA_CONFIRM_TIMEOUT_MS 10000
|
||||||
|
|
||||||
|
|
@ -183,6 +178,10 @@ static void parseHexKey(const String &hex, uint8_t *out) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ledOtaBusy() {
|
||||||
|
leds[0] = (millis() / 100) % 2 ? CRGB::Green : CRGB::Black;
|
||||||
|
}
|
||||||
|
|
||||||
static void otaReset() {
|
static void otaReset() {
|
||||||
otaInProgress = false;
|
otaInProgress = false;
|
||||||
otaHandle = 0;
|
otaHandle = 0;
|
||||||
|
|
@ -192,7 +191,6 @@ static void otaReset() {
|
||||||
otaReady = false;
|
otaReady = false;
|
||||||
otaEnded = false;
|
otaEnded = false;
|
||||||
otaConfirmed = false;
|
otaConfirmed = false;
|
||||||
otaEarlyConfirm = false;
|
|
||||||
if (otaShaStarted) {
|
if (otaShaStarted) {
|
||||||
mbedtls_sha256_free(&otaShaCtx);
|
mbedtls_sha256_free(&otaShaCtx);
|
||||||
otaShaStarted = false;
|
otaShaStarted = false;
|
||||||
|
|
@ -298,8 +296,7 @@ class OtaCharacteristicCallbacks : public NimBLECharacteristicCallbacks {
|
||||||
Serial.printf("OTA: 0xFF received — otaReady=%d, otaEnded=%d, otaConfirmed=%d, otaInProgress=%d\n",
|
Serial.printf("OTA: 0xFF received — otaReady=%d, otaEnded=%d, otaConfirmed=%d, otaInProgress=%d\n",
|
||||||
otaReady, otaEnded, otaConfirmed, otaInProgress);
|
otaReady, otaEnded, otaConfirmed, otaInProgress);
|
||||||
if (!otaEnded) {
|
if (!otaEnded) {
|
||||||
Serial.println("OTA: 0xFF arrived early (esp_ota_end not yet called), deferring");
|
Serial.println("OTA: 0xFF IGNORED — otaEnded is false (esp_ota_end not yet called or failed)");
|
||||||
otaEarlyConfirm = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Serial.println("OTA: 0xFF confirm accepted, setting otaConfirmed=true");
|
Serial.println("OTA: 0xFF confirm accepted, setting otaConfirmed=true");
|
||||||
|
|
@ -414,9 +411,15 @@ void setup() {
|
||||||
pinMode(RELAY1_PIN, OUTPUT);
|
pinMode(RELAY1_PIN, OUTPUT);
|
||||||
pinMode(RELAY2_PIN, OUTPUT);
|
pinMode(RELAY2_PIN, OUTPUT);
|
||||||
|
|
||||||
leds[0] = CRGB::Red;
|
for (int i = 0; i < 3; i++) {
|
||||||
FastLED.show();
|
leds[0] = CRGB::Green;
|
||||||
Serial.println("LED red (no connection), starting BLE...");
|
FastLED.show();
|
||||||
|
delay(200);
|
||||||
|
leds[0] = CRGB::Black;
|
||||||
|
FastLED.show();
|
||||||
|
delay(200);
|
||||||
|
}
|
||||||
|
Serial.println("LED blink done, starting BLE...");
|
||||||
|
|
||||||
NimBLEDevice::init("SylDa_Server");
|
NimBLEDevice::init("SylDa_Server");
|
||||||
NimBLEDevice::setMTU(248);
|
NimBLEDevice::setMTU(248);
|
||||||
|
|
@ -547,18 +550,14 @@ void loop() {
|
||||||
Serial.println("OTA: esp_ota_end OK, setting otaEnded=true, waiting for 0xFF confirm");
|
Serial.println("OTA: esp_ota_end OK, setting otaEnded=true, waiting for 0xFF confirm");
|
||||||
otaEnded = true;
|
otaEnded = true;
|
||||||
otaEndedAt = millis();
|
otaEndedAt = millis();
|
||||||
|
leds[0] = CRGB::Yellow;
|
||||||
|
FastLED.show();
|
||||||
}
|
}
|
||||||
otaReady = false;
|
otaReady = false;
|
||||||
Serial.printf("OTA: otaReady cleared — otaReady=%d, otaEnded=%d, otaConfirmed=%d, otaInProgress=%d\n",
|
Serial.printf("OTA: otaReady cleared — otaReady=%d, otaEnded=%d, otaConfirmed=%d, otaInProgress=%d\n",
|
||||||
otaReady, otaEnded, otaConfirmed, otaInProgress);
|
otaReady, otaEnded, otaConfirmed, otaInProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (otaEnded && otaEarlyConfirm) {
|
|
||||||
Serial.println("OTA: processing deferred 0xFF confirm");
|
|
||||||
otaConfirmed = true;
|
|
||||||
otaEarlyConfirm = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (otaEnded && !otaConfirmed && (millis() - otaEndedAt > OTA_CONFIRM_TIMEOUT_MS)) {
|
if (otaEnded && !otaConfirmed && (millis() - otaEndedAt > OTA_CONFIRM_TIMEOUT_MS)) {
|
||||||
Serial.printf("OTA: 0xFF confirm timeout (%lu ms) — discarding update, resuming normal operation\n",
|
Serial.printf("OTA: 0xFF confirm timeout (%lu ms) — discarding update, resuming normal operation\n",
|
||||||
millis() - otaEndedAt);
|
millis() - otaEndedAt);
|
||||||
|
|
@ -602,46 +601,14 @@ void loop() {
|
||||||
(connActive[0] && bleRelay1[0]) || (connActive[1] && bleRelay1[1]);
|
(connActive[0] && bleRelay1[0]) || (connActive[1] && bleRelay1[1]);
|
||||||
relay2State = t2Active ||
|
relay2State = t2Active ||
|
||||||
(connActive[0] && bleRelay2[0]) || (connActive[1] && bleRelay2[1]);
|
(connActive[0] && bleRelay2[0]) || (connActive[1] && bleRelay2[1]);
|
||||||
|
|
||||||
|
leds[0] = (connectedCount > 0) ? CRGB::Green : CRGB::Black;
|
||||||
} else {
|
} else {
|
||||||
relay1State = false;
|
relay1State = false;
|
||||||
relay2State = false;
|
relay2State = false;
|
||||||
|
ledOtaBusy();
|
||||||
}
|
}
|
||||||
|
|
||||||
CRGB ledColor;
|
|
||||||
|
|
||||||
if (otaInProgress) {
|
|
||||||
ledColor = otaEnded
|
|
||||||
? CRGB::Yellow
|
|
||||||
: (((millis() / 100) % 2) ? CRGB::Green : CRGB::Black);
|
|
||||||
} else {
|
|
||||||
if (connectedCount > 0) {
|
|
||||||
if (connectionStableMs == 0) connectionStableMs = millis();
|
|
||||||
} else {
|
|
||||||
connectionStableMs = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectedCount > 0) {
|
|
||||||
ledColor = (millis() - connectionStableMs >= STABLE_LED_TIMEOUT_MS)
|
|
||||||
? CRGB::Black
|
|
||||||
: CRGB::Yellow;
|
|
||||||
} else {
|
|
||||||
ledColor = CRGB::Red;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool lastRelayActive = false;
|
|
||||||
bool relayActive = relay1State || relay2State;
|
|
||||||
if (relayActive != lastRelayActive) {
|
|
||||||
relayFlashUntil = millis() + 150;
|
|
||||||
}
|
|
||||||
lastRelayActive = relayActive;
|
|
||||||
|
|
||||||
if (millis() < relayFlashUntil) {
|
|
||||||
ledColor = CRGB::Green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
leds[0] = ledColor;
|
|
||||||
|
|
||||||
digitalWrite(RELAY1_PIN, relay1State ? HIGH : LOW);
|
digitalWrite(RELAY1_PIN, relay1State ? HIGH : LOW);
|
||||||
digitalWrite(RELAY2_PIN, relay2State ? HIGH : LOW);
|
digitalWrite(RELAY2_PIN, relay2State ? HIGH : LOW);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
// Auto-generated from version.txt — DO NOT EDIT
|
|
||||||
#define FIRMWARE_VERSION_SERVER "16"
|
|
||||||
#define FIRMWARE_VERSION_CLIENT "2"
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
server=16
|
server=15
|
||||||
client=2
|
client=1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue