Go Down

Topic: [Résolu] Problème de codage (relativement) simple (Read 2183 times) previous topic - next topic

loquesea

Sep 03, 2011, 09:27 pm Last Edit: Dec 17, 2011, 11:31 am by loquesea Reason: 1
Bonjour,

Je débute dans la programmation et l'électronique, aussi j'aimerais avoir une aide en rapport avec un script sur lequel je travaille.

Je vous explique mon projet, je voudrais afficher sur un mur de 25*6 LED le rang de chaque lettre tapé sur un clavier, en binaire.
Ainsi, si je tape 'abcd', la première diode de la première rangée sera allumé (1), la deuxième de la seconde rangée (10), les deux premières de la troisième (11) et la troisième de la quatrième rangée (100). (J'espère etre clair... :/)

Mon soucis se pose lors de l'affichage, j'ai déjà la matrice de faite et elle fonctionne correctement, c'est mon script qui est 'déficient'.
Je n'arrive pas à faire afficher tous les caractères et qu'ils restent affichés, ils s'affichent tous, mais une demi seconde, puis c'est le dernier caractère qui s'affiche sur toutes les rangées.

J'ai essayé avec d'autres boucles (while) mais j'ai surement pas su l'utiliser correctement.

J'espère que mon problème vous semble clair et que vous saurez m'aider.

Je vous joint mon script.

Merci d'avance :)

skywodd

Bonjour,

Comme ça sans regarder le principe je vois des trucs pas nette :

Code: [Select]

int clavier = 0;

int led[5]={2,3,4,5,6}; // 5 led = 5 pin OK donc un tableau allant de 0 à 4

int clock= 11;

int j=0; // cette variable ne sert à rien !?

void setup() {
  Serial.begin(9600);
  for (int i=0; i <=5; i++){ // la boucle va de 0 à 5 -> erreur le tableau ne va que jusqu'a 4 !
    pinMode(led[i], OUTPUT);
  } // et le pinMode de la pin clock ?
}

void loop() {
  if (Serial.available() > 0) {
    clavier = Serial.read();
    //  Serial.print("I received: ");
    //  Serial.println(clavier-64, BIN);
    for(int i=0; i<5; i++){
      int val =(clavier>>i)&1; // peut être remplacer par la macro bitRead pour rendre le debug plus simple
      digitalWrite(led[i], val);
      Serial.print(val);
      Serial.println(); // inutile de faire un print(val) puis un println un println(val) suffit
    }
  }
  digitalWrite (clock,HIGH); // un petit delayMicroseconds(10) serait pas utile entre ces deux digitalWrite ?
  digitalWrite (clock,LOW);
}


Code: [Select]

int clavier = 0;
int led[5]={2,3,4,5,6};
int clock= 11;

void setup() {
  Serial.begin(9600);
  for (int i=0; i < 5; i++)
    pinMode(led[i], OUTPUT);

  pinMode(clock, OUTPUT);
}

void loop() {
  if (Serial.available() > 0) {
    clavier = Serial.read();
    for(int i=0; i < 5; i++){
      int val = bitRead(clavier, i);
      digitalWrite(led[i], val);
      Serial.println(val);
    }
  }
  digitalWrite (clock,HIGH);
  delayMicroseconds(10);
  digitalWrite (clock,LOW);
}


Pour le probléme de refresh sans un schémas et une explication plus clair c'est pas simple de savoir ou ce trouve le probléme.
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

loquesea

Bonsoir,

Voilà ci joint le montage, mais je crois m'être trompé avec la pin 13 , je l'ai branché à la masse alors qu'il me faudrait la brancher à un état haut.
J'intègre vos modifications à mon script, j'ai juste une question quand au delay de la fin, pourquoi ?

Et je ne sais pas comment etre plus clair dans les explications, qu'est ce qui vous échappe ?

Merci de votre aide :)

skywodd


Voilà ci joint le montage, mais je crois m'être trompé avec la pin 13 , je l'ai branché à la masse alors qu'il me faudrait la brancher à un état haut.
J'intègre vos modifications à mon script, j'ai juste une question quand au delay de la fin, pourquoi ?

