Torna indietro   Hardware Upgrade Forum > Software > Programmazione

realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
Hogwarts arriva in fascia media grazie a realme, con una special edition che unisce la Quadra Light-Sensing Color-changing Tech, un baule in stile Hogwarts Express pieno di collezionabili e una scheda tecnica sostanzialmente identica al 16 Pro di partenza: ecco cosa cambia davvero, come si comporta nell'uso quotidiano e quanto vale in base al prezzo di 699,99 euro
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
REDMI Note 17 Pro porta in fascia media una batteria da 8.340 mAh con ricarica HyperCharge a 67W, un display AMOLED da 6,83 pollici capace di picchi di luminosità molto elevati e una struttura certificata TÜV SÜD contro cadute e infiltrazioni d'acqua, il tutto racchiuso in una scocca da 223 grammi. Lo abbiamo provato per diversi giorni tra fotocamera, prestazioni, autonomia e prezzo sul mercato italiano
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra integra un sensore da 1 pollice 8K, ottiche Leica e triplo chip IA. Tra schermo OLED rimovibile, workflow I-Log a 10 bit e stabilizzazione a tre assi, analizziamo le doti tecniche di una gimbal camera pensata per i professionisti
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 12-04-2012, 16:24   #1
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
[C++] funzione di CRC e calcoli errati in parte...

Salve a tutti, ho implementato questa funzione per il calcolo del CRC16 su un vettore di unsigned char,

typedef unsigned short UInt16;
typedef unsigned char UInt8;

UInt16 CRC16(UInt16 crc, UInt8 data)
{
const UInt16 tbl[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040};

return ((crc & 0xFF00) >> 8) ^ tbl[(crc & 0x00FF) ^ (data & 0x00FF)];
}


la vado a richiamare in questo modo all'interno del programma:

UInt16 CalcolaCRC(UInt8 d[ ] ){
UInt16 crc=0;
UInt16 COD;
for(int i=0;i<sizeof(d);i++)
{
COD=CRC16(crc,d[i]);
crc=COD;
}

return COD;
}

se gli passo alcuni vettori, mi calcola il giusto crc, ad esempio richiamandola così:

UInt8 grup[1]={0x05};
UInt8 dlencmd[2]={0x01,0x92};
UInt8 buf[4];
buf[0]=grup[0];
buf[1]=IDPinza; <--questo è un intero
buf[2]=dlencmd[0];
buf[3]=dlencmd[1];

UInt16 crc=CalcolaCRC(buf);

UInt8 buffer[6];
for (int i=0;i<sizeof(buffer);i++){
buffer[i]=buf[i];
}
int sd=SendBuf(Pnum,buffer,6);

quello che mi viene inviato sulla porta seriale è il vettore più il crc che è corretto, cioè mi ritrovo {0x05,0x0C,0x01,0x92,0x40,0xF2}

dove gli ultimi due sono il CRC16 calcolato. Ma usando lo stesso sistema per richiamarla su altri vettori, tipo :

UInt8 grup[1]={0x05};
UInt8 par[2]={0x01,0x91};
UInt8 bf[4];
bf[0]=grup[0];
bf[1]=IDPinza;
bf[2]=par[0];
bf[3]=par[1];
CalcolaCRC(bf);
UInt8 bufer[6];
for (int i=0;i<sizeof(bufer);i++){
bufer[i]=bf[i];
}
int sd=SendBuf(Pnum,bufer,6); <--- Questa serve ad inviare sulla porta seriale

beh, in questo caso me lo ritorna sbagliato. Dovrebbe essere {0x05,0x0C,0x01,0x91,0x00,0xF3} invece mi ritorna {0x05,0x0C,0x01,0x91,0x05,0x01}

e così anche per altri vettori...eppure il sistema per richiamarla è lo stesso...dove sbaglio? Apparentemente sono vettori identici tranne che per alcuni valori...perchè mi dà simili errori? C'è un modo migliore per richiamarla?

Aiutatemi..
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2012, 19:24   #2
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Il codice non è chiarissimo ma mi sembra che il risultato di questa linea

UInt16 crc=CalcolaCRC(buf);

non la utilizzi nel buffer finale.
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2012, 20:26   #3
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
perchè mi ritorna due unsigned int e non so come assegnarli separatamente nelle due posizioni diverse.

Fatto sta che non so come mai, ma la cosa la fa automaticamente nei casi in cui funziona...cioè me li ritrovo divisi in modo corretto come ho indicato...

nessuno mi sa aiutare?
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2012, 21:48   #4
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Quote:
Originariamente inviato da DomusP45 Guarda i messaggi
perchè mi ritorna due unsigned int e non so come assegnarli separatamente nelle due posizioni diverse.
Veramente ritorna un solo unsigned int. E semmai devi assegnare i singoli byte.

Quote:
Fatto sta che non so come mai, ma la cosa la fa automaticamente nei casi in cui funziona...cioè me li ritrovo divisi in modo corretto come ho indicato...
No ... non lo fa affatto automaticamente ma per caso. Si corrompe lo stack e a volte i valori vanno a finire al posto giusto. Ma è sbagliato ... il codice da correggere è questo

Codice:
	unsigned short int crc=CalcolaCRC(buf);
	unsigned char buffer[6];
	for (int i=0; i<sizeof(buf); i++)
		buffer[i]=buf[i];
	buffer[4]=crc & 0xFF;
	buffer[5]=crc>>8;
Occhio alle modifiche che ho apportato rispetto al tuo codice ...
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2012, 22:19   #5
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
Quote:
Originariamente inviato da lorenzo001 Guarda i messaggi
Veramente ritorna un solo unsigned int. E semmai devi assegnare i singoli byte.



No ... non lo fa affatto automaticamente ma per caso. Si corrompe lo stack e a volte i valori vanno a finire al posto giusto. Ma è sbagliato ... il codice da correggere è questo

Codice:
	unsigned short int crc=CalcolaCRC(buf);
	unsigned char buffer[6];
	for (int i=0; i<sizeof(buf); i++)
		buffer[i]=buf[i];
	buffer[4]=crc & 0xFF;
	buffer[5]=crc>>8;
Occhio alle modifiche che ho apportato rispetto al tuo codice ...
Domani provo e ti aggiorno. Ora sto crollando dal sonno...grazie mille per la disponibilità...t aggiorno domani!

EDIT: anche introducendo tale modifica, il CRC calcolato cmq non corrisponde a quell che dovrebbe, solo in alcune funzioni. Con la modifica da te segnalata almeno sono sicuro di assegnarlo bene al vettore...però il problema sui calcoli con talune funzioni rimane...e non riesco a capire perchè...
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.

Ultima modifica di DomusP45 : 14-04-2012 alle 14:49.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 16-04-2012, 12:31   #6
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Dicci quali sono i casi che non vanno ...
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 16-04-2012, 15:26   #7
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
Quote:
Originariamente inviato da lorenzo001 Guarda i messaggi
Dicci quali sono i casi che non vanno ...
Ti posto le funzioni con le modifiche fatte, e ti dico l'output:

La funzione di CRC16 è quella postata sopra, poi c'è questa che la richiama

