Dunque, ho risolto i miei problemi con la libreria EthernetUDP.
Incollo di seguito lo Sketch risultante e che per quel che mi riguarda chiude la prima fase del mio progetto:
/*
Sketch che mi permette di interrogare l'Inverter di un impianto Fotovoltaico per farmi restituire in tempo reale i Watt generati.
Invio una richiesta all'Inverter, leggo la Risposta, la converto in una Stringa Esadecimale e ne estraggo le sole parti che mi interessano.
L'impianto Fotovoltaico è Trifase quindi dalla Stringa Esadecimale dovrò estrarre la potenza generata su ogni fase e sommarle.
Alessio Zelati.
*/
#include <SPI.h> // needed for Arduino versions later than 0018
#include <stdlib.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
// MacAddress dell'Ethernet Shield
byte mac[] = { 0x00, 0x1D, 0x60, 0xAF, 0x03, 0x31 };
// IpAddress assegnato allo Shield
IPAddress localIp(192, 168, 0, 10);
//IPAddress del Managed, ovvero l'oggetto a cui vogliamo rivolgere richieste
IPAddress remoteIp(192, 168, 0, 60);
// Il pacchetto inviato come richiesta al Managed.
// Io l'ho copiato da uno inviato da un programma su PC ed intercettato con WireShark.
// Mi sembra però di capire che si ottiene una risposta anche se si invia un pacchetto vuoto.
const int PACKET_SIZE = 1;
byte packetRequest[] = { 0x00 };
// buffers per la ricezione dei dati.
// Lo faccio lungo 700 perché i pacchetti in arrivo so che sono lunghi 690.
byte packetBuffer[700];
String pacHex; // Stringa in cui verrà "scompattato" il pachetBuffer traducendolo in una Stringa Esadecimale.
EthernetUDP Udp; // No Comment.
void setup() {
Ethernet.begin(mac, localIp);
Udp.begin(8888);
Serial.begin(9600);
}
void loop() {
// Invio un pacchetto qualsiasi
Udp.beginPacket(remoteIp, 33000); // 33000 è la porta del Managed su cui è attiva la comunicazione UDP.
Udp.write(packetRequest, PACKET_SIZE);
Udp.endPacket();
Serial.println("Inviato Pacchetto");
delay(100);
int packetSize = Udp.parsePacket();
if(packetSize) {
Serial.print("Ricevuto pacchetto. Size: ");
Serial.println(packetSize);
Udp.read(packetBuffer, packetSize);
// Trasforma il packetBuffer in una Stringa di caratteri Esadecimali
for (int x = 0; x < packetSize; x++) {
String a = String(packetBuffer[x], HEX);
pacHex += (a.length() < 2) ? "0"+a : a;
}
char pwr1Hex[5]; // 4 caratteri esadecimali contenenti la Potenza generata dalla Fase 1
unsigned int intPwr1; // valore Decimale della Potenza generata dalla Fase 1
char pwr2Hex[5]; // 4 caratteri esadecimali contenenti la Potenza generata dalla Fase 2
unsigned int intPwr2; // valore Decimale della Potenza generata dalla Fase 1
char pwr3Hex[5]; // 4 caratteri esadecimali contenenti la Potenza generata dalla Fase 3
unsigned int intPwr3; // valore Decimale della Potenza generata dalla Fase 1
// Estraggo dalla Stringa Esadecimale i 3 gruppi di 4 caratteri che costituiscono le Potenze generate dall'Inverter Fotovoltaico
pacHex.substring(280, 284).toCharArray(pwr1Hex, 5);
pacHex.substring(284, 288).toCharArray(pwr2Hex, 5);
pacHex.substring(288, 292).toCharArray(pwr3Hex, 5);
// Converto gli Esadecimali in Decimali.
sscanf( (const char*)pwr1Hex, "%4x", &intPwr1 );
sscanf( (const char*)pwr2Hex, "%4x", &intPwr2 );
sscanf( (const char*)pwr3Hex, "%4x", &intPwr3 );
// Stampo i valori ottenuti.
Serial.print(intPwr1);
Serial.print(" ");
Serial.print(intPwr2);
Serial.print(" ");
Serial.print(intPwr3);
Serial.print(" Totale: ");
int tot = intPwr1 + intPwr2 + intPwr3;
Serial.println(tot);
}
// Pulisco il buffer.
Udp.flush();
pacHex = "";
Serial.println("");
delay(5000);
}
// Ho lasciato questo metodo perché è grazie a lui che nella lavorazione sono riuscito a "vedere"
// cosa c'era nel buffer.
// Il metodo scorre tutto il "text" (che contiene la stringa esadecimale) 2 caratteri per volta, li converte in decimale
// Se il valore ottenuto è un carattere Ascii (da 32 a 127) allora lo converte nel carattere corrispondente
// altrimenti prende in esame non 2 ma 4 caratteri e li converte in decimale e quello sarà un dato significativo
// (nel mio caso erano proprio i valori che cercavo di Volt, Ampere, Watt... etc etc etc)
//void to_ascii( unsigned char* dest, char *text ) {
// unsigned int ch ;
// for( ; sscanf( (const char*)text, "%2x", &ch ) == 1 ; text += 2 ) {
// if (31<ch && ch<128) {
// Serial.print((char)ch);
// } else {
// sscanf( (const char*)text, "%4x", &ch );
// Serial.print(ch);
// text += 2;
// }
// Serial.print(" ");
//// *dest++ = ch ;
// }
//// *dest = 0 ;
//}
Chissà se queste poche righe in futuro potranno essere utili a qualcuno.
;0))