Go Down

Topic: Faire un dé électronique avec un 74HC595 (Read 3710 times) previous topic - next topic

VicPi

Bonjour,


j'aimerais faire un dé électronique avec un registre à décalage 74HC595.


Je résume vite fait le code :

1/Si quelqu'un appuie sur le bouton-poussoir..
2/..Un nombre aléatoire est généré, puis envoyé à la fonction displayDataLEDs (qui affichera le nombre au moyen de quelques GROUPES de LEDs
3/  displayDataLEDs analyse le nombre, et définit l'état de chaque groupe de LED, dans un tableau "value"
4/ on transmet les données de chaque LEDs aux sorties du registre à décalage à l'aide de l'instruction shiftOut.

Sauf que :

J'envoie un tableau à l'instruction shiftOut et non une valeur de type "B1001" ou 9 par exemple..

Je ne sais pas comment faire.. En espérant avoir été clair.. Je remercie d'avance ce qui prendront le temps de m'aider  :)

MON CODE :

Code: [Select]
#define WAITTIME 20
int buttonPin = 13; //Broche de raccordement du bouton-poussoir aux différentes LEDs
int shiftPin = 8;
int dataPin = 9;
int storagePin = 10;
byte value[4] = {0};

void setup()
{
 pinMode(dataPin, OUTPUT);
 pinMode(shiftPin, OUTPUT);
 pinMode(storagePin, OUTPUT);
}

void loop()
{
  if (digitalRead(buttonPin) == HIGH) //si le bouton-poussoir est actionné..
    displayDataLEDs(random(1, 7)); //..on génère un nombre compris entre 1 et 6
}

void displayDataLEDs(int nombre) //On récupère ce nombre dans une variable locale "nombre", et on l'affiche grâces à diverses conditions
{
  for (int i = 0; i < 4; i++)
    value[i] = LOW;
    
  for (int i = 0; i < 4; i++)
  {
    int test = 0;
    if (nombre%2 != 0)
      value[i] = HIGH;
    else
      value[i] = LOW;
      
    if (nombre > 1)
      value[i] = HIGH;
    else
      value[i] = LOW;
      
    if (nombre > 3)
      value[i] = HIGH;
    else
      value[i] = LOW;
      
    if (nombre == 6)
      value[i] = HIGH;
    else
      value[i] = LOW;
  }

 digitalWrite(storagePin, LOW);
 shiftOut(dataPin, shiftPin, MSBFIRST, value);
 digitalWrite(storagePin, HIGH);
 delay(WAITTIME);
}

kamill

#1
Aug 09, 2015, 10:10 am Last Edit: Aug 09, 2015, 10:22 am by kamill
Bonjour,

Je pense qu'il y a une erreur dans ton programme, dans value[] tu mets la même valeur pour tous les index.
Il suffit d'une seul byte.
Je suppose que tu as voulu faire ceci:
Code: [Select]
void displayDataLEDs(int nombre) //On récupère ce nombre dans une variable locale "nombre", et on l'affiche grâces à diverses conditions
{
  byte value=0;

  if (nombre%2 != 0)
    value|= B00000001;
  
  if (nombre > 1)
    value|= B00000010;
  
  if (nombre > 3)
    value|= B00000100;
  
  if (nombre == 6)
    value|= B00001000;


 digitalWrite(storagePin, LOW);
 shiftOut(dataPin, shiftPin, MSBFIRST, value);
 digitalWrite(storagePin, HIGH);
 delay(WAITTIME);
}


Si tu n'es pas familier avec le C, value|=x fait un ou de value avec la valeur x et la range dans value.

VicPi

Oui c'est un peu ça, merci, mais c'est plus compliqué que ça en fait, les schémas de mon livre sauront expliquer mieux que moi :

Pour pouvoir afficher 1, 2, 3, 4, 5 ou 6 sur le dé électronique, il faut combiner plusieurs groupes de LEDs, et non pas allumer qu'un seul :



Dans l'exemple que tu m'as donné, j'aimerais, par exemple, que si le nombre vaut 6, il combine : B00000010 + B00000100 + B00001000, car il est supérieur à 1 & 3 et est égal à 6.  :) Ce qui donnerait : B00001110 ..

