Go Down

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

lesto

#15
Feb 18, 2013, 05:30 pm Last Edit: Feb 18, 2013, 05:32 pm by lesto Reason: 1
in che senso non credi che cambi ganchè? con comando[3] stai andando a leggere una zona di memoria al di fuori del tuo array (array overflow, se il sistema operativo, che arduino non ha, rileva una baggianata del genere ti uccide il programma con un errore di Segmentation Fault, uno degli errori più difficili da correggere individuare e più sensibili lato sicurezza!) , per quel che ne sai lì dentro potrebbe esserci la prima lettera della dichiarazione di indipendenza in giapponese  :D
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lollo1100

Arduino Lato Client

Code: [Select]


#include <SPI.h>

#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp.h>
#include <util.h>
#include <WebServer.h>

#define BUTTONON  7                 //  PIN7 INPUT = BUTTON 
#define BUTTONOFF 6                 //  PIN7 INPUT = BUTTON 

int ts1st  = HIGH;                  //  ts1st LEGGE E MEMORIZZA IL LIVELLO DI BUTTON 
int stato1 = HIGH;                  //  stato1 MANTIENE LO STATO DI BUTTON
int ts2st  = HIGH;                  //  ts2st LEGGE E MEMORIZZA IL LIVELLO DI BUTTON 
int stato2 = HIGH;                  //  stato2 MANTIENE LO STATO DI BUTTON
int i = 0;                          //  i CONTA LE VOLTE DI BUTTON ON PUSH
int j = 0;                          //  j CONTA LE VOLTE DI BUTTON OFF PUSH

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x47 };          //  MAC ETHERNET SHIELD
byte ip[] = { 10, 10, 11, 16 };                               //  IP CLIENT
byte server[] = { 10, 10, 11, 45 };                           //  IP SERVER
byte gateway[] = { 10, 10, 11, 1 };                           //  INDIRIZZO ROUTER GATEWAY
byte subnet[] = { 255, 255, 255, 0 };                         //  SUBNET

EthernetClient client;

void setup() { 

  Ethernet.begin(mac, ip, gateway, subnet);                 //  INIZIALIZZA ETHERNET
  Serial.begin(9600);                                       //  INIZIALIZZA LA SERIALE
  pinMode(BUTTONON, INPUT);                                 //  IMPOSTA IL BUTTONON COME INPUT
  pinMode(BUTTONOFF, INPUT);                                //  IMPOSTA IL BUTTONOFF COME INPUT
  delay(150);                                               //  RITARDO DI 150ms



void loop() { 

  ts1st = digitalRead(BUTTONON);                            //  LEGGE E MEMORIZZA IL VALORE DI BUTTONON
  ts2st = digitalRead(BUTTONOFF);                           //  LEGGE E MEMORIZZA IL VALORE DI BUTTONOFF

    if ( ts1st == HIGH && stato1 == HIGH );
  else{
    if ( ts1st == LOW && stato1 == HIGH ){                    //  PULSANTE PUSH FASE ON
      stato1 = LOW;                                           //  IMPOSTA IL NUOVO STATO = LOW
      delay(150);                                             //  RITARDO 150ms
      i++;                                                    //  INCREMENTA CONTEGGIO PUSH
      Serial.print(" IL BOTTONE ON E' STATO PREMUTO ");       //  STAMPA IL NUMERO DI PUSH EFFETTUATI
      Serial.print(i);
      Serial.print(" VOLTE");
      Serial.println();
      if (client.connect(server, 23)){
        client.print("ON ");     
        client.stop();
      }
      else{
        Serial.println("Connessione ON fallita");  //  Altrimenti
        //  Stampa su COM3 Connessione ON fallita
        client.stop();                 //  Chiudi connessione
      }
    }
    if ( ts1st == HIGH && stato1 == LOW )                   //  POSIZIONE DI RIPOSO FASE OFF
      stato1 = HIGH;                                        //  AGGIORNA IL NUOVO STATO DI BUTTONON = HIGH
  }

  if ( ts2st == HIGH && stato2 == HIGH );
  else{
    if ( ts2st == LOW && stato2 == HIGH ){                    //  PULSANTE PUSH FASE ON
      stato2 = LOW;                                           //  IMPOSTA IL NUOVO STATO = LOW
      delay(150);                                             //  RITARDO 150ms
      j++;                                                    //  INCREMENTA CONTEGGIO PUSH
      Serial.print(" IL BOTTONE OFF E' STATO PREMUTO ");      //  STAMPA IL NUMERO DI PUSH EFFETTUATI
      Serial.print(j);
      Serial.print(" VOLTE");
      Serial.println();
      if (client.connect(server, 23)){
        client.print("OFF");     
        client.stop();
      }
      else{
        Serial.println("Connessione OFF fallita");    //  Altrimenti
                                                     //  Stampa su COM3 Connessione ON fallita
        client.stop();                               //  Chiudi connessione
      }
    }
    if ( ts2st == HIGH && stato2 == LOW )                     //  POSIZIONE DI RIPOSO FASE OFF
      stato2 = HIGH;                                          //  AGGIORNA IL NUOVO STATO DI BUTTON = HIGH     
  }
}



Arduino Lato Server

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[2] == ' ' )
    digitalWrite( LED, HIGH );
  if ( comando[0] == 'O' && comando[1] == 'F' && comando[2] == 'F' )
    digitalWrite( LED, LOW );
}



Si Lesto non volevo dire che avevo fatto una cosa azzeccata anzi una sciocchezza enorme ho fatto, ma continua a non accendermi il LED messo sul PIN 7 del mio arduino Server
Grazie

lesto

collegati via telent al server, e invia i comandi tu stesso (non serve premere invio, telnet invia i caratteri mentre li digiti, quindi se sbagli a digitare in realtà il tasto cancella non funziona, anche se SEMBRA farlo)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lollo1100

Lesto capisco cosa intendi, però questo problema che mi è stato assegnato è di fare una rete  in cui ci sono N Client ( N Arduino Uno ) e N server (altri N Arduino Uno ) ognuno ha un ip in pratica gli N client hanno connesse delle pulsantiere touch e vanno a comandare in maniera confusionaria (IP) gli altri server che hanno invece collegati dei Relay quindi i comandi glieli devo passare in questo modo altrimenti risulta complicato . Dovrebbe in soldoni premi un bottone sul lato client accendi una luce o lo scaldabagno di uno dei tanti server.

lesto

si ma per fare i test devi andare per gradi, prima fai funzionare il server con telnet, poi lo fai funzionare con il client.
Altrimenti impazzisci a cercare nel server un errore del client.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lollo1100

Lesto ho fatto come dici tu sono andato su Telnet all'indirizzo IP specificato x il server se faccio 1 e 0 se li digito il led si accende e si spegne se digito "ON " oppure "OFF" con il codice di ON e OFF del server non va guarda il codice sarebbe questo

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[2] == ' ' )
    digitalWrite( LED, HIGH );
  if ( comando[0] == 'O' && comando[1] == 'F' && comando[2] == 'F' )
    digitalWrite( LED, LOW );
}



Sicuramente è xchè client.read legge un carattere alla volta :) però come faccio a fargli leggere i 3 caratteri??? Grazie sempre con telnet dal lato server

lesto

il fatto di leggere 3 caratteri lo stai già facendo, e si fa esattamente così, si legge un carattere alla volta e si riscostruisce.

Quote
se faccio 1 e 0 se li digito il led si accende e si spegne se digito "ON " oppure "OFF" con il codice di ON e OFF del server non va


se non hai ricaricato il codice sul server con le modifiche che abbiamo fatto fin'ora per legger 3 lettere ci credo che non funziona. Se avessi caricato il codice 1 e 0 non dovrebbero più funzionare.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lollo1100

Lesto come dicevo prima

ho caricato questo sketch su un arduino uno

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[2] == ' ' )
    digitalWrite( LED, HIGH );
  if ( comando[0] == 'O' && comando[1] == 'F' && comando[2] == 'F' )
    digitalWrite( LED, LOW );
}



poi sono andato su putty ho aperto la pagina telnet dell ip 10.10.11.17 ok ? e se faccio 1 e 0 ok il led si accende e si spegne se scrivo ON   oppure OFF non succede nulla :) dove sbaglio?

lesto

sbagli che NON hai caricato il codice sull'arduino, altrimenti 1 e 0 NON funzionerebbero.
Poi magari on funzionerebbero nemmeno "ON" e "OFF" (ma dubito), ma sicuramente 0 e 1 non devono funizonare..

cioè mi spieghi se hai veramente caricato quel codice come mai si accende quando scrivi 0 e 1? arduino non se lo inventa certo dal nulla :)

l'unica spiegazione è che sia rimasto sopra il vecchio codice.

Suggerimento: quando carichi il codice togli l'ethernet shield, se il problema persiste fai il reset a mano
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lollo1100

se carico questo codice su arduino

Code: [Select]


#include <SPI.h>                                              //  IMPORTA LIBRERIA SPI
#include <Ethernet.h>                                         //  IMPORTA LIBRERIA ETHERNET

#define LED 7                                                 //  PORTA DIGITALE 7 LED

//  PARAMETRI ETHERNET

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };          //  MAC ETHERNET SHIELD DEL SERVER
byte ip[] = { 10, 10, 11, 17 };                               //  IP ARDUINO SERVER
byte gateway[] = { 10, 10, 11, 1 };
byte subnet[] = { 255, 255, 255, 0 };                             

//  ALTRE VARIABILI

#define dimCmd 8      //  LUNGHEZZA DEL PIù LUNGO COMANDO
int cmd[dimCmd];      //  ARRAY DI COMANDO
int bitRicevuti = 0;  //  NUMERO DI BIT RICEVUTI

boolean connectState = false;                  //  USATA PER VERIFICARE CONNESSIONE CLIENT TO SERVER

unsigned long tempoDaUltimaAzione;             //  TEMPO IN ms DALL'ULTIMA ATTIVITà
unsigned long tempoMassimoPermesso = 300000;   //  5 MINUTI

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();
  delay(150);
}
void loop()
{
  if (server.available() && client.connected()) {  //  BYTE SUL SERVER & CONNECTED

    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 BYE = 0 LED OFF
        digitalWrite( LED, LOW );
  }
}


vado su tera term e digito 1 poi 0 il led si accende e si spegne

se carico l'altro quello del messaggio precedente con ON E OFF e provo da tera term a digitare ON O OFF IL LED  non si accende...vorrei capire perchè

lesto

a me sembra stano che entrambi i codici funzionino, visto che non inizializzi mai la variabile client... ti manca un pezzo!
Fai più attenzione al codice che posti e alla descrizione degli errori...

il pezzo che manca:
Code: [Select]
client = server.available();
il pezzo errato
Code: [Select]
while  (server.available() >3 && client.connected()) {
diventa
Code: [Select]
while (client.available() < 3 && client.connected()) {

infatti server.available() ritorna l'istanza ad un EthernetClient connesso, una volta che abbiamo il client vogliamo sapere il numero di caratteri che ci ha spedito che s ottiene con client.available()

quindi diventa:

Code: [Select]
void loop()
{
  client = server.available();
  if (client){  //se si è connesso qualcuno
    while ( client.connected() && client.available() < 3 ) {                 //  Client-To-Serve                                                                                               
       //aspetta senza far nulla che il client si disconnetta o invii almeno 3 lettere
    }

    if (client.available() < 3) { //il client si è disconnesso, ma non ha inviato 3 lettere
      client.close(); //chiudiamo comunque la comunicazione in modo pulito, e rilasciamo eventuali risorse della classe
      return; //non vogliamo fare altro, ternima questo loop() immediatamente (e quindi passiamo al prossimo loop da capo)
    }
    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[2] == ' ' )
      digitalWrite( LED, HIGH );
    if ( comando[0] == 'O' && comando[1] == 'F' && comando[2] == 'F' )
      digitalWrite( LED, LOW );
}
}
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lollo1100

Grande Lesto mo funziona alla grande cerco pure di capire come hai fatto ;) ...ma tipo io un client posso connetterlo ad N server facendo semplicemente client.connect(server,23); dove ovviamente server è l'IP del server a cui voglio connetterlo giusto ? :D penso che sto ragionamento non faccia una piega ma per inviare un numero ? basta fare client.print(010101, BIN); x dirgli che è binario ? ...grazie mille ancora !

lesto

dipende. Un'oggetto client può essere connesso ad un solo server per volta (se non come fai a dirgli da chi leggere/scrivere?). Ma nulla vieta di avere uno più (magari un array) di oggetti client, ognuno connesso al suo server, e magari anche più di uno connesso allo stesso server.

Mi pare che però l'ethernet shield al massimo gestica 5 connessioni simultanee... Quindi esitono dei limiti, che sono aggirabili in certe condizioni
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lollo1100

credo siano 4 le connessioni contemporanee... una cosa sullo sketch di prima a me client.close() non me lo prendeva io c'ho messo client.stop() diceva che close non era specificato nella libreria ethernet o cmq che non era un comando da applicare a client perchè? cmq con client.stop al posto di client.close va alla grande

lesto

perchè mi son sbagliato io, close non esite, ma vedo che hai risolto il bug da solo  :smiley-mr-green:
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up