Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SdFat.h>
- #include "FastLED.h"
- const uint8_t SdChipSelect = SS;
- SdFile bmpFile;
- SdFat sd;
- #define NUM_LEDS 48
- #define DAT_PIN 11
- #define CLK_PIN 12
- struct CRGB leds[NUM_LEDS];
- void setup() {
- Serial.begin(57600);
- LEDS.addLeds<LPD8806, DAT_PIN, CLK_PIN, BGR>(leds, NUM_LEDS);
- fill_solid(&(leds[0]), 48, CRGB(0, 0, 0));
- if (!sd.begin(SdChipSelect, SPI_FULL_SPEED)) {
- Serial.println("Can't open SD card!");
- while(0);
- }
- }
- void loop()
- {
- // really need to do error checking here
- // but, I digress, this was for testing only
- bmpRead("star.bmp");
- }
- void bmpRead(char *filename) {
- SdFile bmpFile;
- int bmpWidth, bmpHeight;
- uint8_t bmpDepth;
- uint8_t bmpImgOffset;
- uint32_t rowSize;
- boolean goodBmp = false;
- boolean flip = true;
- int row, col; // col unused
- uint32_t pos = 0;
- if ((bmpFile.open(filename, O_READ)) == NULL) {
- Serial.println("Can't find image file.");
- return;
- }
- // Parse BMP header
- if(read16(bmpFile) == 0x4D42) { // BMP signature
- Serial.print("File size: "); Serial.println(read32(bmpFile));
- (void)read32(bmpFile); // Read & ignore creator bytes
- bmpImgOffset = read32(bmpFile); // Start of image data
- Serial.print("Image Offset: "); Serial.println(bmpImgOffset, DEC);
- // Read DIB header
- Serial.print("Header size: "); Serial.println(read32(bmpFile));
- bmpWidth = read32(bmpFile);
- bmpHeight = read32(bmpFile);
- if(read16(bmpFile) == 1) { // # planes -- must be '1'
- bmpDepth = read16(bmpFile); // bits per pixel
- Serial.print("Bit Depth: "); Serial.println(bmpDepth);
- if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
- goodBmp = true; // Supported BMP format -- proceed!
- Serial.print("Image size: "); Serial.print(bmpWidth);
- Serial.print('x'); Serial.println(bmpHeight);
- // BMP rows are padded (if needed) to 4-byte boundary
- rowSize = (bmpWidth * 3 + 3) & ~3;
- // If bmpHeight is negative, image is in top-down order.
- // This is not canon but has been observed in the wild.
- if(bmpHeight < 0) {
- bmpHeight = -bmpHeight;
- flip = false;
- }
- // spit image out to leds array
- for (row = 0; row < bmpHeight; row++) {
- if (flip) { // normal BMP, stored bottom-to-top
- pos = bmpImgOffset + (bmpHeight - 1 - row) * rowSize;
- } else { // drunk BMP, stored top-to-bottom
- pos = bmpImgOffset + row * rowSize;
- }
- bmpFile.seekSet(pos);
- bmpFile.read((char*)leds, NUM_LEDS * 3);
- LEDS.show();
- delay(100); // slowed way down so I can see what it's
- // displaying without needing to constantly
- // be waving the thing like crazy.
- }
- } // end goodBmp
- }
- }
- bmpFile.close();
- if(!goodBmp) Serial.println("BMP format not recognized.");
- }
- // These read 16- and 32-bit types from the SD card file.
- // BMP data is stored little-endian, Arduino is little-endian too.
- // May need to reverse subscript order if porting elsewhere.
- uint16_t read16(SdFile f) {
- uint16_t result;
- ((uint8_t *)&result)[0] = f.read(); // LSB
- ((uint8_t *)&result)[1] = f.read(); // MSB
- Serial.print("read16() result: ");
- Serial.println(result, HEX);
- return result;
- }
- uint32_t read32(SdFile f) {
- uint32_t result;
- ((uint8_t *)&result)[0] = f.read(); // LSB
- ((uint8_t *)&result)[1] = f.read();
- ((uint8_t *)&result)[2] = f.read();
- ((uint8_t *)&result)[3] = f.read(); // MSB
- Serial.print("read32() result: ");
- Serial.println(result, HEX);
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment