Control inalámbrico de luces para casilla rodante con ESP8266 + ESP-NOW
Hola a todos; Quiero compartirles un proyecto que desarrollé para resolver un problema bastante común en casillas rodantes o carros: el cable que une el vehículo con el tráiler para manejar las luces (posición, giro, freno, etc.).
Les parecera un proyecto absurdo, pero justamente hoy en dia "ya es un producto bastante comercial" y brinda varias soluciones practicas frente a problemas que con el uso, ese cable se corta, se sulfata, se desconecta… o simplemente molesta.
La idea de este proyecto fue simple:
Y todo usando ESP8266 y el protocolo ESP-NOW.
¿Cómo funciona el sistema?
El proyecto se divide en dos partes:
1_ Módulo Transmisor (TX) – Va en el vehículo... Este módulo:
2_ Módulo Receptor (RX) – Va en la casilla rodante... Este módulo:
De esta manera:
Vehículo → (Wireless) → Casilla "sin cables entre ambos"...
¿Qué es ESP-NOW?
ESP-NOW es un protocolo de comunicación inalámbrica creado por Espressif (los fabricantes del ESP32); Lo interesante es que:
A diferencia del WiFi tradicional:
La lógica del sketch es bastante simple:
1_ En el Transmisor:
Entrada → Envío → Recepción → Salida
¿Puede hacerlo / armarlo alguien sin experiencia?
Sí!; La idea del proyecto es que cualquiera pueda:
Ventajas del sistema
NOTAS: La versión V1 y V2 difieren de que una esta pensada para emplear el PCB que les comparto, y la otra para implementar los Shield RELAY comerciales que emplean lógica de control inversa...
A_ La version 1 sirve para implementar el diseño del siguiente PCB
RX_LucesWIFI_v1.ino
TX_LucesWIFI_v1.ino
A_ La version 2 sirve para implementar directamente los SHIELD RELAY comerciales
RX_LucesWIFI_v2.ino
TX_LucesWIFI_v2.ino
Hola a todos; Quiero compartirles un proyecto que desarrollé para resolver un problema bastante común en casillas rodantes o carros: el cable que une el vehículo con el tráiler para manejar las luces (posición, giro, freno, etc.).
Les parecera un proyecto absurdo, pero justamente hoy en dia "ya es un producto bastante comercial" y brinda varias soluciones practicas frente a problemas que con el uso, ese cable se corta, se sulfata, se desconecta… o simplemente molesta.
La idea de este proyecto fue simple:
"Reemplazar completamente el cable físico por un sistema inalámbrico confiable"
Y todo usando ESP8266 y el protocolo ESP-NOW.
¿Cómo funciona el sistema?
El proyecto se divide en dos partes:
1_ Módulo Transmisor (TX) – Va en el vehículo... Este módulo:
- Toma las señales de las luces del auto (giro izquierdo, giro derecho, freno, posición, etc.).
- Las detecta mediante entradas protegidas.
- Las envía de forma inalámbrica al módulo receptor.
2_ Módulo Receptor (RX) – Va en la casilla rodante... Este módulo:
- Recibe los datos inalámbricos.
- Activa relés.
- Los relés manejan las luces del carro.
De esta manera:
Vehículo → (Wireless) → Casilla "sin cables entre ambos"...
¿Qué es ESP-NOW?
ESP-NOW es un protocolo de comunicación inalámbrica creado por Espressif (los fabricantes del ESP32); Lo interesante es que:
- No necesita WiFi.
- No necesita router.
- No necesita internet.
- Es muy rápido.
- Es muy estable.
- Consume muy poca energía.
A diferencia del WiFi tradicional:
- No hay red.
- No hay contraseña.
- No hay configuración complicada.
- Solo se emparejan por la dirección MAC y listo.
- Para este tipo de proyecto (donde solo necesitamos enviar estados ON/OFF) es perfecto.
La lógica del sketch es bastante simple:
1_ En el Transmisor:
- Lee el estado de cada entrada.
- Guarda esos estados en una estructura.
- Envía esa estructura mediante ESP-NOW.
- Recibe la estructura.
- Actualiza las salidas según los datos recibidos.
- Activa o desactiva relés.
Entrada → Envío → Recepción → Salida
- No hay delays complejos.
- No hay librerías raras.
- Solo la librería ESP-NOW incluida en el ESP8266.
¿Puede hacerlo / armarlo alguien sin experiencia?
Sí!; La idea del proyecto es que cualquiera pueda:
- Entender cómo funciona el circuito.
- Copiar el sketch en el IDE Arduino.
- Cargarlo en dos ESP8266.
- Armar la placa o hacerlo en protoboard.
- Tener su sistema inalámbrico funcionando.
- No hace falta ser experto en RF.
- No hace falta saber redes.
- No hace falta saber WiFi avanzado.
Ventajas del sistema
- Elimina el cable entre vehículo y casilla
- Reduce falsos contactos
- Fácil de mantener
- Bajo costo
- Escalable (podés agregar más funciones)
- Muy bajo consumo
NOTAS: La versión V1 y V2 difieren de que una esta pensada para emplear el PCB que les comparto, y la otra para implementar los Shield RELAY comerciales que emplean lógica de control inversa...
A_ La version 1 sirve para implementar el diseño del siguiente PCB
RX_LucesWIFI_v1.ino
CSS:
/////////////////////////////////////////////////////////////////////
// Control Inalambrico para luces de carro/casilla rodante //
// NOTA:RX Version 1 con Logica directa para salida RELAY //
// prof.martintorres@educ.ar - ETI PAtagonia //
/////////////////////////////////////////////////////////////////////
#include <esp_now.h>
#include <WiFi.h>
typedef struct struct_message
{
bool izq;
bool der;
bool pos;
bool freno;
bool aux;
} struct_message;
struct_message datosRecibidos;
const int rAux = 2, rIzq = 14, rDer = 12, rPos = 13, rFreno = 15;
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len)
{
memcpy(&datosRecibidos, incomingData, sizeof(datosRecibidos));
digitalWrite(rIzq, datosRecibidos.izq);
digitalWrite(rDer, datosRecibidos.der);
digitalWrite(rPos, datosRecibidos.pos);
digitalWrite(rFreno, datosRecibidos.freno);
// digitalWrite(rAux, datosRecibidos.aux);
}
void setup()
{
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) return;
pinMode(rIzq, OUTPUT);
pinMode(rDer, OUTPUT);
pinMode(rPos, OUTPUT);
pinMode(rFreno, OUTPUT);
// pinMode(rAux, OUTPUT);
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {}
TX_LucesWIFI_v1.ino
CSS:
/////////////////////////////////////////////////////////////////////
// Control Inalambrico para luces de carro/casilla rodante //
// NOTA:TX Version 1 con Logica directa para salida RELAY //
// prof.martintorres@educ.ar - ETI PAtagonia //
/////////////////////////////////////////////////////////////////////
#include <esp_now.h>
#include <WiFi.h>
typedef struct struct_message
{
bool izq;
bool der;
bool pos;
bool freno;
bool aux;
} struct_message;
struct_message datosLuces;
uint8_t broadcastAddress[] = {0x84, 0xCC, 0xA8, 0xAD, 0x01, 0x04}; // <-- PONER LA MAC ACA CON EL OTRO SKETCH QUE ARME
const int PINaUX = 2, pinIzq = 14, pinDer = 12, pinPos = 13, pinFreno = 15;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) return;
esp_now_peer_info_t peerInfo = {};
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
esp_now_add_peer(&peerInfo);
pinMode(pinIzq, INPUT_PULLDOWN);
pinMode(pinDer, INPUT_PULLDOWN);
pinMode(pinPos, INPUT_PULLDOWN);
pinMode(pinFreno, INPUT_PULLDOWN);
// pinMode(pinaUX, INPUT_PULLDOWN);
}
void loop()
{
datosLuces.izq = digitalRead(pinIzq);
datosLuces.der = digitalRead(pinDer);
datosLuces.pos = digitalRead(pinPos);
datosLuces.freno = digitalRead(pinFreno);
// datosLuces.iaux = digitalRead(pinAux);
esp_now_send(broadcastAddress, (uint8_t *) &datosLuces, sizeof(datosLuces));
delay(50);
}
A_ La version 2 sirve para implementar directamente los SHIELD RELAY comerciales
RX_LucesWIFI_v2.ino
CSS:
/////////////////////////////////////////////////////////////////////
// Control Inalambrico para luces de carro/casilla rodante //
// NOTA:RX Version 2 con Logica inversa de salida para SHIELD RELAY//
// prof.martintorres@educ.ar - ETI PAtagonia //
/////////////////////////////////////////////////////////////////////
#include <esp_now.h>
#include <WiFi.h>
typedef struct struct_message
{
bool izq, der, pos, freno, Aux;
} struct_message;
struct_message datosRecibidos;
unsigned long últimaConexion = 0;
//const int rAux = 2; // D4 - Salida Aux
const int rIzq = 14; // D5
const int rDer = 12; // D6
const int rPos = 13; // D7
const int rFre = 15; // D8
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len)
{
memcpy(&datosRecibidos, incomingData, sizeof(datosRecibidos));
últimaConexion = millis(); // Reseteamos temporizador de seguridad
// Lógica para Shield Relay (LOW = ON)
digitalWrite(rIzq, datosRecibidos.izq ? LOW : HIGH);
digitalWrite(rDer, datosRecibidos.der ? LOW : HIGH);
digitalWrite(rPos, datosRecibidos.pos ? LOW : HIGH);
digitalWrite(rFre, datosRecibidos.freno ? LOW : HIGH);
// digitalWrite(rAux, datosRecibidos.Aux ? LOW : HIGH);
}
void setup()
{
WiFi.mode(WIFI_STA);
// Configurar pines como salida y apagarlos (HIGH = OFF)
pinMode(rIzq, OUTPUT); digitalWrite(rIzq, HIGH);
pinMode(rDer, OUTPUT); digitalWrite(rDer, HIGH);
pinMode(rPos, OUTPUT); digitalWrite(rPos, HIGH);
pinMode(rFre, OUTPUT); digitalWrite(rFre, HIGH);
pinMode(rAux, OUTPUT); digitalWrite(rAux, HIGH);
if (esp_now_init() == ESP_OK)
{
esp_now_register_recv_cb(OnDataRecv);
}
}
void loop()
{
// SEGURIDAD: Si no hay señal por más de 2 seg, apagar todo
if (millis() - últimaConexion > 2000)
{
digitalWrite(rIzq, HIGH);
digitalWrite(rDer, HIGH);
digitalWrite(rPos, HIGH);
digitalWrite(rFre, HIGH);
}
}
TX_LucesWIFI_v2.ino
CSS:
/////////////////////////////////////////////////////////////////////
// Control Inalambrico para luces de carro/casilla rodante //
// NOTA:TX Version 2 con Logica inversa de salida para SHIELD RELAY//
// prof.martintorres@educ.ar - ETI PAtagonia //
/////////////////////////////////////////////////////////////////////
#include <esp_now.h>
#include <WiFi.h>
// ESTRUCTURA DE DATOS
typedef struct struct_message
{
bool izq;
bool der;
bool pos;
bool freno;
bool Aux;
} struct_message;
struct_message datosLuces;
uint8_t broadcastAddress[] = {0x84, 0xCC, 0xA8, 0xAD, 0x01, 0x04}; // <--PONER LA MAC ACÁ CON EL OTRO SKETCH QUE ARME
// PINES DE ENTRADA
const int pinIzq = 14, pinDer = 12, pinPos = 13, pinFreno = 15, pinAux = 2;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) return;
esp_now_peer_info_t peerInfo = {};
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
esp_now_add_peer(&peerInfo);
pinMode(pinIzq, INPUT_PULLUP);
pinMode(pinDer, INPUT_PULLUP);
pinMode(pinPos, INPUT_PULLUP);
pinMode(pinFreno, INPUT_PULLUP);
// pinMode(pinAux, INPUT_PULLUP);
}
void loop()
{
datosLuces.izq = !digitalRead(pinIzq);
datosLuces.der = !digitalRead(pinDer);
datosLuces.pos = !digitalRead(pinPos);
datosLuces.freno = !digitalRead(pinFreno);
// datosLuces.Aux = !digitalRead(pinAux);
esp_now_send(broadcastAddress, (uint8_t *) &datosLuces, sizeof(datosLuces));
delay(50);
}