Go Down

Topic: Invio Comandi tra Client e Server (Read 12537 times) previous topic - next topic

lollo1100

Feb 14, 2013, 04:12 pm Last Edit: Feb 15, 2013, 01:01 pm by lollo1100 Reason: 1
Buon pomeriggio a tutti, ho un problema di estetica credo.
Vorrei scambiare comandi tra un Arduino Uno che gioca il ruolo di Client e un Arduino Uno che gioca il ruolo di Server.
Il comando che il client deve inviare al server è il seguente: quando premo un pulsante collegato al mio Arduino Uno client questo deve dire al server
p.s. sono collegati tramite ethernet shield e si scambiano informazioni con il protocollo Telnet sulla porta 23 gli deve dire appunto che è stato premuto il
bottone e che quindi il server deve accendere il Led.
Il problema per ora l'ho risolto con le funzioni print() della libreria client scrivendo appunto print('1'); e print('0'); per accendere e spegnere il Led. Di seguito
posto i due sketch

Sketch del Client
Code: [Select]


                         
#include <SPI.h>      //  Importa Libreria SPI
#include<Ethernet.h>  //  Importa Libreria Ethernet

#define BUTTON 7      //  Porta digitale 7 Bottone ON  
#define BUTTON2 6     //  Porta digitale 6 Bottone OFF

int val = HIGH;       //  Valore Porta digitale 7
int val2 = HIGH;      //  Valore Porta digitale 6

int stato = HIGH;     //  Store stato Porta DGT 7
int stato2 = HIGH;    //  Store stato Porta DGT 6

byte mac[] = {
 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x47 };  
                                //  MAC Ethernet Shield Client
IPAddress ip( 10, 10, 11, 16 );  //  IP Arduino Client
IPAddress server( 10, 10, 11, 45);  //  IP Arduino Server

EthernetClient client; //  Inizializza il Client

void setup() {
 pinMode(BUTTON, INPUT);    //  Imposta PIN DGT 7 INPUT  
 pinMode(BUTTON2, INPUT);   //  Imposta PIN DGT 6 INPUT
 Ethernet.begin( mac,ip );  //  Inizializza Ethernet
 Serial.begin(9600);        //  Inizializza COM3
}  
void loop() {  

 val = digitalRead( BUTTON );    //  val = BUTTON
 val2 = digitalRead( BUTTON2 );  //  val2 = BUTTON2

   if( val == HIGH );    //  Se val = HIGH FASE 0
 else{
   if ( val == LOW && val != stato){  //  Se val = LOW
                                      //  & val diverso da stato
     stato == LOW;                    //  Imposta stato = LOW
     delay(500);                      //  Ritardo 500 mills
     Serial.println("Connessione in corso attendere...");  //  Stampa su COM3
                                      //   "Connessione in corso attendere..."
     if (client.connect(server, 23)){ //  Verifica conn. Client-To-Server
       Serial.println("Connesso ON"); //  Stampa su COM3 Connesso ON
       client.print('1');             //  Stampa '1' su CLIENT
       client.stop();                 //  Chiudi connessione
       stato = HIGH;                  //  Imposta stato = HIGH
     }
     else{
       Serial.println("Connessione ON fallita");  //  Altrimenti
                                      //  Stampa su COM3 Connessione ON fallita
       client.stop();                 //  Chiudi connessione
     }
   }
 }
 if( val2 == HIGH );     //  Se val = HIGH FASE 0
 else{  
   if ( val2 == LOW && val2 != stato2){   //  Se val2 = LOW
                                          //  & val2 diverso da stato2
     stato2 == LOW;                       //  Imposta stato2 = LOW
     delay(500);                          //  Ritardo 500 mills
     Serial.println("Connessione in corso attendere...");  //  Stampa su COM3
                                          //   "Connessione in corso attendere..."
     if (client.connect(server, 23)){
       Serial.println("Connesso OFF");    //  Stampa su COM3 Connesso OFF
       client.print('0');                 //  Stampa '0' su CLIENT
       client.stop();                     //  Chiudi connessione
       stato2 = HIGH;                     //  Imposta stato2 = HIGH
     }
     else{
       Serial.println("Connessione OFF fallita");  //  Altrimenti
                                          //  Stampa su COM3
                                          //  Connessione ON fallita
       client.stop();                     //  Chiudi connessione
     }
   }      
 }
}



Sketch del Server
Code: [Select]




#include <SPI.h>                               //  Importa Libreria SPI
#include <Ethernet.h>                          //  Importa Libreria
                                              //  Ethernet

#define LED 7                                  //  Porta digitale 7 LED

byte mac[] = {
 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };        //  MAC Ethernet Shield del
                                              //  Server
byte ip[] = {
 10, 10, 11, 45};                             //  IP Arduino Server

EthernetServer server(23);                     //  Telnet porta 23
EthernetClient client = 0;                     //  Inizializza il Client

void setup()
{
 pinMode( LED, OUTPUT );                      //  Imposta LED OUTPUT
 Ethernet.begin(mac, ip);                     //  Inizializza Ethernet
 server.begin();
}
void loop()
{
 if (server.available() && client.connected()) {  //  Byte sul Server
                                                  //  &
                                                  //  se è true
                                                  //  Client-To-Server

   char c = client.read();                    //  Legge i Byte su Client

   if ( c == '1' )                            //  Se Byte = '1' LED ON
     digitalWrite( LED, HIGH );
   else
     if ( c == '0' )                          //  Se Byte = '0' LED OFF
       digitalWrite( LED, LOW );
 }
}



Grazie!  

matt-korban

ciao! ma riesci a caricare il programma senza che ti dia errori???

lollo1100

Certo  :)  ovviamente su due Arduino Uno ...su uno (il server) c'è collegato il LED sull'altro il (client) i bottoni è una shield di arduino che ci stanno i bottoni ;) funziona abbastanza bene con 1 client e 1 server

pablos71

#3
Feb 15, 2013, 11:26 am Last Edit: Feb 15, 2013, 11:34 am by pablos Reason: 1
Scusa la domanda qual'è?

Se chiedi "è giusto usare client.print() per ilviare il dato usando il protocollo telnet?", la risposta è si, non vedo come potresti fare diversamente, la libreria ti mette a disposizione l'istruzione client.print e client.read per lavorare con l'ethernet.

Quote
Il problema per ora l'ho risolto con le funzioni print() della libreria client scrivendo appunto print('1'); e print('0'); per accendere e spegnere il Led.

Dov'è il problema?

Perchè dici abbastanza bene?
A volte va a volte no?

Non è chiaro cosa vuoi sapere

ciao
L'esperienza è il tipo di insegnante più difficile ....
Prima ti fa l'esame e poi ti spiega la lezione.

lollo1100

se c'è un modo più elegante (cmq funziona  :) ) ...ah inoltre nella fase di upload dei due codici appena ho caricato quello del client per intendersi ( p.s. dopo aver caricato quello del server nell'altro arduino ) c'è una fase in cui non funziona tanto bene magari sono necessari 2 click x accendere o spegnere solo i primi secondi ?? immagino sia o un problema di protocollo o un problema HW? Un dubbio enorme che ho visto sollevato in un altro post. Nella gestione del bottone sapete dirmi un metodo via sw per evitare l'effetto dell'anti rimbalzo quello spiacevole effetto che mi fa eseguire il blocco di istruzioni dell'avvenuta variazione di stato del pulsante n volte :) ovviamente vorrei evitare di scrivere delay(n) :D grazie mille !!! p.s. dubito ci sia una soluzione sw, ma non sono abbastanza ferrato per esserne certo  :smiley-mr-green: ah magari sarebbe xfetto se non ricorressi alla funzione millis() sarebbe ancora meglio per il problema dell'antirimbalzo.

pictux

Ciao

Quote
Nella gestione del bottone sapete dirmi un metodo via sw per evitare l'effetto dell'anti rimbalzo quello spiacevole effetto che mi fa eseguire il blocco di istruzioni dell'avvenuta variazione di stato del pulsante n volte  ovviamente vorrei evitare di scrivere delay(n)  grazie mille !!! p.s. dubito ci sia una soluzione sw, ma non sono abbastanza ferrato per esserne certo   ah magari sarebbe xfetto se non ricorressi alla funzione millis() sarebbe ancora meglio per il problema dell'antirimbalzo.


Arduino IDE -> File -> Examples -> Digital -> Debounce

lollo1100

si pitusso ma li la gestisce con i millis() poi non è proprio quello che vorrei ottenere io :)  cmq grazie
io vorrei che premo il pulsante verifica il cambiamento di stato una sola volta. ( la verifica la faccio stampando sulla serial senza led )
se hai qualche idea ti ringrazio infinitamente

lestofante

sì, il modo più elegante esiste. Per ora stai inviando i dati in formato char, quindi ad esempio 138 sono 3 char, quindi 3 byte. Se invece della print usi la write, non effettu la conversione in char.
Dunque il valore se è un byte occuperà smepre 1 byte, se un int sempre 2 byte etc..
In questo modo ottimizzi molto la banda, ma perdi la possibilità di leggere direttamente i dati collegandoti da telnet..

Sinceramente io uso questo sistema con la seriale per quando devo comunicare col PC i dati delle letture il più in fretta possibile, sopratutto se i dati sono long o float;
123456789 sono ben 9byte di stringa, ma solo 4 di long, meno della metà!
123456.89 sono ben 9byte di stringa, ma solo 4 di float, meno della metà!
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

lollo1100

scusa lesto ma se tipo faccio client.write ("on"); sullo sketch del client sul lato server....quando server.available() = true... in pratica io faccio char c = client.read();
se scrivo on nel lato client sul server mi da un errore di conversione perchè ovviamente on sono due caratteri e dice che client.read() può leggere solo 1 carattere come posso fargli leggere ON sarebbero 2 byte o sbaglio? ...cmq comunico tramite il protocollo telnet glieli mando con l'ethernet i byte...grazie Lesto e chiunque mi voglia rispondere

lestofante

oddio no, non funziona così.

client.write ("on"); credo non esista, "on" viene sostituito con un array di char (puntatore) e il write vedrà il puntatore come un int (indirizzo di menmoria puntato) e dunque scriverà questo int (2byte)
se vuoi però possiamo fare una client.print("on");


ORA

il server NON sa quanti byte sta per ricevere. quando tu fai read() lui ti legge il primo byte disponibile, o -1 se non è arrivato niente. Quindi nessun errore: alla prima read() leggi 'o', alla seconda leggi 'n'
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

lollo1100

#10
Feb 15, 2013, 03:42 pm Last Edit: Feb 15, 2013, 03:44 pm by lollo1100 Reason: 1
Si infatti anche a me suonava male ti posto i codici ...

Lato Client

Code: [Select]


#include <WebServer.h>  //  Importa Libreria WebServer
#include <SPI.h>        //  Importa Libreria SPI
#include <Ethernet.h>   //  Importa Libreria Ethernet

#define BUTTON 7      //  Porta digitale 7 Bottone ON  
#define BUTTON2 6     //  Porta digitale 6 Bottone OFF

int val = HIGH;       //  Valore Porta digitale 7
int val2 = HIGH;      //  Valore Porta digitale 6

int stato = HIGH;     //  Store stato Porta DGT 7
int stato2 = HIGH;    //  Store stato Porta DGT 6

byte mac[] = {
 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x47 };  
//  MAC Ethernet Shield Client
IPAddress ip( 10, 10, 11, 16 );  //  IP Arduino Client
IPAddress server( 10, 10, 11, 45);  //  IP Arduino Server

EthernetClient client; //  Inizializza il Client

void setup() {
 pinMode(BUTTON, INPUT);    //  Imposta PIN DGT 7 INPUT  
 pinMode(BUTTON2, INPUT);   //  Imposta PIN DGT 6 INPUT
 Ethernet.begin( mac,ip );  //  Inizializza Ethernet
 Serial.begin(9600);        //  Inizializza COM3
}  
void loop() {  

 val = digitalRead( BUTTON );    //  val = BUTTON
 val2 = digitalRead( BUTTON2 );  //  val2 = BUTTON2

   if( val == HIGH );    //  Se val = HIGH FASE 0
 else{
   if ( val == LOW && val != stato){  //  Se val = LOW
     //  & val diverso da stato
     stato == LOW;                    //  Imposta stato = LOW
     delay(500);                      //  Ritardo 500 mills
     Serial.println("Connessione in corso attendere...");  //  Stampa su COM3
     //   "Connessione in corso attendere..."
     if (client.connect(server, 23)){ //  Verifica conn. Client-To-Server
       Serial.println("Connesso ON"); //  Stampa su COM3 Connesso ON
       client.print("ON");             //  Stampa '1' su CLIENT
       client.stop();                 //  Chiudi connessione
       stato = HIGH;                  //  Imposta stato = HIGH
     }
     else{
       Serial.println("Connessione ON fallita");  //  Altrimenti
       //  Stampa su COM3 Connessione ON fallita
       client.stop();                 //  Chiudi connessione
     }
   }
 }
 if( val2 == HIGH );     //  Se val = HIGH FASE 0
 else{  
   if ( val2 == LOW && val2 != stato2){   //  Se val2 = LOW
     //  & val2 diverso da stato2
     stato2 == LOW;                       //  Imposta stato2 = LOW
     delay(500);                          //  Ritardo 500 mills
     Serial.println("Connessione in corso attendere...");  //  Stampa su COM3
     //   "Connessione in corso attendere..."
     if (client.connect(server, 23)){
       Serial.println("Connesso OFF");    //  Stampa su COM3 Connesso OFF
       client.print("OFF");                 //  Stampa '0' su CLIENT
       client.stop();                     //  Chiudi connessione
       stato2 = HIGH;                     //  Imposta stato2 = HIGH
     }
     else{
       Serial.println("Connessione OFF fallita");  //  Altrimenti
       //  Stampa su COM3
       //  Connessione ON fallita
       client.stop();                     //  Chiudi connessione
     }
   }      
 }
}



Lato Server

Code: [Select]


#include <SPI.h>                               //  Importa Libreria SPI
#include <Ethernet.h>                          //  Importa Libreria
                                              //  Ethernet

#define LED 7                                  //  Porta digitale 7 LED

byte mac[] = {
 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };        //  MAC Ethernet Shield del
                                              //  Server
byte ip[] = {
 10, 10, 11, 45};                             //  IP Arduino Server

char comando[3];

EthernetServer server(23);                     //  Telnet porta 23
EthernetClient client = 0;                     //  Inizializza il Client

void setup()
{
 pinMode( LED, OUTPUT );                      //  Imposta LED OUTPUT
 Ethernet.begin(mac, ip);                     //  Inizializza Ethernet
 server.begin();
}
void loop()
{
 while ( server.available() && client.connected() ) {                 //  Client-To-Serve                                                                                              
   char c = client.read();                                            //  Legge i Byte su Client
   comando[0] = c;
   comando[1] = c;
   comando[2] = c;
 }
   if ( comando[0] == 'O' && comando[1] == 'N' && comando[2] == 0x0d )                            //  Se Byte = '1' LED ON
     digitalWrite( LED, HIGH );
     if ( comando[0] == 'O' && comando[1] == 'F' && comando[2] == 'F' )                          //  Se Byte = '0' LED OFF
       digitalWrite( LED, LOW );
}



