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++;
 }
}
asked May 31, 2018 at 6:26
5
  • I am also having issues with PROGMEM. I can't use forloops to iterate through and print a PROGMEM'd array, it just spits out garbage. I have to go character by character using constants. Commented May 31, 2018 at 7:46
  • 2
    The problem is probably not in the code you show, but in some weird interaction with other parts of your program. Please, post a Minimal, Complete, and Verifiable example isolating the problem. Commented May 31, 2018 at 9:03
  • Why compute unsigned int sprite_pointer = 2 + width*y + x;? The array s only has width*height entries, when the for loop goes at the maximum values of x and y, this index will be out-of-bounds. You need 2 bytes more in the s array. What's the size of the font you're passing it? Commented May 31, 2018 at 10:24
  • If this is code from a 3rd party library I would find another library. If its your code, you need to look at simplifying the function so you can see why it doesn't work. If anything goes wrong in the code you program will splat stuff everywhere, If its internet connected you could start a world war :) What does 93 mean? Commented May 31, 2018 at 12:01
  • 1
    Maximilian Gerhardt was right. The array had only (witdh*height) but I wrote (width*height+2) in it. So something else got overwritten and nothing worked. Thanks a lot! Commented May 31, 2018 at 13:39

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.