#include <SD.h>
#include <WS2812Serial.h>
//----------set the three below------//
const int ledsPerStrip = 256;
const int pin = 1;
#define imageHeight 16
#define imageWidth 16
DMAMEM int displayMemory[ledsPerStrip * 6];
int drawingMemory[ledsPerStrip * 6];
const int config = WS2812_GRB;
WS2812Serial leds(ledsPerStrip, displayMemory, drawingMemory, pin, config);
#define RED 0x0000ff
const int chipSelect = BUILTIN_SDCARD;
//buffer to hold pixel data. remains size of pixel number//
const int ARRAY_SIZE = imageHeight * imageWidth;
const int byteBuffSize = ARRAY_SIZE * 3;
byte pixelBUFFER[byteBuffSize];
byte ArrayB[ARRAY_SIZE];
byte ArrayR[ARRAY_SIZE];
byte ArrayG[ARRAY_SIZE];
/////////////////////
void setup(void) {
Serial.begin(9600);
leds.begin();
leds.show();
// if you dont get all leds lighting then going off, check your wiring
Serial.println("init");
delay(500);
Serial.print("Initializing SD card…");
if (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("SD OK!");
}
//////////////////////////////////
void loop() {
bmpDraw("rgb.bmp");
delay(1000);
//do a colour wipe to set all leds to red
for (int i = 0; i < leds.numPixels(); i++) {
leds.setPixel(i, RED);
leds.show();
delay(5);
}
}
//////////////////////////////////////////////
int32_t readNbytesInt(File *p_file, int position, byte nBytes)
{
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 bmpDraw( char* fileName)
{
// Open file
File bmpImage = SD.open(fileName, FILE_READ);
int32_t dataStartingOffset = readNbytesInt(&bmpImage, 0x0A, 4);
// Change their types to int32_t (4byte)
int32_t width = readNbytesInt(&bmpImage, 0x12, 4); //0x12 - dec18
int32_t height = readNbytesInt(&bmpImage, 0x16, 4); //0x16 - dec22
int32_t ImgSize = readNbytesInt(&bmpImage, 0x22, 4); //-dec34
Serial.println(width);
Serial.println(height);
Serial.println(ImgSize);
int16_t pixelsize = readNbytesInt(&bmpImage, 0x1C, 2);
if (pixelsize != 24)
{
Serial.println("Image is not 24 bpp");
while (1);
}
bmpImage.seek(dataStartingOffset);//skip bitmap header
byte R, G, B;
for (int i = 0; i < ARRAY_SIZE; i++) {
ArrayB[i] = bmpImage.read();
ArrayG[i] = bmpImage.read();
ArrayR[i] = bmpImage.read();
}
bmpImage.close();
Serial.println("done writing to Buffer");
// Test
uint32_t ledCount = 0;
uint32_t ledLocation = 0;
for (int y = 0; y < imageHeight; y++) { //for each row
for (int x = 0; x < imageWidth; x++) { //go through each coloumn
//use the & bitwise method to see if an odd or even row, we start rows at zero, so if row is odd, we go backwards
if ( y & 0x01) {
ledLocation = (y * imageWidth) + ((imageWidth - 1) - x);
} else {
// Even rows go forwards
ledLocation = (y * imageWidth) + x;
}
//set the pixel at ledLocation with the next colour in the colour array
leds.setPixel(ledLocation, Color(ArrayR[ledCount], ArrayG[ledCount], ArrayB[ledCount]));
//move on the colour array location by one.
ledCount = ledCount + 1;
}
}
leds.show();
// int ledCount =0;
// for(int i=0; i<width*height;i++){
// leds.setPixel(ledCount,Color(ArrayB[i],ArrayG[i],ArrayR[i]));
// ledCount = ledCount+1;
// }
// leds.show();
}
//------- HELPER FUNCTION------//
// Create a 24 bit color value from R,G,B ////these strips are BGR, but you might need to change this
unsigned int Color(byte g, byte b, byte r)
{
//Take the lowest 8 bits of each value and append them end to end
return ( ((unsigned int)g & 0x1F ) << 16 | ((unsigned int)r & 0x1F) << 8 | (unsigned int)b & 0x1F);
}
//end of helper function