Printing utf8 strings from progmem arrays

Hello, I'm making a project with multilanguage menu. Everything works great but when I tried making the multilanguage part, I got stuck when I need to print strings that have non-English(latin alphabet) letters in it. I made an example here that If you run it, it will print fine the English(latin alphabet) strigs, but when I print some greek words, everything gets problematic.

#include <avr/pgmspace.h>


const char speedView [5] [12] PROGMEM = { { "TAXYTHTA:" }, { "SPEED:   " }, { "Vitesse: " }, { "Velocità:" }, { "Drehzahl:" } };  //gr, en, fr, it, ge
const char speedSel [5] [12] PROGMEM = { { "ΡΥΘΜ ΤΑΧ: " }, { "SET SPEED:" }, { "Vitesse: " }, { "Velocità: " }, { "Drehzahl: " } };  //gr, en, fr, it, ge
const char remaining [5] [12] PROGMEM = { { "ΥΠΟΛΟΙΠΟ:" }, { "REMAIN:  " }, { "Vitesse: " }, { "Velocità:" }, { "Drehzahl:" } };  //gr, en, fr, it, ge
const char endingAt [5] [12] PROGMEM = { { "ΤΕΛΕΙΩΜΑ:" }, { "ENDING:  " }, { "Vitesse: " }, { "Velocità:" }, { "Drehzahl:" } };  //gr, en, fr, it, ge


void setup() {

  Serial.begin(115200);


  
  for (byte k = 0; k < strlen_P(speedView[2]); k++) {
    Serial.print((char)pgm_read_word(speedView[2] + k));
  }
  Serial.println();

  for (byte k = 0; k < strlen_P(speedSel[0]); k++) {
    Serial.print((char)pgm_read_word(speedSel[0] + k));
  }
  Serial.println();

  for (byte k = 0; k < strlen_P(remaining[1]); k++) {
    Serial.print((char)pgm_read_word(remaining[1] + k));
  }
  Serial.println();

  for (byte k = 0; k < strlen_P(endingAt[0]); k++) {
    Serial.print((char)pgm_read_word(endingAt[0] + k));
  }
  Serial.println();

  
}

void loop() {
  // put your main code here, to run repeatedly:
}

That's the output:
image

You'll see that whenever a greek word is printed, somehow it gets printed with the next string of the array.

Any help would be much appreciated!

The array does not have enough space to store the text, utf8 characters can be two or more bytes each. The compiler should be warning about the text being truncated.

1 Like

Hi David, the compiler doesn't give me any errors. With what you've said though I increased the space from all arrays to 20 from 12 and now it works fine.

Thank's a lot!

The for loops are not really necessary you should be able to cast the array element to __FlashStringHelper* and print the string directly, such as

Serial.println((__FlashStringHelper*)speedView[2]);
1 Like

Go to Preferences... and set "Compiler warnings" to "All".

Then, for each array where the compiler tells you a string is too long, increase the size. I found that the first array is OK but the other three need 18 bytes:

const char speedView [5] [12] PROGMEM = { { "TAXYTHTA:" }, { "SPEED:   " }, { "Vitesse: " }, { "Velocità:" }, { "Drehzahl:" } };  //gr, en, fr, it, ge
const char speedSel [5] [18] PROGMEM = { { "ΡΥΘΜ ΤΑΧ: " }, { "SET SPEED:" }, { "Vitesse: " }, { "Velocità: " }, { "Drehzahl: " } };  //gr, en, fr, it, ge
const char remaining [5] [18] PROGMEM = { { "ΥΠΟΛΟΙΠΟ:" }, { "REMAIN:  " }, { "Vitesse: " }, { "Velocità:" }, { "Drehzahl:" } };  //gr, en, fr, it, ge
const char endingAt [5] [18] PROGMEM = { { "ΤΕΛΕΙΩΜΑ:" }, { "ENDING:  " }, { "Vitesse: " }, { "Velocità:" }, { "Drehzahl:" } };  //gr, en, fr, it, ge
1 Like

That should save me many lines. Thank's again!

I have already been stuck with array spacing problems in the past. Now with compiler warnings informing me, I believe I'll be trouble free in the future.

Thank's for the info!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.