Dividere un byte in 4 copie da 2 bit

buongiorno a tutti,
ho una lettura di un sensore tramite I2C e avrei bisogno di dividere un byte letto.
sostanzialmente i primi 2 bit del byte rappresentano un numero da 0 a 3 e così via le altre 3 copie.
sono a conoscenza delle funzioni di bitwise ma non saprei proprio come usarle!
scusate la mia ignoranza...
vi la scio il codice che per ora ho scritto per leggere i dati!

  Wire.beginTransmission(BNNO055_ADDRESS);
  Wire.write(0x35);//invio l'indirizzo del registro che voglio leggere
  Wire.endTransmission(false);//finita la trasmissione libero il bus
  Wire.requestFrom(BNNO055_ADDRESS,1);//mi aspetto di leggere 1 byte
  if (Wire.available()) {
    byte data ;
      data=Wire.read();
      Serial.println(data,BIN);

  }else return;
  delay(1);

Tempo fa avevo trovato questo, ma non so se sia quello che puo servirti.

printf("%d%d\n", byte >> 7, (byte >> 6) & 1);
printf("%d%d\n", (byte >> 5) & 1, (byte >> 4) & 1);
printf("%d%d\n", (byte >> 3) & 1, (byte >> 2) & 1);
printf("%d%d\n", (byte >> 1) & 1, byte & 1);

EDIT: non e' roba mia, trovato in rete.

Puoi usare l'operatore AND sui bit per selezionare gli unici bit che ti interessano e l'operatore SHIFT per poi allineare tutto a destra così da avere il numero corrispondente ...

A A B B C C D D sono gli 8 bit che hai in un byte che chiamiamo "mioByte"...

... se fai mioByte & 0b11000000 metti a zero tutto quello che segue dopo i primi due bit, poi fai lo shift di 6 bit con >> 6 e li hai spostati all'inizio (allineati a destra) quindi: bitAA = (mioByte & 0b11000000) >> 6;

... stessa cosa per le coppie BB, CC e DD solo che fai l'AND selezionando solo i bit che ti servono e cambi lo shift. Ricapitolando:

bitAA = (mioByte & 0b11000000) >> 6;
bitBB = (mioByte & 0b00110000) >> 4;
bitCC = (mioByte & 0b00001100) >> 2;
bitDD = (mioByte & 0b00000011);

Sicuramente si può fare in modo ancora più compatto, ma meno leggibile e ... visto che devi imparare, forse questa è la forma più chiara :wink:

Guglielmo

P.S.: Nota bene che la notazione 0bxxxxxxxx, ovvero indicare i bit di un byte in questo modo, esiste SOLO su Arduino e NON è standard. In altri ambienti darebbe errore di sintassi ... la cosa migliore sarebbe esprimere il valore in esadecimale che è una notazione standard ... 0xC0, 0x30, 0x0C, 0x03.

provo...
bitAA ecc devono essere dichiarate come intero o come byte? ovviamente io vorrei leggere il numero in decimale!

Ottimizza sempre ... dovrà contenere un numero di due bit, quindi un numero che va da 0 a 3 ... cosa sprechi a fare due bytes di un "int"??? Ti basta un "byte" e risparmi il 50% dello spazio :wink:

Guglielmo

Come tu vuoi VEDERE il numero non ha nulla a che fare con come lo memorizzi (sempre una serie di bit è). La Serial.print() prevede dei modificatori (BIN, OCT, HEX, DEC) per "rappresentare" il numero in vari formati, ma, appunto, è solo una "rappresentazione", il valore, nalla memoria della MCU, sempre con una serie di bit in bytes è memorizzato!

Guglielmo

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.