Offline
Full Member
Karma: 0
Posts: 129
|
 |
« on: February 14, 2013, 10:12:27 am » |
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 #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
#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!
|
|
|
|
« Last Edit: February 15, 2013, 07:01:15 am by lollo1100 »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 49
Arduino rocks
|
 |
« Reply #1 on: February 14, 2013, 11:02:00 am » |
ciao! ma riesci a caricare il programma senza che ti dia errori???
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 129
|
 |
« Reply #2 on: February 15, 2013, 04:44:32 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Genova
Offline
Edison Member
Karma: 13
Posts: 2432
|
 |
« Reply #3 on: February 15, 2013, 05:26:39 am » |
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. 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
|
|
|
|
« Last Edit: February 15, 2013, 05:34:18 am by pablos »
|
Logged
|
Meglio imparare dalle cose inutili piuttosto che non imparare niente. [Arduino Mega R3 + Ethernet shield W5100 + SD card 8Gb FAT32]
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 129
|
 |
« Reply #4 on: February 15, 2013, 06:59:32 am » |
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)  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.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Edison Member
Karma: 15
Posts: 1876
Have you mooed today?
|
 |
« Reply #5 on: February 15, 2013, 08:01:22 am » |
Ciao 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
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 129
|
 |
« Reply #6 on: February 15, 2013, 08:59:51 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 81
Posts: 8184
:(){:|:&};:
|
 |
« Reply #7 on: February 15, 2013, 09:07:31 am » |
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à!
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 129
|
 |
« Reply #8 on: February 15, 2013, 09:19:22 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 81
Posts: 8184
:(){:|:&};:
|
 |
« Reply #9 on: February 15, 2013, 09:27:25 am » |
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'
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 129
|
 |
« Reply #10 on: February 15, 2013, 09:42:44 am » |
Si infatti anche a me suonava male ti posto i codici ... Lato Client #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 #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 ?
|
|
|
|
« Last Edit: February 15, 2013, 09:44:29 am by lollo1100 »
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 81
Posts: 8184
:(){:|:&};:
|
 |
« Reply #11 on: February 15, 2013, 11:36:15 am » |
uil tuo codice: 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. 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; 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)
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 129
|
 |
« Reply #12 on: February 18, 2013, 09:51:13 am » |
#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?
|
|
|
|
« Last Edit: February 18, 2013, 10:18:07 am by lollo1100 »
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 81
Posts: 8184
:(){:|:&};:
|
 |
« Reply #13 on: February 18, 2013, 10:42:30 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 129
|
 |
« Reply #14 on: February 18, 2013, 11:27:43 am » |
si giusto ma non credo cambi granchè ...è stato un errore di distrazione cmq grazie Lesto
|
|
|
|
|
Logged
|
|
|
|
|
|