Mandare lo stesso messaggio a 6 schede arduino uno+W5100 con Ethernet Udp

Salve,
dopo aver cercato per mare e per terra varie soluzioni e prove mi arrendo alla mia inesperienza ed alla voglia forse di fare qualcosa di troppo grosso,ma veniamo al dunque:

ho realizzato una serie di schede composte da arduino uno e scheda ethernet W5100 per ogni tenda da sole che ho in casa per un totale di 6 postazioni.
La scheda gestisce l'apertura ,la chiusura della tenda e la luce sul terrazzo.
Visto che ho tutta la casa cablata (ed ho la rete proprio vicino ai cassonetti delle serrande)ho pensato di collegare tutte le 6 postazioni per fare in modo di poter comandare con una chiamata Udp l'apertura , la chiusura delle varie tende, per esempio con l'inserimento dell'antifurto si possano chiudere tutte insieme.
Le schede in modo autonomo funzionano gia' regolarmente ed ho pensato di utilizzare Udp perche' dovrebbe essere piu' semplice la gestione.Allego la bozza del programma di prova per la trasmissione del messaggio, che poi non e' altro che una lettera (A = apertura C= chiusura L = accesione luce ecc, ecc).
Con il primo messaggio trasmetto una lettera che in questo caso per prova e' una J oppure una E e sul ricevitore mi si accende un led oppure si spenge.
Il problema e' che in questo modo ( e non ne conosco altri perche' non sono pratico delle funzioni relative alla libreria Udp) la trasmissione e' lentissima e analizzando il parsePacket () alle volte mi da 1 carattere alle volte 2 alle volte 7. Come posso fare per mandare un solo carattere ?
Spero di essere stato chiaro anche se sicuramente mi farete notare che mi sono dimenticato qualcosa

sketch_jun06b-funzionante_al_07-06-18.ino (1.79 KB)

sketch_jun04b-tx-arduino-cc.ino (1.67 KB)

Prima risposta "al volo", prima di scendere nel dettaglio degli sketch: ma tu alle schede Ethernet mica assegni a tutte lo stesso Mac address, VERO?

No, sono tutti Mac address diversi

Seconda domanda: ma se a te interessa mandare lo stesso dato a tutti i client, perché non mandi un broadcast UDP (sulla porta specifica ovviamente, non usata da altri sistemi) che lo ricevono tutti? Addirittura potresti mandare un broadcast nel cui payload ci metti un identificativo (tu qui usi un solo byte, ne puoi usare due) che il ricevente usa per determinare se sia per lui o meno?
(tra l'altro in questo modo eviti di dover configurare tutti gli indirizzi IP dei client, ognuno si "prende" il suo dato).

EDIT: se può servire ad altri, io uso questo sito per generare Mac address random ma validi:

Ho ricontrollato i MAC address e per essere sicuro ne ho generati dei nuovi con il sito che mi hai proposto e la situazione e' la seguente: ho 3 schede attive su 2 computer diversi. il tx non lo controllo attraverso la seriale, una scheda con ip 192.168.1.182 la seriale mi da "Recived packet of size 7" mentre l'altra scheda il cui indirizzo e' 192.168.1.183 la seriale mi risponde "Recived packet of size 1".
Ora quello che non capisco e' perche' visto che lo sketch e' uguale per tutte e 2 le schede, cambiano solo i MAC e gli IP.
Per quanto riguarda la soluzione broadcast Udp io ne sarei felice di realizzarla ,il problema e' che non ho trovato niente in giro e non ho basi su cui costruire il programma.

Ho fatto ulteriori prove:
la scheda 2 che aveva l'IP 182 e mi dava packet recived 1 adesso ha l'indirizzo 183 e mi da sempre packet 1
la scheda 3 che aveva l'IP183 e mi dava packet recived 7 adesso ha l'indirizzo 185 e mi da packet 2

Molto strano. D'accordo che io uso UDP broadcast, però io mando pacchetti da 8 byte e non sbaglia mai, ma io dichiaro esplicitamente nella write() la lunghezza del pacchetto (IRS_PACKET_SIZE per me vale 8 ). ossia nel client che trasmette:

void sendPacket()
{
  // Solo per debug:
  Serial.print("Sending packet: ");
  for (int i=0; i<IRS_PACKET_SIZE; i++) {
	if (packetBuffer[i] >= ' ' )
		Serial.write(packetBuffer[i]);
	else
		Serial.print(packetBuffer[i], HEX);
    Serial.write(' ');
  }
  Serial.println();
  // ----------
  // Invia il pacchetto
  udp.beginPacket(ipBroadcast, IRS_PORT);
  udp.write(packetBuffer, IRS_PACKET_SIZE);
  udp.endPacket();
  resetPacket();
}

E nel ricevente:

// receive udp messages
bool udpReceive(void)
{
  int packetSize = udp.parsePacket();
  if(packetSize) {
    // read the packet into packetBufffer
    udp.read(pkt,IRS_PACKET_SIZE);
    return true;
  } else
    return false;
}

Prova a farlo anche tu e fammi sapere.

Verifica cosa ritorna beginPacket().

Si, magari torna 0, però il suo problema non mi sembra di pacchetti che non partono, ma che sembra ricevere "altro". Mi chiedo però alcune cose:

  1. Perché manda un byte e poi legge in un array di char il contenuto del pacchetto (io lo farei di dimensione fissa ed esplicitata anche nel write, come ho fatto anche io);
  2. Perché al termine della ricezione manda un "acknowledge" al mittente, senza che in questo ci sia nulla (io toglierei anche questo, che non mi piace molto..)
  3. Visto quello che fanno gli sketch io al posto suo passerei al broadcast UDP, che semplifica tutto, soprattutto la definizione degli IP dei riceventi, mettendo nel payload comunque un byte per identificare l'ID del destinatario (0=tutti, ed è quello che farà ora, ma per prevedere eventuali usi futuri 1= device 1, 2= device 2, eccetera, dove l'ID del device lo mette in configurazione o lo registra in EEPROM)

