[Arduino] Ecran pour DED
Publié : dim. août 09, 2015 10:25 am
Bonjour
Pendant longtemps, j'ai cherché un écran LCD 25*5 pour afficher les données du DED. Et ces écrans sont très difficiles à trouver.
Et un jour j'ai vu le travail effectué par un membre de la 108fvs :
Et en regardant les possibilités de sces écrans, je me suis rendu compte que je faisais fausse route : il ne fallait pas chercher un LCD avec tel types ou nombre de segments, tout écran de type affichage de pixel fait l'affaire.
Par exemple, voilà pour le fun l'affichage du DED sur un écran de 0.96inc de diamètre (27x15mm).
http://www.ebay.com/itm/White-3-5V-0-96 ... 2ed549d368
Il reste à trouver comment lier l'affichage de l'écran et les données "réelles" du DED, et c'est moins facile que ça semble être... :
Je vous propose ce code pour envoyer / recevoir les données entre le C++ et l'arduino :
dans le C++, autant utiliser la fonction WriteData qui permet d'écrire plusieurs octets d'un seul coup :
et dans l'arduino :
et la fonction qui affiche le DED (dans l'arduino toujours) :
Avec ça, l'arduino envoie une lettre au C++ (la lettre S), et dès que le prog C++ le reçoit, il envoie à son tour les 125 caractères du DED.
Là, ça fonctionne (il se peut qu'il y ait deux/trois petits détail à corriger car je l'ai pris d'une partie de mon prog).
Il reste quand même deux points à régler. Et pas des moindres.
Dans le DED de BMS,
-le caractère 01 représente la petite double flèche haut/bas du DED.
-le caractère 02 représente l'astérisque.
Le reste des caractères alphanumériques semble bon, il s'agit de leur code ASCII. Probablement tous les chiffres et les lettres majuscules.
Donc, ça nous donne en affichage des caractères non désirés (ou aucun affichage) lorsque le DED comporte la double flèche ou l'astérisque.
Ensuite, il est primordial de pouvoir afficher les caractères en Inverse vidéo, car souvent ça matérialise la ligne où le réglage doit s'effectuer, or avec l'affichage précédent, on n'a que les caractères "normaux".
Tout comme les caractères du DED sont contenus dans char DEDLines[5][26]; les caractères en inverse sont contenus dans char Invert[5][26];
Le tableau Invert a la même taille que DEDLines. A chaque caractère du DEDLine, si il doit être affiché en inverse le tableau Invert a, à la même position que le DEDLine, le code 02. Sinon, il a le code 0.
Je suis peut être pas très clair, mais le principe est très simple.
Je pense que pour régler d'un coup les deux problèmes, il faudrait se créer soi même sa police de caractères avec les caractères astérisques et double flèche en position 2 et 1 et y inclure les caractère en inverse vidéo. Ensuite, faire une fonction pour que le prog C++ parse et mixe les deux tableaux DEDLines et Invert pour les envoyer vers l'arduino.
Caractères en inverse vidéo, et double flèche.
Voilà leur code dans les tableaux DEDLines et Invert :
La solution de créer/modifier une police de caractères pour le DED est une solution qui me parait comme étant la plus facile à mettre en oeuvre.
Les polices sont stockées, pour u8glib, dans le fichier \U8glib\utility\u8g_font.c et leurs déclarations dans \U8glib\utility\u8g.h
Pour créer une police u8g, il faut prendre une police au format *.dbf et la convertir au moyen du programme bdf2u8g_101.exe (https://code.google.com/p/u8glib/).
Cela signifie qu'il faut au départ créer une police au format bdf. Et pour ça, je vous propose le programme Fony (http://fony.en.softonic.com/)
Soit vous créez votre propre police de caractères, soit vous essayez de récupérer la police déjà existante que vous modifiez pour vos besoins.
par exemple, pour cet essai, vu que j'utilise un petit écran OLED de 0.96 in, j'utilise dessus la police u8g_font_5x8r (et des lunettes). J'ai donc chargé la police qui correspond sur cette page : http://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html, et l'ai modifiée avec Fony.
Ca nous donne ça :
D'une manière absolument arbitraire, j'ai choisi de créer les caractères en mode inverse à la place de leur minuscules, ainsi, au besoin je peux voir sur la fenêtre d'exécution en C++les caractères qui sont envoyés à l'arduino. Et lorsqu'une lettre est envoyée en minuscule, ça signifie qu'elle doit être affichée en inverse vidéo.
Donc, après voir fait la police selon mes vœux, il faut l'exporter au format *.bdf (File/Export/BDF Font) puis utiliser le programme en ligne de commande bdf2u8g_101.exe
Comme argument, j'ai mis :
bdf2u8g_101.exe -b 0 -e 123 DED.bdf ded ded.c
Ce qui a eu pour résultat de me créer un joli fichier ded.c qui contient ma police au format u8g.
J'ai ajouté cette police directement dans le fichier u8g_font.c et sa déclaration dans u8g.h, et ma police DED est prête à être utilisée par l'arduino.
Côté programme en C++, il a fallut parser, c'est à dire prendre chaque caractère, l'analyser et si besoin le convertir à la position auquel il correspond dans la nouvelle police.
Donc, au lieu de faire un simple :
il a fallut :
En gros, ça copie successivement chaque ligne du DED dans dedProv, puis à chaque caractère, il va regarder si il y a, à la même place, le caractère 02 dans Invert. Si c’est le cas, c'est que le caractère doit être affiché en inverse vidéo, et il va modifier le caractère en question pour y donner la position du caractère inverse.
Tout simplement, et ça fonctionne impeccable.
Double flèche :
Caractères en inverse vidéo, et double flèche.
Chiffre, astérisques et dièse en inverse vidéo, et double flèche.
Pour illustrer tout ça, voilà une console, pas très réaliste, mais c'est toujours mieux que de cliquer sur des boutons.
Le montage physique lui-même ne pose aucun souci particulier : les composants sont reliés via le bus I2C, il y a seulement 3 MCP 23017, un PCF 8591(pour les potentiomètres du Trim), et un écran OLED. Chaque composant a fait l'objet d'articles détaillés sur ce forum.
Pendant longtemps, j'ai cherché un écran LCD 25*5 pour afficher les données du DED. Et ces écrans sont très difficiles à trouver.
Et un jour j'ai vu le travail effectué par un membre de la 108fvs :
Et en regardant les possibilités de sces écrans, je me suis rendu compte que je faisais fausse route : il ne fallait pas chercher un LCD avec tel types ou nombre de segments, tout écran de type affichage de pixel fait l'affaire.
Par exemple, voilà pour le fun l'affichage du DED sur un écran de 0.96inc de diamètre (27x15mm).
http://www.ebay.com/itm/White-3-5V-0-96 ... 2ed549d368
Il reste à trouver comment lier l'affichage de l'écran et les données "réelles" du DED, et c'est moins facile que ça semble être... :
Je vous propose ce code pour envoyer / recevoir les données entre le C++ et l'arduino :
dans le C++, autant utiliser la fonction WriteData qui permet d'écrire plusieurs octets d'un seul coup :
Code : Tout sélectionner
// declarations
char cRecu ;
int iRecu;
// while (TRUE){
if (iRecu = Serial.ReadData(&cRecu,1) > 0 ){
if(cRecu == 'S'){
system("cls");
for (int ligne=0; ligne<5 ; ligne++){
Serial.WriteData(flightData->DEDLines[ligne],25);
cout << flightData->DEDLines[ligne] << "." << endl;
}
}
}
Code : Tout sélectionner
//declarations
char serialDED[125]; //Pour l'affichage DED
//void loop()
int DEDRead = 0;
Serial.print("S");//demande d'info au prog en C++
delay(5);
if (Serial.available()>0){
DEDRead = Serial.readBytesUntil('ù', serialDED, 125);
}
if (DEDRead == 125) drawDED(serialDED)
Code : Tout sélectionner
//Affichage du DED
void drawDED(char DED[]){
//DED[] est un array de 125 caractères contenant les 5 lignes du DED
char ligne[26] = {0};
ffDisp.firstPage();
do{
ffDisp.setFont(u8g_font_5x8r); // Police à adapter à ton écran
memcpy (&ligne, &DED[0],25);
ffDisp.drawStr(0, 10, ligne); //Tous les positionnements sont relatifs à ton écran
memcpy (&ligne, &DED[25],25);
ffDisp.drawStr(0, 22, ligne);
memcpy (&ligne, &DED[50],25);
ffDisp.drawStr(0, 34, ligne);
memcpy (&ligne, &DED[75],25);
ffDisp.drawStr(0, 46, ligne);
memcpy (&ligne, &DED[100],25);
ffDisp.drawStr(0, 58, ligne);
} while ( ffDisp.nextPage() );
}
Là, ça fonctionne (il se peut qu'il y ait deux/trois petits détail à corriger car je l'ai pris d'une partie de mon prog).
Il reste quand même deux points à régler. Et pas des moindres.
Dans le DED de BMS,
-le caractère 01 représente la petite double flèche haut/bas du DED.
-le caractère 02 représente l'astérisque.
Le reste des caractères alphanumériques semble bon, il s'agit de leur code ASCII. Probablement tous les chiffres et les lettres majuscules.
Donc, ça nous donne en affichage des caractères non désirés (ou aucun affichage) lorsque le DED comporte la double flèche ou l'astérisque.
Ensuite, il est primordial de pouvoir afficher les caractères en Inverse vidéo, car souvent ça matérialise la ligne où le réglage doit s'effectuer, or avec l'affichage précédent, on n'a que les caractères "normaux".
Tout comme les caractères du DED sont contenus dans char DEDLines[5][26]; les caractères en inverse sont contenus dans char Invert[5][26];
Le tableau Invert a la même taille que DEDLines. A chaque caractère du DEDLine, si il doit être affiché en inverse le tableau Invert a, à la même position que le DEDLine, le code 02. Sinon, il a le code 0.
Je suis peut être pas très clair, mais le principe est très simple.
Je pense que pour régler d'un coup les deux problèmes, il faudrait se créer soi même sa police de caractères avec les caractères astérisques et double flèche en position 2 et 1 et y inclure les caractère en inverse vidéo. Ensuite, faire une fonction pour que le prog C++ parse et mixe les deux tableaux DEDLines et Invert pour les envoyer vers l'arduino.
Caractères en inverse vidéo, et double flèche.
Voilà leur code dans les tableaux DEDLines et Invert :
La solution de créer/modifier une police de caractères pour le DED est une solution qui me parait comme étant la plus facile à mettre en oeuvre.
Les polices sont stockées, pour u8glib, dans le fichier \U8glib\utility\u8g_font.c et leurs déclarations dans \U8glib\utility\u8g.h
Pour créer une police u8g, il faut prendre une police au format *.dbf et la convertir au moyen du programme bdf2u8g_101.exe (https://code.google.com/p/u8glib/).
Cela signifie qu'il faut au départ créer une police au format bdf. Et pour ça, je vous propose le programme Fony (http://fony.en.softonic.com/)
Soit vous créez votre propre police de caractères, soit vous essayez de récupérer la police déjà existante que vous modifiez pour vos besoins.
par exemple, pour cet essai, vu que j'utilise un petit écran OLED de 0.96 in, j'utilise dessus la police u8g_font_5x8r (et des lunettes). J'ai donc chargé la police qui correspond sur cette page : http://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html, et l'ai modifiée avec Fony.
Ca nous donne ça :
D'une manière absolument arbitraire, j'ai choisi de créer les caractères en mode inverse à la place de leur minuscules, ainsi, au besoin je peux voir sur la fenêtre d'exécution en C++les caractères qui sont envoyés à l'arduino. Et lorsqu'une lettre est envoyée en minuscule, ça signifie qu'elle doit être affichée en inverse vidéo.
Donc, après voir fait la police selon mes vœux, il faut l'exporter au format *.bdf (File/Export/BDF Font) puis utiliser le programme en ligne de commande bdf2u8g_101.exe
Comme argument, j'ai mis :
bdf2u8g_101.exe -b 0 -e 123 DED.bdf ded ded.c
Ce qui a eu pour résultat de me créer un joli fichier ded.c qui contient ma police au format u8g.
J'ai ajouté cette police directement dans le fichier u8g_font.c et sa déclaration dans u8g.h, et ma police DED est prête à être utilisée par l'arduino.
Côté programme en C++, il a fallut parser, c'est à dire prendre chaque caractère, l'analyser et si besoin le convertir à la position auquel il correspond dans la nouvelle police.
Donc, au lieu de faire un simple :
Code : Tout sélectionner
for (int ligne=0; ligne<5 ; ligne++){
Serial.WriteData(flightData->DEDLines[ligne],25);
}
Code : Tout sélectionner
char dedProv[25] = {0};
int iProv;
for (int ligne=0; ligne<5 ; ligne++){
memcpy (&dedProv, &flightData->DEDLines[ligne],25);
for (int colonne=0; colonne<25 ; colonne++){
if (flightData->Invert[ligne][colonne] == 02){
iProv = dedProv[colonne];
if (iProv==1){
dedProv[colonne] = 3; //double flèche
}else if(iProv==2) {
dedProv[colonne] = 4; //asterisque
}else if(iProv==35) {
dedProv[colonne] = 16;//dièse
}else if(iProv==32) {
dedProv[colonne] = 15;//espace
}else if(iProv > 47 && iProv <58) {
dedProv[colonne] = dedProv[colonne]-43;//chiffres
}else if(iProv > 64 && iProv <91) {
dedProv[colonne] = dedProv[colonne]+32;//lettres
}
}
}
Serial.WriteData(dedProv,25);
}
Tout simplement, et ça fonctionne impeccable.
Double flèche :
Caractères en inverse vidéo, et double flèche.
Chiffre, astérisques et dièse en inverse vidéo, et double flèche.
Pour illustrer tout ça, voilà une console, pas très réaliste, mais c'est toujours mieux que de cliquer sur des boutons.
Le montage physique lui-même ne pose aucun souci particulier : les composants sont reliés via le bus I2C, il y a seulement 3 MCP 23017, un PCF 8591(pour les potentiomètres du Trim), et un écran OLED. Chaque composant a fait l'objet d'articles détaillés sur ce forum.