Passa al contingut principal

Clonar comandament d’un tendal Bauhaus E3430-GBR. Part 2, Arduino.

Construcció del circuit amb Arduino

En aquesta entrada continuarem amb el clonat del comandament del tendal de Bauhaus, aquesta vegada per a crear el circuit amb un arduino UNO o equivalent.

Partim de què a partir de la captura del senyal amb el sintonitzador SDR havíem aconseguit entendre un poc el protocol del comandament.
El missatge que envia el comandament està fet per diversos blocs que inclouen un preàmbul i el cos del missatge.
El preàmbul de sincronització es troba a l’inici de cada bloc i dura aproximadament 6300us. La seua estructura aproximadament tal com es pot veure en la següent imatge és de:
    • 4800us amb emissió de senyal.
    • 1550us de silenci.

A continuació del preàmbul ve el missatge en si mateix on la pulsació d’emissió del senyal és d’uns 350us, aproximadament, això vol dir que almenys l’estat (en emissió o en silenci) dura 350us.
Podem distingir dos tipus de dades, la primera d’uns 750us en emissió i 350us en silenci (110) que podíem identificar com el valor lògic 1:
La segona és completament invertida a la primera i són 350us en emissió juntament amb 750 de silenci (100) que podíem identificar com al 0 lògic tal com s’aprecia en les següents imatges:
110 → 1 lògic            100 → 0 lògic

 Ja en el post anterior vam obtindre les captures dels senyals que corresponen als 3 botons del comandament, els missatges d’obrir, tancar i parar, en format binari i hexadecimal

CLOSE  
type_a: 1011010100000110010111010101000100010001	B5065D5111
type_b: 1011010100000110010111010101000100011110	B5065D511E

4*(PREÀMBUL)B5065D5111+3*(PREÀMBUL)B5065D511E

OPEN  
type a: 1011010100000110010111010101000100110011	B5065D5133
type b: 1011010100000110010111010101000100111100	B5065D513C
4*(PREÀMBUL)B5065D5133+3*(PREÀMBUL)B5065D513C

STOP 
type a: 1011010100000110010111010101000101010101 B5065D5155
3*(PREÀMBUL)B5065D5155

Ara sols ens cal reproduir aquests senyals mitjançant un Arduino (es pot emprar també un esp8266) i el transmissor de ràdio FS1000A.

Aquest transmissor és molt econòmic i el podem aconseguir per aproximadament 1€ en aliexpress o ebay.

L'esquema proposat inclou 3 polsadors juntament amb les seues resistències en pull-down

També es pot afegir un led addicional i fer-lo parpellejar en prémer qualsevol botó, no obstant això jo no l’he posat per simplificar tant l’esquema com el sketch i he emprat el led intern.

El codi per a enviar els uns i zeros lògics que hem identificat amb anterioritat és molt simple:


#define TIME_SIGNAL 350

void rf433_one()
{
  digitalWrite(PIN_433_OUT, HIGH);
  delayMicroseconds(2 * TIME_SIGNAL);
  digitalWrite(PIN_433_OUT, LOW);
  delayMicroseconds(TIME_SIGNAL);
}
void rf433_zero()
{
  digitalWrite(PIN_433_OUT, HIGH);
  delayMicroseconds(TIME_SIGNAL);
  digitalWrite(PIN_433_OUT, LOW);
  delayMicroseconds(2 * TIME_SIGNAL);
}

Però cal el preàmbul, si recordem era 4800us en emissió i 1550us sense. El temps mínim d’una pulsació de senyal és de 350us (no una pulsació en el comandament del tendal).

4800/350 = 13,7 1550/350=4,4

En el meu cas he fet la prova de generar el preàmbul arredonint els valor a 14 i 5:

void rf433_preamble()
{
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(PIN_433_OUT, HIGH);
  delayMicroseconds(14 * TIME_SIGNAL);
  digitalWrite(PIN_433_OUT, LOW);
  delayMicroseconds(5 * TIME_SIGNAL);
  digitalWrite(LED_BUILTIN, LOW);
}

Ha funcionat correctament, això no vol dir que siga vàlid per a qualsevol dispositiu, cada dispositiu en la banda de 433MHz és un món i empren en molts casos els seus protocols propis, però com hem vist els podem obtindre amb el receptor SDR.

Addicionalment he afegit un separador entre cada missatge missatges i una funció que converteix el codi hexadecimal en binari.

De forma que el sketch queda:



