Con questo articolo parto a spiegarvi come utilizzare arduino e altri strumenti per autocostruirsi un impianto di domotica e relativo antifurto.
Con questo parte di progetto utilizzo arduino per inviare via UDP lo stato degli I/O e anche di ricevere pacchetti UDP per controllare 4 relay.
Tutto il progetto completo è formato da diversi blocchi come questo che comunicano con un server (raspberry pi) che in python controlla il tutto e agisce di conseguenza. Sul Rasberry è installato anche Asterisk che interfacciato con il mio programma python è in grado di ricevere telefonate per attivare l’antifurto o disattivarlo e decidere chi chiamare, tutto tramite voce i segnali DTMF.
Comunque senza perderci troppo con il primo pezzo, cioe’ arduino che invia e riceve pacchetti.
I messaggi che manda sono nel formato “NUMERO SCHEDA” + “NUMERO SENSORE” + “STATO”
ad esempio la scheda 5 arduino con il sensore 6 e lo stato 00001 = 050600001
In questo modo posso utilizzare quanti arduino voglio, di sensori in teoria fino a 99, teniamo conto che arduino si può facilmente espandere con I/O su i2c.
Per il valore utilizzo 5 cifre perchè oltre al segnale on/off posso trasmettere temperature, livello di Co2 e tutto quello può servirvi.
Come porte UDP ho utilizzato 5055 per la trasmissione e 5056 per la ricezione, poi potete comunque modificarle con altre se vi torna comodo.
Nel mio caso ho utilizzato:
- un arduino nano
- un ENC28J60 Ethernet Shield V1.0 per scheda di rete
- un piccola espansione per fare dei collegamenti decenti
- Scheda a 4 relay
serve la libreria per gestire lo shield Ethernet, quindi scaricate la libreria qui:Â https://github.com/ntruchsess/arduino_uip
Installate la libreria in Arduino IDE e qui sotto c’e’ il programma ad hoc che utilizzo su una scheda, più’ sotto vi spiego i vari blocchi:
/* * pin 10 -11 -12 -13 occupati da ethernet * pin 2 -3 -4 -5 -6 -7 -8 -9 digitali * da A0 ad A7 analogici */ #include <UIPEthernet.h> EthernetUDP udpserver; EthernetUDP udp; int success; char IRF; int counter; //lo utilizzo per il conteggio del client per mandare i messaggi al server void setup() { pinMode(2, OUTPUT); //rele pinMode(3, OUTPUT); //rele pinMode(4, OUTPUT); //rele pinMode(5, OUTPUT); //rele pinMode(6, INPUT); // finestra cortile filo rosso pinMode(7, INPUT); // finestra vicino lavandino filo nero pinMode(8, INPUT); // porta cucina filo bianco pinMode(9, INPUT); // sensore lampada 500w portico Serial.begin(9600); //imposto la porta seriale per debug uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; //imposto mac address Ethernet.begin(mac,IPAddress(10,0,0,253)); //imposto ip success = udpserver.begin(5056); // apro la porta udp } void loop() { //controllo nuovi udp-packet: int size = udpserver.parsePacket(); if (size > 0) { do { char* msg = (char*)malloc(size+1); int len = udpserver.read(msg,size+1); msg[len]=0; Serial.print("received: "); Serial.println(msg); if (String(msg[0])=="1") { digitalWrite(2, HIGH); } else { digitalWrite(2, LOW); } if (String(msg[1])=="1") { digitalWrite(3, HIGH); } else { digitalWrite(3, LOW); } if (String(msg[2])=="1") { digitalWrite(4, HIGH); } else { digitalWrite(4, LOW); } if (String(msg[3])=="1") { digitalWrite(5, HIGH); } else { digitalWrite(5, LOW); } free(msg); } while ((size = udpserver.available())>0); //finish reading this packet: udpserver.flush(); // restituisco la lettura delle uscite for (int i=20; i < 24; i++){ success = udpserver.beginPacket(IPAddress(10,0,0,10),5056); String Messaggio = "050" + String(i) + "0000" + String(digitalRead(i-18)); success = udpserver.print(Messaggio); success = udpserver.endPacket(); delay(100); } udpserver.stop(); //restart with new connection to receive packets from other clients Serial.print("restart connection: "); Serial.println (udpserver.begin(5056) ? "success" : "failed"); } // qui parto con le letture dei sensori if (counter > 1200) { for (int i=6; i < 10; i++){ success = udp.beginPacket(IPAddress(10,0,0,1),5055); String Messaggio = "050" + String(i-5) + "0000" + String(!digitalRead(i)); success = udp.print(Messaggio); success = udp.endPacket(); delay(100); } for (int i=0; i < 2; i++){ if (analogRead(i) > 300) { //leggo lo stato degli irf IRF='1'; } else { IRF='0'; } success = udp.beginPacket(IPAddress(10,0,0,1),5055); String Messaggio = "050" + String(i+5) + "0000" + IRF; success = udp.print(Messaggio); success = udp.endPacket(); delay(100); } counter=0; } else { counter = counter + 1; } }
Lo shield per la scheda di rete utilizza i pin di Arduino 10 -11 -12 -13
Quindi questi non li possiamo utilizzare per la nostra domotica.
uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; //imposto mac address Ethernet.begin(mac,IPAddress(10,0,0,253)); //imposto ip success = udpserver.begin(5056); // apro la porta udp
Dobbiamo impostare il mac address per la scheda di rete (utilizzare dei numeri esadecimali a caso), poi impostiamo un IP statico nel range della vostra rete; nella mia rete utilizzo 10.0.0.0/24 quindi ho preso un IP libero a caso  10.0.0.253.. Alla fine imposto la porta di ascolto 5056 per ricevere dati da server (utilizzare certe porte come uscite).
Nel ciclo di loop è tutto abbastanza semplice, leggo i valori degli input e li invio uno a uno via UDP al mio server.
Per la parte della gestione uscite in Arduino rimane in ascolto sulla porta 5056 e riceve una stringa di 4 caratteri che attivano o disattivano i relay (1 attiva 0 disattiva).
Quindi 0001 attiva il primo relay.
Questa è la prima parte del progetto, spero vi possa essere di spunto per i vostri progetti.
Nel prossimo articolo posterò un progetto quasi uguale per Arduino dove invece lo utilizzo solo per leggere ingressi e non ho uscite, quindi manca la parte server.