bmp to led strip

Hi!

I am using a sketch that send color information from a bmp file to a led strip. This sketch uses 1 bmp file, and I would like to use 3 different bmp files to send it to 3 different led strips. We started to modify the code in order to achieve this, but we got stuck in the way.

the original code is as follows:

#include <Adafruit_NeoPixel.h>
#include <SD.h>
#include <SPI.h>

#define SDssPin 53    //arduino mega

int NPPin = 23;       //arduino mega 

int ColorSeq = NEO_GRB;

int BitstreamFreq = NEO_KHZ400;     //ws2811

int g = 0;
int b = 0;
int r = 0;

#define STRIP_LENGTH 75

int frameDelay = 10;
int brightness = 100;

byte x;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIP_LENGTH, NPPin, ColorSeq + BitstreamFreq);

File dataFile;


void setup() {
  strip.begin();
  strip.show();
  setupSDcard();
}


void loop() {
  SendFile("set01.bmp");
}


void setupSDcard() {
  pinMode(SDssPin, OUTPUT);
  while (!SD.begin(SDssPin)) {
  }
}


void SendFile(String Filename) {
  char temp[14];
  Filename.toCharArray(temp, 14);

  dataFile = SD.open(temp);

  if (dataFile) {
    ReadTheFile();
    dataFile.close();
  }
  else {
    delay(1000);
    setupSDcard();
    return;
  }
}


uint32_t readLong() {
  uint32_t retValue;
  byte incomingbyte;

  incomingbyte = readByte();
  retValue = (uint32_t)((byte)incomingbyte);

  incomingbyte = readByte();
  retValue += (uint32_t)((byte)incomingbyte) << 8;

  incomingbyte = readByte();
  retValue += (uint32_t)((byte)incomingbyte) << 16;

  incomingbyte = readByte();
  retValue += (uint32_t)((byte)incomingbyte) << 24;

  return retValue;
}


uint16_t readInt() {
  byte incomingbyte;
  uint16_t retValue;

  incomingbyte = readByte();
  retValue += (uint16_t)((byte)incomingbyte);

  incomingbyte = readByte();
  retValue += (uint16_t)((byte)incomingbyte) << 8;

  return retValue;
}


int readByte() {
  int retbyte = -1;
  while (retbyte < 0) retbyte = dataFile.read();
  return retbyte;
}


void getRGBwithGamma() {
  g = gamma(readByte()) / (101 - brightness);
  b = gamma(readByte()) / (101 - brightness);
  r = gamma(readByte()) / (101 - brightness);
}


void ReadTheFile() {
#define MYBMP_BF_TYPE           0x4D42
#define MYBMP_BF_OFF_BITS       54
#define MYBMP_BI_SIZE           40
#define MYBMP_BI_RGB            0L
#define MYBMP_BI_RLE8           1L
#define MYBMP_BI_RLE4           2L
#define MYBMP_BI_BITFIELDS      3L

  uint16_t bmpType = readInt();
  uint32_t bmpSize = readLong();
  uint16_t bmpReserved1 = readInt();
  uint16_t bmpReserved2 = readInt();
  uint32_t bmpOffBits = readLong();
  bmpOffBits = 54;

  /* Check file header */
  if (bmpType != MYBMP_BF_TYPE || bmpOffBits != MYBMP_BF_OFF_BITS) {
    delay(1000);
    return;
  }

  /* Read info header */
  uint32_t imgSize = readLong();
  uint32_t imgWidth = readLong();
  uint32_t imgHeight = readLong();
  uint16_t imgPlanes = readInt();
  uint16_t imgBitCount = readInt();
  uint32_t imgCompression = readLong();
  uint32_t imgSizeImage = readLong();
  uint32_t imgXPelsPerMeter = readLong();
  uint32_t imgYPelsPerMeter = readLong();
  uint32_t imgClrUsed = readLong();
  uint32_t imgClrImportant = readLong();

  /* Check info header */
  if ( imgSize != MYBMP_BI_SIZE || imgWidth <= 0 ||
       imgHeight <= 0 || imgPlanes != 1 ||
       imgBitCount != 24 || imgCompression != MYBMP_BI_RGB ||
       imgSizeImage == 0 )
  {
    delay(1000);
    return;
  }

  int displayWidth = imgWidth;
  if (imgWidth > STRIP_LENGTH) {
    displayWidth = STRIP_LENGTH;
  }


  /* compute the line length */
  uint32_t lineLength = imgWidth * 3;
  if ((lineLength % 4) != 0)
    lineLength = (lineLength / 4 + 1) * 4;


  // Note:
  // The x,r,b,g sequence below might need to be changed if your strip is displaying
  // incorrect colors.  Some strips use an x,r,b,g sequence and some use x,r,g,b
  // Change the order if needed to make the colors correct.

  for (int y = imgHeight; y > 0; y--) {
    int bufpos = 0;
    for (int x = 0; x < displayWidth; x++) {
      uint32_t offset = (MYBMP_BF_OFF_BITS + (((y - 1) * lineLength) + (x * 3))) ;
      dataFile.seek(offset);

      getRGBwithGamma();

      strip.setPixelColor(x, r, b, g);

    }
  strip.show();
  delay(frameDelay);
  }
}


