Apertura automatica cancello con microcontrollore ESP 32

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.

ESP32-WROOM


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)

Moduli RX e TX 433MHz

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.

Schema di collegamento ESP32 – RX 433MHz

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 😀

Condividi questo articolo :)
Subscribe
Notificami
guest
0 Commenti
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Commenta per partecipare alla discussionex