Salve,
dopo mille peripezie sono riuscito a volte e non sempre a far funzionare facendo cosi' (non riesco ad allegare gli sketch in altro modo per cui chiedo scusa e chiedo anche come fare):

Trasmissione:


#include <SPI.h>        
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  
 0xDE, 0xAB, 0xDE, 0x05, 0xFC, 0xC8 };
IPAddress ip(192, 168, 1, 180);         //centrale di comando
IPAddress remote1IP(192, 168, 1, 181);  //pos. lavanderia
IPAddress remote2IP(192, 168, 1, 182);  //pos. cucina/camera post.
IPAddress remote3IP(192, 168, 1, 183);  //pos. cameretta
IPAddress remote4IP(192, 168, 1, 184);  //pos. camera fronte
IPAddress remote5IP(192, 168, 1, 185);  //pos. salotto
IPAddress remote6IP(192, 168, 1, 186);  //pos. serra
IPAddress remote7IP(192, 168, 1, 187);  //pos. garage
IPAddress remote8IP(192, 168, 1, 188);
unsigned int localPort = 8889;      // local port to listen on

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
char stringa;
void setup() {
 // start the Ethernet and UDP:
 Ethernet.begin(mac,ip);
 Udp.begin(localPort);
pinMode(6,INPUT_PULLUP);
}

void loop() {
 stringa ="";
if (digitalRead(6) == LOW){
  stringa = 74;
 }else{
  stringa = 69;
 }  
   Udp.beginPacket(remote1IP, 8888);
   Udp.write(stringa);
   Udp.endPacket();
   Udp.beginPacket(remote2IP, 8888);
   Udp.write(stringa);
   Udp.endPacket();
   Udp.beginPacket(remote3IP, 8888);
   Udp.write(stringa);
   Udp.endPacket();
   Udp.beginPacket(remote4IP, 8888);
   Udp.write(stringa);
   Udp.endPacket();
   Udp.beginPacket(remote5IP, 8888);
   Udp.write(stringa);
   Udp.endPacket();
   Udp.beginPacket(remote6IP, 8888);
   Udp.write(stringa);
   Udp.endPacket();
   Udp.beginPacket(remote7IP, 8888);
   Udp.write(stringa);
   Udp.endPacket();
   Udp.beginPacket(remote8IP, 8888);
   Udp.write(stringa);
   Udp.endPacket();

delay(10);
}
Ricezione con W5100:

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#include <String.h>
int i;
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAB, 0xDE, 0xA7, 0x3F, 0xEB};
IPAddress ip(192, 168, 1, 185);

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back
String ric ;
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {
 // start the Ethernet and UDP:
 Ethernet.begin(mac, ip);
 Udp.begin(localPort);
pinMode(2,OUTPUT);
 Serial.begin(9600);
}

