De0NanoExtension : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
Ligne 43 : Ligne 43 :
 
==={{Vert|Face Top de la carte}}===
 
==={{Vert|Face Top de la carte}}===
 
Nous avons dimensionné : les résistances : 10KΩ pour les boutons (incrémental/poussoirs), 220Ω pour le reste. Pour les condensateurs : 3 de 0.1uF, 1 de 10uF, et 100uF pour les condensateurs du bouton incrémental.
 
Nous avons dimensionné : les résistances : 10KΩ pour les boutons (incrémental/poussoirs), 220Ω pour le reste. Pour les condensateurs : 3 de 0.1uF, 1 de 10uF, et 100uF pour les condensateurs du bouton incrémental.
 +
 
Les pistes étant assez fines, certaines soudures se sont révélées difficiles.
 
Les pistes étant assez fines, certaines soudures se sont révélées difficiles.
 
Certaines difficultés sont apparues avec quelques vias, trop proches des composants (voir FaceTop2, via entre les deux leds).
 
Certaines difficultés sont apparues avec quelques vias, trop proches des composants (voir FaceTop2, via entre les deux leds).

Version du 19 janvier 2017 à 22:42

Projet carte extension pour DE0Nano 2016/2017 (Violette et Villaire)

Première Partie : Étude théorique

Présentation du projet

Le but de ce projet est de réaliser un shield multifonction, généraliste, sur une De0Nano. Les principaux composants qui vont être utilisés sont un afficheur 4x7 segments, un bouton à codage rotatif, 2 registres à décalage (74HC595), des boutons poussoirs et des leds. Avec un nombre d'entrées/sorties limitées, nous avons décidé de mettre sur la carte 4 leds et 3 boutons poussoirs, en plus du bouton incrémental, de l'afficheur, et des registres à décalage.

Afficheur4x7.jpg BoutonRota.jpeg 74HC595.png

Conception du schéma Eagle

Voici le schéma Eagle complet :

Schéma Eagle.png

Schéma individuel du bouton incrémental : Bouton incrémental.png

Schéma individuel des 3 boutons poussoirs : BoutonPoussoirs.png

Pour l'afficheur 4x7 segments, on a du créer une librairie, car notre composant n'existait pas : Afficheur.png

Nous avons pris la surface d'une carte arduino en modèle, afin d'avoir une idée de la taille du shield à réaliser.

ATTENTION : Pour de la programmation avec Arduino, comme notre shield utilise les broches 0 et 1 de l’Arduino (RX et TX), il faut téléverser le programme avant que le shield ne soit connecté... Pour des raisons pratiques, il serait préférable à l'avenir de laisser ces broches disponibles, quitte à mettre moins de composants de sur la carte.

Conception du routage Eagle

Modèle:Routage complet

Faire tenir tous les composants sur la surface d'une carte arduino est assez compliqué, nous avons donc "dépassé" un petit peu. Vu le nombre de composants à placer et la surface disponible, on se retrouve avec beaucoup de vias.

RoutageComplet.png

Modèle:Routage de la face Top

La face Top comprend le bouton incrémental, l'afficheur 4x7 segments, les 3 boutons poussoirs, les 4 leds, des résistances et des condensateurs, ainsi que les connecteurs.

FaceTop.png

Modèle:Routage de la face Bot

La face Bot comprend quant à elle les 2 composants 74HC595 (registre à décalage), ainsi que des résistances.

FaceBot.png

Deuxième Partie : Réalisation de la carte

Face Top de la carte

Nous avons dimensionné : les résistances : 10KΩ pour les boutons (incrémental/poussoirs), 220Ω pour le reste. Pour les condensateurs : 3 de 0.1uF, 1 de 10uF, et 100uF pour les condensateurs du bouton incrémental.

Les pistes étant assez fines, certaines soudures se sont révélées difficiles. Certaines difficultés sont apparues avec quelques vias, trop proches des composants (voir FaceTop2, via entre les deux leds).

ATTENTION : La carte étant double face, avec des composants CMS des 2 cotés, je vous conseille de passer d’abord la face avec le moins de composant au four, afin d'éviter des incidents au second passage. Avec cette carte, nous avons donc d'abord passer la face Bot au four.

FaceTop.JPG

FaceTop2.jpg

Face Bot de la carte

FaceBot.jpg

Troisième Partie : Test de la carte

Après la réalisation de la carte, il faut maintenant la tester, afin de dépanner les éventuelles erreurs. Nous avons donc réaliser quelques programmes afin de tester les différents composants.

