Go Down

Topic: Invio Byte per configurare OUTPUT sul server (Read 10103 times) previous topic - next topic

lollo1100

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.

leo72

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.

lollo1100

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

leo72

Le notazioni sono utili sono a noi umani  ;)
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


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 :) grazie

lollo1100

posto gli sketch relativi al problema

Code: [Select]


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

Code: [Select]

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();*/
  }
}


leo72


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


Te lo avevo già suggerito  ;)


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:
Code: [Select]
byte comando = Serial.read();
for (byte tempI = 0; tempI < 8; tempI++) {
 digitalWrite(2 + tempI, bitRead(comando, tempI));
}

lollo1100

#7
Feb 25, 2013, 04:52 pm Last Edit: Feb 25, 2013, 04:55 pm by lollo1100 Reason: 1
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

leo72


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.

Quote

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  :smiley-sweat:
Prosegui

lollo1100

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 :


Code: [Select]


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;
  }

leo72

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  :smiley-sweat:

lollo1100

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

leo72

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:
Code: [Select]
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:
Code: [Select]
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ì?

lollo1100

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?...

pablos71

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
Code: [Select]

     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



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

Go Up