Conversione HEX e serial =(

Un altro bel problema :), ci ho già perso circa 20 ore e nn mi viene fuori nulla...

In pratica, devo mandare un pacchetto all' encoder che sta su serial2 che viene trascritta in rs485...

il pacchetto deve essere composto cosi: ( tutto in HEX ) 01 07 35 52 71 04 CRC

dove 01 e 04 soni i byte di inizio e fine

07 sono il numero byte del pacchetto

35 e l'indirizzo del encoder

52 e 71 sono i comandi

Dopo un bel po ho pensato di fare cosi:

byte mex[8] = {01, 07, byte(EncoderAddr), 52, 71, 04, 0}
 mex[8] = Tools::crc(mex);  //fa il crc dei primi 7 campi e restituisce il byte
 Serial2.println(mex, HEX);

ma restituisce error: call of overloaded 'print(byte [8], int)' is ambiguous ......

In pretica devo convertire gli ACSII 52 e 71 (R e q) in esadecimale e inviarli, poi quando mi risponde devo fare il contrario da Hex a int o char e via dicendo

Io vengo dal Java (faticato) e a dire il vero il c++ proprio nn lo sopporto, va bè è ora di impararlo :).

Arduino non mette molte risorse a disposizione per la conversione, sapere come fare??

Per inviare valori esadecimali devi utilizzare Serial.write e non print altrimenti vengono inviati come carattere cioè hai "4F" e non 0x4F che vuoi. Se il protocollo e il modbus esistono anche alcune librerie gia implementate comunque

Come si suol dire PERDERSI IN UN BICHIERE D’ ACQUA XD

Purtroppo non è ModBus e un prot suo, sto encoderino costa 30€ di seconda mano però è assoluto :slight_smile:

ho pensato di usare #include <stdio.h> per poter usare sprintf e sscanf per le conversioni, vi farò sapere se affossano tutto!

Nada de Nada , si resetta in continuazione,

byte crc(byte* query){
  int crc;
  crc = crc << 1;
  int count = sizeof(query);
  int a;
  for ( a= 0; a == (count-2); a++){
  crc = crc ^ query[a];
  crc = crc << 1;
  }
  crc = crc ^ query[count-2];
  return crc; 
}

void Leggi(){
  Adr = 21;
  char* buf;
  sprintf(buf,"%x",Adr);
  byte mex[]= {0x01, 0x07 ,atoi(buf),0x52, 0x71, 0x04, 0x00};   
  mex[sizeof(mex)-1] = crc(mex);  //fa il crc dei primi 6 campi
  int siz = sizeof(mex), i=0;
  while (i < siz){
     Serial.print(mex[i],HEX);
     i++;
   }
   Serial.write("\n");
}

void setup(){
  Serial.begin(9600);
  Serial.println("->Pronto<- :)");
}
void loop(){

    Leggi();
    delay(3000);
     
     
}

Non rispetta il delay e mi manda sempre il mex di pronto + na sfilza di simboli.

Qualche consiglio???

Hai sbagliato parecchie cose... Ad esempio il crc

int count = sizeof(query);

Sizeof non è una funizone, ma un operatore. In questo caso non ti calcola la lunghezza dell'array ma la dimensione del puntatore(2 credo)... Ti si resetta perché il tuo codice causa violazioni di accesso alla memoria(stack smashing). Per scrivere valori "raw" sulla seriale devi fare Serial.write(valore) dove valore è 1 singolo byte, 1 solo! Ciao

Come detto poi per inviare numeri esadecimali devi fare :
Serial.write(mex*);*
e non utilizzare il println che converte Hex in Stringa

ypkdani: Serial.write(mex*);[/quote]* ypkdani intendeva ``` Serial.write(mex[i]); ``` SMF forum aveva preso quel [\i] come bbCode Ciao

Grazie MGuruDC!! non avevo visto

Un pò o risolto, anche grazie al serial.write, in + mi son fatto ste 2 funzioncine:

byte twhex(int num){
    char* buff;
    itoa(num,buff,16);
    return  byte(atoi(buff));
}

byte twhex (char num){
    char* buff;
    printf(buff,"%X",num);
    return  byte(atoi(buff));
}

che swiciano gli int dec e i char in Byte Hex

MarioMas:

byte twhex(int num){

char* buff;
    itoa(num,buff,16);
    return  byte(atoi(buff));
}

byte twhex (char num){
    char* buff;
    printf(buff,"%X",num);
    return  byte(atoi(buff));
}

Umm… non ci siamo…

  1. Con queste funzioni fai un giro di 500km per spostarti di 10 m: se hai in memoria un valore numerico tipo int(2word su arduino):
    0000 0000 - 1010 1010 = 17010 = AA16
    e devi convertirlo in un tipo byte(1word) devi soltanto fare un cast che ti fa perdere tutta la word di sinistra, così ottieni
    1010 1010 = 17010 = AA16
    Quindi
int valore_int_da_convertire = 170 /* 0xAA */;
byte valore_da_inviare_sulla_seriale = byte(valore_int_da_convertire);
// oppure alla vecchia maniera:
byte valore_da_inviare_sulla_seriale = (byte)valore_int_da_convertire;
  1. “atoi(char *)” non supporta le stringhe contenenti numeri esadecimali, solo decimali, la tua funzione restituirebbe sempre 0
  2. Con “char* buff;” hai dichiarato solo il puntatore a carattere, non hai allocato la memoria necessaria. Se non lo fai causi stack smashing.
  3. In questo caso non è necessario fare il cast al valore che ritorni. Probabilmente il compilatore salta questa operazione.
  4. printf su Arduino non c’è… forse intendevi “sprintf”.
  5. tutta la seconda funzione non ha senso… char è già un valore byte non c’è bisogno di convertirlo.

Conclusione: se “scendi” dal java al C/C++, devi studiare… e pure parecchio. Come manuale ti consiglio il Deitel.
Ciao

Credo proprio di dover studiare un bel po MGuruDC :)

tra Java e C++ c'è un oceano.

Cmq ho risolto con la cara vecchia calcolatrice di windows in modalità programmatore e mi sono reso conto delle posizioni dei bit.

Prima d'ora non avevo mai fatto protocolli hardware ma sempre e solo software dove normalmente fai tutto in ASCII

Con senno di poi questo post mi imbarazza un pochino :) ma l'importate è aver capito in concetto di base

Beh per partire bisognerebbe andare con più cautela, ma hai la fortuna di sapere già come si programma... una volta afferrati i concetti fondamentali non ti ferma nessuno XD Ciao