Hello!
This is my first arduino project and i’m trying to build a pov stick that displays bitmaps stored in a micro sd card.
I got stucked when i tried to store the bitmap into a global variable, maybe its a memory issue, but i don’t really know, i come from C# web development
If i read the bitmap in every blink the pov effect is not achieved because of the delay on reading the file, that’s why i need to store the data in a memory for a faster displaying.
This is the code (the commented lines are my try with the pointer thing
I'm using arduino nano:
#include <SD.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel _strip;
const uint8_t STRIP_PIN = 2;
const uint8_t STRIP_LEDS = 32;
const uint8_t SD_CHIP_PIN = 4;
const uint8_t BLINK_DELAY = 1;
int16_t _currentImageMapWidth = -1;
int16_t _currentImageMapHeight = -1;
int16_t _currentImageMapColumnIndex = -1;
bool _loadNextImage = true;
//uint32_t *_currentImageData;
void setup() {
Serial.begin(9600);
while (!Serial) {}
loadSDCard();
loadLedStrip();
}
void loop() {
if(_loadNextImage){
loadNextImage();
} else {
loadNextImage();
//processCurrentImage();
}
}
void loadSDCard(){
Serial.print("Initializing SD card...");
if (!SD.begin(SD_CHIP_PIN)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
}
void loadLedStrip(){
_strip = Adafruit_NeoPixel(STRIP_LEDS, STRIP_PIN, NEO_GRB + NEO_KHZ800);
_strip.begin();
_strip.setBrightness(200);
_strip.show();
}
void loadNextImage(){
File bmpImage = SD.open("test.bmp");
if(bmpImage)
{
byte dataStartingOffset = readNbytesInt(&bmpImage, 0x0A, 4);
int16_t width = readNbytesInt(&bmpImage, 0x12, 4);
int16_t height = readNbytesInt(&bmpImage, 0x16, 4);
byte pixelsize = readNbytesInt(&bmpImage, 0x1C, 2);
_currentImageMapWidth = height;
_currentImageMapHeight = width;
_strip.clear();
_strip.show();
if(_loadNextImage){
_currentImageMapColumnIndex = 0;
} else {
_currentImageMapColumnIndex++;
if(_currentImageMapColumnIndex >= _currentImageMapWidth){
_currentImageMapColumnIndex = 0;
}
}
if(pixelsize == 24){// three bytes per pixel
bmpImage.seek(dataStartingOffset);//skip bitmap header
byte R, G, B;
//_currentImageData = new uint8_t[width * height];
//if(_currentImageData){
int byteIndex = 0;
for(int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
B = bmpImage.read();
G = bmpImage.read();
R = bmpImage.read();
//_currentImageData[byteIndex] = _strip.Color(R, G, B);
byteIndex++;
if(_currentImageMapColumnIndex == x){
setPixel(y, _strip.Color(R, G, B));
}
}
}
_strip.show();
//} else {
// Serial.println("Not enough memory??????");
//}
delay(BLINK_DELAY);
_loadNextImage = false;
}
bmpImage.close();
}
else
{
Serial.println("unable to open image");
}
}
void processCurrentImage(){
Serial.println("reading current Image");
_currentImageMapColumnIndex++;
if(_currentImageMapColumnIndex >= _currentImageMapWidth){
_currentImageMapColumnIndex = 0;
}
_strip.clear();
_strip.show();
// for(int y = 0; y < sizeof(_currentImageData); y++){
// for(int x = 0 ; x < _currentImageMapWidth ; x++){
// if(_currentImageMapColumnIndex == x){
// setPixel(y, _currentImageData[y * x]);
// }
// }
// }
_strip.show();
delay(BLINK_DELAY);
}
void setPixel(uint16_t pixel, uint32_t color) {
_strip.setPixelColor(pixel, color);
}
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;
}
Thanks in advance
Jonathan