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.