Arduino per domotica, collegato in rete come client/server

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

 

baseenc28j60-shield-variations
relay
ArduinoNanoFront_3_sm

 

 

 

 

 

 

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.

 

 

4 commenti

  1. 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

  2. Interessante ma non riesco a scorrere oltre la riga 33 sketch … per capire il resto dello sketch.
    c’è una soluzione ? Grazie Saluti Willy

Lascia una risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *