Gestion afficheurs, 2013/2014, TD1

De Wiki d'activités IMA
Révision datée du 10 juin 2014 à 13:37 par Rkrikori (discussion | contributions) (D. Faut que ça bouge !)
Fichier:Gestion afficheurs compressé.mp4
Vidéo : http://projets-imasc.plil.net/mediawiki/images/d/df/Gestion_afficheurs_compress%C3%A9.mp4

Projet SC :

Gestion d'afficheurs 16 segments


Partie programmation

Cette partie sera décomposée en X parties correspondant aux X difficultés rencontrées lors de ce projet.


1. Gérer la liaison série

Pour transmettre notre programme au banc d'essai, il faut tout d'abord initialiser ce banc d'essai et dire à notre contrôleur (ici l'ordinateur) où il se trouve.

Ceci ne constituais pas une grande difficulté étant donné que de nombreux travaux avaient déjà étaient fait sur la liaison série et que le code permettant de l'initialiser était sur le wiki :

  stty -F /dev/ttyACM0 9600 cs8 \
 -hupcl -icrnl -ixon -opost -onlcr -isig -icanon \
 -iexten -echo -echoe -echok -echoctl -echoke ignbrk

source : http://rex.plil.fr/Enseignement/Systeme/Projet.IMA3/systeme018.html

Il fallait rajouter une sécurité à cette initialisation pour éviter de perdre des données :

  sleep 9999d 3</dev/ttyACM0 &

source : http://rex.plil.fr/Enseignement/Systeme/Projet.IMA3/systeme018.html

Ces données seront réutilisées lors du passage à la FoxBoard. Notre Port série est maintenant configuré, on peut envoyer notre code !

2. Gestion des afficheurs 16 segments

A. Un afficheur : un caractère !

Nous avons vite compris que l'afficheur 16 segments était codé sur 16 bits.

Nous avons dans un premier temps affiché un code 16 bits (le 0x0001 par exemple) sur les 8 segments pour comprendre comment on pouvait gérer les 8 afficheurs.

Après plusieurs essais, nous avons opté pour la création d'un tableau qui contiendrai le message à afficher.

Dans le premier code nous avions un compteur d'afficheur qui recevait les cases du tableau. A chaque incrémentation compteur correspondait une incrémentation tableau, ce qui nous permettait d'afficher des caractères différents sur les afficheurs.


B. L'alphabet latin, un bonheur !

Maintenant que nous savons afficher, il faut maîtriser le contenu de l'affichage.

Nous avons donc mis chaque bit à 1 séparément (ex : 0x0001 puis 0x0002 puis 0x0004 ..) et reportés sur papier quel segment s'allumait pour ce bit.

Nous avons ensuite nommé chaque segment pour pouvoir créer nos caractères !

Cette technique nous permet de modéliser un afficheur :





C. Lire un fichier, c'est la base !

Notre application doit permettre de modifier le message affiché. Pour ce faire, notre page html modifiera un fichier et notre code C lira ce fichier pour créer le message. On présente maintenant le code de l'action "creer_message":

  void cree_message(FILE* fp)
  {
    int i=0,j=0;
    char car;
    while(j<8) { x[j]=0x0000; j++;}                 //Cette boule sert à initialiser les 8 afficheurs au caractère NULL (0x0000)
    while (!feof(fp))
      {
        fscanf(fp,"%c",&car);
        while((car!=carac[i])){i++;}               //Cette boucle stocke dans x le message du fichier en paramètre 
        x[j]=correspondance[i];                    //lit le premier caractere, on le cherche dans le tableau carc[]
        j++;                                       //on stocke dans x le code 16bits correspondant puis on incrémente la case j du message x
        i=0;                                       //on met i à 0 pour la recherche du caractère suivant
      }
    x[j--]=0x0000;                                 //Avec cette methode le dernier caractère est doublé car le fscanf n'est pas fait avant la boucle
    while (j<MAX_SIZE)                             //Ainsi on remet le dernier caractère du message x à NULL puis on met 8 caractère NULL qui serviront 
      {                                            //au défilement
        x[j]=0x0000;
        j++;
      }
  }



D. Faut que ça bouge !

Dans un afficheur publicitaire, les messages défilent de droite à gauche.

Pour reproduire cet effet, nous procédons en 3 étapes!