#define TIME_SIGNAL 350
#define PIN_433_OUT 11
#define PIN_OPEN 10
#define PIN_CLOSE 9
#define PIN_STOP 8

/*
 * Not used due to TIME_SIGNAL*14 also works  * 
 * if not, replace these values in rf433_preamble function * 
#define PREAMBLE_TIME_HIGH 4750
#define PREAMBLE_TIME_LOW 1500
*/

#define SEPARATION_TIME_LOW 350
void rf433_preamble();
void rf433_separator();
void rf433_one();
void rf433_zero();
void rf433_send();
void open_awning();
void close_awning();
void stop_awning();

byte open_signal_a[] = {0xB5, 0x06, 0x5D, 0x51, 0x33};
byte open_signal_b[] = {0xB5, 0x06, 0x5D, 0x51, 0x3C};

byte stop_signal_a[] = {0xB5, 0x06, 0x5D, 0x51, 0x55};

byte close_signal_a[] = {0xB5, 0x06, 0x5D, 0x51, 0x11};
byte close_signal_b[] = {0xB5, 0x06, 0x5D, 0x51, 0x1E};

int openAwning = 0;
int closeAwning = 0;
int stopAwning = 0;

void rf433_preamble()
{
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(PIN_433_OUT, HIGH);
  delayMicroseconds(14 * TIME_SIGNAL);
  digitalWrite(PIN_433_OUT, LOW);
  delayMicroseconds(5 * TIME_SIGNAL);
  digitalWrite(LED_BUILTIN, LOW);
}
void rf433_separator()
{
  digitalWrite(PIN_433_OUT, LOW);
  delayMicroseconds(SEPARATION_TIME_LOW);
}
void rf433_one()
{
  digitalWrite(PIN_433_OUT, HIGH);
  delayMicroseconds(2 * TIME_SIGNAL);
  digitalWrite(PIN_433_OUT, LOW);
  delayMicroseconds(TIME_SIGNAL);
}
void rf433_zero()
{
  digitalWrite(PIN_433_OUT, HIGH);
  delayMicroseconds(TIME_SIGNAL);
  digitalWrite(PIN_433_OUT, LOW);
  delayMicroseconds(2 * TIME_SIGNAL);
}

void close_awning()
{
  rf433_preamble();
  for (byte i = 0; i < 4; i++)
  {
    rf433_send(close_signal_a, 5);
    rf433_separator();
  }
  for (byte i = 0; i < 3; i++)
  {
    rf433_send(close_signal_b, 5);
    rf433_separator();
  }

  delay(10);
}

void open_awning()
{
  rf433_preamble();
  for (byte i = 0; i < 4; i++)
  {
    rf433_send(open_signal_a, 5);
    rf433_separator();
  }
  for (byte i = 0; i < 3; i++)
  {
    rf433_send(open_signal_b, 5);
    rf433_separator();
  }

  delay(10);
}

void stop_awning()
{
  rf433_preamble();
  for (byte i = 0; i < 3; i++)
  {
    rf433_send(stop_signal_a, 5);
    rf433_separator();
  }

  delay(10);
}

void setup()
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(PIN_433_OUT, OUTPUT);
  pinMode(PIN_OPEN, INPUT);
  pinMode(PIN_CLOSE, INPUT);
  pinMode(PIN_STOP, INPUT);

  Serial.println("Hello Awning\n");
}
void loop()
{

  openAwning = digitalRead(PIN_OPEN);
  closeAwning = digitalRead(PIN_CLOSE);
  stopAwning = digitalRead(PIN_STOP);

  if (openAwning == HIGH)
  {
    open_awning();
    Serial.println("OPEN");
  }
  else if (closeAwning == HIGH)
  {
    close_awning();
    Serial.println("CLOSE");

  }
  else if (stopAwning == HIGH)
  {
    stop_awning();
    Serial.println("STOP");

  }
}

/* 
Convert hex to bin and use rf433_one, rf433_zero to send data
*/
void rf433_send(byte *buffer, byte bufferSize)
{
  for (byte i = 0; i < bufferSize; i++)
  {
    byte n = buffer[i];
    for (int i = 7; i >= 0; i--)
    {
      if ((n >> i) & 0X01)
      {
        rf433_one();
      }
      else
      {
        rf433_zero();
      }
    }
  }
}

El proper pas és emprar un Wemos D1 mini i integrar-ho amb el ESPHome i Homeassistant, però això ja serà una altra història.

Comentaris