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.
il tuo programma, NON può visualizzare il tutto in una unica pagina web?
Io vorrei fare in modo che circa 10 arduino comunicano con uno che fa da master/server, dove visualizzo e invio ordini da una pagina web.
Ciao e grazie
si è quello che ho fatto, lo devo mettere nei prossimi articoli quando ho tempo
Interessante ma non riesco a scorrere oltre la riga 33 sketch … per capire il resto dello sketch.
c’è una soluzione ? Grazie Saluti Willy
Ciao Willy, ho sistemato la pagina, adesso lo scroll del codice funziona. Grazie.