problema lettura union

Ciao a tutti,
devo leggere l'header di un file bitmap da una scheda SD,
ho creato la union che segue per leggere I 54 bytes,

typedef union 
{
    struct 
    {
        //BITMAPFILEHEADER (dimensione: 14 byte)
        unsigned short bfType;         //la stringa ASCII "BM" (valore decimale 16973, esadecimale 424D)
        unsigned long bfSize;        //dimensione del file (non affidabile!)
        unsigned long bfReserved;    //0
        unsigned long bfOffBits;     //offset del primo byte della mappa dei pixel a partire dall'inizio del file

        //BITMAPINFOHEADER (dimensione: 40 byte)
        unsigned long biSize;        //dimensione in byte del blocco d'informazioni insieme alle strutture per il modello di colore aggiunte nelle versioni 4 e 5:
        unsigned long biWidth;        //larghezza dell'immagine in pixel
        long biHeight;       //Corrisponde in valore assoluto all'altezza dell'immagine in pixel:
                             //quando il valore è positivo l'immagine è bottom-up (la mappa dei pixel incomincia dalla riga di pixel più in basso e finisce con quella più in alto). Questa è la variante più comune.
                             //quando il valore è negativo l'immagine è top-down (la mappa dei pixel incomincia dalla riga di pixel più in alto e finisce con quella più in basso).
        unsigned int biPlanes;       //sempre 1
        unsigned int biBitCount;     //profondità di colore dell'immagine in bit per pixel, dev'essere uno dei seguenti valori: 1, 4, 8, 16, 24 o 32. In caso di 1, 4 o 8 bit per pixel i colori sono indicizzati. I valori 16 e 32 sono poco comuni. Nella versione 5 del formato si può usare il valore 0 quando viene incapsulata un'immagine JPEG o PNG.
        unsigned long biCompression; //dei seguenti valori: 0 (BI_RGB) La mappa dei pixel non è compressa.1 (BI_RLE8) La mappa dei pixel è compressa con l'algoritmo RLE per 8 bit per pixel. Valido solo per biBitCount = 8 e biHeight > 0.2 (BI_RLE4) La mappa dei pixel è compressa con l'algoritmo RLE per 4 bit per pixel. Valido solo per biBitCount = 4 e biHeight > 0.3 (BI_BITFIELDS) La mappa dei pixel non è compressa ed è codificata secondo maschere di colore personalizzate. Valido solo per biBitCount = 16 o 32; poco comune.
                             //Nella versione 5 del formato sono ammessi inoltre i seguenti valori:  4 (BI_JPEG) La bitmap incapsula un'immagine in formato JPEG.5 (BI_PNG) La bitmap incapsula un'immagine in formato PNG.
        unsigned long biSizeImage;   //Indica la dimensione in byte del buffer mappa dei pixel. Questo valore può essere lasciato a zero quando biCompression è impostato a BI_RGB.
        unsigned long biXPelsPerMeter;//risoluzione orizzontale del dispositivo di output in pixel per metro; 0 se la risoluzione non è specificata.
        unsigned long biYPelsPerMeter;//risoluzione verticale del dispositivo di output in pixel per metro; 0 se la risoluzione non è specificata.
        unsigned long biClrUsed;     //quando biBitCount = 1 0quando biBitCount = 4 o 8 numero di corrispondenze effettivamente utilizzate nella tavolozza dei colori; 0 indica il numero massimo (16 o 256).altrimenti numero di corrispondenze nella tavolozza dei colori (0 = nessuna tavolozza). Per profondità maggiori di 8 bit per pixel la tavolozza non è normalmente necessaria, ma quando c'è può essere usata dal sistema o da alcuni programmi per ottimizzare la rappresentazione dell'immagine.
        unsigned long biClrImportant;//quando biBitCount = 1, 4 o 8 numero di colori utilizzati nell'immagine; 0 indica tutti i colori della tavolozza.altrimentise la tavolozza esiste e contiene tutti i colori utilizzati nell'immagine numero di colorialtrimenti 0
    
    } bitmap_structure;
    byte array_structure[54];
}BM_UNION;