Étape 1 : Créer le message et afficher les 8 premiers caractères → Cette étape est décrite dans la partie précédente Étape 2 : Afficher la suite du message pas à pas → Pour ce faire, on utilise deux boucles, dont une qui commence quand les 8 premiers caractères du tableau ont été affichés → On parcours le tableau au complet en incrémentant à chaque période le code que l'afficheur reçoit de 1 dans le tableau

Étape 3 : Une boucle infinie → On utilise un «  while 1 » sur tout le main pour pouvoir revenir au début de notre tableau contenant le message et ainsi afficher le message en continu !

Cette action est l'action principale de notre application, c'est-à-dire que nous avons choisi de la mettre dans le main étant donné qu'elle boucle sur 1

Voici donc la partie du main qui gère le défilement:


    unsigned char low[MAX_SIZE];                            // correspondance est codé sur 16 bits, mais on ne peut envoyer que 8bits à la fois
    unsigned char high[MAX_SIZE];                           // on découpe donc le tableau message en 2 tableaux low et high
    int sd=serialOpen(SERIAL_DEVICE,SERIAL_BOTH);           // ouverture du port série
    int i=0,z=0,a=0,tot=0;
    while(1)
    {
       FILE*fp=fopen(argv[1],"r");
       if(fp==NULL){ perror("fopen(message)"); exit(-1); }  // vérification du bon déroulement de l'ouverture du fichier passé en argument
       cree_message(fp);                                    // on crée le message x
       for(i=0;i<MAX_SIZE;i++)                              // i va servir à lire dans le message x 

{

          if (i>8) a++;                                     // cette ligne permet d'initialiser rapidement sans devoir décaler les 8 premiers caractères

tot=i+a; // NULL, puis on stocke l'endroit où on va lire dans tot (i + le nombre de fois ou on a été for(z=0;z<8;z++) // au dessus de 8) { low[z] = x[tot] & 0x00ff; // La correspondance est en 16 bits, or l'envoi sur z se fait en 8bits, ces fonctions nous high[z]= x[tot]>>8; // permettent de stocker correctement sur z, z représentant le numéro de l'afficheur if(write(sd,&high[z],sizeof(char))!=1){ perror("main.write"); exit(-1); } //Écriture sur l'afficheur if(write(sd,&low[z],sizeof(char))!=1){ perror("main.write"); exit(-1); } usleep(delai); tot++; } if (tot>MAX_SIZE) i=MAX_SIZE;} // Cette ligne nous permet de sortir un peu plus rapidement de la //boucle lorsque le message a été affiché tot=0; // on réinitialise les variables pour le message suivant, on ferme fp a=0; i=0; z=0; fclose(fp);

      }

On sait désormais lire notre message et le faire défiler, mais nous sommes loin d'avoir répondu au cahier des charges !

D. Le cahier des charges

Les deux grands axes du cahier des charges concernant la programmation sont les suivants :


1) Par le biais d'une page php (que nous verrons plus tard), nous modifierons un fichier.txt contenant le message à afficher. Ce message peut être modifié pendant l’exécution et dois défiler en continu.

2) Par le biais d'une page php, la vitesse de défilement peut être modifiée.


1) Le fichier texte !

La modification du fichier texte

2) La vitesse de défilement






Partie électronique :

Première séance :

Découverte du projet et du cahier des charges.

Prise en main du logiciel altium et suivi partiel du tutoriel.


Deuxième séance :

Fin du tutoriel proposé. Compréhension du schéma.

Définition du cahier des charges de notre projet et proposition de schéma électronique.

Découverte d'un possible problème sur nos afficheurs à anode commune (contrôle par la masse)


Troisième séance :

Mise en place du schéma électronique établi à la séance précédente sur altium.

Correction des quelques problèmes rencontrés puis simulation (réussie) du schéma.

Problème des afficheurs confirmé (courant et tension admissibles), étude avec les deux professeurs des solutions possibles.

Câblage d'une solution retenue (driver de leds + 2 demi afficheurs) -> la solution résolve partiellement le problème (on peut fournir une tension et un courant correct).

Commande de 4 transistors pouvant résoudre le dernier problème électronique (contrôle des afficheurs).


Quatrième séance :

Câblage de l’autre moitié du premier afficheur. Le reste ne sera pas câblé car trop long et inutile pour résoudre le problème des transistors.

Les transistors n’ont pas permis de contrôler séparément chacun des afficheurs, car leur tension de seuil de déclenchement est trop élevée par rapport à la tension que l’on récupère déjà à côté pour les drivers de leds et afficheurs.