PROGMEM const char gammaTable[]  = {
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,
  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,
  4,  4,  4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  7,  7,
  7,  7,  7,  8,  8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11,
  11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16,
  16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22,
  23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30,
  30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 39,
  40, 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 50,
  50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 58, 58, 59, 60, 61, 62,
  62, 63, 64, 65, 66, 67, 67, 68, 69, 70, 71, 72, 73, 74, 74, 75,
  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108,
  109, 110, 111, 113, 114, 115, 116, 117, 118, 120, 121, 122, 123, 125, 126, 127
};


inline byte gamma(byte x) {
  return pgm_read_byte(&gammaTable[x]);
}

continues in #2

and our attempt goes like this:

#include <Adafruit_NeoPixel.h>
#include <SD.h>
#include <SPI.h>

#define SDssPin 53    //arduino mega

int NPPin1 = 2;                          
int NPPin2 = 3;
int NPPin3 = 4;

int ColorSeq = NEO_GRB;

int BitstreamFreq = NEO_KHZ400;     //ws2811

int g = 0;
int b = 0;
int r = 0;

#define STRIP_LENGTH 75

int frameDelay = 10;
int brightness = 100;

byte x;

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(STRIP_LENGTH, NPPin1, ColorSeq + BitstreamFreq);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(STRIP_LENGTH, NPPin2, ColorSeq + BitstreamFreq);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(STRIP_LENGTH, NPPin3, ColorSeq + BitstreamFreq);

File dataFile[3];


void setup() {
  setupLEDs();
  setupSDcard();
  Serial.begin(9600);
}


void loop() {
  SendFile("set01.bmp","set02.bmp","set03.bmp");
}

void setupLEDs() {
  strip1.begin();
  strip1.show();
  strip2.begin();
  strip2.show();
  strip3.begin();
  strip3.show();
}

void setupSDcard() {
  pinMode(SDssPin, OUTPUT);
  while (!SD.begin(SDssPin)) {
  }
}


void SendFile(String Filename1,String Filename2,String Filename3) {
  char temp1[14];
  Filename1.toCharArray(temp1,14);
  char temp2[14];
  Filename2.toCharArray(temp2,14);
  char temp3[14];
  Filename3.toCharArray(temp3,14);
     
  dataFile[0] = SD.open(temp1);
  dataFile[1] = SD.open(temp2);
  dataFile[2] = SD.open(temp3);
     
  if (dataFile[0]&&dataFile[1]&&dataFile[2]) {
    ReadTheFiles();
    dataFile[0].close();
    dataFile[1].close();
    dataFile[2].close();
  }  
  else {
    delay(1000);
    setupSDcard();
    return;
    }
}


uint32_t readLong(byte strip) {
  uint32_t retValue;
  byte incomingbyte;
     
  incomingbyte=readByte(strip);
  retValue=(uint32_t)((byte)incomingbyte);
     
  incomingbyte=readByte(strip);
  retValue+=(uint32_t)((byte)incomingbyte)<<8;
     
  incomingbyte=readByte(strip);
  retValue+=(uint32_t)((byte)incomingbyte)<<16;
     
  incomingbyte=readByte(strip);
  retValue+=(uint32_t)((byte)incomingbyte)<<24;
     
  return retValue;
}



uint16_t readInt(byte strip) {
  byte incomingbyte;
  uint16_t retValue;
     
  incomingbyte=readByte(strip);
  retValue+=(uint16_t)((byte)incomingbyte);
     
  incomingbyte=readByte(strip);
  retValue+=(uint16_t)((byte)incomingbyte)<<8;
     
  return retValue;
}


int readByte(byte strip) {
  int retbyte=-1;
  while(retbyte<0) retbyte= dataFile[strip].read();
  return retbyte;
}


void getRGBwithGamma(byte strip) {
  g=gamma(readByte(strip))/(101-brightness);
  b=gamma(readByte(strip))/(101-brightness);
  r=gamma(readByte(strip))/(101-brightness);
}


void ReadTheFiles() {
  #define MYBMP_BF_TYPE           0x4D42
  #define MYBMP_BF_OFF_BITS       54
  #define MYBMP_BI_SIZE           40
  #define MYBMP_BI_RGB            0L
  #define MYBMP_BI_RLE8           1L
  #define MYBMP_BI_RLE4           2L
  #define MYBMP_BI_BITFIELDS      3L

  uint16_t bmpType[3];
  uint32_t bmpSize[3];
  uint16_t bmpReserved1[3];
  uint16_t bmpReserved2[3];
  uint32_t bmpOffBits[3];
  
  for(int strip = 0; strip < 3; strip++){
    bmpType[strip] = readInt(strip);
    bmpSize[strip] = readLong(strip);
    bmpReserved1[strip] = readInt(strip);
    bmpReserved2[strip] = readInt(strip);
    bmpOffBits[strip] = readLong(strip);
  }
  
  bmpOffBits[0] = 54;bmpOffBits[1] = 54;bmpOffBits[2] = 54;

  for(int strip = 0; strip < 3; strip++){
  /* Check file header */
    if (bmpType[strip] != MYBMP_BF_TYPE || bmpOffBits[strip] != MYBMP_BF_OFF_BITS) {
      delay(1000);
      return;
    }
  }

  /* Read info header */
    uint32_t imgSize[3];
    uint32_t imgWidth[3];
    uint32_t imgHeight[3];
    uint16_t imgPlanes[3];
    uint16_t imgBitCount[3];
    uint32_t imgCompression[3];
    uint32_t imgSizeImage[3];
    uint32_t imgXPelsPerMeter[3];
    uint32_t imgYPelsPerMeter[3];
    uint32_t imgClrUsed[3];
    uint32_t imgClrImportant[3];
  
  for(int strip = 0; strip < 3; strip++){  
    /* Read info header */
    imgSize[strip] = readLong(strip);
    imgWidth[strip] = readLong(strip);
    imgHeight[strip] = readLong(strip);
    imgPlanes[strip] = readInt(strip);
    imgBitCount[strip] = readInt(strip);
    imgCompression[strip] = readLong(strip);
    imgSizeImage[strip] = readLong(strip);
    imgXPelsPerMeter[strip] = readLong(strip);
    imgYPelsPerMeter[strip] = readLong(strip);
    imgClrUsed[strip] = readLong(strip);
    imgClrImportant[strip] = readLong(strip);
  }
  for(int strip = 0; strip < 3; strip++){
    /* Check info header */
    if( imgSize[strip] != MYBMP_BI_SIZE || imgWidth[strip] <= 0 ||
      imgHeight[strip] <= 0 || imgPlanes[strip] != 1 ||
      imgBitCount[strip] != 24 || imgCompression[strip] != MYBMP_BI_RGB ||
      imgSizeImage[strip] == 0 )
      {
      delay(1000);
      return;
      }
  }
  int displayWidth[3]; 
  for(int strip = 0; strip < 3; strip++){
    displayWidth[strip] = imgWidth[strip];
    if (imgWidth[strip] > STRIP_LENGTH) {
      displayWidth[strip] = STRIP_LENGTH;           
    }
  }
  
  uint32_t lineLength[3];
  for(int strip = 0; strip < 3; strip++){
    /* compute the line length */
    lineLength[strip] = imgWidth[strip] * 3;
    if ((lineLength[strip] % 4) != 0)
      lineLength[strip] = (lineLength[strip] / 4 + 1) * 4;
  }  
  

    // Note:  
    // The x,r,b,g sequence below might need to be changed if your strip is displaying
    // incorrect colors.  Some strips use an x,r,b,g sequence and some use x,r,g,b
    // Change the order if needed to make the colors correct.
    
    for(int y=imgHeight[0]; y > 0; y--) {
      int bufpos=0;    
      for(int x=0; x < displayWidth[0]; x++) {
        uint32_t offset1 = (MYBMP_BF_OFF_BITS + (((y-1)* lineLength[0]) + (x*3))) ;
        uint32_t offset2 = (MYBMP_BF_OFF_BITS + (((y-1)* lineLength[1]) + (x*3))) ;
        uint32_t offset3 = (MYBMP_BF_OFF_BITS + (((y-1)* lineLength[2]) + (x*3))) ;
    
        dataFile[0].seek(offset1);
        dataFile[1].seek(offset2);
        dataFile[2].seek(offset3);

        getRGBwithGamma(0);
        strip1.setPixelColor(x,r,b,g);
        getRGBwithGamma(1);
        strip2.setPixelColor(x,r,b,g);
        getRGBwithGamma(2);
        strip3.setPixelColor(x,r,b,g);
      }
    }
  }


