firmware: v8 — handshake GO/OK bidireccional
Problema raiz: el bootloader ROM del ESP32 emite logs a 115200 baud. Al recibirlos a 9600 baud en el ESP8266 salen bytes aleatorios, alguno de los cuales puede ser F/B/L/R (mover ruedas) o '!' (activar espReady). Solucion: handshake con string de 2 chars "GO\n" / "OK\n": - ESP32-CAM envia "GO\n" cada 300ms hasta recibir "OK\n" - ESP8266 descarta todo el buffer al arrancar (basura del bootloader), luego espera exactamente "GO\n" y responde "OK\n" - En loop(), si ESP32 reinicia y manda "G", el ESP8266 repite el handshake - Probabilidad de falso positivo: << 1 en millones vs ~40% del '!' solo Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
// ================================================================
|
// ================================================================
|
||||||
// OTA CONFIG
|
// OTA CONFIG
|
||||||
// ================================================================
|
// ================================================================
|
||||||
#define FW_VERSION 6
|
#define FW_VERSION 8
|
||||||
#define GITEA_HOST "https://git.nacho.myds.me"
|
#define GITEA_HOST "https://git.nacho.myds.me"
|
||||||
#define GITEA_OWNER "Natxo"
|
#define GITEA_OWNER "Natxo"
|
||||||
#define GITEA_REPO "Arduino-Car"
|
#define GITEA_REPO "Arduino-Car"
|
||||||
@@ -99,20 +99,39 @@ static void checkOTA() {
|
|||||||
WiFi.mode(WIFI_OFF); // apaga radio para ahorrar energía
|
WiFi.mode(WIFI_OFF); // apaga radio para ahorrar energía
|
||||||
}
|
}
|
||||||
|
|
||||||
bool espReady = false; // true cuando el ESP32-CAM ha enviado '!'
|
bool espReady = false;
|
||||||
|
|
||||||
|
// ── Handshake con ESP32-CAM ──────────────────────────────────────
|
||||||
|
// Descarta basura del bootloader ROM (115200 baud → bytes aleatorios),
|
||||||
|
// luego espera exactamente "GO\n" y responde "OK\n".
|
||||||
void waitForReady() {
|
void waitForReady() {
|
||||||
// Espera la señal '!' del ESP32-CAM (máx 90s por si hace OTA)
|
// Descarta todo lo que haya en el buffer (logs de arranque del ESP32)
|
||||||
|
delay(300);
|
||||||
|
while (Serial.available()) Serial.read();
|
||||||
|
|
||||||
|
// Espera "GO\n" del ESP32-CAM (máx 90s por si está haciendo OTA)
|
||||||
unsigned long timeout = millis() + 90000UL;
|
unsigned long timeout = millis() + 90000UL;
|
||||||
|
String buf = "";
|
||||||
while (millis() < timeout) {
|
while (millis() < timeout) {
|
||||||
if (Serial.available()) {
|
while (Serial.available()) {
|
||||||
char c = Serial.read();
|
char c = Serial.read();
|
||||||
if (c == '!') { espReady = true; return; }
|
if (c == '\n') {
|
||||||
|
buf.trim();
|
||||||
|
if (buf == "GO") {
|
||||||
|
Serial.print("OK\n");
|
||||||
|
delay(50);
|
||||||
|
while (Serial.available()) Serial.read(); // flush post-handshake
|
||||||
|
espReady = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buf = "";
|
||||||
|
} else if (c != '\r') {
|
||||||
|
if (buf.length() < 8) buf += c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delay(10);
|
delay(10);
|
||||||
}
|
}
|
||||||
// Timeout: arranca igual para no quedarse bloqueado indefinidamente
|
espReady = true; // timeout: arranca igual
|
||||||
espReady = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
@@ -145,10 +164,17 @@ void loop() {
|
|||||||
if (Serial.available()) {
|
if (Serial.available()) {
|
||||||
char c = Serial.read();
|
char c = Serial.read();
|
||||||
|
|
||||||
// Señal de listo del ESP32-CAM (también en loop por si reinicia)
|
// Detecta re-arranque del ESP32-CAM: envía "GO\n" de nuevo
|
||||||
if (c == '!') { espReady = true; return; }
|
if (c == 'G') {
|
||||||
|
Serial.readStringUntil('\n'); // consume "O\n"
|
||||||
|
Serial.print("OK\n");
|
||||||
|
delay(50);
|
||||||
|
while (Serial.available()) Serial.read();
|
||||||
|
espReady = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Ignorar todo hasta recibir '!' — evita movimientos al arrancar
|
// Ignorar todo hasta completar el handshake
|
||||||
if (!espReady) return;
|
if (!espReady) return;
|
||||||
|
|
||||||
if (c == 'F') forward();
|
if (c == 'F') forward();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
// ================================================================
|
// ================================================================
|
||||||
// OTA CONFIG
|
// OTA CONFIG
|
||||||
// ================================================================
|
// ================================================================
|
||||||
#define FW_VERSION 7
|
#define FW_VERSION 8
|
||||||
#define GITEA_HOST "https://git.nacho.myds.me"
|
#define GITEA_HOST "https://git.nacho.myds.me"
|
||||||
#define GITEA_OWNER "Natxo"
|
#define GITEA_OWNER "Natxo"
|
||||||
#define GITEA_REPO "Arduino-Car"
|
#define GITEA_REPO "Arduino-Car"
|
||||||
@@ -24,6 +24,26 @@ const char *password = "Suprak1llm1ndS23S";
|
|||||||
void startCameraServer();
|
void startCameraServer();
|
||||||
void setupLedFlash();
|
void setupLedFlash();
|
||||||
|
|
||||||
|
// ── Handshake bidireccional con ESP8266 ─────────────────────────
|
||||||
|
// Envía "GO\n" cada 300ms hasta recibir "OK\n".
|
||||||
|
// Protege contra basura del bootloader ROM (115200 baud → bytes aleatorios).
|
||||||
|
static void handshakeEsp8266() {
|
||||||
|
unsigned long deadline = millis() + 30000UL; // máx 30s
|
||||||
|
while (millis() < deadline) {
|
||||||
|
Serial.print("GO\n");
|
||||||
|
unsigned long t = millis();
|
||||||
|
while (millis() - t < 300) {
|
||||||
|
if (Serial.available()) {
|
||||||
|
String resp = Serial.readStringUntil('\n');
|
||||||
|
resp.trim();
|
||||||
|
if (resp == "OK") return;
|
||||||
|
}
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Timeout: continúa sin confirmación
|
||||||
|
}
|
||||||
|
|
||||||
// ── OTA: comprueba si hay firmware nuevo y actualiza si hace falta ──
|
// ── OTA: comprueba si hay firmware nuevo y actualiza si hace falta ──
|
||||||
static void checkOTA() {
|
static void checkOTA() {
|
||||||
WiFiClientSecure client;
|
WiFiClientSecure client;
|
||||||
@@ -147,9 +167,8 @@ void setup() {
|
|||||||
// ── Servidor cámara ───────────────────────────────────────────────
|
// ── Servidor cámara ───────────────────────────────────────────────
|
||||||
startCameraServer();
|
startCameraServer();
|
||||||
|
|
||||||
// Señal al ESP8266: estoy listo, puede empezar a procesar comandos
|
// Handshake bidireccional: espera ACK del ESP8266
|
||||||
delay(200);
|
handshakeEsp8266();
|
||||||
Serial.print("!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
7
|
8
|
||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
6
|
8
|
||||||
Reference in New Issue
Block a user