Writing a Bitmap File to SD Card using Teensy 3.6

Hello, I am working on some code for my senior project. I am using the teensy 3.6 and I am trying to write my own custom bitmap file to the SD card. I can initialize the card and populate .txt files with data and be able to open them on my Mac. However, when it come to writing the .bmp files, I believe I created the right header using the Windows header format and I can open up the file on my Mac, but I only get a black image. When I give the SD card to my partner on his Windows machine, it can’t even open the file. I’m stuck here, I want to write a monochrome bitmap file to a 1024 x 768 image, and I wanted to do a simple test of making half the screen black and half the screen white.

Thank you. I followed the examples found here: http://forum.arduino.cc/index.php?topic=177361.0

#include <SPI.h>
#include "SdFat.h"

// Screen size in pixels: 1024 x 768
// 8 bits per pixel

/*
  Initialize variables
*/
File myFile;
SdFatSdioEX SD;

// Signature: 'B' 'M' = 0x42, 0x4D
// Size:      786486 Bytes = 0x00, 0x0C, 0x00, 0x36
const char bmp_header[54] =
{
  0x42, 0x4D, 
  0x36, 0x00, 0x0C, 0x00, 
  0x00, 0x00, 
  0x00, 0x00, 
  0x54, 0x00, 0x00, 0x00, 
  0x40, 0x00, 0x00, 0x00, 
  0x00, 0x03, 0x00, 0x00, 
  0x00, 0x04, 0x00, 0x00, 
  0x01, 0x00, 
  0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 
  0x01, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00
};

char one = 0x01;
char zero = 0x00;

int i, j = 0;

void setup() {
  
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // Wait for USB Serial
  while (!Serial) {
    SysCall::yield();
  }

  Serial.println("Initializing SD card...");

  if (!SD.begin()) {
    Serial.println("Initialization failed!");
    return;
  } else {
    Serial.println("Initialization success!");
  }

  SD.mkdir("BitmapFiles/");

  myFile = SD.open("BitmapFiles/myBitmap.bmp", FILE_WRITE);
  if (myFile) {
    for ( i = 0; i < 54; i++) {
      char ch = bmp_header[i];
      myFile.write((uint8_t*)&ch, 1);
    }

    for (i = 0; i < 393216; i++) {
      myFile.write((uint8_t*)&zero,1);
    }
    for (i = 393216; i < 786432; i++) {
      myFile.write((uint8_t*)&one,1);
    }

    myFile.close();
  }

  Serial.println("Writing complete!");
}

void loop() {
}

Some time ago I successfully modified the example in your link to write BMP files to an SD card. Check out my code in the first post here and study the BMP file format information widely available on the WWW.

I checked it out but I think my issue is writing the image data. Since I want a monochrome bitmap, I set my color depth to 1 bit per pixel and that can be seen in my bmp header. Supposedly, a bit of 1 will be a white pixel and a bit of 0 will be a black pixel. But when I write the image data so that half the image is white and half is black, I get all black. I think it’s because I am writing more than 1 bit to my file.

byte white = 0x01;
byte black = 0x00;

for (i = 0; i < 393216; i++) {
      myFile.write(white);
}
for (i = 393216; i < 786432; i++) {
      myFile.write(black);
}

You are writing one byte per pixel which is incorrect. A monochrome BMP image stores 8 pixels per byte. For a 1024x768 image, this means that the image data will consist of a total of 1024*768/8 = 98304 bytes. When writing the image's pixel data, your code should therefore write 49152 bytes of zero (8 black pixels) and 49152 bytes of 0xFF (8 white pixels) - although the actual colour of the displayed pixel will depend upon the colour table. The colour table could specify red for a zero and green for a one.

When you have 1 bit per pixel, the header must include a colour table - I haven't checked whether your header has one.

Pete P.S. You will have to edit your BMP header to contain the correct byte count (98304).