Invio Byte per configurare OUTPUT sul server

Buongiorno a tutti dovrei scambiare dei comandi tra un Arduino Uno Client e un Arduino Uno Server. Il problema che mi si presenta è il seguente.
Con il metodo client.priny(""); dovrei inviare al mio Server una maschera…la maschera significa una sequenza di 1 e 0 dove il byte 1 significa che quel pulsante (su Arduino Client) comanda quel relay su Arduino server…spero di essermi spiegato…solo quel relay in modo tale di determinare dalla maschera quali relay sul Server vengono pilotati da quel pulsante sul Client. Grazie a tutti coloro che mi vogliano aiutare…p.s. Io immaginavo un ciclo for in cui faccio 8 client.print() sul lato client.

A parte che puoi raggruppare 8 "uni" e "zeri" in un unico byte visto che 1 byte contiene 8 bit che possono assumere il valore appunto di "1" o "0", non capisco il problema. Cos'è che non riesci a fare?

Si tratta di fare appunto un'operazione di scrittura sulla seriale e di lettura lato client.

vorrei mandarglieli in esadecimale ovvero nel lato server fare client.read() due byte da 00 a FF e far si che i miei pin digitali siano attivi o meno come output...tipo avevo pensato di dare un peso ai LED come potenza del 2...e ragionare con degli if ma le combinazioni sarebbero infinite

Le notazioni sono utili sono a noi umani :wink:
Spedire on byte con valore 0xFF, 255, 0b11111111 è la stessa identica cosa per il compilatore.

Se spedisci 1 byte per controllare 8 porte, puoi usare i singoli bit come “interruttori”.
Arduino mette a disposizione delle utilissime e semplici funzioni per manipolare i bit:
http://arduino.cc/en/Reference/Bit

scusa ma dopo aver letto la serie di 0 e 1 hai qualche consiglio x gestire pinMode e soprattuto digitalWrite successivi alla lettura ..quindi la configurazione dei pin e la scrittura dei pin :) grazie

posto gli sketch relativi al problema

byte maskA[] = { 
  0, 0, 0, 0, 0, 1, 0, 0 };      

  if ( ts1st == HIGH && stato1 == HIGH );
  else{
    if ( ts1st == LOW && stato1 == HIGH ){   
      //  PULSANTE PUSH FASE ON
      stato1 = LOW;                                           //  IMPOSTA IL NUOVO STATO = LOW
      delay(200);                                             //  RITARDO 200ms
      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(serverA, 23)){
        for ( int j = 0; j < 8 ; j++ ){
        client.print(maskA[j]);
        }
        client.print('1');   
        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(200);                                             //  RITARDO 200ms
      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(serverA, 23)){
        client.print("OFF ");      
        client.stop();
      }
      else{
        Serial.println("Connessione OFF fallita");            //  ALTRIMENTI
        //  STAMPA SU COM3 "Connessione OFF fallita"
        client.stop();                                        //  CHIUDI CONNESSIONE
      }
    }

questo è lato client

lato server ho questo

byte LED [8] = { 2, 3, 4, 5, 6, 7, 8, 9 };
//  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
char maskRead[8];      //  ARRAY DI COMANDO
char cmd;
/* 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()
{
  Ethernet.begin( mac, ip, gateway, subnet );    //  Inizializza Ethernet
  server.begin();
  delay(150);
}
void loop()
{ 
  client = server.available();
  if (client){  //se si è connesso qualcuno
    while ( client.connected() && client.available() < 4 ) {                 //  Client-To-Serve                                                                                               
                                                                             //  aspetta senza far nulla che il client si disconnetta o invii almeno 3 lettere
    }

    if (client.available() < 9) {      //  il client si è disconnesso, ma non ha inviato 3 lettere
      client.stop();                   //  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;
    for (int j = 0 ; j < 8 ; j++ ){
    c = client.read();                                       //  Legge i Byte su Client
    maskRead[j] = c;
    if ( maskRead[j] == '1' ) 
    pinMode (LED[j],OUTPUT);
    c = client.read(); 
    cmd = c;
    if ( cmd == '1' )
    digitalWrite(LED[j], HIGH);
    }
/*    if ( comando[0] == 'O' && comando[1] == 'N' && comando[2] == ' ' && comando[3] == ' ' ) 
      digitalWrite( LED1, HIGH );
    if ( comando[0] == 'O' && comando[1] == 'F' && comando[2] == 'F' && comando[3] == ' ' ) 
      digitalWrite( LED1, LOW );
          if ( comando[0] == 'O' && comando[1] == 'N' && comando[2] == '1' && comando[3] == ' ' ) 
      digitalWrite( LED2, HIGH );
    if ( comando[0] == 'O' && comando[1] == 'F' && comando[2] == 'F' && comando[3] == '2' ) 
      digitalWrite( LED2, LOW );
    if ( comando[0] == 'C' && comando[1] == 'L' && comando[2] == 'S' ){ 
      client.println();
      client.print("Ciao vai a prendere un po' di Sole");
      client.stop();*/
  }
}