void loop() {
 
 // if there's data available, read a packet
 int packetSize = Udp.parsePacket();
 if (packetSize)
 {
   Serial.print("Received packet of size ");
   Serial.println(packetSize);
   Serial.print("From ");
   IPAddress remote = Udp.remoteIP();
   for (int i = 0; i < 4; i++)
   {
     Serial.print(remote[i], DEC);
     if (i < 3)
     {
       Serial.print(".");
     }
   }
   Serial.print(", port ");
   Serial.println(Udp.remotePort());

   // read the packet into packetBufffer
   Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
   ric =(packetBuffer);
 for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++);
 packetBuffer[i] = 0;
   Serial.println(packetSize);
if (ric == "J"){
digitalWrite (2,HIGH);
}else{
 digitalWrite (2,LOW);
}
   Serial.println("Contents:");
   Serial.println(packetBuffer);
  

   // send a reply, to the IP address and port that sent us the packet we received
   Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
   Udp.write(ReplyBuffer);
   Udp.endPacket();
 }
 delay(10);
//  Udp.flush();
}
Ricezione con ENC26j80:

/*
* UIPEthernet UdpServer example.
*
* UIPEthernet is a TCP/IP stack that can be used with a enc28j60 based
* Ethernet-shield.
*
* UIPEthernet uses the fine uIP stack by Adam Dunkels <adam@sics.se>
*
*      -----------------
*
* This UdpServer example sets up a udp-server at 192.168.0.6 on port 5000.
* send packet via upd to test
*
* Copyright (C) 2013 by Norbert Truchsess (norbert.truchsess@t-online.de)
*/

#include <UIPEthernet.h>

EthernetUDP udp;

void setup() {
pinMode (3,OUTPUT);
 Serial.begin(9600);

 uint8_t mac[6] = {0xDE,0xAB,0xDE,0x17,0x74,0x30};

 Ethernet.begin(mac,IPAddress(192,168,1,184));

 int success = udp.begin(8888);

 Serial.print("initialize: ");
 Serial.println(success ? "success" : "failed");

}

void loop() {

 //check for new udp-packet:
 int size = udp.parsePacket();
 if (size > 0) {
   do
     {
       char* msg = (char*)malloc(size+1);
       int len = udp.read(msg,size+1);
       msg[len]=0;
        if (strcmp(msg , "J")){
         digitalWrite(3,LOW);}
           else{
         digitalWrite(3,HIGH);
           }
           Serial.print("received: '");
       Serial.print(msg);
        free(msg); 
      
       }

   while ((size = udp.available())>0);
   //finish reading this packet:
   udp.flush();
   Serial.println("'");
   int success;
   do
     {
       Serial.print("remote ip: ");
       Serial.println(udp.remoteIP());
       Serial.print("remote port: ");
       Serial.println(udp.remotePort());
       //send new packet back to ip/port of client. This also
       //configures the current connection to ignore packets from
       //other clients!
       success = udp.beginPacket(udp.remoteIP(),udp.remotePort());
       Serial.print("beginPacket: ");
       Serial.println(success ? "success" : "failed");
   //beginPacket fails if remote ethaddr is unknown. In this case an
   //arp-request is send out first and beginPacket succeeds as soon
   //the arp-response is received.
     }
   while (!success);

   success = udp.println("hello world from arduino");

   Serial.print("bytes written: ");
   Serial.println(success);

   success = udp.endPacket();

   Serial.print("endPacket: ");
   Serial.println(success ? "success" : "failed");

   udp.stop();
   //restart with new connection to receive packets from other clients
   Serial.print("restart connection: ");
   Serial.println (udp.begin(8888) ? "success" : "failed");
 }
}

Premetto che le mie conoscenze in questo campo sono veramente piccole e che questi skech sono scopiazzati a destra e sinistra.
Per quanto riguarda il Broadcasting non riesco a mettere insieme niente perche' non sono riuscito a trovare niente sulle funzioni e la sintassi per poterle richiamare.
Ho provato a mettere in pratica quei 2 esempi ma visto che non ho la sintassi giusta mi escono 3 errori di compilazione diversi ( tra l'altro che non ho copiato).
Le prove da me fatte sono con 4 schede 3 in ricezione ed una in trasmissione.
Solo una con W5100 funziona e l'altre ricevono oppure interpretano 3/4/5 caratteri anziche' uno.
Comunque anche la scheda con ENC28j60 riceve il messaggio ma giustamente non accende il led.
Forse mi sono avventurato in una cosa piu' grossa delle mie competenze.
Comunque grazie e sicuramente con il vostro aiuto qualcosa riusciro' a compicciare

Poiché sono fuori casa non posso analizzare meglio gli sketch, però intanto ti scrivo qualche nota/consiglio:

  1. Indenta correttamente! Puoi farlo fare all'IDE premendo Ctrl-T. Non è una questione estetica, ma ti permette di capire meglio cosa stai facendo...

  2. Cerca di evitare come la peste la classe String perché per queste piccole MCU la gestione della memoria è problematica, usa se possibile sempre char[]. E pure la "#include <String.h>" quindi...

  3. Che senso ha mettere nella variabile (String tra l'altro) "ric" il contenuto di packetBuffer?
    ric =(packetBuffer);

  4. ti rendi conto che la for() successiva di fatto non fa nulla perché il suo corpo è vuoto (e che non te ne sei accorto perché non hai indentato bene :wink: )?
    for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++);
    Se volevi azzerare tutto il buffer devi TOGLIERE il ";" finale:

for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++)
  packetBuffer[i] = 0;
  1. Se azzeri il buffer perché poi cerchi di mostrarlo?
  Serial.println("Contents:");
  Serial.println(packetBuffer);

O usi la variabile "ric" o lasci perdere "ric" e usi sempre packetBuffer, che puoi azzerare DOPO averlo stampato (e usato)

  1. Se non verifichi l'acknowledge sul sender, TOGLI anche l'invio del pacchetto di risposta:
  // send a reply, to the IP address and port that sent us the packet we received
  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write(ReplyBuffer);
  Udp.endPacket();
  1. E poi, in fondo, quando dici che riceve più byte di quelli che ti aspetti, esattamente hai verificato COSA ricevi? Duplicati dello stesso comando? Altro? Ma per capirlo devi prima modificare il codice per stampare i valori (magari esadecimali) dei byte che ricevi nel buffer...

Buongiorno,
mille prove fatte, risultato zero!

Buongiorno,
mille prove fatte, risultato zero!
Ristretto le prove a 3 schede una in tx e 2 in rx

  1. ho sempre che su una scheda mi arrivano 2/4 caratteri e sull'altra 1. Ho scambiato i W5100 ed effettivamente si sono scambiati i ruoli. dove mi arrivava 1 carattere adesso ne arrivano 2 e viceversa, quindi forse un problema hardware.

trasmetto cosi'

#include <SPI.h>        
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:

byte mac[] = {  0xDE, 0xAB, 0xDE, 0x05, 0xFC, 0xC8 };
IPAddress ip(192, 168, 1, 180);         //centrale di comando
IPAddress remote1IP(192, 168, 1, 181);  //pos. lavanderia
IPAddress remote2IP(192, 168, 1, 182);  //pos. cucina/camera post.
IPAddress remote3IP(192, 168, 1, 183);  //pos. cameretta
IPAddress remote4IP(192, 168, 1, 184);  //pos. camera fronte
IPAddress remote5IP(192, 168, 1, 185);  //pos. salotto
IPAddress remote6IP(192, 168, 1, 186);  //pos. serra
IPAddress remote7IP(192, 168, 1, 187);  //pos. garage
IPAddress remote8IP(192, 168, 1, 188);

unsigned int localPort = 8889;      // local port to listen on

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
char stringa;
void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);
pinMode(7,INPUT_PULLUP);
}

void loop() {
 byte stringa ;
if (digitalRead(7) == LOW){
   stringa = 74;
  }else{
   stringa = 69;
  }  
    Udp.beginPacket(remote1IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote2IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote3IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    /*
    Udp.beginPacket(remote4IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote5IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote6IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote7IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote8IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
*/
delay(10);

ricevo cosi'

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#include <String.h>
int i;
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:

byte mac[] = { 0xDE, 0xAB, 0xDE, 0xD8, 0x26, 0xE4};
IPAddress ip(192, 168, 1, 183);

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data

byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
byte ric = 0;
// An EthernetUDP instance to let us send and receive packets over UDP

EthernetUDP Udp;

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
  pinMode(7, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    Serial.println("Contents:");
    Serial.println((char*)packetBuffer);
    
   

    if (packetBuffer == 74) {
      digitalWrite (7, LOW);
    } else {
      digitalWrite (7, HIGH);
    }

    for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++)
      packetBuffer[i] = 0;
 Serial.println("Contents1:");
    Serial.println((char*)packetBuffer);

  }

  delay(10);

}
  1. perche' controllando a monitor con il serial.print io vedo il carattere E oppure il carattere J e quando vado a fare l'IF non lo riconosce. (ho provato a fare if con sia con il valore ASCII che con la lettera "J")
    Dopo aver letto il carattere ed azzerato il buffer se io leggo di nuovo il packetBuffer in realta' e' vuoto, allora perche' su una scheda e solo su una vedo EE oppure JJ anziche E oppure J
    Dove sbaglio? PacketBuffer che tipo di dato contiene?

  2. cosa posso trovare come trattati per poter capire meglio come usare il sistema ethernet Udp in broadcasting ,(in biblioteca ho preso "Arduino Progetti e soluzioni" di Michael Margolis, ma non spiega quasi nulla).
    Vorrei fare il broadcasting perche' cosi' la trasmissione e' lentissima.
    Ti ringrazio per tutto il tempo che mi stai dedicando, ma sono in stallo e non so come uscirne

pinzasi:
Vorrei fare il broadcasting perche' cosi' la trasmissione e' lentissima.

Appena ho tempo proverò ad esaminare le altre cose, ma posso intanto dirti che il broadcast si fa semplicemente mettendo come IP destinatario l'indirizzo di broadcast della tua rete, ossia mettendo 255 come ultimo valore (ovvero mettendo ad 1 tutti i bit che nella netmask sono a zero a partire da destra).
Ad esempio se sei nella rete 192.168.1.* (ossia netmask 255.255.255.0), l'indirizzo broadcast sarà 192.168.1.255.
Se un pacchetto UDP lo mandi a quell'indirizzo (e ad una porta specifica che determinerai tu) lo riceveranno tutti gli apparati di rete in ascolto su quella porta.

Tra l'altro il pacchetto NON è una stringa, neanche se ci fai il cast, quindi non usare "Serial.println((char*)packetBuffer);" ma metti una for() per tutti i byte (non tutto il buffer, solo i primi "packetSize"!) e riporta il valore HEX di ogni elemento del buffer e vediamo cosa riceve realmente.

Poi riporta l'output che vedi sui due monitor seriali, così insieme agli sketch magari si capisce meglio cosa hanno fatto/ricevuto...

SukkoPera:
Verifica cosa ritorna beginPacket().

Questo l'hai fatto? ::slight_smile:

Salve, il sito mi ha cancellato per ben 2 volte tutto il post perche' era troppo grande, spero di ricordare tutto, comunque finalmente sono riuscito a far accendere il benedetto led mettendo all'interno del ciclo for in cui leggo il packetBuffer l'IF e mi sono accorto che il packetBuffer e' completamente vuoto per 23 posizioni mentre all'ultima c'e' il carattere J(74) oppure il carattere E(69).
Ho fatto anche delle prove con il Broadcast di cui allego lo sketch e praticamente riesco a leggere il carattere ma se spengo la trasmissione vedo sul Serial.print delle 2 schede il fluire dei caratteri per qualche minuto come se molti pacchetti fossero stati memorizzati all'interno delle schede (ho detto una castroneria?).
Ho fotografato i due monitor ma non riesco ad allegare le foto perche' il sito non me lo permette. Vedro di fare ei messaggi divisi.
trasmissione:

#include <SPI.h>        
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:

byte mac[] = {  0xDE, 0xAB, 0xDE, 0x05, 0xFC, 0xC8 };
IPAddress ip(192, 168, 1, 180);         //centrale di comando
IPAddress remote1IP(192, 168, 1, 181);  //pos. lavanderia
IPAddress remote2IP(192, 168, 1, 182);  //pos. cucina/camera post.
IPAddress remote3IP(192, 168, 1, 183);  //pos. cameretta
IPAddress remote4IP(192, 168, 1, 184);  //pos. camera fronte
IPAddress remote5IP(192, 168, 1, 185);  //pos. salotto
IPAddress remote6IP(192, 168, 1, 186);  //pos. serra
IPAddress remote7IP(192, 168, 1, 187);  //pos. garage
IPAddress remote8IP(192, 168, 1, 188);

unsigned int localPort = 8889;      // local port to listen on

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
char stringa;
void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);
pinMode(7,INPUT_PULLUP);
}

void loop() {
 byte stringa ;
if (digitalRead(7) == LOW){
   stringa = 74;
  }else{
   stringa = 69;
  }  
    Udp.beginPacket(remote1IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote2IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote3IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    /*
    Udp.beginPacket(remote4IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote5IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote6IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote7IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
    Udp.beginPacket(remote8IP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
*/
delay(10);
}

trasmissione Broadcast:

#include <SPI.h>        
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:

byte mac[] = {  0xDE, 0xAB, 0xDE, 0x05, 0xFC, 0xC8 };
IPAddress ip(192, 168, 1, 180);         //centrale di comando
IPAddress remoteIP(192, 168, 1, 255);  //pos. broadcast

unsigned int localPort = 8889;      // local port to listen on

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
char stringa;
void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);
pinMode(7,INPUT_PULLUP);
}

void loop() {

if (digitalRead(7) == LOW){
   stringa = 74;
  }else{
   stringa = 69;
  }  
    Udp.beginPacket(remoteIP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
   
delay(10);
}

ricezione:

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#include <String.h>
int i;
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:

byte mac[] = { 0xDE, 0xAB, 0xDE, 0xDA, 0xB1, 0xC6};
IPAddress ip(192, 168, 1, 182);

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data

byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
byte ric = 0;
// An EthernetUDP instance to let us send and receive packets over UDP

EthernetUDP Udp;

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
  pinMode(7, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    Serial.println("Contents:");
    Serial.println((char*)packetBuffer);
    for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++)
     
 Serial.println("Contents Buffer:");
    Serial.println(packetBuffer[i]);
   

    if (packetBuffer[i] == 74) {
      digitalWrite (7, LOW);
    } else {
      digitalWrite (7, HIGH);
    }

    for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++)
      packetBuffer[i] = 0;
 Serial.println("Contents1:");
    Serial.println((char*)packetBuffer);

  }

  delay(10);

}

pinzasi:
for in cui leggo il packetBuffer l'IF e mi sono accorto che il packetBuffer e' completamente vuoto per 23 posizioni mentre all'ultima c'e' il carattere J(74) oppure il carattere E(69).

Primo, non è completamente vuoto, secondo, il carattere non è all'ultima posizione.
Ma la soluzione a questa cosa la troverai nei miei commenti successivi...

Ho fatto anche delle prove con il Broadcast di cui allego lo sketch e praticamente riesco a leggere il carattere ma se spengo la trasmissione vedo sul Serial.print delle 2 schede il fluire dei caratteri per qualche minuto come se molti pacchetti fossero stati memorizzati all'interno delle schede

Ma tu nel loop() del trasmettitore hai presente cosa fai? Questo:

void loop() {

if (digitalRead(7) == LOW){
   stringa = 74;
  }else{
   stringa = 69;
  }  
    Udp.beginPacket(remoteIP, 8888);
    Udp.write(stringa);
    Udp.endPacket();
   
delay(10);
}

Mandi un pacchetto ogni 10 millisecondi, ossia 100 pacchetti al secondo! non credo che ti serva, e comunque dovresti secondo me mandare il pacchetto solamente se CAMBIA il valore, non in modo continuo! Prova a modificare questa cosa.
In ogni caso, per favore indenta sto codice!!!

Poi nel ricevitore leggo:

   // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    Serial.println("Contents:");
    Serial.println((char*)packetBuffer);
    for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++)
     
 Serial.println("Contents Buffer:");
    Serial.println(packetBuffer[i]);
   

    if (packetBuffer[i] == 74) {
      digitalWrite (7, LOW);
    } else {
      digitalWrite (7, HIGH);
    }

Primo, perché continui ad usare UDP_TX_PACKET_MAX_SIZE nella for(), se la read() ti ha detto che hai "packetSize" byte, perché ti ostini a leggerli tutti e mandarli nella seriale? Non causa problemi, ma non serve a nulla, e nelle posizioni successive potresti trovare residui di altre letture e quindi confonderti!
Devi fare:

for (int i = 0; i < packetSize; i++)

Secondo, ti rendi conto che quella for se non ci metti graffe esegue solamente la "Serial.println("Contents Buffer:");"? Te ne saresti accorto se avessi fatto fare l'indentazione quindi RIPETO, indenta sto benedetto codice, non è così difficile premere Ctrl-T nell'editor....

Terzo, togli la "#include <String.h>" che non serve!

Quarto, ora la soluzione al tuo dilemma.
Quando tu fai, sempre sbagliando perché non indenti decentemente (ma qui te lo indento io come il compilatore lo interpreta):

    for (int i = 0; i < UDP_TX_PACKET_MAX_SIZE; i++)
      Serial.println("Contents Buffer:");
    Serial.println(packetBuffer[i]);

il ciclo for() contiene, come detto, solo la scritta "Contents Buffer" (che quindi nel monitor dovresti vedere ripetuta 32 volte e già questo avrebbe dovuto dirti qualcosa...), ma la cosa importante è che la variabile "i" di questo ciclo "muore" alla fine del for() in quanto l'hai definita internamente. L'istruzione successiva quindi quale variabile "i" legge e quanto vale? Se vai ad inizio del codice troverai una dichiarazione "int i;" che, essendo quindi globale, è questa che viene usata nel "Serial.println(packetBuffer[ i ]);". E quanto vale? Semplice, non l'hai mai usata quindi vale zero. Per cui tu vedi sempre "Serial.println(packetBuffer[0]);" ossia il PRIMO byte, non l'ultimo. Inoltre sarebbe opportuno mostrare i valori in esadecimale perché non è detto che siano caratteri stampabili.

Per cui se cambi quella for() in questo modo vedrai correttamente ed esattamente tutto il contenuto del pacchetto ricevuto:

    Serial.print("Contents Buffer: ");
    for (int i = 0; i < packetSize; i++) {
      Serial.print(packetBuffer[i], HEX);
      Serial.print(" ");
    }
    Serial.println();

PS: se non indenti il codice, non ti rispondo più...

Salve, per quanto riguarda l'identazione l'ho fatta e quello che ho messo era il risultato, probabilmente sto sbagliando qualcosa, e stasera ho riprovato, comunque allego il risultato :

Received packet of size 1
From 192.168.1.180, port 8889
Contents Buffer: 4A 
Contents1:

Received packet of size 1
From 192.168.1.180, port 8889
Contents Buffer: 4A 
Contents1:

Received packet of size 1
From 192.168.1.180, port 8889
Contents Buffer: 4A 
Contents1:

Received packet of size 1
From 192.168.1.180, port 8889
Contents Buffer: 4A 
Contents1:

Received packet of size 1
From 192.168.1.180, port 8889
Contents Buffer: 4A 
Contents1:

Received packet of size 1
From 192.168.1.180, port 8889
Contents Buffer: 4A 
Contents1:

Oppure in alternativa contiene il numero HEX 45 in tutte le locazioni.
Questo vale per tutte e 2 le schede su cui sto lavorando.
Questo per me e' l'approccio al programma che dovro' fare per cui l'informazione sulla rete la mandero' soltanto 2/3 volte e poi mi fermero' fino ad una variazione che mandera' altri 2/3 dati.
In questo caso mi sto rendendo conto dei miei limiti ed il fatto di non avere basi solide su cui lavorare e' palese, comunque ti ringrazio di tutto il tempo che mi hai dedicato e devo dire che ho imparato molto da queste righe, e comunque non mi fermo cerchero' di trovare un buon testo che mi faccia crescere.
Grazie ancora.
Simone

pinzasi:
per quanto riguarda l'identazione l'ho fatta e quello che ho messo era il risultato, probabilmente sto sbagliando qualcosa

Forse hai editato lo sketch anche con un editor esterno che ti ha messo dei TAB che qui una volta incollato lo ha trasformato in un spazio.

Received packet of size 1
From 192.168.1.180, port 8889
Contents Buffer: 4A
Contents1:

Ok, allora leggi sempre 1 byte come dovrebbe, e leggi 4A che è il codice esadecimale del carattere "J". Quindi funziona. O no? Che cosa è quel "Contents1:"?

Oppure in alternativa contiene il numero HEX 45 in tutte le locazioni.

E quella è la "E". Ma che intendi "in tutte le locazioni"? Se dici che è in tutto il buffer non ho idea perché ci siano, ma in ogni caso devi ignorare i byte oltre quelli di "packetSize" (anche perché non ne inizializzi il valore nel setup()).

Questo per me e' l'approccio al programma che dovro' fare per cui l'informazione sulla rete la mandero' soltanto 2/3 volte e poi mi fermero' fino ad una variazione che mandera' altri 2/3 dati.

Ok, ma a che ti serve mandarli 2 o 3 volte? Ne basta una.

comunque ti ringrazio di tutto il tempo che mi hai dedicato e devo dire che ho imparato molto da queste righe, e comunque non mi fermo cerchero' di trovare un buon testo che mi faccia crescere.

Ottimo approccio.
Qualche altro consiglio allora più che altro "stilistico", ad esempio tu fai:

if (digitalRead(7) == LOW){
   stringa = 74;
  }else{
   stringa = 69;
  }  
    Udp.beginPacket(remoteIP, 8888);
    Udp.write(stringa);
    Udp.endPacket();

Se mandi un byte, anzi un carattere, perché appoggiare il valore in una variabile (che usi solo qui)? Inoltre se è parte del tuo protocollo, metti come simbolo costante i due valori. Il tutto diventa più leggibile e compatto.
Ad esempio nella trasmissione:

// a inizio codice
#define COD_LOW 0x4A
#define COD_HIGH 0x45
  ...

    Udp.beginPacket(remoteIP, 8888);
    if (digitalRead(7) == LOW){
      Udp.write(COD_LOW);
    else
      Udp.write(COD_HIGH);
    Udp.endPacket();

e quindi in ricezione (mettendo le stesse #define in testa, tra l'altro tu distingui solo COD_LOW, qualsiasi altro byte lo interpreti come COD_HIGH, invece sarebbe opportuno scartare eventuali pacchetti non corretti):

    if (packetBuffer[0] == COD_LOW)
      digitalWrite (7, LOW);
    if (packetBuffer[0] == COD_HIGH)
      digitalWrite (7, HIGH);

oppure, meglio, perché più chiaro e facilmente espandibile:

    switch (packetBuffer[0]) {
    case COD_LOW:
      digitalWrite (7, LOW);
      break;
    case COD_HIGH:
      digitalWrite (7, HIGH);
      break;
    }

Magari riuscissi a pensare a queste finezze, ho troppa strada da fare ancora per scrivere un codice così pulito. Mi auguro comunque di fare delle belle cose, sono sempre stato autodidatta e magari con piu tempo però alla fine ci arrivo.Comunque il fatto di mandare il messaggio 2 volte è secondo me per evitare di perdere il messaggio per strada e non avere il risultato visto che in Udp non c'è il controllo dei pacchetti. Con 2 volte riduco il rischio.
Che libro mi consiglieresti per approcciare bene il C/ C++.
È bello vedere che ci sono persone che si dedicano agli altri senza nemmeno conoscerle, in un era di egoismo ed arrivismo questo è un comportamento nobile. Complimenti ancora a te ed a tutti quelli che tengono in piedi questo"servizio"
Simone