Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Polestar 3 Performance, test drive: comodità e potenza possono convivere
Polestar 3 Performance, test drive: comodità e potenza possono convivere
Abbiamo passato diversi giorni alla guida di Polestar 3, usata in tutti i contesti. Come auto di tutti i giorni è comodissima, ma se si libera tutta la potenza è stupefacente
Qualcomm Snapdragon X2 Elite: l'architettura del SoC per i notebook del 2026
Qualcomm Snapdragon X2 Elite: l'architettura del SoC per i notebook del 2026
In occasione del proprio Architecture Deep Dive 2025 Qualcomm ha mostrato in dettaglio l'architettura della propria prossima generazione di SoC destinati ai notebook Windows for ARM di prossima generazione. Snapdragon X2 Elite si candida, con sistemi in commercio nella prima metà del 2026, a portare nuove soluzioni nel mondo dei notebook sottili con grande autonomia
Recensione DJI Mini 5 Pro: il drone C0 ultra-leggero con sensore da 1 pollice
Recensione DJI Mini 5 Pro: il drone C0 ultra-leggero con sensore da 1 pollice
DJI Mini 5 Pro porta nella serie Mini il primo sensore CMOS da 1 pollice, unendo qualità d'immagine professionale alla portabilità estrema tipica di tutti i prodotti della famiglia. È un drone C0, quindi in un peso estremamente contenuto e che non richiede patentino, propone un gimbal rotabile a 225 gradi, rilevamento ostacoli anche notturno e autonomia fino a 36 minuti. Caratteristiche che rendono il nuovo drone un riferimento per creator e appassionati
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 12-04-2012, 17: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, 20: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, 21: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, 22: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, 23: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 15:49.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 16-04-2012, 13: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, 16: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 10:10.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 18-04-2012, 12: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, 10: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, 22: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 20-04-2012, 00: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, 10: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 10:59.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 11: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, 11: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, 11: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, 11: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, 12: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 12:27.
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 12: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 13:10.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2012, 13: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, 13: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


Polestar 3 Performance, test drive: comodità e potenza possono convivere Polestar 3 Performance, test drive: comodit&agra...
Qualcomm Snapdragon X2 Elite: l'architettura del SoC per i notebook del 2026 Qualcomm Snapdragon X2 Elite: l'architettura del...
Recensione DJI Mini 5 Pro: il drone C0 ultra-leggero con sensore da 1 pollice Recensione DJI Mini 5 Pro: il drone C0 ultra-leg...
ASUS Expertbook PM3: il notebook robusto per le aziende ASUS Expertbook PM3: il notebook robusto per le ...
Test ride con Gowow Ori: elettrico e off-road vanno incredibilmente d'accordo Test ride con Gowow Ori: elettrico e off-road va...
Narwal Freo Z10 Ultra: il robot con moci...
In 3 minuti le vedete tutte: sono le mig...
Black Friday da record per Tineco: le sc...
La nuova PS5 con Fortnite manda in tilt ...
Amazon, i tagli hanno colpito soprattutt...
Pazzesco: Panasonic Lumix DC-GH5M2E a 79...
Ecco tutte le offerte Black Friday pi&ug...
DJI Neo a 169€, Flip Combo a 309€ e molt...
Quattro persone arrestate negli USA per ...
Kindle Paperwhite Signature Edition, Col...
Boom di vendite per Kindle e Fire TV Sti...
iPhone 17 Pro, il più desiderato,...
Nuovo record, 849€ per i MacBook Air con...
Wi-Fi 8 secondo Intel: la nuova era del ...
MediaWorld e il caso degli iPad Air vend...
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: 11:33.


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