Go Down

Topic: [Resolu] Programmation de base ... (Read 2309 times) previous topic - next topic

zeric

Apr 09, 2012, 09:30 pm Last Edit: Apr 23, 2012, 10:13 pm by zeric Reason: 1
Bonjour,
Bête question que voilà :
Pourquoi je n'affiche pas mon message (ni l'animation) de la boucle "for" du loop  sur le lcd,
alors que je reste appuyé sur le bouton "select" du keypad shield ?
Je vois bien sur le terminal qu'il est dans la boucle, vu le temps qu'il met à afficher le chiffre suivant,
mais rien sur le lcd !
Je pense que je suis fatigué, je n'y arrive plus ... merci d'avance pour votre aide!

Code: [Select]
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char S1[] = "Arduino Rocks ?";
byte bouton;
int vBouton; //LCD keypad shield value

void setup(){
Serial.begin(9600);
pinMode(A0, INPUT);
lcd.begin(16, 2);
titre();
}

void titre(){
lcd.setCursor(15,0);
lcd.print(S1);
 for (byte pos = 0; pos < 15; pos++){
lcd.scrollDisplayLeft();
delay(190);
}
}

void appui(){
vBouton =analogRead(0);
if (vBouton >1010) bouton = 0;
else if (vBouton >715 && vBouton <725) bouton = 1; //select
else if (vBouton >473 && vBouton <483) bouton = 2; //left
else if (vBouton >123 && vBouton <133) bouton = 3; //up
}

void loop(){
appui();
Serial.println(bouton,DEC);
delay(150);
if (bouton==1){
lcd.setCursor(1,1);
lcd.print("En cours");
for (byte i=10; i<15; i++){
lcd.setCursor(i,1);
lcd.print("*");
delay(200);
}
for (byte i=14; i>9; i--){
  lcd.setCursor(i,1);
lcd.print("-");
delay(200);
}
}
}

barbudor

Comment est reliée la broche Vo (broche numéro 3) de ton LCD ?
Essaye en la reliant à GND.

(J'ai perdu presque 1 journée pour la même co....rie)

zeric

#2
Apr 09, 2012, 09:59 pm Last Edit: Apr 10, 2012, 11:10 pm by zeric Reason: 1
c'est celui là :

http://docs.google.com/leaf?id=0B6hLuy3sB5ntYzNmNDQ0OTMtOWZmYi00NjI3LTllZGYtNWM2ZWQ0M2FmODUw&hl=en

Edit: Regardez bien le cablage de ce shield, le transistor est un CMS caché sous le LCD et piloté par la borne D10, il sera donc bienvenu
de ne pas utiliser cette borne dans un sketch sous peine de :
- dans le meilleur des cas, le sketch ne fonctionne pas comme vous voulez.
- dans le pire des cas, D10 = game over !
(ce problème n'interfère pas dans mon code :()

zeric

Et ce n'est pas une histoire de masse, le message lancé depuis le setup s'affiche très bien ...

barbudor

Ok. Parce que avec le montage indiqué et le curseur du potar au milieu, sur mon montage rien ne s'affichait.
Il fallait mettre le curseur très près de la masse pour avoir un contraste qui permettait de voir quelque chose.

Donc le "titre()" s'affiche mais pas le reste.

Sinon, tu n'es pas clair : qu'est-ce qui ne marche pas exactement ?
- la détection du bouton
- l'affichage sur LCD dans la boucle ?

Cas 1 : détection du bouton

Qu'affiche le Serial.println(bouton,DEC); dans la boucle ?
Tu vois bien bouton passer à 1 ?

Les fenètres de comparaison me semblent bien serrées
J'aurais écrit quelque chose du genre :
Code: [Select]

if ( vBouton < 256 )
  bouton = 3;
else if ( vBouton < 512 )
  bouton = 2;
else if ( vBoutton < 768 )
  bouton = 1;
else
  bouton = 0;


Cas 2 : Affichage

Vire tout ce qui concerne le bouton dans la boucle et ne garde que le code d'affichage sur le LCD.
Ca marche ?

zeric

Bonjour,
Tout d'abord, le code que j'ai posté est directement chargeable dans un arduino, que l'on "coiffe" d'un LCD Keypad Shield standard.
Je vais faire plus clair, j'utilise une Duemilanove et l'IDE 0022.
La détection des 3 boutons fonctionne très bien, seul l'affichage de "en cours" et de la petite animation ne se fait pas sur le LCD.
Les fenêtres de comparaison sont très larges à mon goût (le delta ne dépasse jamais 1 lors de l'appui sur un bouton).
Je n'ai pas jugé utile de dire que l'affichage de la boucle fonctionnais sans le bouton, puisque le but est justement de comprendre
pourquoi cela ne fonctionne pas dans ce cas précis.
Merci d'avance.

zeric

Si personne ne trouve le pourquoi du comment, je suis dans la mouise, parce-que c'est un problème en 2 étapes !
Allez, ça aiguisera peut-être l'appétit des plus fort :smiley-sleep: en codage  :
Si j'utilise un variable bistable (à la place de mon test sur le bouton) pour rentrer dans les 2 boucles "for", je ne peux
pas sortir de ces mêmes boucles avec un break conditionné à l'intérieur, et je suis donc obligé d'attendre la fin des 2 boucles...

Code: [Select]
for (byte i=10; i<15; i++){
if (bouton == 2) break; //test du bouton, marche pas!
if (vBouton >473 && vBouton <483) break; //test de la valeur du bouton, marche pas!
if ( (bouton == 2) || (vBouton >473 && vBouton <483) break; //ben décidemment, marche pas!
lcd.setCursor(i,1);
lcd.print("*");
delay(200);
}


...je vais quand même pas faire comme la pub à la télé du gars qui explose ces écrans LCD quand ça le gonfle  ]:D


barbudor

Je suis partit en déplacement mais demain si je suis pas trop crevé quand je rentre je compte faire l'essai moi-même.
j'ai justement un écran LCD sur ma table ;)
A moins que quelqu'un d'autre le fasse avant...
Mais c'est vrai que comme cela, il n'y a rien qui me saute aux yeux.

Quoi que je n'ai pas regardé la specs de ton shield.
Il viens d'où ?
Lien ?
Schémas ?

zeric

Euh, comme quoi, je ne suis pas le seul à être fatigué  :P, le lien qui donne le schéma est un un peu plus haut ;)

barbudor

:P toi-même 
:D

J'avais inversé D8 et D9
Je reteste
I'll be back

barbudor

#10
Apr 11, 2012, 10:04 pm Last Edit: Apr 12, 2012, 01:27 pm by barbudor Reason: 1
J'ai compris.
Ca a été long (et pas très bon  :smiley-sad-blue:) mais j'ai compris

Remplace ton code dans la boucle par :
Code: [Select]
if (bouton==1){
lcd.setCursor(15,1);
lcd.print("En cours");
for (byte i=10; i<15; i++){
lcd.setCursor(15+i,1);
lcd.print("*");
delay(200);
}
for (byte i=14; i>9; i--){
  lcd.setCursor(15+i,1);
lcd.print("-");
delay(200);
}
}


:D
Si ça marche aussi chez toi, réfléchit.
je t'accorde 24H.....

EDIT: Alors ? Tu as trouvé ? Le suspens est à son comble..... Plus que quelques heures !  :smiley-mr-green:

zeric

Bonjour,
Désolé pour les 24h, je ne suis pas connecté depuis  :smiley-red:
Ça m'a permis de me reposer :smiley-sleep:
J'ai donc réfléchi, comme tu me le demandais  ]:D au manque de logique de ton décalage (i+15) !
Et après 2/3 essais  :* , je pense avoir pointé la cause ! (sans avoir à mettre ce décalage)
Ma routine titre() ne devrait normalement pas interférer avec le loop vu qu'elle est appelée une seule et unique fois (dans le setup)
L'enlever étant la solution de facilité, j'ai re-réfléchi  ;) :
C'est pas le positionnement du curseur à 15, c'est pas la boucle for, c'est le "lcd.scrollDisplayLeft();" :smiley-eek:
J'ai bien essayé de comprendre la librairie "LiquidCrystal.cpp", mais le newbie que je suis à besoin d'apprendre  :smiley-roll-sweat:
Donc c'est moi qui n'ai pas compris ou c'est un bug de la librairie ? (je penche pour la 1° solution)

barbudor

Salut

Ce n'est pas un bug de la lib, ou alors un bug de nommage.
Tout le problème tient dans la définition de ce que fait la fonction "lcd.scrollDisplayLeft()", ou plutot la commande correspondante qui est envoyé au LCD.

En fait quand on lit le nom de cette fonction on s'attend à ce qu'elle prenne tous les caractères qui sont dans l'affichage et les décales vers la gauche. En fait ce n'est pas le cas.

Tous les écrans de ce genre sont basés sur le même composant de gestion HD44780 qu'ils soient 2x16, 2x20, jusqu'à 2x40
A l'intérieur du composant il y a une mémoire organisé en 2x40 caractères
Quand l'écran est plus petit que 2x40, ce qui est affiché est une fenêtre sur cette mémoire.
Or cette fenêtre est glissante.

La commande "lcd.scrollDisplayLeft()" ne va pas déplacer les caractères dans la mémoire vers la gauche mais elle va déplacer la fenêtre d'affichage vers la droite.

A l'initialisation, la fenêtre affiche les colonnes 0 à 15.
Ensuite quand tu place ton curseur en 0,16 et que tu écris "Arduino Rocks ?", tu écris dans les colonnes 16 à 32 en mémoire.
La commande lcd.scrollDisplayLeft() va ensuite décaler la fenêtre de visu vers les colonnes 16 à 32 et non pas déplacer les caractères vers 0 à 15.

Donc pour que la phrase "En cours" soit visible en dessous de "Arduino Rocks ?", il faut l'écrire 16 caractères plus loin en (1,16)

Donc ton code marchait bien.
Individuellement les fonctions marchaient toutes seules mais dès qu'on les met ensemble elles donnaient l'impression de ne plus marcher car on ne voyait pas "En cours" s'afficher puisque en dehors de la fenêtre de visu courante.

A+

zeric

Merci barbu !
Je l'aurais vu dès le départ si j'avais mis depuis le départ la dernière modif de mon programme !
(au début j'affichais mon texte au bon endroit, un scroll à droite hors de l'écran, et un retour à gauche vers l'origine)
La fonction ne me plaît pas, je vais faire une routine de scroll...
Bon, je vais retenter la 2°étape et je reviens  XD

zeric

Me revoilà!
Code: [Select]
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

boolean bp1;
byte bouton;
int vBouton; //LCD keypad shield value

void setup(){
Serial.begin(9600);
pinMode(A0, INPUT);
lcd.begin(16, 2);
}

void appui(){
vBouton =analogRead(0);
if (vBouton >1010) bouton = 0;
else if (vBouton >715 && vBouton <725) bouton = 1; //select
else if (vBouton >473 && vBouton <483) bouton = 2; //left
else if (vBouton >123 && vBouton <133) bouton = 3; //up
}

void loop(){
appui();
Serial.println(bouton,DEC);
delay(150);
if (bouton == 1) bp1 = true;

if (bp1 == true){
lcd.setCursor(1,1);
lcd.print("En cours");
for (byte i=10; i<15; i++){
if (bouton == 2) break;
lcd.setCursor(i,1);
lcd.print("*");
delay(200);
}
for (byte i=14; i>9; i--){
if (bouton == 2) break;
  lcd.setCursor(i,1);
lcd.print("-");
delay(200);
//bp1 = false;
}
}
}


Bon, pourquoi mes "break" conditionnés ne fonctionnent que lors de la sortie des 2 boucles ?
Une bonne âme ?

Go Up