Le delay permet d'avoir un etat haut bien stable et permettre au 4017 d'incrémenter son compteur.


Et je ne sais pas comment etre plus clair dans les explications, qu'est ce qui vous échappe ?

Avec le schémas c'est beaucoup plus clair ^^

Aulieu d'utiliser plusieurs digitalWrite il serait plus intérrésant d'utiliser la manipulation de port :
http://www.arduino.cc/playground/Learning/PortManipulation
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

loquesea

:D
oui, heu, seulement j'utilise une Uno moi, vous pensez qu'il me faudrait utiliser une Méga plutot pour ce genre de circuit ?

skywodd


:D
oui, heu, seulement j'utilise une Uno moi, vous pensez qu'il me faudrait utiliser une Méga plutot pour ce genre de circuit ?

Pas besoin d'une mega ;) la maipulation de port est dispo sur tout le ATmega que ce soit une uno ou une mega (ou autre).
Le (+) c'est qu'avec la manip de port chacune des 5 broches sera placé à l'état qui va bien en une seul fois.

Petit exemple avec ton script actuelle :
Quote

int clavier = 0;   
int clock= 11;

void setup() {
  Serial.begin(9600);   
  DDRD |= 0xEC; // Pin D2, D3, D4, D5 en sortie
  pinMode(clock, OUTPUT);
}

void loop() {
  if (Serial.available() > 0) {
    clavier = Serial.read();
    PORTD = (clavier << 2) & 0xEC; // on déplace de 2bit vers la gauche pour évité de perturber le port série sur PORTD.0 et PORTD.1
   
    digitalWrite (clock,HIGH); // peut être que placer le signal d'horloge réglerai le probléme de refresh ? à voir.
    delayMicroseconds(10);
    digitalWrite (clock,LOW);
  }
}
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

loquesea

#6
Oct 07, 2011, 02:59 pm Last Edit: Oct 07, 2011, 03:26 pm by loquesea Reason: 1
Bonjour,

Je me replonge dans ce problème avec plusieurs questions.

Premièrement, je n'ai trouvé dans aucune partie de la documentation que tu m'as fourni (http://www.arduino.cc/playground/Learning/PortManipulation) l'utilisation de ce qu'il me semble etre de l'héxa, seulement du binaire, aussi, le 'DDRD |= 0xEC;' je ne le comprends pas, j'aurais plutot utilisé un 'DDRD = B01111100'

Ensuite, ton code permettait un affichage sur une seule rangée, pas les trois, et de façon aléatoire, un coup c'était la première, un coup la troisième, un coup aucune.

Après, j'ai ressoudé la pin 13 du 4017 à un état haut, ce qui donne, en reprenant ton code :
Code: [Select]

int clavier = 0;  
int clock= 11;
int clkenbl = 10;  

void setup() {
 Serial.begin(9600);  
 DDRD |= 0xEC;
 pinMode(clock, OUTPUT);
 pinMode(clkenbl, OUTPUT);
}

void loop() {
 if (Serial.available() > 0) {
   clavier = Serial.read();
   PORTD = (clavier << 2) & 0xEC;
   digitalWrite (clock,HIGH);
   digitalWrite (clkenbl,HIGH);
   delayMicroseconds(10);
   digitalWrite (clock,LOW);
   digitalWrite (clkenbl,LOW); // sans cet digitalWrite, l'affichage se faisait uniquement sur la première rangée, je ne comprends pas non plus pourquoi... :/
 }
}


Du coup, sur le schéma, la pin 13 du 4017 est relié à la D10 de l'arduino

[edit] Et j'ai remarqué que dans ta table ASCII le 'Z' et le 'a' ne se suivaient pas directement, or, j'aimerais que ce soit le cas, qu'il y ait une continuité entre les lettres, j'ai pensé à un tableau, mais ça me semble laborieux.

Des éclairages ? :)

Merci déjà beaucoup pour ce que tu as pu faire, et d'avance merci pour les prochains conseil :)

skywodd

Quote
Premièrement, je n'ai trouvé dans aucune partie de la documentation que tu m'as fourni (http://www.arduino.cc/playground/Learning/PortManipulation) l'utilisation de ce qu'il me semble etre de l'héxa, seulement du binaire, aussi, le 'DDRD |= 0xEC;' je ne le comprends pas, j'aurais plutot utilisé un 'DDRD = B01111100'

Écrire DDRD = B01111100 ou DDRD = 0x7C revient à faire la même chose, l'ide arduino va juste remplacer le Bxxxxxxxx par le 0xXX correspondant.

Le DDRD |= 0xEC; permet de modifier la configuration des broches D2 à D7 sans toucher à celle de D0 et D1, toucher à ces broches perturberaient le bon fonctionnement du port série.

Quote
Ensuite, ton code permettait un affichage sur une seule rangée, pas les trois, et de façon aléatoire, un coup c'était la première, un coup la troisième, un coup aucune.

Je n'est pas du bien comprendre ton câblage ... le CD4017 est un compteur, donc chaque lignes est contrôlé par les broches D2 ~ D3 et les colonnes par l'incrémentation du compteurs ?
En faite ce qui me perturbe c'est ton câblage du CD4017, le schémas N&B issue de fritzing est relativement illisible, de plus je viens de remarquer une incohérence dans ton montage, la broche 15 (reset) devrait être connecter à la broche 7 (Q3) ainsi à la 3eme impulsions d'horloge le CD4017 repartirai de 0, sans cela il est évident que l'affichage soit saccadé/illisible.

Quote
digitalWrite (clkenbl,LOW); // sans cet digitalWrite, l'affichage se faisait uniquement sur la première rangée, je ne comprends pas non plus pourquoi... :/

Le CD4017 s'incrémente sur des fronts montant il faut donc repasser la broche d'horloge de LOW à HIGH puis à LOW pour générer une impulsion.
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

loquesea

Bon encore une fois merci pour ton aide, mais c'est pas encore fini ! XD

Quote
Je n'est pas du bien comprendre ton câblage ... le CD4017 est un compteur, donc chaque lignes est contrôlé par les broches D2 ~ D3 et les colonnes par l'incrémentation du compteurs ?


C'est ça, seulement que les broches sont D2 D3 D4 et D5

Quote
En faite ce qui me perturbe c'est ton câblage du CD4017, le schémas N&B issue de fritzing est relativement illisible, de plus je viens de remarquer une incohérence dans ton montage, la broche 15 (reset) devrait être connecter à la broche 7 (Q3) ainsi à la 3eme impulsions d'horloge le CD4017 repartirai de 0, sans cela il est évident que l'affichage soit saccadé/illisible.


J'ai résolu ça, et ça s'approche du fonctionnement que j'attends, seulement avec un seul caractère, donc lettre; si j'en envoi plusieurs (2 ou 3), les premiers s'affichent mais un instant juste, le temps de les apercevoir, après seul le dernier est allumé.

Quote
le schémas N&B issue de fritzing est relativement illisible


Tu aurais un autre logiciel libre à me suggérer ?

Après, peut etre mon approche n'est pas bonne. Aussi j'ai pensé à un code qui mettrais en place ce que j'appelle une temporisation, je crois le terme n'est pas le bon, c'est pour ça que j'explique :
l'idée serais de stocker dans une variable chaque lettre tapée, pour ensuite les rebalancer sur le circuit de façon cyclique, dans une boucle, un exemple ? En voici un :

je tape AZE, le script stocke dans la première variable, que j'appellerais c1, pour caractère un, le A, dans c2, Z, et dans c3, E.
Et il les renvoie de façon cyclique dans le circuit.

Existe-t-il une fonction ainsi dans le 'langage' Arduino ?
J'ai beau eut chercher j'ai pas trouvé.

Merci encore pour ton aide :)

loquesea

Bonjour,

alors je crois que c'est bon, on m'as aidé à comprendre le problème, en fait le 4017 ne gère qu'une rangée, alors que je voulais qu'il y ait les trois d'allumées, aussi il me faut utiliser un multiplexeur ou un registre à décalage comme indiqué dans ce tuto ( http://www.instructables.com/id/Make-a-24X6-LED-matrix/ )
Je change alors ma stratégie et essaye cette méthode.

Je marque le sujet comme résolu puisque le circuit et le script sont amenés à changer,

Merci :)

Go Up