2

I am currently working on a display library. The font should be stored in PROGMEM. The code looks something like this:

unsigned int i = 0;
Serial.println(pgm_read_byte(&font[1]),HEX);
unsigned char width = pgm_read_byte(&font[0]);
unsigned char height = pgm_read_byte(&font[1]); 
unsigned char spacing = pgm_read_byte(&font[2]);

The strange thing is that the code breaks (Serial spits out random characters, OLED displays only noise or nothing) when I remove the

Serial.println(pgm_read_byte(&font[1]),HEX);

If I replace it with something like

Serial.println("Hello World!");

the code breaks as well, but in a different way. I think pgm_read_byte() returns different things with different Strings in the Serial.println() function.

Is there something going on with the compiler? Are there some optimization options that I should change? Or am I doing it completely wrong?

Here is the whole function:

/**
 * 
 * Displays text using a predefined sprite in PROGMEM
 * Only fonts with a uniform letter spacing are supported
 * The font must have the following format
 * Byte   Description
 *  0.    X width of one letter in pixel
 *  1.    Y height of one letter in bytes (8 pixel)
 *  2.    letter spacing in pixels
 *  3.    data
 *  .      .
 *  .      .
 *  .      .
 *  N.    data
 * 
 * The data is arranged like this
 *    | 0 | 1 | 2 | 3 | 4 | ... |126|127
 *     b0  b1  b2
 *     b3  b4  b5
 *    LSB D0
 * In each byte the data is displayed like this
 *    .
 *    .
 *    .
 *    MSB D7
 * 
 * A font starts with the symbol "!" (ASCII 33) and ends with the symbol "~" (ASCII 126).
 * Each symbol in between has to be present. The letters have to be arranged like this
 * Letter     A       B       C     
 * Bytes    b0 b1   b2 b3   b4 b5
 *          b6 b7   b8 b9  b10 b11
 * 
 * @param unsigned char disp[]          the display buffer where the text should be shown
 * @param const unsigned char font[]    the font in PROGMEM
 * @param const char *string            the string to display
 * @param unsigned char X               x location
 * @param unsigned char Y               y location
 * @param int mode                      blend mode
 */
void gfx::text(unsigned char disp[], unsigned char *font, const char *string, unsigned char X, unsigned char Y, int mode){
  unsigned int i = 0;
  Serial.println(pgm_read_byte(&font[1]),HEX);
  unsigned char width = pgm_read_byte(&font[0]);
  unsigned char height = pgm_read_byte(&font[1]); 
  unsigned char spacing = pgm_read_byte(&font[2]);
  while(string[i])
  {
    if(string[i] > 32 && string[i] < 127){  //only display valid characters, otherwise leave a blank spot
      unsigned char s[width*height];
      unsigned char c = string[i] - 33;
      //transfer pixel with and height to the sprite
      s[0] = width;
      s[1] = height;
      //copy the other bytes
      for(int y = 0; y < height; y++){
        for(int x = 0; x < width; x++){
          unsigned int sprite_pointer = 2 + width*y + x;
          unsigned int font_pointer = 3 + c*width + x + y*width*93;
          s[sprite_pointer] = pgm_read_byte(&font[font_pointer]);
        }
      }
      sprite(disp,s,X+i*(width + spacing),Y,mode); 
    }  
    i++;
  }
}
w7sbc
  • 21
  • 1

0 Answers0