:) non ci fare caso ai commenti sul lato server quelli erano dello sketch che mi funzionava... x quanto riguarda l'anti rimbalzo l'unica soluzione è mettere delay(500); oppure come diceva pitusso ?

lestofante

uil tuo codice:
Code: [Select]
while ( server.available() && client.connected() ) {                 //  Client-To-Serve                                                                                               
    char c = client.read();                                            //  Legge i Byte su Client
    comando[0] = c;
    comando[1] = c;
    comando[2] = c;
  }

La mia correzzione

Prima di tutto la read() restituisce il primo carattere disponibile o -1 se non ci sono dati. Quindi devi assicurarti di avere ALMENO 3 caratteri dsponibili.
Code: [Select]
while ( client.connected() && server.available() >= 3 ) {                 //  Client-To-Serve                                                                                               
    char c = client.read();                                            //  Legge i Byte su Client
    comando[0] = c;
    comando[1] = c;
    comando[2] = c;
  }
}


poi: c è una variabile che contoiene l'ultimo carattere letto; tu stai prendendo quetrso carattere e copiandolo 3 volte nell'array comando. Invece vuoi leggere i 3 caratteri;
Code: [Select]
while ( client.connected() && server.available() >= 3 ) {                 //  Client-To-Serve                                                                                               
    char c = client.read();                                            //  Legge i Byte su Client
    comando[0] = c;
    c = client.read();                                            //  Legge i Byte su Client
    comando[1] = c;
    c = client.read();                                            //  Legge i Byte su Client
    comando[2] = c;
  }
}


Infine nel caso della stringa "ON", essendo di soli 2 caratteri non renderebbe mai "server.available() >= 3 " vero; quindi lato client puoi fare client.print("ON "); (notare lo spazio finale)

e ovviamente quel "0x0d" che non ha senso va cambiato in ' ' (notare lo spazio)

Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

lollo1100

#12
Feb 18, 2013, 03:51 pm Last Edit: Feb 18, 2013, 04:18 pm by lollo1100 Reason: 1
Code: [Select]

#include <SPI.h>                               //  Importa Libreria SPI
#include <Ethernet.h>                          //  Importa Libreria
//  Ethernet

#define LED 7                                  //  Porta digitale 7 LED

char comando[3] ;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };        //  MAC Ethernet Shield del Server

byte ip[] = { 10, 10, 11, 17 };                             //  IP Arduino Server

EthernetServer server = EthernetServer(23);    //  Telnet porta 23
EthernetClient client = 0;                     //  Inizializza il Client

void setup()
{
 pinMode( LED, OUTPUT );                      //  Imposta LED OUTPUT
 Ethernet.begin(mac, ip);                     //  Inizializza Ethernet
 server.begin();
}
void loop()
{
 while ( client.connected() && server.available() >= 3 ) {                 //  Client-To-Serve                                                                                              
   char c = client.read();                                            //  Legge i Byte su Client
   comando[0] = c;
   c = client.read();                                            //  Legge i Byte su Client
   comando[1] = c;
   c = client.read();                                            //  Legge i Byte su Client
   comando[2] = c;
 }
 if ( comando[0] == 'O' && comando[1] == 'N' && comando[3] == ' ' )
   digitalWrite( LED, HIGH );
 if ( comando[0] == 'O' && comando[1] == 'F' && comando[3] == 'F' )
   digitalWrite( LED, LOW );
}


scusa ma non mi funziona così  dove sbaglio

sul lato client ho scritto

client.print("ON ");

e

client.print("OFF");

dovrei stampare un carattere alla volta nel lato client?

lestofante

Code: [Select]
comando[0] == 'O' && comando[1] == 'N' && comando[3]
gli array partono a contare da 0, quindi un array da 3 elementi ha indici 0, 1 e 2...

edit: lo stesso vale per OFF
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

lollo1100

si giusto ma non credo cambi granchè ...è stato un errore di distrazione cmq grazie Lesto

Go Up