[Résolu] Caractère d'une chaîne de caractères en nom de variable

Salut à tous,

Pour mon projet (toujours le même) utilisant un TLC5940, j’affiche des lettres grâce à une fonction écrite par moi-même (voir ce post).

J’ai donc créé des tableaux de bytes pour définir chaque lettre, avec pour nom de la variable la lettre elle-même.
Exemple:

extern byte A[15] = {1,1,1,1,1,1,0,1,0,0,1,1,1,1,1};

Pour simplifier l’affichage d’une phrase, je cherche à écrire une fonction avec un String en paramètre.
Exemple (le code ne fonctionne pas pour l’instant):

void lirePhraseLettresFixes(String Hphrase, int HPLEIN)
{
  int longueur = Hphrase.length();
  byte Hlettre;
  
  for (int Hi = 0; Hi < longueur; longueur++)
  {
    Hlettre = Hphrase.charAt(Hi);
    lireLettre(Hlettre,HPLEIN);
    delay(500);
  }
}

Mon problème est de transformer chaque caractère du String en nom de variable, pour pouvoir faire appel à la fonction de lecture de lettre dont je reposte le code:

void lireLettre(byte Hlettre[], int HPLEIN)
{
  Tlc.clear();
  Tlc.update();
  
  int Hi;
  for (Hi = 0; Hi < 15; Hi++)
  {
    if (Hlettre[Hi] == 1)
    {
      Tlc.set(Hi,HPLEIN);
      Tlc.update();
      delay(1);
    }
    else
    {
      Tlc.set(Hi,0);
      Tlc.update();
      delay(1);
    }
  }
}

Si quelqu’un a une idée, une suggestion, des reproches à faire à mon code (qu’il soit mal écrit et/ou pas commenté), je suis preneur :slight_smile:

Une bonne soirée à tous.

salut :slight_smile:

tu devrais appeler ta fonction “affiche” plutot que “lire” si elle permet d’afficher :slight_smile:

après j’ai pas compris grand chose à ton problème… mais, sache qu’il n’est pas possible de créer une variable à partir d’une valeur contenu dans une autre…

ALors je ne sais pas si ça va te servir, mais, en C (donc, sans la lib string (c++), que je ne connais pas…) une chaine de caractère est un tableau de char.

donc, si tu vois ou je veux en venir :o, si tu envoies à ta fonction, un tableau de char, pour avoir chaque lettres par la suite, il suffit de parcourir ton tableau à l’aide d’une boucle…

en essayant de reprendre les fonctions que tu utilises :

//dans la fonction loop, ou à l'endroit ou tu veux envoyer la chaine à la fonction affichage
    char chaine[50] = "Abracadabra, vlà du chocolat !";
    afficheChaine(chaine);
void afficheChaine(const char* chaine)
{
    int Hi = 0;
    do
    {
        //ici on affiche les lettres une après l'autre si Hi, est la lettre, et HPLEIN lla valeur PWM 
      Tlc.set(chaine(Hi),HPLEIN);
      Tlc.update();
      delay(1);
      Hi++;
    }
    while(chaine[Hi] != '\0');
}

en C applicatif ça donnerai ca :

#include <stdio.h>
void afficheChaine(const char* chaine)
{
    int n = 0;
    do
    {
        printf("%c", chaine[n]); //ici on affiche les lettres une après l'autre
        n++;
    }
    while(chaine[n] != '\0');
}


int main(int argc, char *argv[])
{
    char chaine[50] = "Abracadabra, vlà du chocolat !";
    afficheChaine(chaine);

    return 0;
}

haa, j'ai lu tout ton topic précédent...

En fait, tu as fait autant de tableau byte que de lettres. maintenant, tu veux envoyer ces tableaux bytes à ta fonction, selon le texte que tu as écris...

en fait, t'as pas le choix, il faut que tu fasses un tableau de correspondance ASCII...

par exemple A=65, B= 66 etc pour les majuscules... voir : http://fr.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange pour les autres un truc dans ce genre là

void char2byte(const char lettre, byte **pMatrice)
{
  switch (lettre)
    {
    case 65: //A
      *pMatrice = A;
      break;
    case 66 : //B
      *pMatrice = B;
      break;
    case 67: //C
     *pMatrice = C;
      break;
    case 68 : //D
     *pMatrice = D;
      break;
    default :
      //pour les lettres non gérées
      *pMatrice = VIDE;
    }
}

Bonjour,

Merci pour tes réponses vohu. Très bonne idée, j'avoue ne pas avoir pensé à faire une correspondance ASCII... :roll_eyes:

Il ne me reste plus qu'à coder ça ce soir et tester :)

Question subsidiaire: il faut mieux utiliser une structure if... else if... ou switch case... pour économiser des octets?

niveau mémoire, concrêtement, j'en sais absolument rien...

mais logiquement oui, car si tu fais que des majuscules, il te faut 27 condition, soit, 27 instructions supplémentaires, alors que switch n'en utilise qu'une seule.

Je viens de vérifier..

Donc, switch est plus rapide. pour l'utilisation de la mémoire, en fait, il utilise un goto, donc, ça sous entend qu'il a du rentenir en ram la totalité du switch... Je ne suis pas sur, mais, du coup, je pense que switch est plus gourmand en mémoire, pour justement aller plus vite, et ne faire qu'un seul test et fait ensuite un goto Le if elseif, doit tester à chaque fois, c'est plus long, mais du coup, il n'a pas besoin de lire toutes les cases en avance...

est ce que quelqu'un pourrai confirmer ??

Je n'ai jamais vérifié comme rarement limité à ce point en mémoire coté pc c'est surtout plus propre niveau code, mais ton raisonnement me semble logique.

alors, on vient de m'expliquer que c'est pas si simple que ça...

selon le compilateur, le code ASM produit, peut revenir exactement au même que les elseif et donc faire le test à chaque "case", donc ca ne jouerai que sur la lisibilité.

mais si c'est le cas, je trouve ça un peu con en fait... ça ne revient qu'à un avantage de lisibilité...

D'un côté oui ses valeurs à comparé doivent de toute façons être stocker en mémoire (équivalent à un tableau ?) donc vérifier chaque emplacement mémoire ? J'avoue que sans voire ce qu'il ce passe au plus bas niveau c'est difficile à savoir. :~

(pour un codeur la lisibilité du code est quand même primordial, maintenant si quelqu'un à une bonne explication je suis preneurs :d)

vohu: selon le compilateur, le code ASM produit, peut revenir exactement au même que les elseif et donc faire le test à chaque "case", donc ca ne jouerai que sur la lisibilité.

Effectivement, si la bonne condition est le dernier 'case', il devra tester toutes les autres avant et donc tout est aussi stocké en mémoire... Surtout qu'en Assembleur, il ne me semble pas que le switch case existe!

osaka: pour un codeur la lisibilité du code est quand même primordial, maintenant si quelqu'un à une bonne explication je suis preneurs :d

C'est vrai que le switch case est beaucoup plus lisible au final, d'autant plus qu'il y a moins à écrire :)

Bon... J'ai essayé ta solution vohu et........

Ça marche super bien :)

Bon j'avais commis 2 erreurs: j'avais pris les valeurs hexadécimales des caractères ASCII, sans le préciser. J'ai tout remis en décimal. Et la 2ème erreur était que j'avais plus que mal déclaré mon objet String... :/

Et j'ai aussi galéré avec les pointeurs dans ma fonction, mais j'en suis arrivé au bout grâce à toi (et aux autre Arduinautes, pour toutes mes autres questions).

Le seul bémol que je n'avais pas avant, une sorte de clignotement entre chaque lettre (ou pendant, mais ça ne reste pas allumé quand la lettre est affichée): http://www.youtube.com/watch?v=UimTP9xE3J0

On le voit bien, surtout à la fin où j'affiche 5 espaces de suite. J'essaierai de trouver le pourquoi du comment quand j'aurais un peu plus de temps.

Cool :) merci, ça fait plaisir d'aider aussi un peu, surtout quand on débute aussi :blush:

concernant les clignotements, j'en sais trop rien, peut être de mettre des diodes de roue-libre avec un condo pour enlever des résidus ou trucs dans le genre mais là faut un mec qui fait de l'éléctronique..

Hum... Je pense pas que le coup de la diode soit la solution: le TLC5940 sort du 0V pour allumer les leds, le (+) provient de l'alimentation.

Donc le 5940 me sort de façon très rapide un 0V parasite, pour x raison qu'il me reste à déterminer.

Je poserai la question sur futura-sciences, et si je ne trouve rien, je sortirais l'oscilloscope ce week-end :)

tu nous donneras la réponse ?? :o

Bien sûr!!! C’est pourquoi je ne mets pas en résolu pour l’instant :slight_smile:

Bon, j’ai trouvé le pourquoi du comment de la raison du clignotement de mon montage: les instructions ‘Tlc.clear()’ et ‘Tlc.update()’ au début de la fonction ‘lireLettre()’:

void lireLettre(byte Hlettre[], int HPLEIN)
{
  Tlc.clear();
  Tlc.update();
  
  int Hi;
  for (Hi = 0; Hi < 15; Hi++)
  {
    if (Hlettre[Hi] == 1)
    {
      Tlc.set(Hi,HPLEIN);
      Tlc.update();
      delay(1);
    }
    else
    {
      Tlc.set(Hi,0);
      Tlc.update();
      delay(1);
    }
  }
}

Je n’ai eu qu’à les supprimer, pour ne plus avoir le problème.

Par contre, le soucis sera de ne pas avoir ma “matrice” effacée dans certains cas, il faudra que je trouve une solution.
Je verrais ça quand j’aurais un peu plus de temps, je dois de toute façon revoir tout mon code pour l’améliorer, le rendre plus lisible et le commenter.

Donc merci vohu, et tous les autres qui m’aident depuis mes débuts sur le forum :slight_smile:

Résolu!

ben pour éffacer, tu codes une fonction toi même...

il suffit d'envoyer un caractère " " espace :)

C'est une des solutions auxquelles j'ai pensé, mais je verrai en temps voulu :)

en fait, t'as pas le choix, il faut que tu fasses un tableau de correspondance ASCII...

par exemple A=65, B= 66 etc pour les majuscules.

En même temps les codes des caractères ASCII se suivent donc au lieu de faire une longue suite de if then ou de case ou peut faire des simplifications. Un tableau pour les lettres, un tableau pour les chiffres. Si le code ASCII est compris entre 'A' et 'Z' on adresse le tableau de lettres en l'indexant avec codeASCCI-'A' Si le code ASCII est compris entre '0' et '9' on adresse le tableau de chiffres en l'indexant avec codeASCCI-'0' Comme ça il n'y a que deux IF

fdufnews:

en fait, t'as pas le choix, il faut que tu fasses un tableau de correspondance ASCII...

par exemple A=65, B= 66 etc pour les majuscules.

En même temps les codes des caractères ASCII se suivent donc au lieu de faire une longue suite de if then ou de case ou peut faire des simplifications. Un tableau pour les lettres, un tableau pour les chiffres. Si le code ASCII est compris entre 'A' et 'Z' on adresse le tableau de lettres en l'indexant avec codeASCCI-'A' Si le code ASCII est compris entre '0' et '9' on adresse le tableau de chiffres en l'indexant avec codeASCCI-'0' Comme ça il n'y a que deux IF

Salut fdunews,

Je vois où tu veux en venir, mais pas forcément comment...

Je possède actuellement des tableaux de ce type pour chaque lettre:

extern byte A[15] = {1,1,1,1,1,1,0,1,0,0,1,1,1,1,1};

Seulement, vu la configuration des leds (5X3), je ne peux pas faire toutes les lettres. Donc regrouper toutes mes définitions de lettre, avec des trous dans le tableau par rapport aux lettres qui me manque, et la relative difficulté à retrouver chaque lettre dans le tableau (sauf, bien sûr, si le code est correctement commenté) ne rendent pas la chose pratique. Sans compter l'appel de la lettre: pour le A majuscule (donc 65 en décimal ASCII), je devrais enlever 65 pour obtenir mon 0 indexé... Pas très propre!

Par contre, c'est clair que ça m'enlèverait le grand switch case, et donc j'économiserais de l'espace mémoire.

Si j'ai mal interprété ton message, ou si c'est bien ce que tu voulais dire, fais le moi savoir :)

Merci d'avance