Je récupère une chaine de caractère via un GET http (réponse en ISO-8859-1) et je souhaite l'afficher sur un écran LCD.
Cette chaîne de caractère pouvant contenir des caractères accentués, je cherche à les remplacer par des caractères non accentués en utilisant string.replace avant d'afficher sur mon écran.
Cela ne fonctionne pas.
Ci-dessous mon code (expurger de toute la partie extraction / LCD):
1 - En fin de Setup je remplace des accents dans une chaine de caractère accentuée, cela fonctionne.
2 - Dans le loop j'essaye de faire la meme chose sur les caractères que je récupère de ma réponse http.
Cela fonctionne quand j'essaye de substituer un "D" par un "x"
Cela ne fonctionne plus quand j'essaye de substituer un "é" par un "e"
Je ne comprends pas quelle différence il y a entre mes 2 tests, mais j'imagine que j'ai un problème d'encodage quelque part.
Auriez vous une piste s'il vous plait ?
Merci !
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
Ethernet.begin(mac, ip);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected");
// Make a HTTP request:
client.println("GET /index.php?api_lang=fr&localidad=48949&affiliate_id=4d2q7ug3fmoa&v=2 HTTP/1.1");
client.println("Host: api.tameteo.com");
client.println("Connection: close");
client.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed");
}
char *tests = "bébébébébé";
String test(tests);
Serial.println(test);
test.replace("é","e");
Serial.println(test);
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
String str(c);
str.replace("é","e");
str.replace("D","x");
Serial.print(str);
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
while(true);
}
}
bonjour,
pourquoi ne pas faire l'inverse?
faire le get sur un fichier php qui lui va traiter avec str_replace?
lorsque tu recois un caractère avec accent, c'est un code et non la lettre accentuée, donc normal que ca ne fonctionne pas. http://www.codeshttp.com/iso88591.htm
Ce sont des datas météo que je récupère d'un flux RSS.
Mettre en place un serveur web intermédiaire pour faire le traitement de substitution, nettoyer les datas dont je n'ai pas besoin, ... effectivement pourquoi pas, mais si j'avais pu m'en passer ...
Concernant la piste du caractère accentué codé : si cela étais le cas, j'imagine que mes lignes :
if (client.available()) {
char c = client.read();
String str(c);
str.replace("é","e");
str.replace("D","x");
Serial.print(str);
}
m'afficheraient alors chaque caractère du code et non pas directement le car. accentué.
La gestion des caractères accentués est différente suivant le codage utilisé (UTF8, UTF16, ISO....)
Normalement dans l'entête de l'HTML que tu reçois il y a le type d'encodage utilisé par la page.
Exemple la page du forum Arduino
J'ai bien des accents et non des codes. Ce que j'ai affiché dans le post précédent est ce que j'ai
si je mets
Serial.print(c)
après
char c = client.read();
comme je le disais dans mon premier post,
<?xml version="1.0" encoding="ISO-8859-1" ?>
Donc oui j'ai bien conscience que je dois avoir un pb d'encodage, mais je ne vois pas comment m'en sortir ...
c'est pas le xml dans le navigateur qui nous intéresse, mais ce que recois le nono
tu fais prendre toute la page sans changer quoi que ce soit et regardes ce sui se passe avec les accents comment ils arrivent.
sachant que chaque caractère a un code propre, il suffit après de remplacer par le bon code.
Le problème c'est que l'IDE encode les caractères accentués en UTF-8 si je ne me trompe pas.
Pour résoudre ton problème, dans ton programme, il faut mettre le code ASCII dans le test et non pas le caractère directement comme ça tu ne sera pas tributaire de l'encodage utilisé par la chaîne Arduino.
if (client.available()) {
char c = client.read();
switch (c){
case 232: // caractère è
c='e; break;
case 233: // caractère é
c='e; break;
}
Serial.print(c);
}
J'ai utilisé le code ACSII étendu dans mon exemple. Adapte en fonction de ce que ton soft reçoit comme codes.
L'IDE fait sa cuisine avec les chaines que l'on met dans le programme.
Si on compile le code suivant:
char chaine[]={"J'ai placé une chaine avec des àéè accents"};
void setup(void){
Serial.begin(9600);
Serial.println(chaine);
}
void loop(void){
}
On retrouve à la fin du .hex qui est chargé les constantes.
Pour la compréhension, j'ai mis au-dessus du "binaire" les caractères codés en mettant à chaque fois un underscore suivi du caractère. On voit que tous les caractères accentués sont codés sur 2 octets. Le premier étant C3.
Pas de problème.
En plus, à ma connaissance, c'est écrit nulle part. C'est en cherchant pourquoi j'avais des caractères bizarres à la console que j'ai trouvé ça.
fdufnews:
C'est en cherchant pourquoi j'avais des caractères bizarres à la console que j'ai trouvé ça.
Je me garderais bien de contre-dire mais j'ai une interrogation :
Si j'utilise une interface USB/TTL et un terminal comme screen (sous Linux) les accents sont bien représentés.
La version améliorée de l'IDE proposée par Majenko, qui a ré-écrit le terminal, ne présente pas non plus de pb avec les accents.
Vu comme celà j'aurais tendance à penser que le pb des accents n'est pas dans le code hex mais dans le terminal de L'IDE. Je n'ai pas pu contrôler la véracité de l'info mais j'ai lu que l'IDE utilisait unicode et non pas UTF-8.
J'ai repris le même programme
Voir en pièce jointe la recopie d'écran
J'utilise minicom comme terminal.
Je fais un reset une première fois pour afficher en texte.
Je modifie la configuration de minicom pour faire afficher la chaîne reçue en hexadécimal et je fais un second reset qui affiche en hexa. On retrouve bien les C3 xx
Oui le code compilé (et donc la RAM à l'exécution) stocke les caractères accentués en UTF-8.
Donc un "é" occupe physiquement 2 octets, dont le premier est C3.
Je pense que cela provient du compilo et non de l'IDE (pour s'en assurer il suffit d'ouvrir le source avec un éditeur de fichier hexadécimal)
Oui dans l'IDE standard Arduino, le terminal série "de base" interprète les caractères supérieurs à 127 selon la norme UNICODE.
Il faut donc transcoder les caractères >127 en fonction de ce qu'attend le media en sortie.
Perso je me suis fait une petite librairie pour contourner simplement tous ces problèmes (mais limitées aux caractères spéciaux usuels).
bricoleau:
D'après ce que j'ai pu investiguer sur le sujet :
Oui le code compilé (et donc la RAM à l'exécution) stocke les caractères accentués en UTF-8.
Donc un "é" occupe physiquement 2 octets, dont le premier est C3.
Je pense que cela provient du compilo et non de l'IDE (pour s'en assurer il suffit d'ouvrir le source avec un éditeur de fichier hexadécimal)
bonjour
petit test avec l'exemple ASCIItable modifié pour aller jusqu'à 255
et avec ça dans le setup
Serial.println("ASCII Table ~ Character Map éèàù");
testé avec 4 prog termianaux serie
cette ligne part dans les choux à l'affichage en ce qui concerne les caracteres accentués
alors que les caracteres accentués s'affichent corcectement dans la boucle (33-255)
le code asciitable modifié "avé l'assen"
/*
ASCII table
Prints out byte values in all possible formats:
* as raw binary values
* as ASCII-encoded decimal, hex, octal, and binary values
For more on ASCII, see http://www.asciitable.com and http://en.wikipedia.org/wiki/ASCII
The circuit: No external hardware needed.
created 2006
by Nicholas Zambetti
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
<http://www.zambetti.com>
*/
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// prints title with ending line break
Serial.println("ASCII Table ~ Character Map éèàù"); // ajout de caractere avé l'assen :D
}
// first visible ASCIIcharacter '!' is number 33:
int thisByte = 33;
// you can also write ASCII characters in single quotes.
// for example. '!' is the same as 33, so you could also use this:
//int thisByte = '!';
void loop() {
// prints value unaltered, i.e. the raw binary version of the
// byte. The serial monitor interprets all bytes as
// ASCII, so 33, the first number, will show up as '!'
Serial.write(thisByte);
Serial.print(", dec: ");
// prints value as string as an ASCII-encoded decimal (base 10).
// Decimal is the default format for Serial.print() and Serial.println(),
// so no modifier is needed:
Serial.print(thisByte);
// But you can declare the modifier for decimal if you want to.
//this also works if you uncomment it:
// Serial.print(thisByte, DEC);
Serial.print(", hex: ");
// prints value as string in hexadecimal (base 16):
Serial.print(thisByte, HEX);
Serial.print(", oct: ");
// prints value as string in octal (base 8);
Serial.print(thisByte, OCT);
Serial.print(", bin: ");
// prints value as string in binary (base 2)
// also prints ending line break:
Serial.println(thisByte, BIN);
// if printed last visible character '~' or 255, stop:
if(thisByte == 255) { // you could also use if (thisByte == '~') {
// This loop loops forever and does nothing
while(true) {
continue;
}
}
// go on to the next character
thisByte++;
}
bricoleau:
D'après ce que j'ai pu investiguer sur le sujet :
Oui le code compilé (et donc la RAM à l'exécution) stocke les caractères accentués en UTF-8.
Donc un "é" occupe physiquement 2 octets, dont le premier est C3.
Je pense que cela provient du compilo et non de l'IDE (pour s'en assurer il suffit d'ouvrir le source avec un éditeur de fichier hexadécimal)
Les caractères sont encodés avec le C3 dans le .ino