Apertura automatica cancello con microcontrollore ESP 32
Qualche etologo sostiene che la pigrizia sia il primo motore immobile dell’innovazione. Non disapprovo questa tesi. Io però, oltre che indolente, sono anche smemorato. La combo è micidiale.
Troppo spesso mi è capitato di uscire dal garage, lasciare che la serranda mi si chiudesse alle spalle e all’ultimo clack realizzare di avere dimenticato le chiavi di casa in auto.
Non vi racconto lo sconforto.
Vi racconto invece come ho deciso di affrontare il problema.
Soluzione 1
A tutta prima ho cercato su internet qualche bridge bluetooth – radio.
I prezzi oscillavano dai 50 ai 200 euro sul noto sito di Ecommerce, cui si aggiungeva un obolo annuale di almeno 20 euro da versare al costruttore.
Ho dunque abbandonato questa via impervia e irta di ostacoli (parafrasando, non intendo pagare).
Soluzione 2: DIY
Do it yourself! Questa dovrebbe essere la filosofia di vita di ogni ingegnere che si rispetti.
Nel garage motorizzato nel quale poso l’auto, non è presente una connessione internet.
L’unica possibilità era pertanto comunicare via Bluetooth ad un microcontrollore il quale, ricevuto un segnale instradato con il giusto protocollo, comunicasse con un trasmettitore il segnale di apertura alla serranda.
Necessitavo quindi di:
- Un microcontrollore
- Un modulo Bluetooth
- Un trasmettitore TX 433MHz
- Un ricevitore RX 433MHz per sniffare il codice di apertura del cancello.
Scelta dei componenti
La scelta del microcontrollore è ricaduta sulla scheda ESP32 wroom DEVKIT 1. Il motivo è che il Bluetooth è integrato. Possedevo già degli ESP 8086, ma essendo solamente Wi-Fi non potevano servire lo scopo.

Attenzione ai PIN:

Per quanto riguarda i moduli RX/TX, ho trovato due moduli ipereconomici su Temu con tanto di antenna (inutile nel mio caso, posizionandomi a pochissimi metri dal ricevitore)

Dopo un paio di settimane ho ricevuto l’ordine. Era giunto il momento di sporcarsi le mani.
Prima fase: sniffing del segnale
Dopo avere correttamente installato i DRIVER per permettere all’ESP di funzionare con un normale ARDUINO IDE, utilizzo la libreria RCSwitch per decodificare il segnale dal telecomando.

La mia grande fortuna è che la centralina del cancello funziona a codice fisso e non a rolling code, o le cose si sarebbero complicate drammaticamente (va pure sottolineato che fui io a chiedere l’installazione della centralina a codice fisso).
Ho pertanto connesso con dei semplici jumper femmina femmina il modulo RX all’ESP.
il Vin con l’alimentazione da 3.3V, il GND col GND, e il DataIn con il PIN D23.

