Pages: 1 2 [3]   Go Down
Author Topic: Invio Comandi tra Client e Server  (Read 2249 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

finchè è così semplice ci arrivo anche io  smiley-roll-blue Grazie ancora...ma per scambiare questi comandi tra client e server mi basta studiare i comandi della libreria Ethernet sia lato server che lato client giusto x intenderci qui http://arduino.cc/en/Reference/Ethernet giusto?
Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

l'importante è che non ti fai problemi a chiedere cose che non capisci.

Per esempio del mio codice è tutto chiaro?

ricordati del reference: http://arduino.cc/en/Reference/HomePage
e del reference delle librerie ufficiali: http://arduino.cc/en/Reference/Libraries
tra cui la Ethernet: http://arduino.cc/en/Reference/Ethernet

ti salveranno ore di lavoro
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 0
Posts: 175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

scusa Lesto sto cercando di capire adesso in maniera intuitiva sono andato a provarlo e ho notato che in pratica da telnet per potergli far cambiare o stato al led prima di passargli ON  o OFF devo andare a capo poi ho visto che tipo ha un comportamento anomalo sulla chiusura del telnet...forse devo capirlo meglio ...anche se le cose che mi hai scritto vicino alle istruzioni un pò mi aiutano ... semmai Grazie di ogni chiarimento...intanto continuo a capire la logica dello sketch ho scritto una stupidaggine cmq devo capire bene come legge i comandi il protocollo telnet ho visto che non è necessario andare a capo però certe volte li prende certe volte no poi delle volte pare che si blocca e se non scrivo i comandi alternati non riprende ovvero se faccio OFF OFF OFF OFF e non mi funziona magari l'OFF devo prima ridigitare ON  ..e poi OFF lo prende mi devo vedere il protocollo telnet è evidente  smiley-red ho notato un'altra stranezza nel senso se magari lascio aperta la connessione telnet con tera term stranamente funziona anche il collegamento client-to-server tra arduino invece non dovrebbe funzionare come mai???
« Last Edit: February 19, 2013, 09:40:46 am by lollo1100 » Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ah, semplice, errore mio.
Quando legge un comando, ricomincia il loop() e l'oggetto client attuale viene perso sovrascritto dalla Server.available(), però dato che il client non viene chiuso correttamente, la ethernet shield lo tiene collegato.

Quindi:
1. essendo l'oggetto client perso dopo la lettura, il client rimane connesso ma da codice non è più raggiungibile
2. telent invia il carattere appena lo digiti, però in realtà finisce in un buffer e alle volte ci vuole un pò prima che il buffer sia inviato: ifatti il protocollo TCP usa circa 128 byte di intestazione per inviare un messaggio, la cui dimensione massima compreso l'header (MTU) è di circa 1400byte, a seconda della rete.. capisci che sprecare 128byte di header per iviare una lettera è (preziosa) banda sprecata, quidi il SO alle volte aspetta qualche istante per vedere se scrivi altro, se sì alora manda un mesaggio unico. l'attesa è nell'ordine di meno di un secondo comunque.
3. l'invio non serve, anzi. noi leggiamo di 3 caratteri in 3 caratteri, quindi un unvio sfalserebbe il valore of OFF in (invio = X) XOF, il successivo comando letto sarebbe FOF e così via... ricordati che telnet non può cancellare, quindi se premi invio + una lettera sbagliata + cancelli hai in realtà scritto 3 lettere, e quindi lo sfaso si annulla e puoi di nuovo funzionare.

per risolvere ci sono varie strade:
1. disconnetti il client dopo aver letto il suo messaggio. Brutto, perchè la connessione TCP impiega un sacco di banda e risorse (vedi 3 way handshacke) quindi meglio tenere il client collegato fichè si può. Però così è facile fare più client
2. non chiamare client = server.available(); se un client è già connesso
3. sistemare il codice per funzionare con un array di client e accettare quindi fino a 3 client alla volta (sistema 1 + 2)
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 0
Posts: 175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

si quel discorso dell'andare a capo ...era il fatto che mi sbagliavo a scrivere e a quel punto l'unica soluzione dato che cancellare non serve a nulla è andare a capo se non sbaglio...quindi eventualmente x fare una connessione telnet alla volta come dovrei agire??? dovrei cambiare lo sketch del server? non ho ben capito..ho visto che infatti il problema è in client = server.available(); e if (client) ...però come lo risolvo per farlo riconnettere solo con 1 connessione un ultima cosa...io ho scaricato Simulator for Arduino x fare le simulazioni sai consigliarmi un software ?? x fare queste cose vorrei testare un collegamento con + arduino caricarci gli sketch che scrivo e simularli...magari sarebbe il massimo se il simulatore fosse gratuito ...grazie 1000
Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

devi agire che non fai server.available fichè c'è un client connesso... non è difficile, provaci smiley

non ho mai usato simulatori, come puoi vedere con un poco di fantasia si può fare tutto a mano
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 0
Posts: 175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ora dovrei fare un'altra cosa ma ho un piccolo problema...dovrei far si che il mio arduino uno che lavora da client si comporti da server con la porta telnet e venga configurato magari questo arduino si connette con diversi IP ogni pulsante connesso ad arduino client va a comandare dei server con IP differenti sulla rete...dovrei vedere su tera term o putty la configurazione degli ip delle subnet e delle maschere...per maschere si intenderebbe "10101000" dove gli 1 indica su quali relay di quel server il mio client va ad agire riesco a visualizzare tutto ok...solo che non vedo la mask in configurazione binaria posto di seguito lo sketch

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

#define BUTTONON  7                                           //  PIN7 INPUT = BUTTON  
#define BUTTONOFF 6                                           //  PIN7 INPUT = BUTTON  
#define dimBuff 36 //length of longest command string plus two spaces for CR + LF
char textBuff[dimBuff]; //someplace to put received text
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
boolean conf = false;
unsigned long timeOfLastActivity;
int charsReceived = 0;

byte serverA[] = { 10, 10, 11, 17 };
byte serverB[] = { 10, 10, 11, 4 };
byte serverC[] = { 10, 10, 11, 5 };
byte serverD[] = { 10, 10, 11, 7 };
int mask = 4; //se gli passo 4 mi si vede 100 invece io vorrei vedere 00000100 se gli passo 00000100 mi si vede 10000000 p.s. l'ho passato anche come byte mask = 00000100; forse devo mettere [] ?
int Aserver1 = 10;
int Aserver2 = 10;
int Aserver3 = 11;
int Aserver4 = 17;
int subnet1 = 255;
int subnet2 = 255;
int subnet3 = 255;
int subnet4 = 0;
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x47 };           //  MAC ETHERNET SHIELD
byte ip[] = {
  10, 10, 11, 45 };                               //  IP CLIENT
byte server1[] = {
  10, 10, 11, 17 };                               //  IP SERVER1
byte server2[] = {
  10, 10, 11, 18 };                               //  IP SERVER2
byte gateway[] = {
  10, 10, 11, 1 };                                //  INDIRIZZO ROUTER GATEWAY
byte subnet[] = {
  255, 255, 255, 0 };                             //  SUBNET

EthernetClient client;
EthernetServer server = EthernetServer(23);    //  Telnet porta 23

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

}  

void loop() {  
  if (server.available() && !conf ){
    conf = true;
    client = server.available();
    client.println("\nConfigurazione Arduino Client");
    client.println("\nPremere SHOW CNF per ottenere le CONFIGURAZIONI IP & MASK ");
    printPrompt();
  }
  
  if (client.connected() && client.available()) getReceivedText();
  
  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(server1, 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(server1, 23)){
        client.print("OFF");      
        client.stop();
      }
      else{
        Serial.println("Connessione OFF fallita");            //  ALTRIMENTI
        //  STAMPA SU COM3 "Connessione OFF fallita"
        client.stop();                                        //  CHIUDI CONNESSIONE
      }
    }
    if ( ts2st == HIGH && stato2 == LOW )                     //  POSIZIONE DI RIPOSO FASE OFF
      stato2 = HIGH;                                          //  AGGIORNA IL NUOVO STATO DI BUTTONOFF = HIGH    
  }
}
void printPrompt()
{
  timeOfLastActivity = millis();
  client.flush();
  charsReceived = 0; //count of characters received
  client.print("\n>");
}

void getReceivedText()
{
char c;
int charsWaiting;
 
// copy waiting characters into textBuff
//until textBuff full, CR received, or no more characters
charsWaiting = client.available();
do {
c = client.read();
textBuff[charsReceived] = c;
charsReceived++;
charsWaiting--;
}
while(charsReceived <= dimBuff && c != 0x0d && charsWaiting > 0);
 
//if CR found go look at received text and execute command
if(c == 0x0d) {
parseReceivedText();
// after completing command, print a new prompt
printPrompt();
}
 
// if textBuff full without reaching a CR, print an error message
if(charsReceived >= dimBuff) {
client.println();
printErrorMessage();
printPrompt();
}
// if textBuff not full and no CR, do nothing else;
// go back to loop until more characters are received
 
}
void parseReceivedText()
{
// look at first character and decide what to do
switch (textBuff[0]) {
case 'S' : showConfiguration(); break;
case 0x0d : break; //ignore a carriage return
default: printErrorMessage(); break;
}
}

void printErrorMessage()
{
client.println("\nComando sconosciuto !");
}
void showConfiguration()
{
  
if (textBuff[1] == 'H' && textBuff[2] == 'O' && textBuff[3] == 'W' && textBuff[4] == ' ' && textBuff[5] == 'C' && textBuff[6] == 'N' && textBuff[7] == 'F' ){
  client.println();
  client.print("\nServer A:");
  client.print(" IP : ");
  client.print(Aserver1);
  client.print(".");
  client.print(Aserver2);
  client.print(".");
  client.print(Aserver3);
  client.print(".");
  client.println(Aserver4);
  client.print("          SUBNET : ");
  client.print(subnet1);
  client.print(".");
  client.print(subnet2);
  client.print(".");
  client.print(subnet3);
  client.print(".");
  client.println(subnet4);
  client.print("          MASK : ");
  client.println(mask,BIN);
}
  else
printErrorMessage();
}

si vede sia ip che subnet alla grande ma la mask si vede male.
Grazie
Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

4 in binario è 100, se tu gli passi 00000100  in realtà stai passando 100 che è decimale, e in bianario vale appunto 1100100

per cambiare il numero di zeri da stamapre davanti devi agire sul codice della print()... oppure "smonti" mask bit per bit (vedi bitshift, operatore >>)e ogni bot fai una pritnt di '0' o '1'
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 0
Posts: 175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

quindi l'unico modo x fargli stampare 4 in binario a 8 bit ovvero 00000100 è stampare un bit alla volta? oppure c'è un modo con client.print(4,BIN8); NON esiste lo so ...ma x dirgli stampami 4 in binario su 8 bit ... Grazie Lesto scusa anche un'altra cosa ma se volessi configurare degli IP da Telnet dovrò passarglieli BYTE A BYTE ovvero 192.168.10.1 sarà 192...poi 168....poi 10....poi 1...oppure con client.write(data) riesco a passargli tutto insieme ? 
« Last Edit: February 20, 2013, 09:08:35 am by lollo1100 » Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
oppure c'è un modo con client.print(4,BIN8); NON esiste lo so
non esiste proprio nulla di simile nella classe Serial, cedi http://arduino.cc/en/Serial/Print, devi farti tu una funzione apposta sorry..


l'ip se ci faci caso è formato da 4 byte, separati da un punto per convenienza di rappresentazione (senza 127.0.0.1 sarebbe 127000000001)

problema è che da telnet invii caratteri, e i caratteri corrispondenti al byte 0 e 1 (e la maggiorn parte dei byte in generale) sono caratteri non visibili (invio, suona il ciucalino, tab, e motli altri, vedi tabella ascii), quindi o usi un telnet più serio che ti permette di settare il valore dei singoli byte da inviare, oppure resti bloccato dal fatto di dover riscostruire gli ip letterea per lettera
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 0
Posts: 175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

se volessi quindi inserirlo da telnet l'ip LETTERA X LETTERA magari 10...poi 10 ...poi 11...poi 19 tipo come posso fare? ...magari x visualizzare a monitor dopo averlo immesso l'insieme dei 4 byte dell'IP non so se mi sono spiegato ...devo in fase di configurazione inserire 4 BYTE i 4 BYTE dell'ip e magari voglio pure visualizzarli ...le variabili di appoggio immagino siano int Aserver1 ; int Aserver2; int Aserver3; int Aserver4;
posto di seguito il codice non funzionante

il file è allegato

Scusa una cosa ...come mai se sono on line...mi dice che il mio stato è off line? smiley parlo del forum qui di arduino
 

* BUTTON_AND_CLIENT_PROVA3.ino (10.44 KB - downloaded 4 times.)
« Last Edit: February 20, 2013, 10:29:28 am by lollo1100 » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi sono arenato nel passare degli interi magari un byte che rappresenta i numeri che vanno da 0 a 255 al mio codice ...ovvero vorrei inviare tramite telnet aprendo magari Tera term o putty l'insieme dei 4 byte X.X.X.X dove X è appunto un numero tra 0 e 255...come posso fare?
Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ogni cifra da telnet è un char, devi unire tutti i char fino al . o all'invio, aggoingi all'array di char il carattere '\0'(che vuol dire fine stringa) e poi fai

int numero = atoi(arrayDiChar);
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Full Member
***
Karma: 0
Posts: 175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

allego il codice del mio Arduino Client...io a questo punto vorrei inserire un indirizzo IP da telnet e farglielo memorizzare Byte a Byte su Aserver1 Aserver2 Aserve3 Aserver4 ecct x B x C x D
tipo digito 10.10.11.16 infatti ho aumento la dimBuff = 16
Grazie a Tutti

Ciao Lesto scusa mi puoi dare un riferimento per la funzione atoi(arraydichars) immagino o String invece che array di chars ...però vorrei capire bene come funziona Grazie




* BUTTON_AND_CLIENT_PROVA6.ino (11.93 KB - downloaded 5 times.)
« Last Edit: February 21, 2013, 05:13:03 am by lollo1100 » Logged

Pages: 1 2 [3]   Go Up
Jump to: