Stockage des caractères accentués

Bonjour

Je suis en cours de développement d'un programme assez verbeux pour arduino, avec plusieurs canaux de sortie des messages :

  • Liaison série
  • Ecran LCD
  • Serveur HTTP
  • Serveur UDP
  • Mail

Chaque message est stocké en mémoire flash (utilisation de PROGMEM), et peut contenir des caractères accentués (je programme français, moi monsieur :P).

Evidemment, il faut un filtre pour chaque sortie mais ça je maîtrise (Liaison série é=>e, HTTP é => &eacute, LCD é => caractère personnalisé, UDP non filtré, etc.)

Mon problème est que je n'arrive pas à stocker correctement les caractères accentués dans ma chaîne initiale.
Par exemple, l'instruction ci-dessous ne donne pas le résultat attendu

prog_char lib_parm08[] PROGMEM = "Périodicité des relevés de température";

Voici quelques lignes de code permettant de cerner le problème (sans PROGMEM mais c'est kif)

char maligne[] = "caractère accentué abc";

void setup(){
  Serial.begin(9600);
  Serial.println(maligne);    //affichage de la ligne entière

  uint8_t i=0;
  while (maligne[i])          //affichage caractère par caractère 
  {
    Serial.print(maligne[i]);
    Serial.print(',');
    Serial.print((uint8_t) maligne[i], DEC);
    Serial.println();
    i++;  
  }

  Serial.println();
  Serial.println('é'); //un caractère littéral accentué seul ?

  Serial.println();
  char moncar = 'é'; //un caractère seul ?
  Serial.print(moncar);
  Serial.print(',');
  Serial.print((uint8_t) moncar, DEC);
  Serial.println();

  moncar = (char) 130; //et avec le bon code ascii ?
  Serial.print(moncar);
  Serial.print(',');
  Serial.print((uint8_t) moncar, DEC);
  Serial.println();
}

void loop(){
}

Avec pour résultat :

caractère accentué abc
c,99
a,97
r,114
a,97
c,99
t,116
Ã,195
¨,168
r,114
e,101
,32
a,97
c,99
c,99
e,101
n,110
t,116
u,117
Ã,195
©,169
,32
a,97
b,98
c,99

-15447

©,169
<un caractère spécial en forme de carré, non représentable ici>,130

J'en déduis donc que le compilo :

  • utilise deux octets pour stocker les caractères accentués contenus dans une chaîne littérale (par ex : é => 195.169), selon une nomenclature que je ne connais pas.
  • considère le littéral 'é' comme un int (195*256+169+15447 = 65536 CQFD), et du coup ne laisse que l'octet LSB quand je le balance dans un char.

En synthèse, est-ce que quelqu'un sait me dire comment coder ma chaîne littérale pour que cet abruti de compilo comprenne que je veux qu'il me stocke la valeur 130 dans l'octet correspondant au 'é' inclus dans ma chaîne ?

Je veux juste ça, pitié, SVP et tout le reste fonctionnera. :sweat_smile:

PS : le compilo en question c'est celui de l'IDE Arduino standard (spa bien je sais, mais je débute et je n'ai pas encore creusé de solution alternative).

Je ne pense pas que cela vienne du compilateur (il n'est pas arduino) mais plutôt du "Serial Monitor" (je ne sais pas comment appeler cette bête en français) de l'IDE Arduino.

Je constate la même chose avec l'IDE arduino par contre quand j'utilise un terminal "sceen" sous Linux avec strictement le même programme les caractères accentués s'affichent correctement -> il doit bien exister des programmes équivalents à "screen" sous win$.

PS : il existe un fork de l'IDE (voir Majenko: UECIDE: A New Fork of the IDE - Libraries - Arduino Forum )
http://uecide.org

L'auteur à entièrement réécrit le "Monitor" (plus d'autres choses) pour corriger tout une série de soucis comme celui là.

Bonjour

Merci mais flûte j'ai du mal expliquer mon problème.

Je ne cherche pas à afficher des caractères accentués sur le pauvre terminal série inclus dans l'IDE Arduino.
Mon problème est que quand je mets un littéral "aéa" dans mon code source, ce n'est pas ce que je retrouve dans le code exécutable, et donc en RAM. Et à partir de là ça fout en vrac mes fonctions qui permettent de filtrer proprement les accents selon le canal d'affichage.

Pour un "aéa", je m'attendais à avoir 4 caractères en RAM : 97.130.97.0 exprimé en valeur numérique de l'octet correspondant.

Au lieu de cela, je me retrouve avec 5 caractères en RAM : 97.195.169.97.0

Je ne sais pas si la conversion en 5 caractères est effectuée par l'IDE avant de balancer le source au compilo, ou si c'est au niveau du compilo (peut-être d'après des options de compil à la noix imposée par l'IDE).

Sans changer d'outillage, je devrais pouvoir contourner le problème en codant {'a',0x82,'a',0x00} au lieu de "aéa".
Mais qui aurait envie de se taper tous ses libellés sous ce format ?

ah si, avec une séquence d'échappement je dois pouvoir limiter la casse.

Mon "aéa" serait alors codé "a\x82a".
M'enfin c'est pas génial de se taper tous les libellés comme ça.

Une meilleure idée ?

La programmation n'est pas ma meilleure spécialité mais je ne comprends pas ce qui te fait dire que c'est un défaut de stockage en mémoire.
Peut être que je n'ai pas compris mais pour moi tu ne fais que des affichages avec des Serial.print , c'est donc un défaut d'affichage.
Je n'ai pas de carte sous la main mais j'aurais bien testé ton code avec un autre "Serial_Monitor" que celui de l'IDE arduino rien que pour lever le doute et en avoir le coeur net.

Bonjour,

Cherche "avrgcc unicode" sur google :wink:

Bienvenue dans le monde de l'UTF-8 et des encodages de caractères qui plantent.
Halala, les wchar_t, tu va bien t'amuser :slight_smile:
(et oui, les anglais ils codent en anglais, pas de bol chez eux les accents ça existe pas. Et vu que c'est eux qui font le compilateur ...)

ok merci

C'est bon j'ai farfouillé et compris le m***dier dans lequel j'ai mis le doigt ]:slight_smile:
unicode, ascii, utf8, wchar_t, ...

Je vais faire quelques tests et voir comment je peux m'en sortir sans trop de bobos
Ca risque d'être délicat car, cerise sur le gâteau, cette partie de mon code est censée être multi plateformes (Arduino + PC Windows + linux) :cold_sweat:

bricoleau:
Ca risque d'être délicat car, cerise sur le gâteau, cette partie de mon code est censée être multi plateformes (Arduino + PC Windows + linux) :cold_sweat:

T'inquiète pas pour ça, les wchar_t sont supportés par tout les compilateurs un peu récents :wink:
Mais avant faut avoir une version qui marche et là ... good luck :grin:

Edit: pense à enregistrer tes fichiers de code source en UTF-8 SANS BOM.
Ça t'évitera des heures de debug pour rien.