ciao a tutti.
sono nuovo del forum e sono un neofita sia di programmazione che di arduino.
ho un problema che non riesco a risolvere e dopo alcuni giorni che sbatto la testa ovunque non arrivo da nessuna parte.
ho due arduino uno collegati ad uno swich di rete con due ethernet sheld wiznet, voglio remotizzare dei comandi a dei servo ovvero voglio utilizzare un arduino per pilotare i servo e l'altro per acquisire i dati di un potenziometro e inviarli via udp.
quindi modificando l'esempio base UDPsendreceiverstrig sono riuscito a farli comunicare,uno invia e l'altro riceve.
sino a quando si tratta di messaggi es; Udp.write("ciao") tutto ok. ma non so assolutamente come mandare dei valori in modo separato o codificarli e riconoscerli separatamente dall'altra parte ovvero inviare per esempio val1=111 val2=90
e dall'altra parte ritrovarmi i due valori e scriverli su un uscita.
magari per qualcuno è una stupidata ma per me è una montagna dove non trovo neanche il sentiero per partire.
grazie in anticipo a chiunque risponda
In C/C++ (Arduino) devi imparare ad usare le stringhe, vettore di caratteri terminato da null '\0'. NON la classe String che su queste MCU con poca SRAM possono dare problemi.
Quello che vuoi costruirti è un tuo protocollo. Per semplificare ti conviene stabilire delle parole a lunghezza fissa, esempio (non per il tuo caso specifico) vuoi accendere/spegnere dei rele numerati da 1 a 12 , io manderei delle frasi del tipo R04 => accendi rele numero 4. r04=> spegni il rele numero 4. Nota che mando sempre 2 cifre e la 'R' oppure 'r' mi dice se accendo o spengo.
Nello sketch a questo punto non è difficile "analizzare" la frase ricevuta per stabilire i "comandi" che Arduino deve svolgere.
Una parte della frase è un valore che dovrai convertire da testo a numero vero e proprio. Puoi usare atoi().
Nel tuo caso se devi mandare valori diversi per usi diversi invece di val1=111 val2=90 io spedirei A111 e B090, come vedi la prima lettera indica il primo o secondo valore, mentre dal secondo carattere hai sempre il valore (al max. 3 cifre).
Tu ora come ricevevi quella frase "ciao" ? Hai il codice ?
Invece da dove spedisci ? Da un PC o da un altro Arduino?
Ciao karma.
Allora, io invio da un Arduino e ricevo su di un altro Arduino e per verificare utilizzo il monitor seriale!
Ora mando lo sketch di invio
```
**[code]#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 176);
IPAddress remote (192,168,1,177);
unsigned int localPort = 8889;
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac, ip);
Udp.begin(localPort);
Serial.begin(9600);
}
void loop() {
Udp.beginPacket(remote,8888);
Udp.write("hello");
Udp.endPacket();
delay(10);
}**
```
[/code]
E questo è quello per ricevere
#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
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xAE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
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
// 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);
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(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);
}
@ ziopi88 : Si parla d'altro, ma prova a guardare le mie spiegazioni in QUESTO thread ... magari possono aiutarti ![]()
Guglielmo
@ziopi, quello che spedisci lo ricevi e te lo ritrovi dentro a stringa "packetBuffer".
Quello che non sò è se spedendo 2 volte "hello" dentro a quella stringa avrai prima un "hello" e poi un'altro "hello" oppure ti ritrovi 2 hello in un unica ricezione. Il tuo che spedisce lo fa di continuo, cosa ricevi? Un "hello" alla volta?
Se si, invece di "hello" puoi spedire dei comandi come detto prima.
char buf[20];
....
comando='A'; // singolo carattere
valore=67;
snprint(buf,20,"%c%03d",comando,valore); // scrive dentro a buf "A067" vedi printf del C
Udp.write(buf);
%c stampa un carattere, %d un numero, con 03 lo riempie di 0 per 3 posizioni
http://www.cplusplus.com/reference/cstdio/snprintf/?kw=snprintf
http://www.cplusplus.com/reference/cstdio/printf/
Allora, gpb01 ho letto quel articolo simile e secondo mè puo darsi che abbia lo stesso problema... devo avere un Po di tempo ed iniziare a fare esperimenti.
Invece per nido 69ita: allora, se scrivo
Udp.write("hello")
Udp.write("hello")
Dall'altra parte sulla seriale mi trovo hellohello
Ma se invio esempio
int val=123
Udp.write(val)
Dall'altra parte mi ritrovo es y
Logico, se usi write() con un numero lui invia sempre il valore di quel numero (singolo byte) e non 3 cifre.
Devi convertire quella val in testo. Vedi il mio post precedente con esempio. Lo converto e lo rendo anche a dimensione fissa.
ciao di nuovo non so perché non riuscivo a connettermi al forum dal mio portatile.... appena facevo il log in si incartava il sito.
cmq dopo varie letture ed esperimenti non arrivo da nessuna parte..... =( =( =(
codice tx
#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
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 176);
IPAddress remoto(192,168,1,177);
unsigned int localPort = 8889;
int val1=234;
int val2=90;
int val3=34;
char stringa[UDP_TX_PACKET_MAX_SIZE] = {val1,val2,val3}; //buffer to hold incoming packet,
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac, ip);
Udp.begin(localPort);
Serial.begin(9600);
}
void loop() {
Udp.beginPacket(remoto,8888);
Udp.write(stringa,UDP_TX_PACKET_MAX_SIZE);
Udp.endPacket();
delay(10);
}
codice rx
#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
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xED, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
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
// 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);
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(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);
}
risultato sulla seriale: Received packet of size 24
From 192.168.1.176, port 8889
Contents:
êZ"
nid69ita ho cercato il tuo ultimo post ma non so quale sia.
mi date una dritta su dove posso andare a studiarmi questo argomento senza stressarvi l'anima =( =(
Mi riferivo a questo:
http://forum.arduino.cc/index.php?topic=252874.msg1790912#msg1790912
uso il comando snprint() oppure itoa()
Tu qui spedisci numeri come numeri e non come testo:
int val1=234;
int val2=90;
int val3=34;
char stringa[UDP_TX_PACKET_MAX_SIZE] = {val1,val2,val3};
Questi valori se li stampi a video sono 234=ê 90=Z e 34="
Quindi hai ricevuto i valori giusti. Devi però stamparli come numeri:
Serial.println( int(remote[i]), DEC);
Essendo array remote di char, la print tende a stamparti i valori come caratteri
ok sono scemo era sotto il naso....
arrivano tx
int val1=234;
int val2=90;
int val3=34;
char stringa[UDP_TX_PACKET_MAX_SIZE] = {val1,val2,val3}; //buffer to hold incoming packet,
rx
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
for (int i = 0; i < 4; i++)
{
Serial.print(packetBuffer[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
risposta
From 192.168.1.176, port 8889
Contents:
-22.90.34.0Received packet of size 24
ho provato a leggere 3 volte http://www.cplusplus.com/reference/cstdio/snprintf/?kw=snprintf ma non riesco davvero a capire nulla =(
cmq con questa strada sto avendo risultati quindi l'unica è continuare di qua...e soprattutto forse capisco cosa sto facendo oppure ci arrivo a scopio ritardato.
cmq avrei ancora alcune domandine
perchè comprende male i valori superiori a 100??
poi perchè anche se io modifico lo skech e mando un solo val dall'altra parte mi trovo , un valore giusto e poi altri 3 valori diversi divisi da tre puntini???
grazie per la pazienza.
-
Indipendentemente da quante cifre spedisci nel codice c'e' quel for() che è un ciclo per stampare sempre 4 valori. La cosa migliore sarebbe mandare come primo valore il numero di elementi spediti. Quel for() ora è fisso e si aspetta sempre 4 cifre.
-
Quell' if (i < 3) stampa sempre 3 puntini tra le cifre. Levalo.
-
Poi tu stampi (te lo ripeto, l'ho scritto sopra) le cifre che ricevi prendendole da buffer che è un array/vettore di char, perciò stai stampando i valori come caratteri. I char poi sono con il segno.
Un char accetta un byte (8 bit) quindi valori da 0-255 se unsigned (senza segno) oppure -128+127 se con segno.
Un char è con segno. Il valore contenuto è sempre uguale. 10 con o senza segno è sempre lo stesso. Valori superiori a 127 sono interpretati nei char come negativi. Se stampi però usando la conversione a unsigned sei a posto (si chiama cast in linguaggio C ).
Serial.println( (unsigned int)remote[i], DEC); // converte char in unsigned int, cast