0

I'm EXTREMELY new to Arduino and fairly new to programming as a whole, but I thought it would be fun to try and write a program that draws arbitrary 1-bit bitmaps to an LED matrix using the Adafruit RGBMatrixPanel library. I'm trying to draw this image to the screen:

a 32x16 red-and-black image of text reading HEY! in a serif font

But it conks out after 16 pixels each row...

the same image, but with only the HE visible - the rest of the image is black

Below is my code in full. It seems like the bit mask only works for the first 16 columns, but I can't seem to figure out why it stops at that point. I'm using an Arduino Nano, if that helps.

#define CLK  8   
#define OE   9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2

RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
unsigned long int pixelGrid[] = {
  0x00000000,
  0x31CEFDCE,
  0x78CCFCCC,
  0x78CC84CC,
  0x78CC04CC,
  0x78CC04CC,
  0x78CC24CC,
  0x78783CFC,
  0x783024FC,
  0x303004CC,
  0x303004CC,
  0x303004CC,
  0x003084CC,
  0x3030FCCC,
  0x3078FDCE, 
  0x00000000
};
unsigned long int bitMask = 0x00000001;
void setup() {
  matrix.begin();
  uint8_t r=0, g=0, b=0;

  for(uint8_t y=0; y<16; y++) {
    unsigned long data = pixelGrid[y]; // select row of bits from image
      for (byte x = 0; x <32; x++) { //iterate through columns
        if (data & (bitMask << x)) {// works!
          r = 1; // set LED to ON
        }
        else {
          r = 0; // LED is OFF
        }
      matrix.drawPixel(x, y, matrix.Color333(r, g, b));
    }
  }
}

void loop() {
}

Here's the part of the code that's probably messing up, isolated:

for (byte x = 0; x <32; x++) {
        if (data & (1 << x)) {
          r = 1;
        }
        else {
          r = 0;
        }

Thanks for your help!

Edit: Changing the data variable from int to long to avoid it being truncated lead adds another column of pixels, but it kind of looks like they're all squished into column 16 for some reason:same image as image 2, except there is a vertical line running from (16, 1) to (16, 14)

Note: I tried drawing a rectangle from (0,0) to (31, 15) to make sure that all the LEDs worked, and I was able to do that.

Edit 2: Instead of the bitmask being 1, I made it so that:

unsigned long int bitMask = 0x00000001;
// ...
 if (data & (bitMask << x)) { // works!
          r = 1; // set LED to ON
        }
        else {
          r = 0; // LED is OFF
        }

I'm guessing regular numbers default to 16-bit unsigned ints. The issue is fixed, woo! I edited the big code block to match.

  • I'd try exchanging the x and y coordinates in matrix.drawPixel(x, y, matrix.Color333(r, g, b)); to see if the data is layed out in landscape and not in portrait. – Kwasmich May 29 at 11:28
  • Changing the x/y coordinates rotates the image 90 degrees, as expected: i.imgur.com/GXzS4LG.png It's a 32x16 panel, so I unfortunately can't check if it goes down any lower. – NGD May 29 at 12:01
0

'pixelGrid[]' are longs but your temp inside the for() loop, 'data', is an int. Thus, it gets only half the data. Easy mistake to make (and they can be so hard to spot when you know perfectly well what you meant... :)

Update:

By switching the int to long, I've successfully unlocked a seventeenth column! Unfortunately, it looks like all the pixels are bunched up in that seventeenth column.

Another error of the same kind (I missed it the first time around): Change (1 << x) to (1L << x). The original expression is calculated as int and the result is widened in the assignment to 'data' (and I think there was compiler bug int the code that did that, besides). The corrected expression is calculated as a long in the first place, which is what I think you intended.

Update 2:

From your question Edit 2:

I'm guessing regular numbers default to 16-bit unsigned ints.

You are correct - ints of unspecified size default to 16-bits in the Arduino gcc compiler used by the Arduino IDE (and just about everywhere else in the Arduino domain that I know of). The language standard leaves the compiler writer free to choose the size of an int that best fits the target-machine's architecture. 16-bits is the most common, but by no means the only - size implemented in most compilers. For this reason, most compilers' pre-processors implement specific-sized data types, and application writers - you & I - are advised to use these wherever data-size matters. For the Arduino's gcc compiler, there are predefined types such as int8_t (signed 8-bit int), uint32_t (unsigned long int), etc. int is an ok "I don't care, just as long as it works" option. When you do care - specify.

(If my answer helped you, please upvote it or select as best answer. The latter has the important function on this site of marking the question as "completed" so it doesn't keep re-appearing as an unanswered question.)

| improve this answer | |
  • By switching the int to long, I've successfully unlocked a seventeenth column! Unfortunately, it looks like all the pixels are bunched up in that seventeenth column...i.imgur.com/tgpcnH3.png – NGD May 29 at 11:55
  • perhaps you edit your question? Both code, and error description... – DataFiddler May 29 at 12:40
  • Marked you as best answer just now. Thank you for all your help! – NGD May 30 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.