lunedì 19 ottobre 2015

DIY Homekit con Arduino

Dopo un primo esperimento con DIY HomeKit (a questo post) non ero particolarmente contento perche' comunque i costi di Raspberry e la gestione in generale non erano ottimali ed ho provato a replicare la cosa su Arduino


Per il modulo Bluetooth ho usato un modulo Bluetooth LE HM-10 del costo di circa 5 euro (qui). Attenzione, non tutti i moduli BT per Arduino supportano BT4 LE. Il modulo riporta sul retro la scritta AC-BT-V4 ed al comando AT+NAME? risponde con HMSoft

Il modulo si comanda tramite stringhe AT (per l'elenco completo dei comandi si puo' leggere qui il manuale di istruzioni)

Cio' che interessa e' la sequenza di comando
AT+ROLE1
AT+IMME1
AT+DISI?

all'ultimo comando il dispositivo risponde in questo modo
---------------------------------------------------------
OK+DISIS
OK+DISC:4C000215:B9407F30F5F8466EAFF925556B57FE6D:71884DF6B6:F1A84DF67188:-086
OK+DISC:00000000:00000000000000000000000000000000:0000000000:C493974F69E2:-084
OK+DISC:4C000215:B9407F30F5F8466EAFF925556B57FE6D:DB2A91AEB6:D81691AEDB2A:-084
OK+DISCE
---------------------------------------------------------
Sono stati avvistati 3 beacons (due Estimote ed un Eddystone riconoscibile da tutti zeri perche' il protocollo non e' riconosciuto)

Prendendo la riga evidenziata in giallo
iBeacon ID = B9407F30F5F8466EAFF925556B57FE6D
Major = 7188
Minor = 4DF6
Measured power (182 decimale) =B6
Mac Address = F1A84DF67188
RSSI = -86

Passando quindi ad Arduino

I collegamenti sono banali (verra' usata la Seriale Software di Arduino)
BT VCC +3.3V Arduino
BT GND GND Arduino
BT RXD D2 Arduino
BT TXD D3 Arduino

Nello sketch seguente se viene individuato il beacon con minor AEB6 viene attivato il pin D13 in modo da aprire il contatto su un rele'; se per piu' di 50 secondi non viene piu' messo in lista il beacon con minor AEB6 il pin D13 va Low e si chiude il rele (il codice si commenta da solo)

--------------------------------------------------------------------------------------
#include <SoftwareSerial.h>

SoftwareSerial mySerial(3, 2); 
char risposta[115];
int conta;
int rele = 13;
long tempo;

void setup()  
{
  Serial.begin(9600);
  mySerial.begin(9600);
  mySerial.write("AT+ROLE1");
  mySerial.write("AT+IMME1");
  if (mySerial.available())
     {
       while (mySerial.available()>0){
       }
     }
     
  pinMode(rele, OUTPUT);
  tempo = 0; 
}

void loop() 
{
  mySerial.write("AT+DISI?");
  if (mySerial.available())
     {
       conta = 0;
       while (mySerial.available()>0){
         risposta[conta] = mySerial.read();
         conta = conta + 1;
       }
     }   
  if ((risposta[56] == 'A') && (risposta[57] == 'E') && (risposta[58] == 'B') && (risposta[59] == '6')) 
    {
      //Serial.println("ATTENZIONE");
      digitalWrite(rele, HIGH);
      tempo = 0;
    }
  delay(500);
  tempo = tempo + 1;
  if (tempo > 100)
        {
          digitalWrite(rele, LOW);
          tempo = 101;
        }
  
}