Codice:
UInt16 CalcolaCRC(UInt8 d[])
{
    UInt16 crc=0;
    UInt16 COD;
    for(int i=0;i<sizeof(d);i++)
    {
        COD=CRC16(crc,d[i]);
        crc=COD;
    }
    
    return COD;
e la funzione di preparazione del buffer su cui calcolare il CRC che è questa:

Codice:
void PreparaBuffer(UInt8 *par,UInt8 *dat, UInt8 *bufer)
{
    if (par[0]==(0x05))
        {
          UInt8 grup[1]={0x05};
          UInt8 buf[8];
           buf[0]=grup[0];
           buf[1]=IDPinza;
           buf[2]=par[0];
           buf[3]=par[1];
           buf[4]=dat[0];
           buf[5]=dat[1];
           buf[6]=dat[2];
           buf[7]=dat[3];
           UInt16 crc=CalcolaCRC(buf);
           for (int i=0;i<sizeof(buf);i++){
                 bufer[i]=buf[i];
                 }
                 bufer[8]=crc & 0xFF;
                 bufer[9]=crc>>8;
        }
    else if(par[0]==(0x01))
       {
             UInt8 grup[1]={0x05};
             UInt8 buf[4];
             buf[0]=grup[0];
             buf[1]=IDPinza;
             buf[2]=par[0];
             buf[3]=par[1]; 
             UInt16 crc=CalcolaCRC(buf);
             for (int i=0;i<sizeof(buf);i++){
                        bufer[i]=buf[i];
                        }  
                bufer[4]=crc & 0xFF;
                bufer[5]=crc >> 8;
        }
    
    }
che è divisa in due tipologie perchè la prima è quella in cui all'utente si chiede il parametro (float) in mm a cui spostare la pinza, il secondo pezzo invece è per mandare comandi senza parametri (buffer più corto).

nel main la cosa avviene così:

Codice:
 UInt8 dlencmd[2]={0x01,0x8B};
    UInt8 bufer[6];
    PreparaBuffer(dlencmd,0,bufer); 
    int i=SendBuf(Pnum,bufer,6);
che nel caso di funzioni di posizionamento, cambia in

Codice:
int  Posiziona(float param)
    UInt8 dlencmd[2]={0x05,0xB0};
    UInt8 bufer[10];
    UInt8 *pr=(unsigned char *)&param;
    PreparaBuffer(dlencmd,pr,bufer);
    int sd=SendBuf(Pnum,bufer,10);
dove param è il parametro immesso da utente (millimetri).

Ora, ad esempio: se faccio una funzione di ACK, che ha dlencmd come indicato sopra, il buffer inviato risultante è corretto:

dal vettore 0x05,0x0C,0x01,0x8B mi invia quello completo di CRC corretto, che è

0x05 0x0C 0x01 0x8B 0x81 0x38.

Un'altra funzione simile che è questa

Codice:
UInt8 dlencmd[2]={0x01,0x91};
    UInt8 buffer[6];
    PreparaBuffer(dlencmd,0,buffer);
    int sd=SendBuf(Pnum,buffer,6);
che come vedi richiamo in modo identico, dal vettore

0x05 0x0C 0x01 0x91 dovrebbe dare 0x05 0x0C 0x01 0x91 0x00 0xF3 invece mi restituisce 0x05 0x0C 0x01 0x91 "00 AC" che se la lancio di nuovo diventa "00 B6" e ancora se la lancio diventa "00 F3"...insomma, non è corretto sto fatto che cambia...ed al terzo tentativo diventa corretta, poi se la lancio ancora, di nuovo 00 00 ...

Lo stesso per la funzione di posizionamento, immettendo 10 dovrebbe darmi

0x05 0x0C 0x05 0xB0 0x00 0x00 0x20 0x41 0x94 0x40

dove 0x00 0x00 0x20 0x41 è 10 (float) convertito. Invece, immettendo 10 quello che ottengo è

0x05 0x0C 0x05 0xB0 0x00 0x00 0xE3 0xAC 0x00 0x2B e la parte che dovrebbe rappresentare il 10 è sbagliata e cambia di volta in volta richiamando la funzione sempre con 10 come input.

Ecco i problemi quali sono...come posso risolvere??
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.

Ultima modifica di DomusP45 : 19-04-2012 alle 09:10.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 18-04-2012, 11:00   #8
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
allora, nessuno mi sa dire dove potrebbe essere l'errore?
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 19-04-2012, 09:11   #9
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
up
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 19-04-2012, 21:06   #10
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Quote:
Originariamente inviato da DomusP45 Guarda i messaggi
0x05 0x0C 0x01 0x91 dovrebbe dare 0x05 0x0C 0x01 0x91 0x00 0xF3
E a me restituisce proprio i valori corretti in grassetto...

Purtroppo, se non fornisci un codice preciso di prova (da copiare e incollare) non so dirti dove sbagli.

Ovvero, non scrivere "una funzione simile" ma fornisci esattamente il codice che stai provando (con i valori precisi ... ad esempio, non so mai quanto valga IDPinza per le prove ...)
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 19-04-2012, 23:52   #11
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
Quote:
Originariamente inviato da lorenzo001 Guarda i messaggi
E a me restituisce proprio i valori corretti in grassetto...

Purtroppo, se non fornisci un codice preciso di prova (da copiare e incollare) non so dirti dove sbagli.

Ovvero, non scrivere "una funzione simile" ma fornisci esattamente il codice che stai provando (con i valori precisi ... ad esempio, non so mai quanto valga IDPinza per le prove ...)
IDPinza vale 12...lo capisci dalla traduzione che vedi (0C) nell'array di byte. Facciamo così, domani mattina ti posto tutti i pezzi di codici per intero (che ora è tardi e non ce la faccio) e appena puoi mi rispondi..grazie ancora per la disponibilità!
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 09:50   #12
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
ecco qua i vari pezzi e come li richiamo. Calcola che io sto creando una classe per la gestione di tale pinza, quindi ci sono 3 file Prova.h, Prova.cpp e main.cpp.

Ora, ti elenco le varie cose nell'ordine:

la definizione dei tipi

Codice:
typedef unsigned short UInt16;
typedef unsigned char UInt8
funzione di richiamo calcolo CRC

Codice:
Int16 Prova::CalcolaCRC(UInt8 d[]){
    UInt16 crc=0;
    UInt16 COD;
    for(int i=0;i<sizeof(d);i++)
    {
        COD=CRC16(crc,d[i]);
        crc=COD;
    }
    
    return COD;
}
Questa funzione mi prepara il buffer per l'invio a seconda del valore della prima posizione del parametro "par" che gli viene passato e gli altri parametri che vedi (dat,velo,acc) sono quelli chiesti all'utente che vengono presi "float" e convertiti come vedrai più avanti

Codice:
void Prova::PreparaBuffer(UInt8 *par,UInt8 *dat,UInt8 *velo, UInt8 *acc, UInt8 *bufer)
{
    //se arriva un posizionamento semplice
    if (par[0]==(0x05))
        {
          UInt8 grup[1]={0x05};
          UInt8 buf[8];
           buf[0]=grup[0];
           buf[1]=IDPinza;
           buf[2]=par[0];
           buf[3]=par[1];
           buf[4]=dat[0];
           buf[5]=dat[1];
           buf[6]=dat[2];
           buf[7]=dat[3];
           UInt16 crc=CalcolaCRC(buf);
           for (int i=0;i<sizeof(buf);i++){
                 bufer[i]=buf[i];
                 }
                 bufer[8]=crc & 0xFF;
                 bufer[9]=crc >> 8;
        }
    //se arriva una istruzione di comando
    else if(par[0]==(0x01))
       {
             UInt8 grup[1]={0x05};
             UInt8 buf[4];
             buf[0]=grup[0];
             buf[1]=IDPinza;
             buf[2]=par[0];
             buf[3]=par[1]; 
             UInt16 crc=CalcolaCRC(buf);
             for (int i=0;i<sizeof(buf);i++){
                        bufer[i]=buf[i];
                        }  
                bufer[4]=crc & 0xFF;
                bufer[5]=crc >> 8;
        }
    //se arriva un posizionamento complesso
    else if(par[0]==(0x09)){
        UInt8 grup[1]={0x05};
        UInt8 buf[14];
        buf[0]=grup[0];
        buf[1]=IDPinza;
        buf[2]=par[0];
        buf[3]=par[1];
        buf[4]=dat[0];
        buf[5]=dat[1];
        buf[6]=dat[2];
        buf[7]=dat[3];
        buf[8]=velo[0];
        buf[9]=velo[1];
        buf[10]=velo[2];
        buf[11]=velo[3];
           UInt16 crc=CalcolaCRC(buf);
           for (int i=0;i<sizeof(buf);i++){
                 bufer[i]=buf[i];
                 }
                 bufer[12]=crc & 0xFF;
                 bufer[13]=crc >> 8;
    }
    else if(par[0]==(0x0D)){
        UInt8 grup[1]={0x05};
        UInt8 buf[18];
        buf[0]=grup[0];
        buf[1]=IDPinza;
        buf[2]=par[0];
        buf[3]=par[1];
        buf[4]=dat[0];
        buf[5]=dat[1];
        buf[6]=dat[2];
        buf[7]=dat[3];
        buf[8]=velo[0];
        buf[9]=velo[1];
        buf[10]=velo[2];
        buf[11]=velo[3];
        buf[12]=acc[0];
        buf[13]=acc[1];
        buf[14]=acc[2];
        buf[15]=acc[3];
           UInt16 crc=CalcolaCRC(buf);
           for (int i=0;i<sizeof(buf);i++){
                 bufer[i]=buf[i];
                 }
                 bufer[16]=crc & 0xFF;
                 bufer[17]=crc>>8;
      }
    if (par[0]==(0x06))
        {
          UInt8 grup[1]={0x05};
          UInt8 buf[9];
           buf[0]=grup[0];
           buf[1]=IDPinza;
           buf[2]=par[0];
           buf[3]=par[1];
           buf[4]=(0x00);
           buf[5]=(0x00);
           buf[6]=(0x00);
           buf[7]=(0x00);
           buf[8]=(0x07);
           UInt16 crc=CalcolaCRC(buf);
           for (int i=0;i<sizeof(buf);i++){
                 bufer[i]=buf[i];
                 }
                 bufer[9]=crc & 0xFF;
                 bufer[10]=crc >> 8;
        }
    }
Questa è la funzione di posizionamento, che si occupa di richiamare prepara buffer, e di inviare poi il comando. In tale funzione converto i parametri che gli vengono passati da float a unsigned char...e la cosa però in output sulla porta non è fatta in modo corretto purtroppo e non riesco a capire perchè, visto che quello è il sistema.

Codice:
int Prova::Posiziona(float pos, float vel, float corr) 
{
    OpenComport(Pnum, BDRATE);
    //se velocità e corrente non sono state specificate
    if ((vel==0)&&(corr==0)){
      UInt8 dlencmd[2]={0x09,0xB0};  
      UInt8 bufer[14];
      float veloc=10;
      UInt8 *ps=(UInt8 *) &pos;
      UInt8 *v=(UInt8 *) &veloc;
      PreparaBuffer(dlencmd,ps,v,0,bufer);
      int sd=SendBuf(Pnum,bufer,10);
      return sd;
     }
    //se posizionamento in accelerazione
    else if((vel!=0)&&(corr==0)){
      UInt8 dlencmd[2]={0x09,0xB0};  
      UInt8 bufer[14];
      UInt8 *pr=(UInt8 *) &pos;
      UInt8 *v=(UInt8 *) &vel;
      PreparaBuffer(dlencmd,pr,v,0,bufer);
      int sd=SendBuf(Pnum,bufer,14);
      return sd;
    }
    else if((vel!=0)&&(corr!=0)){
      UInt8 dlencmd[2]={0x0D,0xB0};  
      UInt8 bufer[18];
      UInt8 *pr=(UInt8 *) &pos;
      UInt8 *v=(UInt8 *) &vel;
      UInt8 *ac=(UInt8 *) &corr;
      PreparaBuffer(dlencmd,pr,v,ac,bufer);
      int sd=SendBuf(Pnum,bufer,18);
      return sd;
    }
    
 }
Questa è la funzione che non riesce a darmi il CRC corretto, nonostante sia fatta identica ad altre che invece danno il risultato corretto.

Codice:
int Prova::Stopper()
{
    OpenComport(Pnum, BDRATE);
    UInt8 dlencmd[2]={0x01,0x91};
    UInt8 buffer[6];
    PreparaBuffer(dlencmd,0,0,0,buffer);
    int sd=SendBuf(Pnum,buffer,6);
    return sd; //indicherà l'avvenuta trasmissione o -1 se errore
}
Questa è la funzione di calcolo vero e proprio del CRC, che viene richiamata ricorsivamente.

Codice:
UInt16 Prova::CRC16(UInt16 crc, UInt8 data)
{
const UInt16 tbl[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040};

return ((crc & 0xFF00) >> 8) ^ tbl[(crc & 0x00FF) ^ (data & 0x00FF)];
}
ed un altra funzione che lo stesso mi crea problemi di output è questa:

Codice:
int Prova::GetState() //richiesta stato della pinza
{
    OpenComport(Pnum, BDRATE);
    UInt8 dlencmd[2]={0x06,0x95}; 
    UInt8 bufer[11];
    PreparaBuffer(dlencmd,0,0,0,bufer);
    int i=SendBuf(Pnum,bufer,11);
    return i;   
}
Perchè quando viene messa in output non ha 00 00 00 00 ma altro, e vista com'è fatta PreparaBuffer, non riesco a capire come fa a non metterci in quelle posizioni quello che ho indicato per "par[0]=0x06" (che è riferito a questa funzione).

Ora passiamo al main , le cose le richiamo così:

Per controllo sui parametri inseriti all'inizio ho fatto così:

Codice:
cout<<"Immetti l'ID della pinza (intero): ";
    cin.getline(IDE,4);
    ID = atoi(IDE);
    if (ID<=0){
        cout<<"Hai immesso parametri sbagliati.Riprova."<<endl;
        exit(0);
    }    
    else if(ID>0){   
        cout<<endl<<"Immetti il numero della porta seriale da aprire (intero): ";
        cin.getline(NUMERO,4);
        NUM = atoi(NUMERO);
        if (NUM<=0){
        cout<<"Mi dispiace hai immesso parametri sbagliati.Riprova."<<endl;
        exit(0);
            }
    }
E non mi crea nessun problema tale conversione. Il numero IDPinza che interessa è 12.

Per il posizionamento, all'utente lo chiedo così:

Codice:
void pos(Prova pinza)
    {  
        
        cout<<endl<<"Immetti i parametri di posizionamento (mm): ";
        //raccolta parametri
        cin>>par;
        cout<<endl<<"Immetti la velocità: (immetti 0 per velocità standar 10mm/s): ";
        cin>>vel;
        cout<<endl<<"Immetti l'accelerazione: (immetti 0 per accelerazione default: ";
        cin>>ac;
        int i=pinza.Posiziona(par,vel,ac);
         
    }
La funzione Stopper, la richiamo così:

Codice:
 int i=pinza.Stopper();

Ebbene,
- Stopper non produce il risultato corretto come ti ho indicato nei post precedenti (e non capisco perchè)., anzichè 0x05 0x0C 0x01 0x91 0x00 0xF3 porta inzialmente 0x00 0x00 al posto degli ultimi due, poi dopo 3 "lanci" 0x00 0xF3 poi di nuovo 0x00 0x00...

- Posiziona non produce la conversione giusta dei parametri da float a unsigned e nemmeno il calcolo del CRC corretto.Es. Se immetto 10 come parametro posizione e 8 come velocità , 0 come acceler, deve passare (10, 8, 0) , e quindi quello che deve produrmi è 0x05 0x0C 0x09 0xB0 0x00 0x00 0x20 0x41 0x00 0x00 0x00 0x41 0x2D 0xEB, dove 00 00 20 41 è "10" convertito, 00 00 00 41 è 8, ed 2D EB è il crc, invece mi viene fuori: 05 0C 09 B0 00 00 20 41 00 EF 8A 41 C7 2B (crc sbagliato e conversione sbagliata, che cambia di volta in volta) e se invece immetto solo 10 (dovrebbe poi passare 10, 10 ,0) passa solo un 10 ed è sbagliata la lunghezza del buffer...

- GetState al posto di avere
buf[4]=(0x00);
buf[5]=(0x00);
buf[6]=(0x00);
buf[7]=(0x00);
buf[8]=(0x07);

in queste posizioni ha valori diversi da 0 e il calcolo del CRC ovviamente è sbagliato, dovrebbe venire fuori 0x05 0x0C 0x06 0x95 0x00 0x00 0x00 0x00 0x07 0x05 0xC2, dove 05 e C2 è il crc corretto. E invece non viene fuori così.

Più dettagliato di così non so essere. Spero che mi riuscirai a dare una mano!! Grazie!!
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.

Ultima modifica di DomusP45 : 20-04-2012 alle 09:59.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 10:14   #13
ESSE-EFFE
Member
 
Iscritto dal: May 2009
Messaggi: 186
Quote:
Originariamente inviato da DomusP45 Guarda i messaggi
Codice:
Int16 Prova::CalcolaCRC(UInt8 d[])
{
    UInt16 crc=0;
    UInt16 COD;
    for(int i=0;i<sizeof(d);i++)
    {
        COD=CRC16(crc,d[i]);
        crc=COD;
    }
    
    return COD;
}
Prova a controllare cosa restituisce sizeof(d)...
__________________
ESSE-EFFE.com
Sviluppo software e Web
Creazione loghi - Bergamo
ESSE-EFFE è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 10:19   #14
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
Quote:
Originariamente inviato da ESSE-EFFE Guarda i messaggi
Prova a controllare cosa restituisce sizeof(d)...
deve restituire la grandezza del vettore che gli passo. Perchè?
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 10:27   #15
ESSE-EFFE
Member
 
Iscritto dal: May 2009
Messaggi: 186
Quote:
Originariamente inviato da DomusP45 Guarda i messaggi
deve restituire la grandezza del vettore che gli passo. Perchè?
E hai controllato che sia proprio così?
__________________
ESSE-EFFE.com
Sviluppo software e Web
Creazione loghi - Bergamo
ESSE-EFFE è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 10:34   #16
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
Quote:
Originariamente inviato da ESSE-EFFE Guarda i messaggi
E hai controllato che sia proprio così?
beh, tutte le altre funzioni che ci sono diverse da stopper, vengono richiamate uguali. E per tutte le altre funziona perfettamente il calcolo del CRC. Tra parentesi molte delle altre sono identiche come grandezza a Stopper, differiscono per un solo parametro in pratica al posto 0x91 c'è un altro valore. Pertanto, se calcola bene tutte le altre, perchè dovrebbe sbagliare proprio questa? e perchè è l'unica che se ripeto il lancio più volte, cambia il crc, mentre per le altre questo non accade?
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 11:24   #17
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Quella sizeof che ti è stata indicata restituisce *sempre* 4 perché la sizeof, in quel caso, restituisce la "grandezza" del puntatore e non il suo numero di elementi (un puntatore da 32 bit è sempre 4 byte ...).

Quindi, funzionerà (anche se per caso) solo per buffer grandi 4 byte e non per buffer di grandezza diversa.

Per cui cambia la

Codice:
UInt16 CalcolaCRC(UInt8 d[], int lenbuffer){
    UInt16 crc=0;
    UInt16 COD;
    for(int i=0;i<lenbuffer;i++)
    {
        COD=CRC16(crc,d[i]);
        crc=COD;
    }
    
    return COD;
}
e chiamala sempre con

Codice:
UInt16 crc=CalcolaCRC(buf, sizeof(buf));
a patto che buf non sia a sua volta un puntatore passato dall'esterno.

Ultima modifica di lorenzo001 : 20-04-2012 alle 11:27.
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 11:31   #18
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
beh, buf come hai visto è il risultato di "PreparaBuffer"...questa cosa può quindi creare problemi? Ora faccio la modifica che mi hai consigliato...e ti aggiorno...

EDIT: Non funziona lo stesso...la prima volta che chiamo stopper, lo da corretto, poi sempre sbagliato...GetState succede la stessa cosa...e Posiziona mi converte male i valori...
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.

Ultima modifica di DomusP45 : 20-04-2012 alle 12:10.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 12:10   #19
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
beh, buf come hai visto è il risultato di "PreparaBuffer"...questa cosa può quindi creare problemi? Ora faccio la modifica che mi hai consigliato...e ti aggiorno...

EDIT: Non funziona lo stesso...la prima volta che chiamo stopper, lo da corretto, poi sempre sbagliato...GetState succede la stessa cosa...e Posiziona mi converte male i valori...
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 12:25   #20
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Quote:
Originariamente inviato da DomusP45 Guarda i messaggi
EDIT: Non funziona lo stesso...la prima volta che chiamo stopper, lo da corretto, poi sempre sbagliato...GetState succede la stessa cosa...e Posiziona mi converte male i valori...
In che senso "la prima volta" e in che senso "poi" ...?

Se hai fatto una modifica al codice, mostra la parte modificata e il main o il codice con cui provi il nuovo codice.

E mostra i dati ottenuti, quelli corretti e quelli sbagliati ...!
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole! realme 16 Pro Harry Potter Edition: il nuovo mid...
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce Recensione REDMI Note 17 Pro: il midrange con ba...
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema Insta360 Luna Ultra: la potenza del sensore da 1...
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
28 offerte Amazon da non perdere: e-bike...
'Il rapporto con Sony è rimasto f...
Vision AI Upscaling e Micro RGB AI Engin...
NVIDIA GeForce RTX 6000, anche il leaker...
In arrivo la 'pagella' per i datacenter:...
Celle perovskite-silicio al 34% grazie a...
Apple prepara il suo nuovo hub intellige...
La Cadillac Lyriq-V elettrica sbarca in ...
Amazon: arriva l'opzione per aggiungere ...
Un developer usa Claude Code per creare ...
Relativity Space annuncia i progressi ne...
Il nuovo Resident Evil supera ogni prece...
Hai appena sconfitto un boss e parte lo ...
Ray tracing anche senza montagne di VRAM...
TSMC prepara il processo a 1,4 nm: quatt...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 22:35.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v