Arduino Mega /Ecran TFT Adafruit / dessiner un tableau / afficher des variables

Bonjour,

je suis en train de créer un circuit de voiture HotWheels pour mon fils et j'ai acheté auprès d'Adafruit un écran TFT ainsi que la carte driver RA8875.

J'ai suivi le tutoriel du fabricant et tout est bien connecté.

A présent, je voudrais afficher sur l'écran un tableau qui affiche seulement les voitures qui ont franchi la ligne d'arrivée. J'ai l'information quelles sont les voitures qui ont franchi la ligné d'arrivée dans mon tableau de variable "résultat".

Mon challenge est d'afficher / dessiner un tableau (de n ligne et p colonne) à l'ecran qui se remplira de la manière suivante :
Rank Num.Piste chrono Vitesse
1 3 1.234 sec 250km/h
2 1 +0.123 sec 243km/h
3 2 +1.578 sec. 220km/h
4 4 + 1.698 sec. 215km/h

Donc comment créer une fonction de n lignes et p colonnes dans laquelle je peux dessiner des lignes et colonnes, envoyer du texte (ligne 1 du tableau : rank, num.piste, chrono, vitesse etc....), des valeurs de variables (1,2,3,4) et du texte/variable (1.234sec) dans les cases du tableau?

Une idée de tutoriel ?

je vous remercie,
xavier

vous avez regardé les exemples de la bibliothèque ?

buildtest.ino vous montrer comment effacer l'écran et tracer des lignes (et autres figures)

textmode.ino vous montre comment afficher du texte

Si le projet comporte une carte SD:
je conseille plutôt une image de fond fait sur un ordi, et il ne suffit alors pour l'affichage de récupérer cette image sur la carte SD et d'afficher seulement les nombres. C'est ce que j'ai fait pour "paint sur Arduino", pour avoir une calculatrice, pour dessiner une pièce avec des volets... voir cette page pour des explications, celle ci pour un apperçu de quelques résultats.

Bonjour

Suite à la maintenance, plus moyen de le connecter à mon compte donc voici le nouveau !

Je vous remercie pour vos réponses.

Effectivement, j ai parcouru les exemples proposés par adafruit. Je vais rentrer un plus dans le code et si j ai un souci, je vous en parlerai.

Merci aussi pour l idée d une image fixe mais je préfère créer un tableau au fur et à mesure.

Bien à vous
Xavier

Il n'est pas question de faire une image fixe, mais d'utiliser une image de fond et de remplir seulement les parties texte. J'ai utilisé ce principe pour un système de menus. Chaque case est une image de fond, et le contenu est du texte. Quand je veux une case, je mets l'image et ensuite le texte.

Bonjour

Je te remercie JML.

J ai pris le temps de comprendre:

  • pour faire les lignes et rectangle avec le RA8875.
  • la fonction dtostrf() pour convertir et afficher mes variables de mon tableau de float.

J'ai réussi a sortir cette interface.--> voir photo

en revanche, je ne trouve pas comment régler les problèmes suivants:
1/ suivant la valeur qui sera affichée dans la colonne "track", il faudra dessiner un rectangle d'une couleur ou autre..faut il le faire avec une fonction switch?
2/ dans la boucle for, si i = 0 puis i = 1, ca écrit par dessus. comment faire pour que le curseur se positionne dans la case du dessous?

type or paste code here
void loop()
{
  tft.textTransparent(RA8875_BLACK);
  tft.textEnlarge(1);
  char string[15] = "RESULT";
  char string1[15] = "TRACK";
  char string2[15] = "TIME";
  char string3[15] = "SPEED";
  tft.textSetCursor(50, 24);
  tft.textWrite(string);
  tft.textSetCursor(250, 24);
  tft.textWrite(string1);
  tft.textSetCursor(450, 24);
  tft.textWrite(string2);
  tft.textSetCursor(650, 24);
  tft.textWrite(string3);

  //LIGNE
  tft.drawLine(20, 88, 800, 88, RA8875_BLACK);
  tft.drawLine(20, 176, 800, 176, RA8875_BLACK);
   tft.drawLine(20, 264, 800, 264, RA8875_BLACK);
   tft.drawLine(20, 352, 800, 352, RA8875_BLACK);
  // COLONNE
  tft.drawLine(200, 20, 200, 480, RA8875_BLACK);
  tft.drawLine(400, 20, 400, 480, RA8875_BLACK);
  tft.drawLine(600, 20, 600, 480, RA8875_BLACK);
  tft.fillRect(200, 88, 200, 88, RA8875_GREEN);
  
  int resultat [2] = {1 , 2};
  float chronometre [2] = {10.12, 14.15};
  char resultatchar [2];
  char chronometrechar [2];
  for (int i=0; i<1;i++)
  {
  tft.textTransparent(RA8875_BLACK);
  tft.textSetCursor(100,112);
  tft.textEnlarge(1);
  dtostrf(resultat[i], 2, 0, resultatchar);
  tft.textWrite(resultatchar);
  
  tft.textTransparent(RA8875_BLACK);
  tft.textSetCursor(100,200);
  tft.textEnlarge(1);
  dtostrf(chronometre[i], 5, 2, chronometrechar);
  tft.textWrite(chronometrechar);
  }
}

je vous remercie pour votre aide
xavier

Pour le problème 1, le plus simple me semble de créer un tableau (array) contenant les couleurs. Appelons le couleurs[4] par exemple s'il contient 4 couleurs différentes.
Il te suffit de créer un rectangle dont la couleur de remplissage ou de contour est couleurs[track]

Pour le problème 2, cette ligne
for (int i=0; i<1;i++)
n'est pas vraiment une boucle puisque i ne prend que la valeur 0. 'i' n'atteint jamais 1. Tu peux le vérifier avec un simple
Serial.println(i);
dans le bloc du if

Hello

Je te remercie lesept pour l idée du tableau couleur... je vais essayer

Pour la boucle for, j avais collé le code avec seulement i =0 par inattention. Quand i=1, ça écrit par dessus le texte alors que je précise que le point du curseur a changé.

Je ne comprends pas pourquoi.

Si quelqu’un a une idée... elle est l bienvenue!

Ici tu écris toujours au même endroit, quelle que soit la valeur de i.
Si tu veux changer de case, par exemple écrire dans la case du dessous, tu dois augmenter le second argument. Il doit être égal à 112+i* le hauteur de la case.

HELLO Lesept,

j 'ai réussi :slight_smile: j'ai bien galéré avec les tableaux, les variables"i" et "j" etc....mais je m'en suis sorti!

Je te remercie pour tes précieux conseils.



#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_RA8875.h"

// Library only supports hardware SPI at this time
// Connect SCLK to UNO Digital #13 (Hardware SPI clock)
// Connect MISO to UNO Digital #12 (Hardware SPI MISO)
// Connect MOSI to UNO Digital #11 (Hardware SPI MOSI)
#define RA8875_INT 3
#define RA8875_CS 10
#define RA8875_RESET 9

Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET);
uint16_t tx, ty;
int i =0;
int j =0;
void setup()
{
  Serial.begin(9600);
  Serial.println("RA8875 start");

  /* Initialize the display using 'RA8875_480x80', 'RA8875_480x128', 'RA8875_480x272' or 'RA8875_800x480' */
  if (!tft.begin(RA8875_800x480)) {
    Serial.println("RA8875 Not Found!");
    while (1);
  }

  tft.displayOn(true);
  tft.GPIOX(true);      // Enable TFT - display enable tied to GPIOX
  tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight
  tft.PWM1out(255);
  tft.fillScreen(RA8875_WHITE);

  /* Switch to text mode */
  tft.textMode();
  tft.cursorBlink(32);
}

void loop()
{
  tft.textTransparent(RA8875_BLACK);
  tft.textEnlarge(2);
  char string[15] = "POS.";
  char string1[15] = "TRACK";
  char string2[15] = "TIME";
  char string3[15] = "SPEED";
  tft.textSetCursor(50, 24);
  tft.textWrite(string);
  tft.textSetCursor(250, 24);
  tft.textWrite(string1);
  tft.textSetCursor(450, 24);
  tft.textWrite(string2);
  tft.textSetCursor(650, 24);
  tft.textWrite(string3);

  //LIGNE
  tft.drawLine(20, 96, 800, 96, RA8875_BLACK);
  tft.drawLine(20, 192, 800, 192, RA8875_BLACK);
   tft.drawLine(20, 288, 800, 288, RA8875_BLACK);
   tft.drawLine(20, 384, 800, 384, RA8875_BLACK);
  // COLONNE
  tft.drawLine(200, 20, 200, 480, RA8875_BLACK);
  tft.drawLine(400, 20, 400, 480, RA8875_BLACK);
  tft.drawLine(600, 20, 600, 480, RA8875_BLACK);
  // COLORIAGE DE LA CELLULE
 // tft.fillRect(0, 88, 200, 88, RA8875_BLACK);
  
int piste [4]= {1,2,3,4};
char racechar [6];
float race [4][4] {
{1,2,3,4}, // classement
{4,2,1,3}, // numero des pistes
{5.022, 6.543, 8.876, 9.644}, // ecart
{645, 630,520,450}, // vitesse
  } ;
  
// couleurs des afficheurs
int couleur[4] = {RA8875_RED, RA8875_YELLOW, RA8875_CYAN, RA8875_GREEN};
  
for (j =0; j<4;j++) // j permet de passer d'une voiture a une autre et de passer a la ligne suivante sur l'ecran
{
   for (i=0; i<1;i++) // i permet d ecrire les données d'une voiture horizontalement à l'ecran
   {
    // faire un if si race 0/j est nul alors la voiture n est pas arrivée et donc ecire qquelque chose
    
    // AFFICHAGE RESULT
 tft.textTransparent(RA8875_BLACK);
  tft.textSetCursor(60,100+(j*100));
  tft.textEnlarge(2);
  dtostrf(race[i][j], 2, 0, racechar);
  tft.textWrite(racechar);
for (int k=0; k<4; k++)
  {
    if (race[i+1][j] == piste [k])
    { tft.fillRect(200,(race[0][j]*96), 200, 96, couleur[k]); 
  }}
  // AFFICHAGE TRACK
  tft.textTransparent(RA8875_BLACK);
  tft.textSetCursor(280,100+(j*100));
  tft.textEnlarge(2);
  dtostrf(race[i+1][j], 1, 0, racechar);
  tft.textWrite(racechar);
  

// AFFICHAGE CHRONO
  tft.textTransparent(RA8875_BLACK);
  tft.textSetCursor(440,100+(j*100));
  tft.textEnlarge(2);
  dtostrf(race[i+2] [j], 5, 3, racechar);
  tft.textWrite(racechar);
  
 // AFFICHAGE VITESSE

  tft.textTransparent(RA8875_BLACK);
  tft.textSetCursor(650,100+(j*100));
  tft.textEnlarge(2);
  dtostrf(race[i+3] [j], 3, 0, racechar);
  tft.textWrite(racechar);
  }
  }
}

Avec la photo...

Je vais remettre ça au propre entre ce qui doit aller dans le setup et le loop et il restera à l insérer dans mon code existant

Parfait ! Reste à mettre des unités, les secondes pour les temps et les m/s pour les vitesses ?
Bravo, il y aura une vidéo avec une course?

Hello lesept

Effectivement je dois encore faire des concaténations en ajoutant un “+” pour les écarts, “sec” et “km/h”... une idée sinon je chercherai sur des tutos :grinning:

J ai un ami qui vient demain pour avec son fer à souder donc la vidéo sera dispo d ici peu :crazy_face:

Juste deux remarques
Lorsque tu trace les lignes tu fais

  tft.drawLine(20, 96, 800, 96, RA8875_BLACK);
  tft.drawLine(20, 192, 800, 192, RA8875_BLACK);
   tft.drawLine(20, 288, 800, 288, RA8875_BLACK);
   tft.drawLine(20, 384, 800, 384, RA8875_BLACK);

donc les lignes sont espacées de 96 points
Lorsque tu écris le texte tu fais

  tft.textSetCursor(60,100+(j*100));

donc à chaque ligne le texte se décale de 4 verticalement.
Pour éviter ce genre de problème, il est recommandé de créer des constantes en début de programme et de les utiliser dans le reste du programme. Cela simplifie la tâche en évitant les erreurs comme ⎄'celles que je viens de citer et cela aussi permet de retoucher très rapidement la mise en page si tu veux la faire évoluer par la suite

const int HAUTEUR_CASE 96
const int LARGEUR_CASE 200

La seconde remarque c'est que les lignes de texte ne sont pas centrées dans les lignes. Mais là, c'est plus du pinaillage.

Je te remercie fdufnews pour ta contribution.

Effectivement, je suis allé un peu vite en besogne.
Je garde ton idée de créer des variables qui définissent longueur et largeur.. ça sera plus simple pour maintenance.

Pour centrer le texte, faut q je regarde si une fonction existe dans le RA8875 sinon je le ferai à la mano.

La première ligne est bien centrée. Il suffit de placer les autres n*HAUTEUR_CASE pour régler le problème.

Hello lesept...

Une petite photo de la structure assemblée ... reste juste à coller (je dois construire un pied aussi pour incliner la porte du départ ) placer et souder les composants et finaliser les petits détails de code.

À droite sur la photo, la boîte orange contient le servomoteur ainsi que le bouton de départ.

La « gate orange » au milieu est pour enregistrer les temps de passage qui seront comparés à ceux de l arrivée pour calculer les vitesses.

La boîte blanche à gauche est la ligne d arrivée qui accueillera les afficheurs, écran tft etc...

Enfin, tout à gauche, je vais mettre des coussins en plastique gonfle (comme pour les colis) pour arrêter mes voitures

Super !
J'admire les gens qui arrivent à des projets présentables, moi je ne sais pas faire mieux qu'on proto à peine fini...

C est vrai que c est un peu « longuet » à faire lesept mais quand j en ai marre, je pense au moment où je le présenterai à mes jumeaux et du coup, je m y remets.

Aussi, autant arduino avec l électronique et le code ´ est pas simple mais construire la structure en bois demande bcp de temps entre les mesures, les découpes, les torillons et les couches de peinture. Va falloir que je monte un business avec ça ! :rofl:

Hello Lesept...

J'ai bien cherché et fini par trouver comment concatener. :hot_face:

Exemple pour la vitesse :

      tft.textTransparent(RA8875_BLACK);
  tft.textEnlarge(2);
  tft.textSetCursor(540,120+(j*texte_vertical));
    dtostrf(race[i+4] [j], 5, 1, racechar);
     snprintf(outputbuffer,15, "%s km/h", racechar);
    tft.textWrite(outputbuffer);

j ai retravaillé le tableau d'affichage....et pour que cela soit lisible de loin, j'ai enlevé la colonne "écart avec la première voiture" pour afficher dans la colonne "time" le chrono de la première voiture puis les écarts avec les autres.

Il ne reste plus qu'à intégrer cela dans mon code final et de souder demain :grinning: