IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Scroller un texte sur un écran LCD


Sujet :

Arduino

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 7
    Points : 3
    Points
    3
    Par défaut Scroller un texte sur un écran LCD
    Bonjour !
    Depuis quelques semaines je suis sur un projet de faire une librairie pour Arduino. Cette librairie à pour but de permettre à l'utilisateur de créer un menu.
    Dans ce mode de création de menu j'ai un champ de texte contrôlé par une télécommande IR (haut et bas pour changer de lettre, gauche et droite pour déplacer le curseur)

    J'aimerai que lorsque que le curseur soit à droite de l'écran et qu'on appui sur la touche de droite, le texte se décale d'un cran.
    Exemple:

    Texte complet: damien abcdef
    damien abc -> amien bcd
    amien bcd -> mien cde

    Bref, vous avez compris.

    Mon texte est gardé en mémoire sous forme de chiffres dans un tableau.

    Par exemple, pour le texte "ABC", charInt[2] contiendra 3 (le 2e caractères est 2e lettre de l'lalphabet)

    Comment faire pour transformer le nouveau tableau en char* ?
    Il me faut un char* pour l'écrire sur l'écran.

    J'espère que vous comprendrez :p

    Merci d'avance !
    Cordialement.

  2. #2
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 647
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 647
    Points : 11 136
    Points
    11 136
    Par défaut
    Bonjour,

    en espérant que cela pourra t'aider :
    http://www.arduino.cc/en/Tutorial/LiquidCrystalScroll

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    La librairie qui contrôle l'écran a été fait par moi, j'en ai pas pris une sur internet.
    Le lien vers lequel tu me redirige et un lien qui parle d'un include.

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Citation Envoyé par LDami Voir le message
    J'aimerai que lorsque que le curseur soit à droite de l'écran et qu'on appui sur la touche de droite, le texte se décale d'un cran.
    Exemple:

    Texte complet: damien abcdef
    damien abc -> amien bcd
    amien bcd -> mien cde

    Bref, vous avez compris.
    Je suis peut être le seul mais je n'ai pas bien compris. Tu souhaites qu'une fois l'écran rempli, que l'affichage se décale à droite au fur et a mesure que tu appuis sur la flèche droite de la télécommande ?
    Si je reprends ton exemple, je pense que ça donne plutôt ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    /* Texte complet : "damien abcdefghijklmnopqrstuvwxyz" 
     * sur un afficheur 1 ligne de 16 caractères ça donne : "damien abcdefghi" 
     */
     
    "damien abcdefghi" 
    appui sur le bouton [->] de la télécommande
     
    "amien abcdefghij" 
    appui sur le bouton [->] de la télécommande
     
    "mien abcdefghijk"  
    appui sur le bouton [->] de la télécommande
     
    "ien abcdefghijkl"
    Est ce que c'est ça que tu souhaites ? Car j'ai un peu de mal a comprendre la démarche et la logique dans l'exemple que tu donnes.


    Citation Envoyé par LDami Voir le message
    Comment faire pour transformer le nouveau tableau en char* ?
    Il me faut un char* pour l'écrire sur l'écran.
    En C, il n'y a pas de différence entre un tableau de "char" et un pointeur sur "char*".
    Par exemple :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    char tableau [33] = {'d', 'a', 'm', ...., 'x', 'y', 'z'};
     
    void decalage_text (char *le_text, int longueur_text, int nombre_de_caractere_a_decaler) 
    {
     ...
    }
     
    void main (void) 
    {
       decalage_text(tableau, 33, 1); 
       // je passe en paramètre le tableau, 
       // sa longueur pour contrôle interne anti debordement, 
       // et le nombre de caractère a décaler
    }

    Je pense que tu es confronté a un problème d'algorithme que tu peux régler avec un buffer tournant, voir ci dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
       Zone d'affichage de 16 caractères max sur le LCD
     
       +----------------------------------------------+
       |d  a  m  i  e  n     a  b  c  d  e  f  g  h  i|
       +----------------------------------------------+
     
        ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^ 
        |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
     
       [d][a][m][i][e][n][ ][a][b][c][d][e][f][g][h][i][j][k]
     
    ************************************************************
     
    Appui sur la bouton [->] de la télécommande = Permuter le tableau (buffer tournant)
     
     1) état initial 
       [d][a][m][i][e][n][ ][a][b][c][d][e][f][g][h][i][j][k]
     
     
     2) sortir le premier élément et le mémoriser
       [ ][a][m][i][e][n][ ][a][b][c][d][e][f][g][h][i][j][k]
     
        d
     
     
     3) échanger tous les éléments de mon tableau vers la gauche
       l'élément 0 est remplacé par l'élément 1 ainsi de suite
       [a][m][i][e][n][ ][a][b][c][d][e][f][g][h][i][j][k][ ]
     
     
     
     4) remettre l'élement mémorisé a l'étape 2 au fond du tableau
       [a][m][i][e][n][ ][a][b][c][d][e][f][g][h][i][j][k][ ]
     
    						       d
     
     
     5) raffraichir l'affichage avec le nouveau tableau
     
     
     
       Zone d'affichage de 16 caractères max sur le LCD
     
       +----------------------------------------------+
       |a  m  i  e  n     a  b  c  d  e  f  g  h  i  j|
       +----------------------------------------------+
     
        ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^ 
        |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
     
       [a][m][i][e][n][ ][a][b][c][d][e][f][g][h][i][j][k][d]

    Citation Envoyé par LDami Voir le message
    La librairie qui contrôle l'écran a été fait par moi, j'en ai pas pris une sur internet.
    Ca c'est très bien !
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  5. #5
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 647
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 647
    Points : 11 136
    Points
    11 136
    Par défaut
    Citation Envoyé par LDami Voir le message
    La librairie qui contrôle l'écran a été fait par moi, j'en ai pas pris une sur internet.
    Le lien vers lequel tu me redirige et un lien qui parle d'un include.
    En fait, je me suis dit que tu pourrais t'en inspirer Après, tout dépend du genre d'écran que tu vas utiliser.


    Je pense que l'idée proposée par Vincent répondra à ta question.

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    En fait j'utilise cette écran: http://www.avdweb.nl/Article_files/A...a-5110-LCD.jpg
    84*48px, donc 10 colonnes, 7 lignes.

    Je souhaite faire de cette façon:
    Une variable globale qui contient le texte complet en chiffres. (Exemple: "ABC" sera: 1, 2, 3 dans le tableau)
    Une variable globale qui contient le texte affiché avant défilement. (char* qui contient les lettres)
    Une variable qui contient le nouveau texte après défilement. (char* qui contient les lettres)

    Voici le code actuel:
    http://pastebin.com/hr02CJWE
    Je ne comprend pas pourquoi, mais ma boucle for ne fonctionne plus, genre le print "MoveText: boucle for" ne s'affiche pas...

  7. #7
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 647
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 647
    Points : 11 136
    Points
    11 136
    Par défaut
    Bonsoir,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int index; index < 10; index++)
    tu oublies d'initialiser ta variable index !

    Qu'est-ce que curseurPos ?
    Pour ta variable decalage comment gères-tu les extremum (decalage > index et decalage < 0) ?

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Citation Envoyé par Auteur Voir le message
    Bonsoir,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int index; index < 10; index++)
    tu oublies d'initialiser ta variable index !

    Qu'est-ce que curseurPos ?
    Pour ta variable decalage comment gères-tu les extremum (decalage > index et decalage < 0) ?
    T'inquiète pas pour index, il est grand, il se débrouille ! x)
    Non plus clairement je n'ai pas "besoin" de le faire car il sera mis à zéro par défaut, je l'ai rajouté par sécurité et compréhension.

    curseurPos est la position de mon curseur, si il vaut 2, c'est le 3ème caractère que je modifie (le premier vaut 0), donc je modifie la valeur charInt[2];

    charInt:
    2, 5, 3, 5, 4
    Le curseur serai sur le 3.

    Si il vaut zéro, il est tout à gauche de l'écran (au bout du texte)
    Si il vaut 10, il est tout à droite de l'écran, mais il reste du texte derrière, on peut encore appuyer sur la touche droite.
    Si il vaut 15, tout le texte est défilé, les 5 premiers caractères ne sont pas visibles. On voit que les 10 derniers.

    Le décalage est égale à curseurPos -10 (si curseurPos > 10, car si inférieur pas de décalage)
    Les extremes je les verrai plus tard

    En fait j'ai encore modifié mon script, pour la dernière fois.
    Je me suis rendu compte que stocker tout mon texte en valeurs décimales était moins lourd.

    Il y a donc deux valeurs:

    charInt[MAX_CHAR] contient tout le texte
    charIntDisplayed[MAX_SCREEN_COLUMNS] contient le texte affiché
    J'ai aussi une table static char* alphabet[27].
    Exemple: alphabet[3] = C

    A partir de ça, comment récupérer les valeurs décimales de charIntDisplayed pour les mettre dans une variable char*, avec l'aide du tableau alphabet ?

    Merci d'avance.

  9. #9
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Est ce que tu pourrais poster le code complet ici sur ce forum ?
    Pour la remarque de Auteur sur la variable "i", on doit supposer qu'il s'agit d'une variable globale ?

    Je ne comprends pas pourquoi tu parles de stockage de valeur décimal qui prenne moins de place car je n'ai rien vu de tel dans le morceau de code que tu nous mets à disposition.

    Je pense que pour que l'on te répondre il faudrait que l'on voit tout le code.
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  10. #10
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Montrer tout le code ?

    Il y a 6 fichiers (3 includes), 1500 lignes...
    Cela risque d'être long

    Déplacement du curseur: (HAUT ou BAS)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    void Menu::MoveCursor(int move)
    {
    	if(curseurPos == 10 && move == DROITE) // Si curseur à droite de l'écran et que l'on appui sur DROITE
    	{
    		MoveText(DROITE);
    		curseurPos ++;
    	}
    	else if(curseurPos == 1 && move == GAUCHE) // Si curseur à gauche de l'écran et que l'on appui sur GAUCHE
    	{
    		MoveText(GAUCHE);
    		curseurPos --;
    	}
    	else // Si curseur entre 0 et 10
    	{
    		MenuScreen.ClearLine(CURSEUR_LINE);
    		curseurPos += move; // Additionne si DROITE, soustrait si GAUCHE
    		MenuScreen.SendString("'", CURSEUR_LINE, (curseurPos-1)*8 +1);
    	}
    	Serial.write("curseurPos: ");
    	Serial.println(curseurPos);
    }
    Remplacement d'un caractère: (HAUT ou BAS)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    void Menu::ReplaceChar(int move)
    {
    	int intLetter = charInt[curseurPos];
    	int pos = curseurPos*8;
    	char* newChar;
    	if(move == -1)
    	{
    		if(intLetter == 26) // Z = 26e charactère de la table alphabet
    		{
    			charInt[curseurPos] = 0;
    			newChar = " ";
    		}
    		else
    		{
    			charInt[curseurPos] = intLetter+1;
    			newChar = alphabet[intLetter+1];
    		}
    	}
    	else
    	{
    		if(intLetter == 0) // [SPACE] = 0e charactère de la table alphabet
    		{
    			charInt[curseurPos] = 26;
    			newChar = "Z";
    		}
    		else
    		{
    			charInt[curseurPos] = intLetter-1;
    			newChar = alphabet[intLetter-1];
    		}
    	}
    	MenuScreen.ClearCharacter(2, curseurPos-1); // On supprime le caractère
    	MenuScreen.SendString(newChar, 2, pos-8); // On écrit le nouveau caractère à la même place.
    }
    Déplacement du texte: (GAUCHE ou DROITE)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    void Menu::MoveText(int move)
    {	
    	if(move == GAUCHE) 
    		decalage --;
    	else if(move == DROITE)
    		decalage ++;
     
    	char* textToShow; // Variable qui contiendra le texte à envoyer dans MenuScreen.SendScreen
    	boolean changed = false;
    	for(int index = 0; index < MAX_SCREEN_COLUMNS; index++) // Pour chaque caractère affichable à l'écran
    	{
    		if(move == DROITE) // ABC.. -> .BCD.
    		{
    			charIntDisplayed[index] = charInt[index+decalage]; // On stock le texte qui va être affiché
     
    			textToShow[index] = alphabet[charIntDisplayed[index]]; // On récupère la lettre qui correspond à la valeur décimale précédemment stocké dans charIntDisplayed
     
    			Serial.write("charInt[index-decalage]: ");
    			Serial.println(charInt[index-decalage]);
    			Serial.write("décalage: ");
    			Serial.println(decalage);
    			Serial.write("charIntDisplayed[index]: ");
    			Serial.println(charIntDisplayed[index]);
    			changed = true;
    		}
    	}
    	if(changed)
    	{
    		MenuScreen.ClearLine(2); // On supprime toute la ligne
    		MenuScreen.SendString(textToShow, 2); // On réécrit toute la ligne
     
    		Serial.write("textToShow: ");
    		Serial.println(textToShow);
    	}
    }
    Cette méthode ne fonctionne pas, la boucle for plante et se met en boucle infini:
    Logs: http://pastebin.com/GSMxK3gD


    Création de la zone de texte éditable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    void Menu::SetInputText(int line)
    {
    	for(int i = 0; i < MAX_SCREEN_COLUMNS; i++)
    	{
    		MenuScreen.SendString("A", line, i*8);
    		charIntDisplayed[i] = 1; // Texte affiché sous forme décimale, A = 1
    	}
     
    	for(int i = 0; i < MAX_CHAR; i++)
    		charInt[i] = 1; // Texte complet, A = 1
     
    	decalage = 0; // Aucun décalage (on démarre avec le curseur tout à gauche)
     
    	MenuScreen.SendString("'", line+1, 0);
    }
    Variables:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                    static char* alphabet[27]; // Table alphabet, sert uniquement à lire. Ne peut pas être const car sinon non convertible dans un autre char.
    		int charInt[MAX_CHAR]; // Contient tout le texte
    		int charIntDisplayed[MAX_SCREEN_COLUMNS]; // Contient le texte affiché
    		int decalage; // 0 = Premiers caractères affichés, 1 = premier caractère masqué ...
     
    		int curseurPos = 1;

  11. #11
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Tu utilises des pointeurs de pointeurs et pointeur de tableau et j'espère que tu maîtrises ça sur le bout des doigts. Sache que c'est généralement inutile.

    Voilà le problème que je vois ici :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
       char* textToShow; // !!! Pointeur, et non Variable, qui contiendra !!! l'adresse !!! du texte à envoyer dans MenuScreen.SendScreen
     
       [...]
     
       for(int index = 0; index < MAX_SCREEN_COLUMNS; index++)	
       {
     
          if(move == DROITE)		
          {
     
             [...] 			
     
             textToShow[index] = alphabet[charIntDisplayed[index]]; 
     
            // attention... pointeur de pointeur. 
            // textToShow ne point sur rien en amont de ce code.
     
            // en faisant "textToShow[index] =" tu souhaites mettre dans l'emplacement mémoire, pointé par textToShow, quelque chose.
            // sauf que textToShow n'est pas initialisé

    Je n'ai pas encore tout regardé.
    Je pense que la première source d'ennui est "static char* alphabet[27];"
    Car je ne vois pas d'intêret d'avoir un pointeur sur un tableau, qui est déjà un pointeur (puisque alphabet est une adresse)

    Y a t-il une raison très particulière ?
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  12. #12
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    En fait je ne connais pas bien les pointeurs donc je fais comme je peux :p

    En effet en y pensant ça peut être bizarre !

    Ce que le code comprend c'est:

    adresse{textToShow[index]} = adresse{alphabet[....]}

    Mais c'est pas plus mal non ?

    Au final textToShow[index] devrait contenir une lettre. Je n'utilise pas les bons types de variables ?

    La partie du code qui gère l'affichage est composé de bout de codes trouvés sur internet, et la fonction pour afficher un texte à un paramètre char* qui contient le texte à afficher.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    void LCD::SendString(char* strToWrite, int line, int pos)
    {
    	digitalWrite(13, HIGH);
    	status = BUSY;
     
    	this->Write(0, 0x80 | pos); // Déplace le "curseur" de l'écran pour lui indiquer où il devra écrire le prochain caractère
    	this->Write(0, 0x40 | line); // Idem
     
     
    	while (*strToWrite)
    		this->Character(*strToWrite++);
     
    	digitalWrite(13, LOW);
    	status = IDLE;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void LCD::Character(char character)
    {
    	this->Write(LCD_DATA, 0x00); //Blank vertical line padding
    	for (int index = 0 ; index < 5 ; index++)
    		this->Write(LCD_DATA, LCD::ASCII[character - 0x20][index]); //ASCII contient le code hexa des pixels à afficher, rien à voir avec alphabet[]
     
    	this->Write(LCD_DATA, 0x00); //Blank vertical line padding
    }
    Merci de vos réponses

  13. #13
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Citation Envoyé par LDami Voir le message
    En fait je ne connais pas bien les pointeurs donc je fais comme je peux :p
    Pas de soucis, ce n'était absolument pas une critique de ma part

    Citation Envoyé par LDami Voir le message
    Au final textToShow[index] devrait contenir une lettre. Je n'utilise pas les bons types de variables ?
    Ce qui ce passe en faisant cela :
    char* textToShow signifie que textToShow est une variable de type pointeur, probablement 16 bits sur ton microcontrôleur, qui pointe nul part donc potentiellement n'importe où.
    Dans ton exemple si index vaut 2 : textToShow[2] = 'A';
    Ca veut dire que tu veux mettre la lettre 'A' dans la case mémoire pointée par (textToShow + 2), ne sachant pas où pointe textToShow peut être que (textToShow +2) c'est la pile, ou le Timer, ou un port d'entrée/sortie ou même un emplacement mémoire...

    Si textToShow doit contenir une et seulement 1 seule lettre alors textToShow aurait du être un "char" tout simplement et pas un pointeur sur "char"
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char lettre = 'A';
    SendString(&lettre, 1, 1);
    // par contre SendString va planter ou doit être modifier voir mon commentaire dans le dernier code tout en bas

    Si textToShow doit contenir plusieurs lettres alors textToShow aurait du être un tableau "char" ou bien un pointeur vers un tableau vide.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char tableau_a_afficher [27];
    tableau_a_afficher [0] = 'A';
    tableau_a_afficher [1] = 'B';
    SendString(tableau_a_afficher, 1, 1);
    // par contre SendString va planter ou doit être modifier voir mon commentaire dans le dernier code tout en bas
    ou avec un pointeur qui n'a pas d'intérêt car ça va manger un peut de mémoire inutilement mais c'est pour l'exemple.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char tableau_a_afficher [27];
    char *textToShow = tableau_a_afficher;
    *textToShow = 'A';
    *textToShow++ = 'B';
    SendString(textToShow, 1, 1);
    // par contre SendString va planter ou doit être modifier voir mon commentaire dans le dernier code tout en bas

    En ce qui concerne le code que tu as récupéré, voir ci dessous, j'ai glissé mon commentaire perso
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    void LCD::SendString(char* strToWrite, int line, int pos)
    {
    	[...]
    	while (*strToWrite) // personnellement je trouve ça dangereux comme condition !!!!
    // en C quand tu initialise par exemple char* string = "ceci est une chaîne"; le compilateur insert à la fin un caractère que tu ne vois pas : \0 
    // c'est le caractère de fin de chaînes. Et ce fameux \0 est la condition de sortie de la boucle while. Sauf que quand tu te mets a faire des 
    // copie de tableau ou de chaîne de caractère en jouant avec des pointeurs de pointeurs de tableau, si jamais ce caractère passe à la trape
    // la boucle while va planter et comme juste en dessous on se sert d'un pointeur, celui ci ira attérir n'importe où !!! Donc plantage.
    // Ce code n'est pas prévu pour recevoir un caractère unique de type char. Ni même un tableau initialisé manuellement.
    //
    // Exemple qui marche :
    // char* test1 = "Bonjour";
    // SendString(test1, 1, 1);
    //
    // Exemple qui marche :
    // char test2 [] = "Bonjour";
    // SendString(test2, 1, 1);
     
    // Exemple qui devrait planter car pas de \0:
    // char test3 [7] = {'B', 'o', 'n', 'j', 'o', 'u', 'r'};
    // SendString(test3, 1, 1);
     
    // Exemple qui devrait planter car pas de \0:
    // char test4 [7];
    // test4 [0] = 'B'; 
    // test4 [1] = 'o'; 
    // test4 [2] = 'n'; 
    // test4 [3] = 'j'; 
    // test4 [4] = 'o'; 
    // test4 [5] = 'u'; 
    // test4 [6] = 'r';
    // SendString(test4, 1, 1);
     
    // Et là ça remarche car on gère le \0:
    // char test5 [8];
    // test5 [0] = 'B'; 
    // test5 [1] = 'o'; 
    // test5 [2] = 'n'; 
    // test5 [3] = 'j'; 
    // test5 [4] = 'o'; 
    // test5 [5] = 'u'; 
    // test5 [6] = 'r';
    // test5 [7] = '\0';
    // SendString(test5, 1, 1);
     
     
    		this->Character(*strToWrite++);
     
    	[...]}

    Petite remarque au passage, sur un micro il faut éviter d'embriquer des fonctions (fonction qui en appel une autre et qui en rappel une autre etc...) car la pile dans un micro n'est pas très grande contrairement a un PC. Et on arrive vite au stack overflow !!!

    Est ce que je suis clair dans mon explication ? Ou veux tu que j'explique autrement ?
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  14. #14
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Condition d'arret de boucle dangeureuse mais finalement normale pour gérer des chaines de caractères en C : comment crois-tu que fonctionne une fonction aussi basique que strlen() ?

  15. #15
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Oui en effet, "strlen" fonctionne de cette manière et il fonctionne parfaitement bien en utilisant "strcpy" car ce dernier inclus le caractère de fin de chaîne afin de rendre compatible la sortie de boucle sur un '\0'.
    Mais LDami nous fait des copies de tableau de caratères manuellement si je puis dire et sans "strcpy" d'où l'oubli du '\0' et il créait des incompatibilités.

    J'aurai surement du préciser que c'est une condition dangeureuse dans ce contexte.

    Pire encore, sur un microcontrôleur du gabarit de Arduino, tu as rarement un OS pour te protéger des "segments faults" et un tel problème peut t'envoyer potentiellement écrire n'importe où. Si tu étais entrain de faire un pousse seringue à affichage graphique... je te raconte pas les dégâts
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

Discussions similaires

  1. Réponses: 1
    Dernier message: 03/07/2011, 12h07
  2. Réponses: 3
    Dernier message: 29/10/2010, 10h24
  3. Longueur d'une chaine Text sur l'écran
    Par GSXRider dans le forum C#
    Réponses: 2
    Dernier message: 20/02/2008, 09h23
  4. Alignement d'un texte sur des écrans de taille différent
    Par Kuchiki Byakuya dans le forum Balisage (X)HTML et validation W3C
    Réponses: 9
    Dernier message: 05/02/2007, 19h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo