Skip to main content
1 of 2

reading a monochromatic bitmap with arduino for plotting

Complete newbie here.

I am following this thread: How to read bitmap image on Arduino specifically the third reply from : frarugi87 in my attempt to plot a monochromatic bitmap image with a plotter device. basically: bitmap>SD card board>arduino uno> plotted image

I attempted to modify their code to work with monocromatic bitmaps and removed the print to file function:

    // MODIFIED CODE FROM BELOW CONTRIBUTOR
    
    // (c) Michael Schoeffler 2016, http://www.mschoeffler.de


    
    #include <SD.h> //Load SD library
    int chipSelect = 4; //chip select pin for the MicroSD Card Adapter
    File file; // file object that is used to read and write data

int32_t readNbytesInt(File *p_file, int position, byte nBytes)  // FUNCTION WHICH READS A DETERMINED AMMOUNT OF BYTES INTO A SINGLE VARIABLE 
{
    if (nBytes > 4)
        return 0;

    p_file->seek(position);

    int32_t weight = 1;
    int32_t result = 0;
    for (; nBytes; nBytes--)
    {
        result += weight * p_file->read();
        weight <<= 8;
    }
    return result;
}





    
    void setup() {
      Serial.begin(9600); // start serial connection to print out debug messages and data
      
      pinMode(chipSelect, OUTPUT); // chip select pin must be set to OUTPUT mode
      if (!SD.begin(chipSelect)) { // Initialize SD card
        Serial.println("Could not initialize SD card."); // if return value is false, something went wrong.
      }
      
      if (SD.exists("bitmap.bmp")) { // if "bitmap.bmp" exists, say so
        Serial.println("Found The Bitmap File.");
     
      }

      file = SD.open("bitmap.bmp", FILE_READ);   // open the file to an object for reading
      
      // DETERMINE HOW LARGE THE BITMAP FILE IS
      int howmany;
      howmany = file.available();
      Serial.println(howmany);    // print the how large the file is 


      
      // DETERMINE STARTING IMAGE ARRAY LOCATION IN THE BITMAP FILE
      int32_t dataStartingOffset = readNbytesInt(&file, 0x0A, 4); 
      Serial.println("The starting location in the fiile is...");
      Serial.println(dataStartingOffset);

      
      // DETERMINE THE IMAGE HEIGHT AND WIDTH
      int32_t imgwidth = readNbytesInt(&file, 0x12, 4);
      Serial.println("The image width is the following pixels:");
      Serial.println(imgwidth);
      int32_t imgheight = readNbytesInt(&file, 0x16, 4);
      Serial.println(imgheight);
      
      
      // MODIFIED CODE. DOES THE COLOR DEPTH LOCATION WORK IN THE BITMAP AND DOES IT GIVE CORRECT INFO ABOUT THE FILE?
      int16_t pixelsize = readNbytesInt(&file, 0X1C, 2);
      if (pixelsize != 24)
      { 
        Serial.println("This image is most definitely not 24 bpp");
        Serial.println(" it is actually a depth of :");
        Serial.println(pixelsize);
       
      }


       file.seek(dataStartingOffset);   //skip bitmap header and go directly to the image data array. 

     
     /*  for(int32_t i = 0; i < imgheight; i ++) {
        for (int32_t j = 0; j < imgwidth; j ++) {
            B = file.read();
            Serial.println("height and width location from bottom");
            Serial.println(i);
            Serial.println(j);
            Serial.println("B");
            Serial.println(B);
        }
        Serial.println("height advance");
    }


*/
      int B;

      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

            B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

        B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

            B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

            B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);


      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

      
      B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);

        B = file.read();
      Serial.println(B, BIN);
      B = file.read();
      Serial.println(B, BIN);



    file.close();
   
    Serial.println("done write");

    
    }

But when I read a 16x16 monochromatic bitmap: see below

enter image description here

at what I assume is the color table starting location (given by dataStartingOffset variable) I get strings two bytes of correct color information, followed by two bytes of just...zeros. Is this a bitmap formatting thing?

serial output for 16x16 bitmap looks like this:(only up to 9 of the 16 lines starting from the bottom)

Found The Bitmap File. 126 The starting location in the file is... 62 The image width is the following pixels: 16 16 This image is most definitely not 24 bpp it is actually a depth of : 1 1111111 11111110 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 11111111 11111111 0 0 1111111 11111110 0 0 done write

and when I try to read a bitmap that is around 200 x 200 pixels, I get very strange height and width numbers that are negative and my above code does not work at all! Does a 16x16 bitmap have different byte structure formatting than a 200x200?

any help is appreciated. again I am a complete newbie here. I am just trying to figure out how to read a bitmap.