BM_UNION bm_union;

a questo punto leggo la struttura e la trasmetto al serial monitor col seguente codice

        //read whole bm_union.array_structure
        char numChars=myFile.read(bm_union.array_structure,54);
        char z[2]; //buffer needed by itoa
        Serial.write(itoa(numChars,z,10));  //third value is base (bin =2; dec=10)
        Serial.write(" bytes read from beginning of file.\n");

        //print all the bm_union.array_structure
        for(byte cc=0;cc<54;cc++){
          Serial.write(itoa(bm_union.array_structure[cc],z,16));  //third value is base (bin =2; dec=10)
          Serial.write(" ");
        }
        Serial.write("\n");
        Serial.write("\n");
        //type should be "BM" (hex 42 4d)
        Serial.write(itoa(bm_union.bitmap_structure.bfType,z,16));  //third value is base (bin =2; dec=10)
        Serial.write(" bfType.\n");
        //size is (hex 92 b4 0a 00)
        Serial.write(ltoa(bm_union.bitmap_structure.bfSize,z,16));  //third value is base (bin =2; dec=10)
        Serial.write(" bfSize.\n");
        //reserved is usually null (00 00 00 00)
        Serial.write(ltoa(bm_union.bitmap_structure.bfReserved,z,16));  //third value is base (bin =2; dec=10)
        Serial.write(" bfReserved.\n");
        //offset is hex 3e 00 00 00
        Serial.write(ltoa(bm_union.bitmap_structure.bfOffBits,z,16));  //third value is base (bin =2; dec=10)
        Serial.write(" bfOffBits.\n");
        //Bi size is hex 28 00 00 00
        Serial.write(ltoa(bm_union.bitmap_structure.biSize,z,16));  //third value is base (bin =2; dec=10)
        Serial.write(" biSize.\n");
        //biWidth is hex 91 0d 00 00
        Serial.write(ltoa(bm_union.bitmap_structure.biWidth,z,16));  //third value is base (bin =2; dec=10)
        Serial.write(" biWidth.\n");

quello che ottengo sul serial monitor è il seguente risultato:

54 bytes read from beginning of file.
42 4d 92 b4 a 0 0 0 0 0 3e 0 0 0 28 0 0 0 91 d 0 0 49 6 0 0 1 0 1 0 0 0 0 0 54 b4 a 0 c4 e 0 0 c4 e 0 0 0 0 0 0 0 0 0 0

4d42 bfType.
a bfSize.
3e0000 bfReserved.
280000 bfOffBits.
d910000 biSize.
6490000 biWidth.

Ora tralasciando la questione little endian noto che dopo che ha letto la prima variabile "bfType" che è di due bytes, si perde due bytes per strada (92 b4), tutto il resto delle variabili è come se fossero shiftate verso destra di due posizioni,
dove mi sono perso??
Grazie mille in anticipo

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

Mi domando l'array z è di due caratteri char z[2], ti sono sufficienti a memorizzare un valore long in esadecimale??? Se non bastano aumenta la dimensione dell'array.

torn24:
Mi domando l'array z è di due caratteri char z[2], ti sono sufficienti a memorizzare un valore long in esadecimale??? Se non bastano aumenta la dimensione dell'array.

no, non è quello il problema, e non è che sia un gran problema comunque, visto che c'é anche la questione little/big endian avevo già risolto tutti e due I problemi senza più utilizzare la union, ma facendo riferimento agli elementi dell'array per caricare I valori nelle variabili, così

unsigned int bfSize=bm_union.array_structure[2] | bm_union.array_structure[3]<<8 | bm_union.array_structure[4] <<16 | bm_union.array_structure[5] <<32;

è il porting di una porzione codice che avevo scritto per un'altra piattaforma e che problemi non me ne dava

volevo solo capire cosa non funziona qui..

grazie comunque