LED Matrix missing Code

plumped

Member
Good evening all!

I have been working in C for a while now to get my LED matrix up and running by christmas. Nevertheless the board doesn't want to show me a bmp file anymore. Did I forget something in the code?
@Mortemkopf was already a huge help for me with the basics and his older code "OctobmpPOVfromSD".

https://codeshare.io/zy7DP7


I would be infinitely grateful if someone could contribute the final tip so that I can finally pack the thing :D

BR & Have a good one
 
Probably obvious, but did you open the Arduino serial monitor?
Code:
  while (!Serial) {
    yield();
  }

Paul
 
First, try running File > Examples > SD > listfiles, just to check that your SD card really is working and has the BMP file. Not much point digging into the details if the problem is as "simple" as the SD card not detected or not having the file.

Then, a few questions. Which Teensy are you using? Which version of Arduino & Teensyduino do you have installed? (click Help > About to check) Can you share the BMP file, so I or anyone else here could try to reproduce the problem?
 
First, try running File > Examples > SD > listfiles, just to check that your SD card really is working and has the BMP file. Not much point digging into the details if the problem is as "simple" as the SD card not detected or not having the file.

Then, a few questions. Which Teensy are you using? Which version of Arduino & Teensyduino do you have installed? (click Help > About to check) Can you share the BMP file, so I or anyone else here could try to reproduce the problem?


Hi Paul and thank you for your feedback.

"listfiles" is running as expected with no failures.
Screenshot 2021-12-01 233018.jpg

Im using Teensy 4.1 with Arduino 1.8.13 & Teensyduino 1.55

As files I use for example this kind of files: View attachment 2.bmpView attachment 1.bmpView attachment 0.bmp

Of course with the correct naming while using in the code
 
Hi, I don't recognise chunks of the code you posted. Do you get the serial monitor print statements from the drawbmp functions. Also, I can't see anywhere where the programme sets the leds, whether its leds.show() or whatever. Perhaps i missed it. So, SD can be read, so that can be discounted, leds can be display a general pattern or show that they can be lit?
 
Hi, I don't recognise chunks of the code you posted. Do you get the serial monitor print statements from the drawbmp functions. Also, I can't see anywhere where the programme sets the leds, whether its leds.show() or whatever. Perhaps i missed it. So, SD can be read, so that can be discounted, leds can be display a general pattern or show that they can be lit?

Hi Morton

I am still completely new to the field :) I do not quite understand what you mean. The one with the leds.show() makes sense to me. that was missing but still is not working.

SD card is readable and the LEDs are able to lit (in other programs like "rainbow" or "fire"). On the hardware side, everything should be correct. However, I am not familiar with C programming at all. which is why I turned to you. As is well known, one learns best from mistakes :-D


I'm not sure if I can render this as it is currently with OctoWS2811 or if I need to use some special formatting here (write pixel).
 
Hi, we all have to learn, and hopefully are still doing so. Exactly which test (rainbow / fire / etc) worked with your leds? under the teensyduino file menu > examples (Fastled or octows2811 or other)? from the above, I assume that you are using ws2811 leds.

Also, did you get the serial print statements show up from the drawbmp function?
 
All the examples under Examples<OctoWS2811<Rainbow are working.
Im using WS2812B (neopixel) but they are working correctly with the WS2811 library

I get the following serial print statements as output from serial:

Code:
-=Loading image 'tee.bmp'
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
Image size: 16x16
File size: 824
.
.
.
 
your code in post #1 never calls the leds to show their colour status, even if the colour status is updated from the buffer. also, in that code (which isn't mine), there are a bunch of other issues related to image size buffers, have a scan through the code placed on this thread post number 27: https://forum.pjrc.com/threads/54440-Bitmap-with-Teensy3-5/page2

dont forget to set the size parameters for your image / led number

That code clearly has the call to update and show the leds, and also sets out an example to light up the leds with a pattern, and also has some serial output to check where the programme is falling over. You call comment out or add in serial prints to help debug.
 
your code in post #1 never calls the leds to show their colour status, even if the colour status is updated from the buffer. also, in that code (which isn't mine), there are a bunch of other issues related to image size buffers, have a scan through the code placed on this thread post number 27: https://forum.pjrc.com/threads/54440-Bitmap-with-Teensy3-5/page2

dont forget to set the size parameters for your image / led number

That code clearly has the call to update and show the leds, and also sets out an example to light up the leds with a pattern, and also has some serial output to check where the programme is falling over. You call comment out or add in serial prints to help debug.


Hi Mortom, I finally found time to test this and it helped me a lot! I have now additionally noticed that I am missing power accordingly and the colors drift off..
Therefore, I ordered a sufficient power supply and am still waiting for delivery. But the bpm is successfully displayed with your snippet!
 
glad you got the BMP showing with the 'real' code. not sure where your original code came from, but whatever the case, you need to break it down into smaller parts and check the flow, otherwise its just garbage and you wont be able to leverage it to make your own project work how you want it to work.
 
glad you got the BMP showing with the 'real' code. not sure where your original code came from, but whatever the case, you need to break it down into smaller parts and check the flow, otherwise its just garbage and you wont be able to leverage it to make your own project work how you want it to work.


Hi Morton!

I have received my powersupply which is now working brilliant. One last thing is the LED coloring. WS2811_GRB is the correct setting if i try to calibrate with your code snipped

Code:
//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);
  }

Means red/green/blue are shown correctly when i change the hexcode in
Code:
#define RED    0x0000ff

Anyhow, if I load up a bmp file, the colors are completely messed up. Not sure if it has to do with your

Code:
//------- 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 r, byte b, byte g)
{

But i have tried different settings with no success.

This is my calibration picture, i never get black (off) and white for the face "contures"

View attachment 0.bmp

Any idea? I think there is something mixing up in your code from your first post here, isnt it?

Teensy 4.1
WS2812B
5V
 
hi, so easiest way to get the colours sorts is to load a bmp that has three sections, one each of R,G and B, so that you can focus in on things. The priority would be to set the set the LEDs call "WS2811_whatever" to the description on what you bought, and then set the defines to that order. then test your RGB blocks image, and reorder the helper function.

Another way is to run the colour wipe test routine for #define RED 0x0000ff, but move the ff value to the location of R that the seller states is the order of R and G and B. if leds are RGB, then try 0xff0000
 
hi, so easiest way to get the colours sorts is to load a bmp that has three sections, one each of R,G and B, so that you can focus in on things. The priority would be to set the set the LEDs call "WS2811_whatever" to the description on what you bought, and then set the defines to that order. then test your RGB blocks image, and reorder the helper function.

Another way is to run the colour wipe test routine for #define RED 0x0000ff, but move the ff value to the location of R that the seller states is the order of R and G and B. if leds are RGB, then try 0xff0000

Hi Morton & thank you so much for your inputs!

I have created a template with all needed colors (plus indicator 2 white squares for rotation control)
Screenshot 2021-12-08 232754.jpg

After calibration the output looks like this:
RGB.jpg

Looks okay!!

But then i open up a normal bmp for example this one:
View attachment 0.bmp

Screenshot 2021-12-08 234746.jpg
First: rotated 90 degrees counterclockwise and looks like this :rolleyes: ;)

colors are completely messed


Screenshot 2021-12-08 234647.jpg



So how the hell is that happening?



Actual code:

Code:
#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
 
Last edited:
that is odd. The four colour test BMP file comes out correct, but the next BMP file doesn't. Both files were formatted to the same BMP type, 24bit?
 
that is odd. The four colour test BMP file comes out correct, but the next BMP file doesn't. Both files were formatted to the same BMP type, 24bit?

Yes they are the same (i have recreated both the same way).
details.jpg

And this is a new try with a Bird:
Screenshot 2021-12-09 114312.jpg

Results in:
IMG_0338.jpg

what strikes me immediately, the image is mirrored vertically... Could it be related to this?
 

Attachments

  • 0.bmp
    824 bytes · Views: 46
confusing, and i am really not sure why this is happening. It certainly looks like for the non test image (bird) the line leds.setPixel(ledLocation, Color(ArrayR[ledCount], ArrayG[ledCount], ArrayB[ledCount]));
should have the colour values in a different order. In your image of the leds, red image comes out as blue, and blue comes out as green. might be worth a quick swap test like this:
leds.setPixel(ledLocation, Color(ArrayG[ledCount], ArrayB[ledCount], ArrayR[ledCount]));

for the rotation of the pixels, you could use an array to hold the reference pixel location, and reference that. so instead of using

Code:
  for (int i = 0; i < ARRAY_SIZE; i++) {
    ArrayB[i] = bmpImage.read();
    ArrayG[i] = bmpImage.read();
    ArrayR[i] = bmpImage.read();
  }

you would reference an array of pixel locations that are offset by the rotation and flipped. Flipping could be done by filling the array in reverse:
Code:
  for (int i = ARRAY_SIZE; i >0; i--) {
    ArrayB[i] = bmpImage.read();
    ArrayG[i] = bmpImage.read();
    ArrayR[i] = bmpImage.read();
  }

but you still need to shift them around on the rotation. relocating pixels can be done by using a reference array, such that when you say to put the colour data for Red into the ArrayR[] array at location i, you can change that to say put it at location myRealLocations like this ArrayR[ myRealLocations ]. in the array myRealLocations[] you just write out the real locations of the pixels. This can also be done in maths, where locatoin of pixel 15 is actual the nth led on the grid.

However, there seems to be something fundamentally odd, and this feels like a lash up really.
 
confusing, and i am really not sure why this is happening. It certainly looks like for the non test image (bird) the line leds.setPixel(ledLocation, Color(ArrayR[ledCount], ArrayG[ledCount], ArrayB[ledCount]));
should have the colour values in a different order. In your image of the leds, red image comes out as blue, and blue comes out as green. might be worth a quick swap test like this:
leds.setPixel(ledLocation, Color(ArrayG[ledCount], ArrayB[ledCount], ArrayR[ledCount]));

for the rotation of the pixels, you could use an array to hold the reference pixel location, and reference that. so instead of using

Code:
  for (int i = 0; i < ARRAY_SIZE; i++) {
    ArrayB[i] = bmpImage.read();
    ArrayG[i] = bmpImage.read();
    ArrayR[i] = bmpImage.read();
  }

you would reference an array of pixel locations that are offset by the rotation and flipped. Flipping could be done by filling the array in reverse:
Code:
  for (int i = ARRAY_SIZE; i >0; i--) {
    ArrayB[i] = bmpImage.read();
    ArrayG[i] = bmpImage.read();
    ArrayR[i] = bmpImage.read();
  }

but you still need to shift them around on the rotation. relocating pixels can be done by using a reference array, such that when you say to put the colour data for Red into the ArrayR[] array at location i, you can change that to say put it at location myRealLocations like this ArrayR[ myRealLocations ]. in the array myRealLocations[] you just write out the real locations of the pixels. This can also be done in maths, where locatoin of pixel 15 is actual the nth led on the grid.

However, there seems to be something fundamentally odd, and this feels like a lash up really.


I will try the rotation thing of course and the quick swap test!

Im using #include <WS2812Serial.h> atm. Could that issue any problem or is there something known? Do i have to focus on something special here about the settings? I use Teensy 4.1 with WS2812b pixels. Maybe there is some known Problem?

@PaulStoffregen maybe any Idea about this combination? (hope this is the right method to mention someone)
 
no, it should not be anything to do with ws2812serial. its probably just a bit of adjusting how the pixel data is retrieve from the the three colour arrays. for the colours take a look at the "leds.setPixel(ledLocation, Color(ArrayG[ledCount], ArrayB[ledCount], ArrayR[ledCount]));" changes and test
 
no, it should not be anything to do with ws2812serial. its probably just a bit of adjusting how the pixel data is retrieve from the the three colour arrays. for the colours take a look at the "leds.setPixel(ledLocation, Color(ArrayG[ledCount], ArrayB[ledCount], ArrayR[ledCount]));" changes and test

Okay now its getting funny!

The "Bird" worked with the quick swap of the array.

But for all the other pictures it was wrong again ;) (tested 2 different ones)

I now use my initial code for this picture (without swaping or something) with this bmp:
View attachment 0.bmp

Screenshot 2021-12-09 233004.jpg

With the Result:

sdfsdf.jpg
correct colloring....

For the "Bird" i need to use the color swap from your answer above to get it shown correctly! ("leds.setPixel(ledLocation, Color(ArrayG[ledCount], ArrayB[ledCount], ArrayR[ledCount]));" )



I know that I have seen a color converter somewhere in the code of the manufacturer of the "bmps", but I am not quite sure anymore... yet I wonder how the hell this can deviate....

This is the original repository with all the bmp files & Code:
https://github.com/Jerware/GameFrameV2

The position which i mentioned in the code is this one Line 144:
Code:
unsigned long
prevRemoteMillis = 0, // last time a valid remote code was received
[COLOR="#FF0000"]colorCorrection = 0xFFFFFF[/COLOR], // color correction setting
colorTemperature = 0xFFFFFF, // color Temperature
remoteCodeMenu = 0,
remoteCodeNext = 0,
remoteCodePower = 0,
menuPowerCounter = 0, // counter for holding menu button to turn off power
lastTime = 0, // used to calculate draw time
drawTime = 0, // time to read from sd
holdTime = 200, // millisecods to hold each .bmp frame
swapTime = 0, // system time to advance to next frame
baseTime = 0, // system time logged at start of each new image sequence
buttonTime = 0, // time the last button was pressed (debounce code)
menuEndTime = 0, // pause animation while in menu mode
menuEnterTime = 0; // time we enter menu

And also uses
Code:
FastLED.setCorrection(colorCorrection);
Line 281
 
Back
Top