lollo1100:
scusa ma dopo aver letto la serie di 0 e 1 hai qualche consiglio x gestire pinMode e soprattuto digitalWrite successivi alla lettura …quindi la configurazione dei pin e la scrittura dei pin :slight_smile: grazie

Te lo avevo già suggerito :wink:

leo72:
Se spedisci 1 byte per controllare 8 porte, puoi usare i singoli bit come “interruttori”.
Arduino mette a disposizione delle utilissime e semplici funzioni per manipolare i bit:
http://arduino.cc/en/Reference/Bit

Con 1 byte spedisci 8 bit, quindi lo stato dei tuoi pin 2…9.
A quel punto basta un semplice for per impostare lo stato:

byte comando = Serial.read();
for (byte tempI = 0; tempI < 8; tempI++) {
  digitalWrite(2 + tempI, bitRead(comando, tempI));
}

perchè comando è Serial.read(); non dovrebbe essere client.read(); i miei 2 Arduino comunicano attraverso l'Ethernet Shield...cmq non capisco il codice non è che mi puoi dare qualche delucidazione xfavore ? ...leggo intanto i comandi della classe bit almeno provo a capire. Grazie Stavo rivedendo quello che mi hai scritto solo che in pratica io ho delle maschere fatte così byte maskA[] = {1,0,0,1,0,1,0,1}; ad esempio quindi dovrei per forza inviare gli otto byte che compongono l'array maskA no ? mi sbaglio ? a meno che non modifico il codice sul lato client. Grazie ancora

lollo1100:
perchè comando è Serial.read(); non dovrebbe essere client.read(); i miei 2 Arduino comunicano attraverso l’Ethernet Shield…

Ok. La logica è comunque la stessa, inviare cioè un byte.

cmq non capisco il codice non è che mi puoi dare qualche delucidazione xfavore ? …leggo intanto i comandi della classe bit almeno provo a capire. Grazie
Stavo rivedendo quello che mi hai scritto solo che in pratica io ho delle maschere fatte così byte maskA = {1,0,0,1,0,1,0,1}; ad esempio quindi dovrei per forza inviare gli otto byte che compongono l’array maskA no ? mi sbaglio ? a meno che non modifico il codice sul lato client. Grazie ancora

Scusami, vedo che la gestione dei bit, vedo che non ti è chiara.
Ma che livello hai di conoscenze informatiche? I bit sono la base base dell’informatica :sweat_smile:
Prosegui

Si so cosa è un bit…tranquillo sono un ingegnere Elettronico…io intendo in questo caso specifico ti chiedevo lumi…
poi volevo chiederti una cosa…c’è un metodo di qualche classe che dato un byte maskA = { 0, 1, 0, 1, 1, 1, 0, 0 } mi restituisca il valore esadecimale corrispondente ovvero in questo caso 0x5C grazie …se esiste un metodo come si chiama io adesso faccio una cosa un pò strana guarda :

byte maskA[] = { 
  0, 0, 0, 0, 0, 1, 0, 0 };    

int maskAA1 = 0;
int maskAA2 = 0;

    for (int i = 0; i < 4; i++){ 
    if ( maskA[i] == 1 )
      maskAA1 += pow( 2, i );
  }
  for (int i = 0; i < 4; i++){ 
    if ( maskA[i] == 1 )
      maskAA2 += pow( 2, i );
  }
  switch (maskAA1){
  case 10 : 
    maskAA1 = 'A'; 
    break;
  case 11 : 
    maskAA1 = 'B'; 
    break;
  case 12 : 
    maskAA1 = 'C'; 
    break;
  case 13 : 
    maskAA1 = 'D'; 
    break;
  case 14 : 
    maskAA1 = 'E'; 
    break;
  case 15 : 
    maskAA1 = 'F'; 
    break;
  }
  switch (maskAA2){
  case 10 : 
    maskAA2 = 'A'; 
    break;
  case 11 : 
    maskAA2 = 'B'; 
    break;
  case 12 : 
    maskAA2 = 'C'; 
    break;
  case 13 : 
    maskAA2 = 'D'; 
    break;
  case 14 : 
    maskAA2 = 'E'; 
    break;
  case 15 : 
    maskAA2 = 'F'; 
    break;
  }

Non che io sappia.

Però continuo a ribadire che non capisco il motivo per cui vuoi perseverare questa strada. Vediamo se ho capito: vuoi comporre da 8 byte con valore 0/1 2 byte che siano in notazione esadecimale.

Ti chiedo: ma c'è un motivo? Perché complicarsi così tanto la vita? Non riesco a capire questa cosa. Stai facendo comunicare 2 Arduino, giusto? Quindi il protocollo te lo stabilisci tu. Oppure gli Arduino sono il mezzo di trasmissione di un'informazione che ti arriva in quel formato?

Scusami se rompo ma io tendo solitamente a semplificarmi la vita, non a complicarmela :sweat_smile:

anche io solo che volevo mandare 2 BYTE da 0 a F x ogni Byte... in modo di non mandare gli 8 Byte che compongono quel comando ...tu cosa mi consigli di fare io all'inizo avevo mandato tutta la maskA 8 byte di 0 o 1 e li facevo leggere nel lato server...se oltre alla mask ricevevo un 1 accendevo il led se ricevevo 0 spegnevo il led...però mo tocca farlo in esadecimale fare la conversione lato client e riconvertire nel lato server...tu cosa mi consigli è + veloce la comunicazione mandando solo 2 Byte??? Grazie Leo

No, è più veloce la comunicazione mandando 1 solo byte... te lo sto dicendo fin dall'inizio ;)

Assegni il bit 0 al pin 2, il bit 1 al pin 3.... il bit 7 al pin 9. Se ora viene premuto il pulsante sul pin 2, tu assegni il valore 1 al pin 0 del tuo byte:

bitSet(comando, 0);

Adesso il tuo byte comando ha il seguente valore: 0b00000001 Se viene premuto il pulsante sul pin 5, assegni il valore 1 al pin 3 del tuo byte:

bitSet(comando, 3);

Adesso il tuo byte comando vale: 0b00001001

Lo spedisci e dall'altra parte imposti i pin con il codice che ti ho già scritto. Non è più facile così?

cioè...è quello che faccio io ...io sul lato server ho una maschera sono 8 bit che sono 1 o 0 io gli mando quella poi faccio corrispondenza biunivoca tra i led 2 a 9 e i bit facendo un nuovo byte di led in cui lo 0 sarebbe il led 2 e il 7 il led 9 ...come dovrei scrivere mandando un solo byte sul lato server scusa?...

Dovrebbe fare un client.write e mandare un carattere ascii per fare quello che dici tu Leo. Il client.print converte tutto in caratteri, quindi spedire 255 per avere dall'altra parte un 11111111 spedisce comunque 3 byte + \n.

io ad esempio spedisco al client

      client.print((String)PINA + "," + (String)PINB + ",");
      client.print((String)PINC + "," + (String)PIND + ",");
      client.print((String)PINE + "," + (String)PING + ",");
      client.print((String)PINH + "," + (String)PINJ + ",");
      client.print((String)PINL + "," + (String)PINF + ",");
      client.print((String)PINK);

per avere lo stato di 70 pin spedisco da minimo 21 a massimo 40 byte dipende dai valori

se volessi usare solo 11 byte dovrei spedire 11 char con client.write e poi fare le conversioni varie (char to byte to bit) ma diventa un delirio.

Spiegati meglio Leo come useresti un client.print o un serial.print

ciao

pablos questa differenza tra client.print e client.write...l'ho colta il mio problema è il seguente ho un maschera 8 byte ...quindi sono 8 0/1...questi dovrebbero essere convertiti in esadecimale quindi da 0 ad F e inviati al server. Quest'ultimo deve leggere o 0 o F e riconvertirlo in binario x capire quali di 8 led come dice Leo i pin da 2 a 9 sono effettivamente output il byte corrispondete è 1, se è 0 il corrispondente pin non è attivo. a quel punto dovrei contemporaneamente a quanto detto inviare ulteriori 2 byte da 00 a FF x determinare il comportamento del LED in questione se è attivo (in base alla maschera precedente). Per la convezione da binario a HEX mi sono avvalso di una conversione binario - decimale a quel punto se il valore è 10 con un case switch attribuivo il carattere A ... se era 11 il B ecct in ricezione (lato server) dovrò fare la cosa opposta ovvero da 0 o F (Ah ovviamente) x fare la conversione ho spedito due mini array da 4 byte l'una quindi un singolo carattere esadecimale alla volta...tornando al discorso server dovrei a partire dal carattere esadecimale ricevuto riempire due mini array da 4 x impostare lo stato dei pin da 2 a 9 ...e poi leggere ulteriori 2 byte x il comportamento dei pin. Grazie a tutti coloro che mi vogliano aiutare

Scusa ma non riesco a capire. Aiutami per favore...

lollo1100: pablos questa differenza tra client.print e client.write...l'ho colta il mio problema è il seguente ho un maschera 8 byte ...quindi sono 8 0/1...

Hai 1 byte, mi pare di capire.

questi dovrebbero essere convertiti in esadecimale quindi da 0 ad F e inviati al server.

Perché devi convertirli in esadecimale?

Quest'ultimo deve leggere o 0 o F e riconvertirlo in binario x capire quali di 8 led

Perciò se devi riportarli a binario, non puoi spedire direttamente il byte originario?

dice x essere più elastico se volessi controllare il server da un hyper terminal hai qualche suggerimento ? a riguardo

Hai 1 byte, mi pare di capire.

si ho 1 byte la maschera è 1 byte

scusa se volessi convertire da binario a decimale

int maskA1;

byte maskA[] = { 
  0, 0, 0, 0, 0, 1, 0, 0 };                       //  MASK A DEFAULT

  for(int i = 0; i < 8 ; i++){
      if ( maskA[i] == 1 )
      maskA1 += pow( 2, i );
  }

lollo1100: dice x essere più elastico se volessi controllare il server da un hyper terminal hai qualche suggerimento ? a riguardo

Ecco, ora la cosa mi può anche tornare. Fino ad ora infatti era una conversione senza senso :sweat_smile: