Conversione ASCII in binario

Ciao a tutti ho cercato nei vari forum ma non ho trovato nulla di risolutivo alla mia richiesta,
Ho collegato un espansore di uscite della microchip mcp23017 ad arduino uno.
Quello che voglio fare adesso e’:
tramite monitor seriale , settare le uscite della porta A dell’mcp con valori binari
es:
00000111
quindi settare 3 uscite alte e lasciare le altre basse .
Qui iniziano i problemi perche’ il monitor seriale da quel poco che ho capito per ogni carattere che inserisco lo invia in ascii nel caso specifico se volessi inserire nella variabile pippo il valore di "00000111 "
il monitor mi trasmette : 49 quindi la variabile pippo assume 49 e di conseguenza avro in risposta :
110001
Aspetto qualche dritta
Grazie

Ecco la parte di codice che sto’ usando al momento

SET_PORT = Serial.read(); //leggo il primo byte
if (SET_PORT==10) return;
if (SET_PORT==97) return;
if (SET_PORT==115) return;
if (SET_PORT==-1) return;
Wire.beginTransmission(0x20);
Wire.write(0x12); // GPIOA
Wire.write(11111111); // port A
Wire.endTransmission();
Wire.beginTransmission(0x20);
Wire.write(0x13); // GPIOB
Wire.write(SET_PORT); // port B
Wire.endTransmission();
Serial.println(SET_PORT,DEC);

Mah ... o definisci un carattere terminatore tu (esempio il classico CR) o imposti il monitor seriale per trasmettere solo quando si preme CR.

A quel punto tu, sul monitor seriale, scrivi gli 8 bit come una stringa di 8 caratteri, premi CR, leggi il tutto dalla seriale, verifichi che contenga solo caratteri 0 ed 1 e non porcherie e poi, banalmente crei il tuo byte binario partendo da quella stringa.

Guglielmo

si, ogni carattere che viene digitato su monitor seriale viene inviato separatamente. Probabilmente esiste un metodo per impedire questo, ma io non lo conosco. Di conseguenza il metodo che usi per il comando porte non porta risultato. Quanto a darti una soluzione alternativa me ne viene in mente una: caricare un array con gli stati richiesti. Questo array andrebbe caricato da seriale e, se caricato correttamente, riportato sui pin di Arduino Sono stato preceduto

Silente: ... Sono stato preceduto

... e, se leggi bene, vedi anche come evitare che ogni carattere venga inviato appena premuto, attendendo, ad esempio, il CR. Nel monitor seriale, in basso a destra prima della velocità ;)

Così, scrive la stringa che vuole (es. 01001111), preme CR e la riceve tutta assieme. Comunque NON cambia molto, anche se riceveva carattere a carattere, bastava attende un CR ad indicare il fine stringa.

La stringa del 'C' è un array di char quindi ... ;)

Guglielmo

Grazie Se non ho capito male dovrei regolare il serial monitor "ritorno carrello CR" Digitere 00000111 e poi premo invio corretto?

Corretto, ma poi, comunque dovrai leggere carattere a carattere, verificare che ogni carattere sia solo '0' o '1' (altrimenti non è valido), salvarlo in un char array di 9 posizioni (non dimenticare che le stringhe del 'C' sono terminate dal carattere 0x00 che devi considerare nello spazio che riservi) e poi processare gli 8 caratteri per ottenere i tuoi 8 bit ;)

Più lungo da dire che da fare :D

Guglielmo

ciao, dunque ho provato e magari sbaglio, se inserisco un numero binario il monitor seriale lo stampa comunque decimale . Per esempio mettendo il carrello in CR e digitando 11100000 mi restituisce

49 48 48 48

la mia domanda e'; come li converto in binario ma ancora piu' importante commetto qualche errore nei passaggi ?

Eh certo, 49 è il codice ASCII del carattere "1" e 48 dello "0". Quindi se vuoi convertire una stringa di caratteri ASCII nel'equivalente byte per prima cosa accumulerai i caratteri fino al terminatore, poi devi prendere il codice di ogni carattere ricevuto, sottrarre 48 ed avrai i valori dei bit 0 e 1. Questi poi devi "comporli" in un byte a seconda della loro potenza di 2, e sapendo se usi LSB o MSB. LSB prima il bit meno significativo MSB prima quello più significativo. diciamo che usi il MSB, ossia "11100000" corrisponde al valore decimale 224.

Ti fai intanto una variabile dove accumuli il valore, es. "byte valore=0;" quindi ogni cifra/bit che ricevi diciamo che ce l'hai in una variabile "byte bit" e fai:

valore = valore*2 + bit;

Al termine di tutte le cifre ricevute avrai nella variabile "valore" il byte. Occhio che non puoi immettere più di 8 bit ovviamente...

devo pero' scrivere cosi' il dato

1 49 enter 1 49 enter 1 49 enter 0 48 enter 1 49 enter 1 49 enter 1 49 enter 1 49 enter

dovrei salvarli in 8 varibili da queste poi dovrei sottrarre 48 e una volta fatta l'operazione le devo concatenare MSB nella variabile SET_PORT

se concettualemte ho capito "spero"' e puo' funzionare , trovo pero' scomodo dover dare in pasto al monitor valori singoli

1 1 1 0 1 1 1 1

piuttosto che una "stringa"

11101111

se pero' la inserisco in questo modo il valore che mi restituisce il monitor e' :

49 49 49

Ma hai seguito quanto ti ho spiegato nei post precedenti ? ? ? :o :o :o

Li scrivi tutti assieme, fai invio e nel programma li leggi uno alla volta, li metti in un array di char, sottrai a ciascuno 0x30 (che è l'equivalente di 48 decimale) ed ha i tuoi bit nell'array !!!

Guglielmo

Ciao Formula

puoi anche usare le stringhe nel monitor scrivi la stringa es 00001010 pulsante invia o enter
nel monitor lasci come impostazione nessun fine riga e poi leggi la striga intera con qualcosa del tipo

  // include the library code:
  #include <LiquidCrystal.h>
  
  // initialize the library with the numbers of the interface pins
  LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  
  String Mystring=String(255,BIN); //create string 11111111
  int Mybyte;
  boolean Check;
  int retroPin;
  int Poe; //potenza di un numero
  
void setup() {
  // put your setup code here, to run once:

  // LED Display connected to digital pin 10:
  // sets the digital pin as output:
  pinMode(retroPin, OUTPUT);     
  // sets retro off:
  digitalWrite(retroPin,LOW);
    
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  delay(1000);
  // Print a message to the LCD.
          //"0123456789012345"  
  lcd.print(" String Manipul ");
  digitalWrite(retroPin,HIGH);
  delay(1000);
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600); 
}

void loop() {
  // put your main code here, to run repeatedly:
  while (Serial.available()==0) {
  }
    Mystring=Serial.readStringUntil('/n');
    Serial.flush();
    lcd.setCursor(1,1);
    lcd.print(Mystring);
    lcd.print(" =     ");
    Serial.print("Mystring = ");
    Serial.println(Mystring);
    
  Verifica();
  //Serial.println("Verifica");
  
  if (Check==true) {
    //Serial.println("If Check=True Then ...");
    BinToDec();
    lcd.setCursor(12,1);
    lcd.print(Mybyte);
    Serial.print("Binary (");Serial.print(Mystring);Serial.print(") Converted To ");Serial.println(Mybyte,DEC);
  }
}

void Verifica() {
  Check=false;
  //Serial.println("Verifica Check=False");
  //Serial.print("Mystring.length() = ");
  //Serial.println(Mystring.length());
  
  if (Mystring.length()==8) {
    Check=true;
    //Serial.println("Lunghezza = 8 Check=True");
  }
  else {
    Check=false;
    //Serial.println("Lunghezza <> 8 Check=False");
    return;
  }
  
  for(int i=0;i<=7;i++) {
    if (Mystring.charAt(i)!='1' && Mystring.charAt(i)!='0') {
      Check=false;
      //Serial.print("If Mystring.CharAt(");Serial.print(i);Serial.println(") <> 1 and <> 0 Then"); 
      //Serial.println("Carattere <> 0 e <> 1 Check=False Return");
     return;
    }
  }  
}

void BinToDec() {
  //Serial.println("BinToDec");
  Mybyte=0;
  for(int i=0;i<=7;i++) {
    if (Mystring.charAt(7-i)=='1') {
      //Serial.print("If Mystring.CharAt(");Serial.print(i);Serial.println(")==1 then somma");
      Mybyte=Mybyte+PowToEsp(2,i);
      //Serial.print("2 elevato (");Serial.print(i);Serial.print(")=");Serial.println(PowToEsp(2,i));
      //Serial.print("Mybyte = ");
      //Serial.println(Mybyte);
    }
  }
  //Serial.print("Mybyte = "); Serial.println(Mybyte);
}

int PowToEsp(byte base,byte esp) { //elevamento a esp di base
  int poe=int(base);
  if (esp==0) {return 1;}
  if (esp==1) {return int(base);}
  for(int i=2;i<=esp;i++) {
  poe=int(poe*base);
  }
  return poe;
}

se non hai un display collegato commenta tutte le righe inerenti puoi utilizzarla col solo monitor

testata e funzionante poi tieni presente che mcp 230117 va inizializzato e programmato
al reset tutte le porte sono ingressi nessuna uscita devi impostare i registri direzione dati.

Ciao
Paolo

gpb01: Ma hai seguito quanto ti ho spiegato nei post precedenti ? ? ? :o :o :o

Credo di no, visto che quello che hai ripetuto anche tu, l'avevo scritto anche io nel post #7:

per prima cosa accumulerai i caratteri fino al terminatore, poi devi prendere il codice di ogni carattere ricevuto, sottrarre 48 ed avrai i valori dei bit 0 e 1. Questi poi devi "comporli" in un byte a seconda della loro potenza di 2, e sapendo se usi LSB o MSB. LSB prima il bit meno significativo MSB prima quello più significativo. diciamo che usi il MSB, ossia "11100000" corrisponde al valore decimale 224.

Ovviamente non scrivendogli io il codice, ma dando le indicazioni precise per sapere cosa fare. Per cui fino a che non vedo un suo codice, io passo...