firmware: v6 — handshake ! + heartbeat movimiento

ESP32-CAM:
- Envia '!' por Serial cuando el servidor esta listo
- Watchdog subido a 800ms (compatible con heartbeat 150ms)

ESP8266:
- waitForReady(): bloquea hasta recibir '!' (max 90s)
- loop(): ignora comandos hasta recibir '!' — sin movimiento al arrancar
- Si ESP32 se reinicia (OTA), detecta nuevo '!' y reanuda

Web (index.html):
- Heartbeat: reenvio del comando de movimiento cada 150ms mientras tecla/boton pulsado
- Mantiene vivo el watchdog y garantiza que el motor no pare solo
- carStop() limpia el intervalo y envia S al soltar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Natxo1000
2026-06-02 12:56:50 +02:00
parent e634138924
commit c1b587b0a8
10 changed files with 355 additions and 315 deletions

View File

@@ -7,7 +7,7 @@
// ================================================================
// OTA CONFIG
// ================================================================
#define FW_VERSION 4
#define FW_VERSION 6
#define GITEA_HOST "https://git.nacho.myds.me"
#define GITEA_OWNER "Natxo"
#define GITEA_REPO "Arduino-Car"
@@ -99,39 +99,58 @@ static void checkOTA() {
WiFi.mode(WIFI_OFF); // apaga radio para ahorrar energía
}
bool espReady = false; // true cuando el ESP32-CAM ha enviado '!'
void waitForReady() {
// Espera la señal '!' del ESP32-CAM (máx 90s por si hace OTA)
unsigned long timeout = millis() + 90000UL;
while (millis() < timeout) {
if (Serial.available()) {
char c = Serial.read();
if (c == '!') { espReady = true; return; }
}
delay(10);
}
// Timeout: arranca igual para no quedarse bloqueado indefinidamente
espReady = true;
}
void setup() {
// 1. Pines de motor y parada inmediata — evita que las ruedas giren al arrancar
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// 1. Pines y parada inmediata
pinMode(ENA, OUTPUT); pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
stopMotors();
// 2. Serial antes del OTA — así el ESP32-CAM puede enviar el pitido a tiempo
// 2. Serial temprano (el ESP32 puede mandar el pitido de OTA)
Serial.begin(9600);
// 3. OTA (WiFi on → check → WiFi off). El ESP32-CAM tarda >20s en enviar
// comandos de motor, así que no hay riesgo de movimiento involuntario.
// 3. OTA via WiFi
checkOTA();
// 4. Resto de periféricos
analogWriteRange(255);
analogWriteFreq(1000);
servoX.attach(SERVO_X_PIN);
servoY.attach(SERVO_Y_PIN);
pinMode(buzzerPin, OUTPUT);
servoX.write(posX);
servoY.write(posY);
// 5. Esperar señal '!' del ESP32-CAM antes de procesar comandos
waitForReady();
}
void loop() {
if (Serial.available()) {
char c = Serial.read();
// Señal de listo del ESP32-CAM (también en loop por si reinicia)
if (c == '!') { espReady = true; return; }
// Ignorar todo hasta recibir '!' — evita movimientos al arrancar
if (!espReady) return;
if (c == 'F') forward();
else if (c == 'B') backward();
else if (c == 'L') left();