Coche RC con OTA via Gitea
- ESP32-CAM: servidor web, stream MJPEG, control motores via Serial - ESP8266/Wemos D1: control motores DC, servos pan/tilt, buzzer - OTA automatico en arranque via Gitea (HTTPS, WiFiClientSecure) - Interfaz web rediseñada: full-screen, tema gaming, reconexion de stream - partitions.csv con esquema dual OTA (2x1.75MB) para ESP32-CAM - firmware/ con version.txt inicial para cada placa Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
186
ESP8266/ESP8266.ino
Normal file
186
ESP8266/ESP8266.ino
Normal file
@@ -0,0 +1,186 @@
|
||||
#include <Servo.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClientSecureBearSSL.h>
|
||||
#include <ESP8266HTTPClient.h>
|
||||
#include <ESP8266httpUpdate.h>
|
||||
|
||||
// ================================================================
|
||||
// OTA CONFIG
|
||||
// ================================================================
|
||||
#define FW_VERSION 1
|
||||
#define GITEA_HOST "https://git.nacho.myds.me"
|
||||
#define GITEA_OWNER "Natxo"
|
||||
#define GITEA_REPO "Arduino-Car"
|
||||
#define GITEA_BRANCH "main"
|
||||
// WiFi — mismas credenciales que usa el ESP32-CAM
|
||||
#define WIFI_SSID "Natxo"
|
||||
#define WIFI_PASS "Suprak1llm1ndS23S"
|
||||
// ================================================================
|
||||
|
||||
// ==== Pines motores ====
|
||||
const int ENA = D1;
|
||||
const int ENB = D5;
|
||||
const int IN1 = D6;
|
||||
const int IN2 = D7;
|
||||
const int IN3 = D2;
|
||||
const int IN4 = D0;
|
||||
|
||||
// ==== Pines servos ====
|
||||
const int SERVO_X_PIN = D3;
|
||||
const int SERVO_Y_PIN = D4;
|
||||
|
||||
// ==== Pines buzzer ====
|
||||
const int buzzerPin = D8;
|
||||
|
||||
Servo servoX;
|
||||
Servo servoY;
|
||||
|
||||
int currentSpeed = 150;
|
||||
int posX = 90;
|
||||
int posY = 90;
|
||||
|
||||
// ── OTA: comprueba si hay firmware nuevo y actualiza si hace falta ──
|
||||
static void checkOTA() {
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASS);
|
||||
|
||||
int tries = 0;
|
||||
while (WiFi.status() != WL_CONNECTED && tries < 20) {
|
||||
delay(500);
|
||||
tries++;
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
WiFi.disconnect();
|
||||
WiFi.mode(WIFI_OFF);
|
||||
return; // sin WiFi, arranque normal
|
||||
}
|
||||
|
||||
BearSSL::WiFiClientSecure client;
|
||||
client.setInsecure(); // cert Let's Encrypt/autofirmado — OK para LAN privada
|
||||
HTTPClient http;
|
||||
|
||||
String base = String(GITEA_HOST) + "/" + GITEA_OWNER + "/" + GITEA_REPO
|
||||
+ "/raw/branch/" + GITEA_BRANCH + "/firmware/esp8266/";
|
||||
|
||||
http.begin(client, base + "version.txt");
|
||||
http.setTimeout(5000);
|
||||
int code = http.GET();
|
||||
String body;
|
||||
if (code == HTTP_CODE_OK) body = http.getString();
|
||||
http.end();
|
||||
|
||||
if (code == HTTP_CODE_OK) {
|
||||
int remoteVer = body.trim().toInt();
|
||||
if (remoteVer > FW_VERSION) {
|
||||
BearSSL::WiFiClientSecure updateClient;
|
||||
updateClient.setInsecure();
|
||||
ESPhttpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
||||
ESPhttpUpdate.rebootOnUpdate(true);
|
||||
ESPhttpUpdate.update(updateClient, base + "firmware.bin");
|
||||
// Si llega aquí, el update falló — continúa arranque normal
|
||||
}
|
||||
}
|
||||
|
||||
WiFi.disconnect();
|
||||
WiFi.mode(WIFI_OFF); // apaga radio para ahorrar energía
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// OTA primero (usa WiFi)
|
||||
checkOTA();
|
||||
|
||||
// Esperar hasta que hayan pasado ~15s desde el arranque
|
||||
// para dar tiempo al ESP32-CAM a conectarse y levantar el servidor
|
||||
unsigned long elapsed = millis();
|
||||
if (elapsed < 15000) {
|
||||
delay(15000 - elapsed);
|
||||
}
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
pinMode(ENA, OUTPUT);
|
||||
pinMode(ENB, OUTPUT);
|
||||
pinMode(IN1, OUTPUT);
|
||||
pinMode(IN2, OUTPUT);
|
||||
pinMode(IN3, OUTPUT);
|
||||
pinMode(IN4, OUTPUT);
|
||||
|
||||
stopMotors();
|
||||
|
||||
analogWriteRange(255);
|
||||
analogWriteFreq(1000);
|
||||
|
||||
servoX.attach(SERVO_X_PIN);
|
||||
servoY.attach(SERVO_Y_PIN);
|
||||
|
||||
pinMode(buzzerPin, OUTPUT);
|
||||
|
||||
servoX.write(posX);
|
||||
servoY.write(posY);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.available()) {
|
||||
char c = Serial.read();
|
||||
|
||||
if (c == 'F') forward();
|
||||
else if (c == 'B') backward();
|
||||
else if (c == 'L') left();
|
||||
else if (c == 'R') right();
|
||||
else if (c == 'S') stopMotors();
|
||||
|
||||
else if (c == 'V') {
|
||||
int val = Serial.parseInt();
|
||||
if (val >= 0 && val <= 255) currentSpeed = val;
|
||||
}
|
||||
else if (c == 'X') {
|
||||
int val = Serial.parseInt();
|
||||
if (val >= 0 && val <= 180) { posX = val; servoX.write(posX); }
|
||||
}
|
||||
else if (c == 'Y') {
|
||||
int val = Serial.parseInt();
|
||||
if (val >= 0 && val <= 180) { posY = val; servoY.write(posY); }
|
||||
}
|
||||
else if (c == 'H') {
|
||||
int val = Serial.parseInt();
|
||||
digitalWrite(buzzerPin, val > 0 ? HIGH : LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==== Funciones de movimiento ====
|
||||
void forward() {
|
||||
analogWrite(ENA, currentSpeed);
|
||||
analogWrite(ENB, currentSpeed);
|
||||
digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH);
|
||||
digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH);
|
||||
}
|
||||
|
||||
void backward() {
|
||||
analogWrite(ENA, currentSpeed);
|
||||
analogWrite(ENB, currentSpeed);
|
||||
digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
|
||||
digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW);
|
||||
}
|
||||
|
||||
void left() {
|
||||
analogWrite(ENA, currentSpeed);
|
||||
analogWrite(ENB, currentSpeed);
|
||||
digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH);
|
||||
digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW);
|
||||
}
|
||||
|
||||
void right() {
|
||||
analogWrite(ENA, currentSpeed);
|
||||
analogWrite(ENB, currentSpeed);
|
||||
digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
|
||||
digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH);
|
||||
}
|
||||
|
||||
void stopMotors() {
|
||||
analogWrite(ENA, 0);
|
||||
analogWrite(ENB, 0);
|
||||
digitalWrite(IN1, LOW); digitalWrite(IN2, LOW);
|
||||
digitalWrite(IN3, LOW); digitalWrite(IN4, LOW);
|
||||
}
|
||||
Reference in New Issue
Block a user