Test des leds

const int L1 = 10; //Déclaration des broches
const int L2 = 11; 
const int L3 = 12; 
const int L4 = 13; 

void setup() 
{
  pinMode(L1, OUTPUT); //Les broches sont des broches de sortie
  pinMode(L2, OUTPUT); 
  pinMode(L3, OUTPUT); 
  pinMode(L4, OUTPUT); 
}
void loop() 
{

  digitalWrite(L1, HIGH); //Toutes les leds s'allument pendant 1 seconde
  digitalWrite(L2, HIGH); 
  digitalWrite(L3, HIGH);
  digitalWrite(L4, HIGH);
  delay(1000);
  digitalWrite(L1, LOW); 
  digitalWrite(L2, LOW);
  digitalWrite(L3, LOW); 
  digitalWrite(L4, LOW); 
  delay(1000);
  
}

Les 4 leds fonctionnent donc correctement.

TestLed.JPG

Test des boutons poussoirs

int pinBouton;
int pinBouton2;
int pinBouton3;
int pinLed1, pinLed2, pinLed3; //Déclaration des variables

void setup()
{
  pinBouton = 3;
  pinBouton2 = 5;
  pinBouton3 = 6;   

  pinLed1 = 10;
  pinLed2 = 11;
  pinLed3 = 12; //Initialisation des variables



  pinMode(pinBouton, INPUT); //Mode lecture pour les boutons
  pinMode(pinBouton2, INPUT);
  pinMode(pinBouton3, INPUT);

  pinMode(pinLed1, OUTPUT); //Mode écriture pour les leds
  pinMode(pinLed2, OUTPUT);
  pinMode(pinLed3, OUTPUT); 
}

void loop()
{

  
  boolean etatBouton = digitalRead(pinBouton);
  boolean etatBouton2 = digitalRead(pinBouton2);
  boolean etatBouton3 = digitalRead(pinBouton3); //Lecture de l'état du bouton et stockage dans etatBouton
  
  if (etatBouton==LOW) //Test si bouton appuyé
  {
    digitalWrite(pinLed1,LOW);   //led1 allumée
    digitalWrite(pinLed2,HIGH); //led2 éteinte
    digitalWrite(pinLed3,HIGH);//led3 éteinte
  }

  if (etatBouton2==LOW) //Test si bouton2 appuyé

  {
    digitalWrite(pinLed1,HIGH);  //led1 éteinte
    digitalWrite(pinLed2,LOW);  //led2 allumée
    digitalWrite(pinLed3,HIGH);//led3 éteinte
  }

   if (etatBouton3==LOW) //Test si bouton3 appuyé

  {
    digitalWrite(pinLed1,HIGH); //led1 éteinte
    digitalWrite(pinLed2,HIGH);//led2 éteinte
    digitalWrite(pinLed3,LOW);//led3 allumée
  }

 

}

Chaque bouton allume une led, les 3 boutons fonctionnent.

TestBouton.jpg TestBouton2.jpg TestBouton3.jpg

Test de l'afficheur 4x7 segments

//On définit les broches utilisées par les registres à décalage pour l'afficheur 4x7
#define LATCH_DIO 4
#define CLK_DIO 7
#define DATA_DIO 8 
 
const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90}; //Segments utilisés pour afficher les nombres de 0 à 9         
const byte SEGMENT_SELECT[] = {0xF1,0xF2,0xF4,0xF8}; //Définition des segments utilisés
 
void setup ()
{

pinMode(LATCH_DIO,OUTPUT); //Définition des broches en sorties
pinMode(CLK_DIO,OUTPUT);
pinMode(DATA_DIO,OUTPUT);
}

void loop()
{
WriteNumberToSegment(0 , 0); //On affiche les nombres 0-1-2-3 sur l'afficheur
WriteNumberToSegment(1 , 1);
WriteNumberToSegment(2 , 2);
WriteNumberToSegment(3 , 3);
}
 

void WriteNumberToSegment(byte Segment, byte Value) //On écrit un nombre décimal entre 0 et 9 sur les segments 
{
digitalWrite(LATCH_DIO,LOW);
shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]);
shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
digitalWrite(LATCH_DIO,HIGH);
}

L'afficheur affiche bien les nombres 0-1-2-3, il fonctionne donc correctement.

TestAfficheur.JPG

Test du bouton incrémental

//1ere sortie du codeur
#define PinA 1  
//2e sortie du codeur  
#define PinB 0  
  
volatile boolean mouvement;
volatile boolean up;
int valeur = 0;

void routineInterruption ()  {
  if (digitalRead(PinA))
    up = digitalRead(PinB);
  else
    up = !digitalRead(PinB);
  mouvement = true;
}

void setup (){
  pinMode(PinA, INPUT);
  pinMode(PinB, INPUT);

  //Activation des pullups internes de l'Arduino, si on n'utilise pas de pullups externes.
  //  digitalWrite (PinA, HIGH);
  //  digitalWrite (PinB, HIGH);

  attachInterrupt (0, routineInterruption, FALLING); //Interruption sur front descendant

  Serial.begin (9600);   //Initialisation du moniteur série
  Serial.println("Veuillez tourner le bouton");
}
void loop(){
  if (mouvement)  { //On a détecté une rotation du bouton
    if (up)
      valeur++;
    else
      valeur--;
    mouvement = false;

    Serial.println (valeur);

  }
}

Quatrième Partie : Réalisation d'un programme

Nous avons décidé de tester la carte avec une carte Arduino UNO. Le programme utilisé est :

/* Define shift register pins used for seven segment display */
#define LATCH_DIO 4
#define CLK_DIO 7
#define DATA_DIO 8

/* Segment byte maps for numbers 0 to 9 */
const byte SEGMENT_MAP[] = {
  0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};
/* Byte maps to select digit 1 to 4 */
const byte SEGMENT_SELECT[] = {0xF1,0xF2,0xF4,0xF8};

byte x=0;
byte x1=0;
byte x2=0;
byte x3=0;

#define PinA 1    //  1ere sortie du codeur
#define PinB 0    //  2e sortie du codeur

volatile boolean mouvement;
volatile boolean up;

unsigned int valeur = 0;  

// routine déclanchée quand le signal A passe de haut a bas


void setup ()
{
  /* Set DIO pins to outputs */
  pinMode(LATCH_DIO,OUTPUT);
  pinMode(CLK_DIO,OUTPUT);
  pinMode(DATA_DIO,OUTPUT);

  pinMode(PinA,INPUT);
  pinMode(PinB,INPUT);  

  // activation des pullups internes de l'Arduino, si on n'utilise pas de pullups externes.
  //  digitalWrite (PinA, HIGH); 
  //  digitalWrite (PinB, HIGH); 

  attachInterrupt (0,routineInterruption,FALLING);   // interruption sur front descendant

  Serial.begin (9600);   // initialisation du moniteur série
  Serial.println("Veuillez tourner le bouton");
}

void routineInterruption ()  {     
  //if (digitalRead(PinA))
    up = digitalRead(PinA);
  
  //  else
  //  up = !digitalRead(PinB);
  mouvement = true;
}


/* Main program */
void loop()
{

  /* Update the display with the current counter value */


  if (mouvement)  {		  // on a détecté une rotation du bouton  
    if (up)
      //valeur++;
      incrementBCD(&valeur);
    else
      //valeur--;
      decrementBCD(&valeur);
    mouvement= false;         

    Serial.println (valeur);

  }

  WriteNumberToSegment(0 , (valeur&0xF000)>>12);
    delay(1);
    WriteNumberToSegment(1 , (valeur&0x0F00)>>8);
    delay(1);
    WriteNumberToSegment(2 , (valeur&0x00F0)>>4);
    delay(1);
    WriteNumberToSegment(3 , (valeur&0x000F));
    delay(1);
}

/* Write a decimal number between 0 and 9 to one of the 4 digits of the display */
void WriteNumberToSegment(byte Segment, byte Value)
{
  digitalWrite(LATCH_DIO,LOW);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
  digitalWrite(LATCH_DIO,HIGH);
}

void incrementBCD(unsigned int *cnt) { 
  (*cnt)++;    
  if ((*cnt & 0x000F) > 0x0009) *cnt += 6; 
  if ((*cnt & 0x00F0) > 0x0090) *cnt += 0x0060;
  if ((*cnt & 0x0F00) > 0x0900) *cnt += 0x0600; 
  if ((*cnt & 0xF000) > 0x9000) *cnt += 0x6000;  
} 

void decrementBCD(unsigned int *cnt) { 
  (*cnt)--;    
  if ((*cnt & 0x000F) == 0x000F) *cnt -= 6; 
  if ((*cnt & 0x00F0) == 0x00F0) *cnt -= 0x0060; 
  if ((*cnt & 0x0F00) == 0x0F00) *cnt -= 0x0600; 
  if ((*cnt & 0xF000) == 0xF000) *cnt -= 0x6000; 
}