1

I have a bitmap to draw defined as below.

PROGMEM const unsigned char ship1 [] = {0x18, 0x3C, 0x7E, 0xFF, 0x81, 0xC3};

It is then used by the arduboy library's draw slow bitmap function like so:

arduboy.drawSlowXYBitmap(5,5, ship1, 8 , 6, WHITE);

Can anyone explain to me why the bitmap only draws correctly with the PROGMEM keyword? I omitted it at first and it causes the bitmap to look completely different.

I see that this keyword makes the data get written to flash instead of SRAM.

The hardware I am using is the Arduboy.

The arduboy.drawSlowXYBitmap() function is from https://github.com/Arduboy/Arduboy

void Arduboy::drawSlowXYBitmap
(int16_t x, int16_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color)
{
  // no need to dar at all of we're offscreen
  if (x+w < 0 || x > WIDTH-1 || y+h < 0 || y > HEIGHT-1)
    return;

  int16_t xi, yi, byteWidth = (w + 7) / 8;
  for(yi = 0; yi < h; yi++) {
    for(xi = 0; xi < w; xi++ ) {
      if(pgm_read_byte(bitmap + yi * byteWidth + xi / 8) & (128 >> (xi & 7))) {
        drawPixel(x + xi, y + yi, color);
      }
    }
  }
}

Imagine two programs identical apart from the PROGMEM keyword. The program only contains the lines mentioned above and the relevant calls to refresh the display. What I want an explanation of is why I get a garbled image without it and a fine image with it.

  • 3
    It depends on the application code (which you didn't give us!). If the code uses pgm_read_byte to read from the pointer, it will read from program memory (flash). Else, from RAM. If you change a variable's storage from PROGMEM to RAM but don't adapt the code, errors like yours happen (reading from the wrong mem addr). – Maximilian Gerhardt Jun 1 '18 at 13:11
  • @MaximilianGerhardt I have added the only other relevant line in the code but this is a library call so I will have to find the source code. In both cases the variable is a const the only difference was the Progmem keyword. – kenjara Jun 1 '18 at 14:21
  • 1
    I was right on the money: github.com/Arduboy/Arduboy/blob/master/src/Arduboy.cpp#L630 – Maximilian Gerhardt Jun 1 '18 at 14:38
  • @MaximilianGerhardt Ok that makes sense and it clearly works fine with the progmem keyword but could you explain why this happens then when the only change is whether the code is built with the keyword or not. – kenjara Jun 1 '18 at 14:49
  • 1
    Because without the PROGMEM keyword your doesn't put the data in the same place that the library is going to look for it. You put it in SRAM and the library is looking at the same address in flash. Imagine sending a letter to the right street address but with the wrong city and zip. – Delta_G Jun 1 '18 at 22:04

Your Answer

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

Browse other questions tagged or ask your own question.