Voici le code du sketch sans le 74HC595, si ça peut t'aider :(

Code: [Select]
#define WAITTIME 20
int GroupA = 8;  // LED 4
int GroupB = 9;  // LED 1 + 7
int GroupC = 10; // LED 3 + 5
int GroupD = 11; // LED 2 + 6
int buttonPin = 13; // Bouton-poussoir à la broche 13

void setup(){
  pinMode(GroupA, OUTPUT);
  pinMode(GroupB, OUTPUT);
  pinMode(GroupC, OUTPUT);
  pinMode(GroupD, OUTPUT);
}

void loop(){
  if(digitalRead(buttonPin) == HIGH)
  displayPips(random(1, 7)); // Générer un nombre entre 1 et 6
}

void displayPips(int value){
  // Éteindre tous les groupes
  digitalWrite(GroupA, LOW);
  digitalWrite(GroupB, LOW);
  digitalWrite(GroupC, LOW);
  digitalWrite(GroupD, LOW);
  // Commande de tous les groupes
  if(value%2 != 0) // La valeur est-elle impaire ?
    digitalWrite(GroupA, HIGH);
  if(value > 1)
    digitalWrite(GroupB, HIGH);
  if(value > 3)
    digitalWrite(GroupC, HIGH);
  if(value == 6)
    digitalWrite(GroupD, HIGH);
  delay(WAITTIME); // Ajouter une courte pause
}


Merci encore et bonne journée :)

kamill

Bonjour VicPi,

Si c'est aussi simple que ça, ça fait exactement la même chose que ton sketch, mais avec un 74HC595, en supposant que le groupe A est sur Q0, le groupe B sur Q1 ...

VicPi

kamill, je ne comprends vraiment pas, dans ton sketch, pour moi, on ne peut qu'allumer un seul groupe de LEDs à la fois :(

VicPi

(par exemple pour afficher 3, il faut allumer le groupe A et B)

kamill

#6
Aug 09, 2015, 02:12 pm Last Edit: Aug 09, 2015, 02:28 pm by kamill
Ca commande bien plusieurs groupes à la fois.
Chaque bit dans la valeur que tu envoies au 74HC595 commande une sortie.
Par exemple pour le 6 tu envoies B00001110 ce qui met les sorties Q1, Q2 et Q3 à 1, ce qui commande bien les groupes B, C et D

VicPi

"Si tu n'es pas familier avec le C, value|=x fait un ou de value avec la valeur x et la range dans value."
Je n'ai pas bien compris cette phrase, peux tu l'a reformuler ?

Je pense que tu as raison et que c'est juste mon manque de connaissance sur le langage qui me pose problème.

En fait, ce que tu veux dire c'est que, quand on précise qu'on travail avec des binaires (ça se dit ça ?) :

si value = B1001
puis si on fait, value = B0100

alors en réalité elle devient B1101, c'est bien ça que tu veux dire ?

Merci kamill :)

Yan_duino

#8
Aug 09, 2015, 02:58 pm Last Edit: Aug 09, 2015, 02:59 pm by Yan_duino
bonjour,
essai avec la fonction switch...case

Code: [Select]


void displayDataLEDs(int nombre) //On récupère ce nombre dans une variable locale "nombre", et on l'affiche grâces à diverses conditions
{

switch nombre

case 1  value= b00000001

case 2 value= b00000010   etc



puis envoyer value avec la fonction  shift out...

ps: ceci est une piste, je te laisse chercher pour la mise en forme.
A+  Yan_duino


kamill

#9
Aug 09, 2015, 03:01 pm Last Edit: Aug 09, 2015, 03:07 pm by kamill
C'est tout à fait que ce que tu as compris.
Le | est un 'OU binaire' (c'est à dire bit à bit).

donc si on prend le cas de 3

 if (nombre%2 != 0)
   value|= B00000001;    // value prend la valeur B00000001
 
 if (nombre > 1)
   value|= B00000010;   // value prend la valeur B00000011

Les tests suivants ne sont pas vrais, donc à la fin on a value=B00000011
Quand tu envoies cette valeur au 74HC595 tu actives donc les groupes A et B


VicPi


kamill


Go Up