[résolu] caracteres accentués sur st7735

Bonjour à tous

Je tente de me faire une petite station météo à partir des infos de http://www.wunderground.com/

Le sketch est téléversé sur un Arduino pro mini.

L’affichage se fait sur un lcd 1.8"

La connexion sur le site se fait grâce au super ESP8266

Le code n’est pas celui d’un pro car il fait avec des morceaux trouvés à droite et gauche :wink: Mais il fonctionne

Le symbole “°” (degré) est appelé avec la fonction : tft.write(0xf8); et il s’affiche bien

Si j’appelle des caractères accentués ils s’affichent bien aussi.

Mais si le les mets sous forme de texte ça ne marche pas ! :frowning: les caractères accentués sont remplacés >:(

quelqu’un peut il m’aider svp

#include <SPI.h>  
#include <Adafruit_GFX.h>  
#include <Adafruit_ST7735.h> 

#include <ArduinoJson.h>
#include <SoftwareSerial.h>


#define cs   10  // Pins for the display
#define dc   9
#define rst  8 

#define SSID "ssid" // insert your SSID
#define PASS "password" // insert your password
#define LOCATIONID "LE_MEUX" // location id
#define DST_IP "23.222.152.140" //api.wunderground.com
#define ESP_RST 4

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);



SoftwareSerial dbgSerial(2,3); // RX, TX for debugging

const int buffer=300;

int passNum = 1;

// Array of desired weather conditions
// These must be in the order received from wunderground!
//
// Also, watch out for repeating field names in returned json structures,
// and fields with embedded commas (used as delimiters)
char* conds[]={"\"city\":","\"weather\":","\"temp_c\":","\"relative_humidity\":","\"wind_dir\":","\"wind_kph\":","\"pressure_mb\":"};
int num_elements = 7; // number of conditions you are retrieving, count of elements in conds
char close_brace ='}';
char comma = ',';

void setup()

{ 
     
pinMode(ESP_RST,OUTPUT);
reset();
Serial.begin(9600);
Serial.setTimeout(5000);

Serial.println("Init");
  tft.initR(INITR_BLACKTAB);
  tft.setRotation(1);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(2, 2);
  tft.setTextColor(ST7735_WHITE);

  
}
void loop()
{
reset();
delay(4000); //ESP8266 takes a while to restart
// try to connect to wifi
boolean connected=false;
for(int i=0;i<5;i++){
if(connectWiFi()){
connected = true;
break;
}
}

Serial.println("AT+CIPMUX=0"); // set to single connection mode
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += DST_IP;
cmd += "\",80";
Serial.println(cmd);
if(Serial.find("Error")) return;
cmd = "GET /api/votreclé/conditions/q/";
cmd += LOCATIONID;
cmd +=".json";
cmd += " HTTP/1.1\r\nHost: api.wunderground.com\r\n\r\n";
Serial.print(F("AT+CIPSEND="));
Serial.println(cmd.length());
if(Serial.find(">")){

}else{
Serial.println(F("AT+CIPCLOSE"));
delay(1000);
return;
}
Serial.print(cmd);
unsigned int i = 0; //timeout counter
char json[buffer]="{"; // array for Json parsing

int n = 1; // character counter for json

for (int j=0;j<num_elements;j++){
while (!Serial.find(conds[j])){} // find the part we are interested in.

String Str1 = conds[j];
for (int l=0; l<(Str1.length());l++)
{json[n] = Str1[l];
n++;}
while (i<60000) {
if(Serial.available()) {
char c = Serial.read();

if(c==',') break;
json[n]=c;
n++;
i=0;
}
i++;
}
if (j==num_elements-1)
{json[n]=close_brace;}
else
{json[n]=comma;}
n++;
}
parseJSON(json);

// Done with processing for now - close connection
Serial.println(F("AT+CIPCLOSE"));
delay(5000);
// Only check weather every 10 minutes
// So you don't go over quota on wunderground (for free api license)
delay(600000);
}
void parseJSON(char json[300])
{
StaticJsonBuffer<buffer> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
if (!root.success())
{
tft.print("parseObject() failed");
return;

}
const char* city = root["city"];
const char* weather = root["weather"];
double temp_c = root["temp_c"];
const char* relative_humidity = root["relative_humidity"];
const char* wind_dir = root["wind_dir"];
double wind_kph = root["wind_kph"];
const char* pressure_mb = root["pressure_mb"];




tft.fillScreen(ST7735_BLACK);
  tft.setCursor(45, 1);
  tft.setTextColor(ST7735_BLUE);
  tft.setTextSize(2);
  tft.print(city);
  tft.setCursor(2, 21);
  tft.setTextColor(ST7735_RED);
  tft.setTextSize(3);
  //tft.print("Temp: ");
  tft.print(temp_c);
  tft.print(" ");
  tft.write(0xf8);
  tft.println("C");
  tft.setTextSize(2);
  tft.setCursor(2, 100);
  tft.setTextColor(ST7735_GREEN);
  tft.print(weather);
  tft.setCursor(2, 48);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(2);
  tft.print("Press: ");
  tft.print(pressure_mb);
  tft.setTextSize(1);
  tft.println("mb");
  tft.setCursor(2, 65);
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(2);
  tft.print("Humidit: ");
  tft.print(relative_humidity);
  tft.setCursor(2, 83);
  tft.setTextColor(ST7735_CYAN);
  tft.setTextSize(2);
  tft.print("vent:");
  tft.print(wind_kph);
  tft.setTextSize(1);
  tft.println("K/h");
  


}

void reset()
{
digitalWrite(ESP_RST,LOW);
delay(100);
digitalWrite(ESP_RST,HIGH);
}
boolean connectWiFi()
{
Serial.println(F("AT+CWMODE=1"));
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.println(cmd);
delay(2000);
if(Serial.find("OK")){
tft.setCursor(2,120); 
tft.println(F("Connected to WiFi..."));
delay(500); // Allow display to print
return true;
}else{
tft.setCursor(2,120);  
tft.println(F("Can't Connect..."));
delay(500);
return false;
}

}

Salut,

Et oui la librairie stream.h dont hérite la lib du ST est limité à une table ASCII de 128 caractères, où il n'y a pas les accents.

Une béquille : créer ta propre fonction dans ce style :

printTFT("dégagé"); 

...


void printTFT(char* machaine) {

int i=0;

while(machaine[i]!=NULL) {

if(machaine[i]==0xf8) tft.write(0xf8);
else tft.print(machaine[i]=;
i++;
}

}

Merci B@tto pour cette réponse.

Je me doutais qu'il y avait quelque chose dans le genre limitation.

Ce qui est troublant c'est que l'on peut afficher des caractères en les appelant, mais pas en demandant un print.

Si tu as le temps de regarder mon code et de m'aider à implémenter une fonction pour pallier à cela ce sera avec plaisir.

En attendant je vais me pencher sur ta proposition de "béquille" :)

totof60: Si tu as le temps de regarder mon code et de m'aider à implémenter une fonction pour pallier à cela ce sera avec plaisir.

Justement c'est que je t'ai proposé xD après je viens de me rendre compte qu'on peut faire plus versatile très simplement :

void loop() {

printTFT("dégagé"); 

...
}

void printTFT(char* machaine) {

int i=0;

while(machaine[i]!=NULL) {

if(machaine[i]>=128) tft.write(byte(machaine[i]));
else tft.print(machaine[i]);
i++;
}

}

Test tu me diras si ça marche. Et pour mon explication j'ai un gros doute : je sais plus si c'est stream.h qui est limité ou l'IDE Arduino ...

merci c’est super sympa de m’aider

comme tu l’as compris je debute !!

voici la modif que j’ai faite , mais je dois l’avoir mal faite car ça ne fonctionne pas

....

void parseJSON(char json[300])
{
StaticJsonBuffer<buffer> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
if (!root.success())
{
tft.print("parseObject() failed");
return;

}
const char* city = root["city"];
const char* weather = root["weather"];
double temp_c = root["temp_c"];
const char* relative_humidity = root["relative_humidity"];
const char* wind_dir = root["wind_dir"];
double wind_kph = root["wind_kph"];
const char* pressure_mb = root["pressure_mb"];




tft.fillScreen(ST7735_BLACK);
  tft.setCursor(45, 1);
  tft.setTextColor(ST7735_BLUE);
  tft.setTextSize(2);
  tft.print(city);
  tft.setCursor(2, 21);
  tft.setTextColor(ST7735_RED);
  tft.setTextSize(3);
  //tft.print("Temp: ");
  tft.print(temp_c);
  tft.print(" ");
  tft.write(0xf8);
  tft.println("C");
  tft.setTextSize(2);
  tft.setCursor(2, 100);
  tft.setTextColor(ST7735_GREEN);
  
//modif=============================================================

int i=0;

while(weather[i]!=NULL) {

if(weather[i]>=128) tft.write(byte(weather[i]));
else tft.print(weather[i]);
i++;
}

  
  
  //tft.print(weather)
  
  //fin de modif========================================================

  tft.setCursor(2, 48);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(2);
  tft.print("Press: ");
  tft.print(pressure_mb);
  tft.setTextSize(1);
  tft.println("mb");
  tft.setCursor(2, 65);
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(2);
  tft.print("Humidit: ");
  tft.print(relative_humidity);
  tft.setCursor(2, 83);
  tft.setTextColor(ST7735_CYAN);
  tft.setTextSize(2);
  tft.print("vent:");
  tft.print(wind_kph);
  tft.setTextSize(1);
  tft.println("K/h");
  


}

.....
  1. je vois pas les modifs
  2. ça marche pas c’est très vague …

La modif est encadrée par : // modif === et // fin de modif ====

ça marche pas : les caractères restent les mêmes

Ok essaye ça : modifie ça

const char* weather = root["weather"];

en

const byte* weather = root["weather"];

J'avais zappé qu'un char est signé (-128 à 127) alors qu'un byte ne l'ai pas (0 à 255). Donc pour accéder aux caractères > 128 il faut forcement une variable capable d'aller à plus de 128.

error: conversion from 'ArduinoJson::JsonVariant' to 'const byte*' is ambiguous

Là c'est incompatible avec la lib Json !!

Vire le const

Je pense qu'il faudrait regarder les données brutes reçues. Les caractères accentué pourrait être codés en UTF8.

@ B@tto toujours la même erreur en virant le const (merci de ton aide )

@ fdufnews je ne pense pas que cela vienne de là ( mais je peux me tromper !!) car il est possible d'afficher des caractères accentués en les appelant avec write et son code hex mais pas avec print

Je viens de faire une requête et le résultat est ci-dessous.
Le é est codé C4 A9

Sans_titre.png

Alors là je suis incapable de comprendre ce que cela veut dire !!!

mais si tu as une solution je suis preneur , merci d'avance

Très belle,complète et compréhensible explication de pepe merci à lui.

Si j'ai bien compris je dois par exemple dans mon cas pour : "weather":"Nuages épars" rechercher les caractères accentués et les remplacer par leurs équivalents en hexa ?

C'est vers cette solution que je m'orientais avant de venir " pleurnicher"sur ce forum. ;) Mais je ne sais pas encore le faire !!!

Si il y a une petite aide merci d'avance.

En attendant,je suis content de toutes ces explications qui feront certainement avancer certains

Hello,

Le plus simple ne serait pas simplement de faire appel à une fonction de conversion UTF8 vers ANSI ?

Merci à tous

Je pense que par rapport à mon niveau de compétence je vais aller vers la solution simple

if (!strcmp(weather, "Nuages épars"))
    tft.print("Nuages \x82pars");

Je n’ai pas encore vérifié mais il ne doit pas y avoir beaucoup de conditions avec des caractères accentués

J'ai partiellement solutionné mon problème en incluant des conditions. :D

Je modifierai mon code en fonction des conditions météo qui seront accentuées.

Il y a certainement plus simple !! vu que c'est apparemment seulement le caractère "é" qui pose problème dans mon cas.

Si vous avez des propositions je suis preneur.

tft.setCursor(2, 96);
  tft.setTextColor(ST7735_GREEN);
  if (!strcmp(weather, "Nuages épars"))
    tft.println("Nuages \x82pars");
   if (!strcmp(weather, "Ciel dégagé"))
    tft.println("Ciel d\x82gag\x82"); 
    else

Cette expérience m'aura permis d'avancer un peu plus dans la programmation d'Arduino merci à tous

Oui !! bien vu!!!

En recherchant des infos sur mon problème, j'ai découvert ce post : https://github.com/adafruit/Adafruit-GFX-Library/issues/22

Il fait référence à ce fameux caractère manquant. J'ai donc corrigé le fichier glcdfont.c de ma lib GFX

Voici le résultat grâce à votre aide. Je ne sais pas si on peut passer le sujet en " résolu" vu que ce n'est que partiellement résolu ?