Attenzione a utilizzare il pin giusto per i dati. Ci ho perso mezz’ora. Se uno non funziona, provare l’altro.
A questo punto, non restava che scrivere un po’ di codice.
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(9600);
mySwitch.enableReceive(23); // PIN D23
}
void loop() {
if (mySwitch.available()) {
Serial.print("Ricevuto ");
Serial.print( mySwitch.getReceivedValue() );
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocollo: ");
Serial.println( mySwitch.getReceivedProtocol() );
mySwitch.resetAvailable();
}
}
Così facendo, sono riuscito a sniffare la seguente stringa:
Ricevuto ABCDEFG / 20bit Protocollo: 11
Questa stringa va assolutamente messa da parte.
Parte 2: ideazione di un protocollo di trasmissione
Attenzione: il protocollo non si riferisce alla trasmissione elettromagnetica del segnale, ma al contenuto del messaggio.
Ho immaginato che, effettivamente, le informazioni necessarie perché la TX a 433Mhz aprisse il cancello, erano solo il messaggio, la lunghezza dell’informazione e il protocollo (stavolta il protocollo è quello del segnale, gestito automaticamente dalla libreria RCSwitch).
Di getto, ho pensato pertanto di usare la seguente convenzione
<c>ABCDEFGH…_ILMNOP_QRSTU</c>
ABCDEFGH… sono al massimo 20 cifre (la password del cancello)
ILMNOP è il protocollo
QRSTU la lunghezza dei BIT
I tag <c> e </c> segnalano l’inizio e la fine della trasmissione.
Parte 3: realizzazione dell’apparato di trasmissione e iniziazione server Bluetooth
Connettendo in modo analogo il modulo TX all’ESP32 a quanto fatto per l’RX, ho utilizzato il seguente codice, facendo attenzione a ripulire costantemente la memoria occupata in modo che a lungo andare non crashasse.
#include <BluetoothSerial.h>
#include <RCSwitch.h>
BluetoothSerial SerialBT;
RCSwitch mySwitch = RCSwitch();
// Configurazione
const int txPin = 22; //PIN D22 SULL'ESP 32
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32_BT_Test");
mySwitch.enableTransmit(txPin);
Serial.println("Bluetooth + RCSwitch pronto");
Serial.println("Formato messaggio: <c>CODICE_PROTOCOLLO_LUNGH_BIT</c>");
}
void loop() {
static bool isReading = false;
static String buffer = "";
while (SerialBT.available()) {
char c = SerialBT.read();
if (!isReading && c == '<') {
buffer = "<";
isReading = true;
continue;
}
if (isReading) {
buffer += c;
// Fine messaggio
if (buffer.endsWith("</c>")) {
processMessage(buffer);
buffer = "";
isReading = false;
}
// Protezione buffer troppo lungo
if (buffer.length() > 60) { // 20+5+5 cifre + 2 underscore + margine
Serial.println("Errore: messaggio troppo lungo, scartato");
buffer = "";
isReading = false;
}
}
}
}
// Funzione per processare il messaggio
void processMessage(String &msg) {
// Rimuove <c> e </c>
msg.replace("<c>", "");
msg.replace("</c>", "");
// Dividi in tre parti tramite underscore
int firstUnderscore = msg.indexOf('_');
int secondUnderscore = msg.indexOf('_', firstUnderscore + 1);
if (firstUnderscore == -1 || secondUnderscore == -1) {
Serial.println("Errore: formato messaggio non valido");
return;
}
String codeStr = msg.substring(0, firstUnderscore);
String protocolStr = msg.substring(firstUnderscore + 1, secondUnderscore);
String bitLengthStr = msg.substring(secondUnderscore + 1);
codeStr.trim();
protocolStr.trim();
bitLengthStr.trim();
// Converti in numeri
long code = codeStr.toInt();
int protocol = protocolStr.toInt();
int bitLength = bitLengthStr.toInt();
// Validazioni
if (codeStr.length() == 0 || protocolStr.length() == 0 || bitLengthStr.length() == 0) {
Serial.println("Errore: valori mancanti");
return;
}
if (protocol <= 0 || protocol > 11) {
protocol = 1; // fallback protocollo
}
if (bitLength <= 0 || bitLength > 24) { // lunghezza bit plausibile
bitLength = 12; // fallback
}
mySwitch.setProtocol(protocol);
// Invia il codice
mySwitch.send(code, bitLength);
Serial.print("Messaggio inviato -> Codice: ");
Serial.print(code);
Serial.print(", Protocollo: ");
Serial.print(protocol);
Serial.print(", Lunghezza bit: ");
Serial.println(bitLength);
}
Parte 4: client Bluetooth
Stavo pensando di realizzare un client Bluetooth con Android Studio in modo da chiamare con GEMINI (a voce) da Google Auto o dal telefono il server Bluetooth, per praticità ho preferito scaricare dal Play Store l’app Serial Bluetooth terminal e configurare lì la stringa da inoltrare al bridge BT – Radio.
Time saving. D’altronde sono indolente…

Un po’ di fotine varie



Confezionamento
Per proteggere ESP e TX (poiché la RX ha fatto il suo sniffando i codici e non occorre connetterla elettronicamente all’ESP) ho utilizzato un vecchio scatolotto che faceva da comando per le luci di Natale (poi fulminate).
Dovrò solo cercare un’anima pia che con una fresa rimuova un gancio di plastica che mi impedisce di disporre il microcontrollore all’interno.

Col trapano creerò un secondo foro per il cavo USB.
Funziona tutto perfettamente!


THE END 😀