PROGMEM const char gammaTable[]  = {
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,
  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,
  4,  4,  4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  7,  7,
  7,  7,  7,  8,  8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11,
  11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16,
  16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22,
  23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30,
  30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 39,
  40, 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 50,
  50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 58, 58, 59, 60, 61, 62,
  62, 63, 64, 65, 66, 67, 67, 68, 69, 70, 71, 72, 73, 74, 74, 75,
  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108,
  109, 110, 111, 113, 114, 115, 116, 117, 118, 120, 121, 122, 123, 125, 126, 127
};


inline byte gamma(byte x) {
  return pgm_read_byte(&gammaTable[x]);
}

The problem seems to be in the readByte and ReadTheFiles functions. Perhaps somebody sees the mistake?

thanks!

It would be easier to assist if you told us what "the problem" is and why it "seems to be in the readByte and ReadTheFiles functions." Are you getting error messages? What do they say? What wrong behavior is the sketch exhibiting?

sorry…

the problem is that, it doesnt work.

no compilation errors, it simply doesnt do what it should

the reason why we think the problem is in the readByte and ReadTheFiles functions is because we did some print in before those functions and we got to see the messages correctly in the serial monitor

Can you actually have three files open at the same time?
Which processor are you using?

Can you actually have three files open at the same time?

I dont know

Which processor are you using?

Arduino Mega 2560

The library website says that you can open more than one file at the time, but we also found information in the forum about cases where it didnt work.

Nevertheless, we also found another library (SdFat) which should open more than one file at the time, and I tried it out, but it still doesnt work, so I suppose the library is not the problem...

sorted out

there was a missing part of the code in the function Read Bytes

    strip1.show();
    delay(frameDelay);
    strip2.show();
    delay(frameDelay);
    strip3.show();
    delay(frameDelay);

the program works ok with both the SD library from arduino and the SdFat library.

:smiley: