Conversione esadecimale

Buongiorno ragazzi,
oggi ho un pò di tempo libero da dedicarmi allo sviluppo di qualche programmino utilizzando arduino mega.

Sto avendo qualche problema nella conversione da esadecimale a decimale tenendo conto che il valore esadecimale si trova all'interno di una stringa

   String valorees = "0x4294";
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print((valorees ,DEC));  // risultato corretto 17044 invece leggo 10

Purtroppo sono vincolato a utilizzare la stringa perchè quel risultato è frutto di un concatenamento.

Credo che la strada corretta sia trasformare la stringa in numero tramite la atoi (anche se non sono sicuro che accetti anche la base in cui il numero é scritto), e poi "printare" il numero. Certamente come hai fatto non va (anzi, probabile dia errore di compilazione, non ricordo che la print accetti 2 parametri quando usata con i char*) perché gli passi una stringa, e non un numero

Il risultato di quella stringa è un concatenamento di altre due conversioni in esadecimali separate

Ok, e quindi?

Togli il concatenamento e converti!
0x4294=0x4200+0x94

Scusami Silente, ma pensavo che quello che hai scritto tu "perché gli passi una stringa, e non un numero" fosse una domanda.

Le domande hanno il punto interrogativo... :slight_smile:

Datman:
Togli il concatenamento e converti!
0x4294=0x4200+0x94

Rimuovendo il concatenamento e la conversione in esadecimale, ottengo due numeri decimali: 66 e 148.

Come mai nel 0x42 aggiunge altri due zeri? In questo modo il risultato decimale viene corretto.

Gli zeri sono "segnaposto".
In decimale, ad esempio:
1234=1200+34
654321=650000+4300+21

Come faccio a capire se vanno aggiunti oppure no?

Con i tuoi risultati:
66*256+148=17044.

Nella notazione decimale, i pesi delle cifre sono in base 10:
... 10^4 10^3 10^2 10^1 10^0
123456 = 110^5 + 210^4 + 310^3 + 410^2 + 510^1 + 610^0

Nella notazione esadecimale sono in base 16, perciò:
4294 = 416^3 + 216^2 + 916^1 + 416^0
N.B.: qualunque numero<>0 elevato a 0 fa 1, perché è come dividerlo per sé stesso.

In avr la libreria base c ha sia atoi() che strtol()
Quindi usi strtol() ma vuole comunque una stringa classica del C non quella schifezza problematica di String
http://www.cplusplus.com/reference/cstdlib/strtol/
Usa c_str() delle String per avere la stringa C classica
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/c_str/
prova:

String valorees = "0x4294";
long num;
num=strtol(valorees.c_str(),NULL,16);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(num,DEC);

Inoltre non hanno senso quelle doppie parentesi lcd.print( (valorees ,DEC) );

Comunque, qui non è proprio il caso di passare per le stringhe! Basta rimanere nella matematica.

Datman:
Comunque, qui non è proprio il caso di passare per le stringhe! Basta rimanere nella matematica.

Sicuro ? l'utente parla di dati dentro ad una stringa, magari la riceve da seriale.

Anche se Giovanni riceve delle stringhe, non può convertirle mantenendole separate?

Buongiorno ragazzi,
scusatemi il ritardo ma in questi giorni sono stato davvero impegnato.

Mi spiego meglio…

Io ho la necessità di convertire un numero in esadecimale utilizzando la conversione IEEE754. Una volta convertito da esadecimale a decimale devo inviare il numero dividendolo in “Word alta” e “Word bassa”.
Giusto per fare qualche prova ho scritto, grazie anche al Vostro aiuto, il seguente codice:

union mix_t {                  // Conversione IEEE754
  float f;
  struct
  { byte b1;
    byte b2;
    byte b3;
    byte b4;
  } s;
} mix;


Void setup(){

}
Void loop(){

}

void CONESAD() {
  mix.s.b3 = 0x61;
  mix.s.b2 = 0xB3;
  mix.s.b1 = 0x33;
  mix.f  = 35.0;
  
  String e1 = String(mix.s.b4, HEX);
  String e2 = String(mix.s.b3, HEX);
  String e3 = String(mix.s.b2, HEX);
  String e4 = String(mix.s.b1, HEX);

  String prova =  "0x" + e1 + e2;
  String prova2 = "0x" + e3 + e4;

  for (int i = (prova.length() + 1); i<7; i++){
     prova = prova + "0";
  }
  for (int i = (prova2.length() + 1); i<7; i++){
     prova2 = prova2 + "0";
  }
 
  long num;
  num = strtol(prova.c_str(), NULL, 16);
  intero = num, DEC;
  num = strtol(prova2.c_str(), NULL, 16);
  intero2 = num, DEC;

}

Ripeto che quello di sopra è una bozza della bozza.
L’utilizzo delle stringhe le vorrei eliminare.

Utilizzando la bozza postata, diverse volte ho ottenuto il risultato sperato ma con il valore 35.0 ho qualche problema.

In esadecimale IEE754 mi diventa 0x42c00000 quando dovrebbe essere 0x420C0000.

Cosa mi consigliate di fare?

Non usare union e consimili immondizie

Castra a puntatore di byte l'indirizzo della float e usalo come un array di byte

Va letto all'indietro

Comunque il tuo problema è la soppressione degli zeri superflui

Quindi in realtà ti stiamo rispondendo per la stessa cosa che chiedi anche qui ?
Scrittura esadecimale modbus