On a cependant une petite simulation de 3 caractères (IMA) pour montrer que notre montage fonctionne (on peut afficher les caractères désirés, mais le défilement ne s'effectue pas. Il faudrait trouver quatre transistors capables de se déclencher avec les 3,3V max que la nanoboard peut fournir, sachant que les leds s'allument avec une tension minimale de 3,8V).


Explications détaillées :

Après avoir pris en main la NanoBoard grâce au tutoriel proposé (http://rex.plil.fr/Enseignement/Systeme/Projet.IMA3/tutoriel_nanoboard.pdf), nous avons établi un cahier des charges pour notre projet.
Voici l’idée globale retenue pour le circuit :

Schéma théorique


Explications :


On récupère les informations du port série, ainsi que son signal d’horloge. On mémorise ces informations grâce aux bascules, elles même gérées par un démultiplexeur relié à l’horloge du port série. On cadence ainsi les informations afin que le multiplexeur les reçoivent une par une. Le décodeur va ensuite choisir tour à tour un afficheur grâce au signal d’horloge, et le multiplexeur envoie ainsi une information sur tous les afficheurs, mais seulement un sera allumé à ce moment grâce au décodeur.
Il nous est possible d’envoyer qu’un seul bus de 16 bits sur les afficheurs reliés en dérivation, car la fréquence de sélection du décodeur est bien plus rapide que la fréquence rétinienne de l’homme. On a donc l’impression que le message est fixe avec un caractère affiché sur chaque afficheur, alors qu’en réalité il a toujours qu’un seul afficheur d’allumé.

Après plusieurs essais, voici notre circuit définitif sur Altium :

Circuit sur Altium


Nous avons dissocié les deux compteurs afin de pouvoir contrôler la fréquence d’affichage des caractères.

Simulation :


Simulation

Dans le rectangle du haut nous pouvons envoyer le code binaire d’un caractère à afficher. Le rectangle du dessous permet d’envoyer ce code en mettant l’horloge à 1. Au milieu nous gérons la fréquence d’affichage (ici 2Hz afin d’avoir le temps de prendre une photo). Puis dans l’avant dernier rectangle on peut voir que notre code binaire se déplace correctement. Et dans le dernier un voit quel afficheur est sélectionné par le décodeur.

Tests sur l'oscilloscope


On voit ici de D7 à D4 les 4 bascules, et de D0 à D3 les 4 codes binaires envoyés.

Câblage :


Après cette simulation concluante, nous avons commencé le câblage. Celui-ci s’est avéré fastidieux dès le départ, car le simple fait d’avoir 4 afficheurs pour lesquels il fallait 16 fils chacun nous promettait de nous y faire consacrer une bonne partie de la séance.
En regardant la datasheet de la NanoBoard sur internet nous avons constaté que les sorties de la carte pouvaient fournir au maximum 3,3V chacune (dont une à 5V), et notre encadrant nous a dit qu’il valait mieux ne pas tirer plus de 20mA par sortie.
Le problème alors rencontré est que nos afficheurs ont une led par petits segments, et deux par grands segments. Après quelques tests avec l’encadrant, nous avons constaté qu’il fallait minimum 3,8V pour un grand segment si on voulait l’allumer avec 20mA. La NanoBoard ne permettait donc pas d’allumer tous les segments (ce sont des afficheurs à anode commune).

Datasheet des afficheurs
Câblage









Un rapide calcul nous a permis de déterminer la valeur des résistances à mettre avant chaque afficheur : une résistance de 50Ω (47Ω) pour un petit segment, une de 300Ω pour un grand (270Ω).
La solution retenue après discussion avec les deux encadrants a été d’utiliser deux amplificateurs (drivers ULN2803) pour avoir une bonne tension sur nos afficheurs. Le problème créé avec cette solution est que nous ne pouvions plus contrôler séparément nos afficheurs. Nous avons donc eu l’idée d’utiliser un transistor par afficheur, qui recevrait l’ordre de commande des sorties de la carte correspondants à celles du décodeur.
Après plusieurs tests, nous avons compris que ceux utilisés (des TMOS) ne pourraient fonctionner car leur tension de seuil VGS est plus élevée que les 3,3V que peut fournir notre carte.

Julian 7.jpg



Conclusion :


Ce projet nous a permis de mettre en pratique nos connaissances informatiques et électroniques acquises au cours de l'année.
Nous aurions aimé pouvoir relier directement la partie informatique à la partie électronique afin de pouvoir tester la totalité du projet.