Décompte du nouvel an 2024

Bonjour,

Devant gérer une fête de nouvel an avec une soixantaine de personnes, je devais faire le décompte 10, 9, 8...1, 2024, mais de façon originale. Merci Arduino qui passait par là.

Le but était donc de cacher un peu le décompte pour que les gens ne s'aperçoivent que le décompte état commencé le plus tard possible. Ce qui a été réussi, beaucoup m'on dit qu'ils avait compris à 5 seulement. Dix, neuf, huit, sept, six ont été dit haut et fort sans qu'ils le remarquent. Pourtant c'était à minuit moins quelques. C'est un jeu qui a commencé exactement à 23h48mn50s.

La vidéo sur place n'a pas été faite, j'en ai fait une pour que vous puissiez comprendre après coup. Elle est légèrement accélérée:

http://arduino.dansetrad.fr/Decompte/Decompte.mp4

Il a fallu faire cela vite fait à la dernière semaine.

J'avais récupéré l'électronique d'un afficheur de lycée, genre celui qui indique la liste des profs absents. On suppose qu'il marchait, mais il y a eu un problème d'informatique et plus moyen de communiquer. Le fabricant avait disparu. Voici ce que j'ai récupéré:

La carte mère est à 68HC11, mais inutilisable pour moi (si quelqu'un la veut?) d'autant plus que je n'ai ni le schéma ni le programmateur d'EEprom.

Le 5V et le GND des afficheurs est facile grâce aux connecteurs d'alimentation. Les afficheurs se montent en série, et d'origine il y avait plusieurs lignes en parallèle. V est une évidence à cause des 3 alims 5V/20A.

Il y a des petits afficheurs de 4 digits et des grand de 8 digits qui sont presque des doubles des petits. Sur les petits il y a 7 transistors (7 lignes), sur les grands 7 aussi.

Les lecture des nom des circuits intégrés était faisable, j'en ai déduis un schéma très probable:

Pour piloter le tout avec ce que j'avais sous la main, j'ai utilisé une nano et un clavier 4x4, j'avais besoin d'au moins quelques boutons pour la remise à l'heure. Comme la dérive de la nano est d'une seconde toute les 4 heures et que c'est pour une soirée, j'utilise l'horloge millis() C'est rare quand j'utilise millis(), profitons en! Un son a été rajouté avec tone() pour donner le départ et la fin d'une recherche.
Comme il y a pleins de boutons, chaque chiffre de l'heure peut être incrémenté ou décrémenter, deux servent à régler la luminosité, et deux pour régler le niveau sonore (un qui fait un son, l'autre qui passe en mode normal.

Le schéma de branchement de la Nano est le suivant:

/* Câblage:

         GND ────── 0V
     PB4 = D8 ───── Strobe
 PB5 Sck = D13 ──── Clk
PB3 Mosi = D11 ──── Din
  PB1 ~1 = D9 ───── OE
     PC2 = A2 ───── Mux 2
     PC1 = A1 ───── Mux 1
     PC0 = A0 ───── Mux 0
	 
	                  ┌───────┐   ││
	 PB2 = D10 ────┬──┤ 4,7kΩ ├───┤├──────── vers sono
	               │  └───────┘   ││100nF
	             ┌─┴─┐
				 │   │
				 │1kΩ│
				 │   │
				 └─┬─┘
				   │
				  GND 
*/
//   4    5    6    7
//   │    │    │    │
//   ├─\  ├─\  ├─\  ├─\         .
//   │ └──│─┴──│─┴──│─┴──▷├─┐
//   ├─\  ├─\  ├─\  ├─\      ├─ 3
//   │ └──│─┴──│─┴──│─┴──┤◁─┘
//   ├─\  ├─\  ├─\  ├─\         .
//   │ └──│─┴──│─┴──│─┴──▷├─┐
//   └─\  └─\  └─\  └─\      ├─ 2
//     └────┴────┴────┴──┤◁─┘
//
// Correspond à la matrice carrée triple:
//     │   2   │  3   │  4   │  5   │  6  │  7  │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   2 │   X   │  /   │ -10s │ +10s │ -1s │ +1s │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   3 │   /   │   X  │ -10h │ +10h │ -1h │ +1h │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   4 │ -10mn │ faib │  X   │  /   │  /  │  /  │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   5 │ +10mn │ fort │  /   │  X   │  /  │  /  │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   6 │ -1mn  │ /Son │  /   │  /   │  X  │  /  │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   7 │ +1mn  │ Son  │  /   │  /   │  /  │  X  │
//   ──┴───────┴──────┴──────┴──────┴─────┴─────┘

Il y a des diodes dans la matrice de boutons pour n'utiliser que 6 entrées, je ne savais pas si la gestion des boutons se ferait par scan ou par interruptions, et dans ce dernier cas il vaut mieux mettre tout le monde sur le même port.

Le programme était le suivant:

#include <avr/pgmspace.h> // pour la fonte de caractères qui est en mémoire programme
#include "font.h"

/* Câblage:

         GND ────── 0V
     PB4 = D8 ───── Strobe
 PB5 Sck = D13 ──── Clk
PB3 Mosi = D11 ──── Din
  PB1 ~1 = D9 ───── OE
     PC2 = A2 ───── Mux 2
     PC1 = A1 ───── Mux 1
     PC0 = A0 ───── Mux 0
	 
	                  ┌───────┐   ││
	 PB2 = D10 ────┬──┤ 4,7kΩ ├───┤├──────── vers sono
	               │  └───────┘   ││100nF
	             ┌─┴─┐
				 │   │
				 │1kΩ│
				 │   │
				 └─┬─┘
				   │
				  GND 
*/

#define NOMBRE_AFFICHEURS 2 // Chaque afficheur à 4 digits
#define OUTPUT_ENABLE PORTB |= 0b00000010 // PB1, D9
#define OUTPUT_DISABLE PORTB &= 0b11111101
#define STROBE_ENABLE PORTB |= 0b00000001 //PB0, D8
#define STROBE_DISABLE PORTB &= 0b11111110
#define CLK_VALIDE PORTB |= 0b00100000 //PB5, D13
#define CLK_REPOS PORTB &= 0b11011111
#define DIN_1 PORTB |= 0b00001000 //PB3, D11
#define DIN_0 PORTB &= 0b11110111
#define LIGNE PORTC // Ligne de l'afficheur (0 à 6)


// Variables
volatile uint32_t afficher[NOMBRE_AFFICHEURS][7]; // Ce qui va être affiché. Dialogue entre Main et la fonction d'interruption
boolean allume = true; // Si false l'afficheur ne s'allume pas
word lumiere = 16; // Luminosité de l'afficheur 0..2000 (0=éteint, 2000=maxi)


void affiche(String phrase)
/* Prend la phrase et met les bonx pixels dans la variable afficher. 
   La phrase est centrée
   Dure environ 0,3ms par afficheur */
{
  static uint32_t prepareAfficheur[7]; // Permet de préparerl'affichage
  char num=phrase.length(); // Nombre de caratères
  byte espace=(NOMBRE_AFFICHEURS*4-num)>>1; // Nombre d'espaces à ajouter avant d'écrire
  byte decalage = espace;
  for (byte unAfficheur=0; unAfficheur<NOMBRE_AFFICHEURS; unAfficheur++) // Un afficheur c'est 4 matrices 5x7, mais 24 pixels à transférer (3x8)
  {
    for (byte uneLigne=0; uneLigne<7; uneLigne++) prepareAfficheur[uneLigne] = 0xFFFFFFFF; // 7 lignes de 24 bits mis dans ldes uint32_t. Par défaut tout éteint
    for (uint32_t caractere=0; caractere<4; caractere++) // Pour lire un caractère, trouver ses bits et les ranger dans les différentes lignes
    {
      if (espace>0) espace--; // Ne rien faire si c'est les espaces du départ, mais on a un espace à mettre en moins
      else // C'est un caractère e la chaîne (qui peut d'ailleurs être un espace)
      {
        uint32_t base;
        if (num-- <= 0) base = 0; // fin de phrase, on donne l'adresse de l'espace
        else base = (phrase[caractere+4*unAfficheur-decalage]-' ') * 7; // Offset du premier octet de définition
        for (uint32_t ligne=0; ligne<7; ligne++) // Pour les 7 lignes de la définition d'un caractère
        {
          uint32_t valeur = pgm_read_byte_near(font + base + ligne); // Lecture de la matrice de définition du caractère
          valeur <<= (caractere * 5 + 4); // Que l'on positionne dans les 24 bits à faire tranférer
          prepareAfficheur[ligne] &= ~valeur; // On met donc des 0 pour chaque pixel allumé
        }
      }
    }
    for (byte uneLigne=0; uneLigne<7; uneLigne++) afficher[unAfficheur][uneLigne] = prepareAfficheur[uneLigne]; // Transfert de ce qui a été préparé
  }  
}


void coucou(void) // Bruitage d'accueil (pour inviter à chercher des mots)
{
  allume = false;
  OUTPUT_DISABLE;
  tone(10, 523); // Do
  delay(200);
  tone(10, 784); // Sol
  delay(200);
  tone(10, 659, 400); // Mi
  allume = true;
}


void byebye(void) // Bruitage pour dire c'est fini
{
  allume = false;
  OUTPUT_DISABLE;
  tone(10, 262); // Do
  delay(200);
  tone(10, 247); // Si
  delay(200);
  tone(10, 220); // La
  delay(200);
  tone(10, 196); // Sol
  delay(200);
  tone(10, 175, 400); // Fa
  allume = true;
}


void setup()
{
  Serial.begin(115200); // Débuggage
  
  // Broches utilisées
  DDRC = 0b00000111; // Adresse de la ligne, autres bits non utilisés
  DDRB = 0b00101111; // Broches de contrôle
  
  pinMode(2,INPUT_PULLUP); // Pavé numérique 8x8
  pinMode(3,INPUT_PULLUP);
  pinMode(4,INPUT_PULLUP);
  pinMode(5,INPUT_PULLUP);
  pinMode(6,INPUT_PULLUP);
  pinMode(7,INPUT_PULLUP);

  // Timer 2: 490Hz pour être synchrone avec le PWM naturel du timer 1 si besoin
  // Avec 7 lignes, le rafraichissement est à 70Hz
  TIMSK2 = 1; // Interruptions en route
}

ISR(TIMER2_OVF_vect)
// On n'affiche qu'une seule ligne 490 fois par seconde. Pour afficher les caractères
// en entier c'est la succession des 7 appels qu le fera.
// Pour afficher la suivante, il faut la renvoyer
// dans le registre à décalage et faire le transfert. Les données sont préparées dans
// la variable "afficher"
// J'aurais pu passer par le SPI, mais j'ai eu la paresse de regarder comment il faut
// le configurer. Mais les broches le permettent.
// Cette fonction dure environ 0,1ms pour 2 afficheurs
{
  static byte ligne; // Numéro de la ligne 0..6 
  static uint32_t envoi; // les 24 valeurs de l'envoi

	// Incrémenter la ligne du dernier appel
	if (++ligne == 7) ligne = 0;
	
	// Tranférer des données dans le registre à décalage
  // Pour un seul afficheur, on transfert un unsigned long qui est préparé
  for (byte unAfficheur=0; unAfficheur<NOMBRE_AFFICHEURS; unAfficheur++) // Pour plusieurs afficheurs
  {
    envoi = afficher[unAfficheur][ligne]; // On récupère le long à envoyer
    for (byte colonne=0; colonne<24; colonne++) // 24 pixels à envoyer, 20 aurait suffit si on n'avait qu'un seul afficheur
    {
      if ((envoi & 1) == 1) DIN_1; else DIN_0; // Envoi d'un bit
      CLK_VALIDE; // Envoi du bit, la validation se fait sur le front montant
      envoi = envoi >> 1; // Décalage pour préparer le bit suivant. Mis ici pour rallonger l'impulsion d'horloge
      CLK_REPOS; // Reposd e l'hologe. Front inactif
    }
  }
  OUTPUT_DISABLE; // Eteindre l'afficheur pour éviter d'envoyer la donnée sur la ligne précédente
	LIGNE = ligne; // Passer à la ligne suivante
  STROBE_ENABLE; STROBE_DISABLE; // Valider les données transmises
  if (allume) OUTPUT_ENABLE; // Rallumer l'afficheur

  // Intensité variable sans le PWM
  // Si on allume au maxi, c'est environ 2ms (490Hz). Allumer 10µs c'est 1/400
  if (lumiere < 1500)
  {
    delayMicroseconds(lumiere);
    OUTPUT_DISABLE;
  }
}


struct element { // Evénement élémentaire
    unsigned long duree; // En secondes
    String mot; // Ce qu'il faut afficher
    byte musique; // 0:pas de musique, 1:coucou, 2:byebye
};


String chrono="00-00-00"; // Affichage de l'heure
String affichageEnCours; // Le mot affiché
long temps, // Temps corrigé en seconde
     tempsAfficheur, 
     correction=17*3600L+0*60+0, // Heure à l'allumage, correction de la dérive. Ici départ à 17h
     prochain; // Heure du prochain événement
byte indiceDepart = 0; // Index dans la suite des événements
word memoireLumiere; // Memorisation de lumière pendant le jeu

const element departs[] = { // Suite des événements
  {23*3600L+43*60+50,"",0}, // Temps mort du départ
  {300,"",1}, // Bip 5mn avant
  {60,"RAY",1}, // -> démarrage du jeu 23h48:50, explications 23h48
  {10," ",2},
  {60,"CHA",1},
  {3," ",2},
  {60,"FAN",1},
  {3," ",2},
  {60,"CUI",1},
  {3," ",2},
  {60,"LOU",1},
  {3," ",2},
  {55,"DIS",1},
  {3," ",2},
  {50,"NEU",1},
  {3," ",2},
  {45,"UIT",1},
  {3," ",2},
  {40,"SAIT",1},
  {3," ",2},
  {35,"SIS",1},
  {3," ",2},
  {30,"CINQ",1},
  {2," ",2},
  {25,"QUATRE",1},
  {2," ",2},
  {20,"TROIS",1},
  {2," ",2},
  {15,"DEUX",1},
  {1," ",2},
  {10,"UN",1},
  {1," ",2},
  {10,"2024",1},
  {0,"",0}};

void change(byte abscisse, byte ordonnee, long valeur)
// Change le valeur de correction (met à l'heure) pour un bouton
// Cette fonction scanne une touche du keypad et agit en conséquence
//
// Câblage
//   4    5    6    7
//   │    │    │    │
//   ├─\  ├─\  ├─\  ├─\         .
//   │ └──│─┴──│─┴──│─┴──▷├─┐
//   ├─\  ├─\  ├─\  ├─\      ├─ 3
//   │ └──│─┴──│─┴──│─┴──┤◁─┘
//   ├─\  ├─\  ├─\  ├─\         .
//   │ └──│─┴──│─┴──│─┴──▷├─┐
//   └─\  └─\  └─\  └─\      ├─ 2
//     └────┴────┴────┴──┤◁─┘
//
// Correspond à la matrice carrée triple:
//     │   2   │  3   │  4   │  5   │  6  │  7  │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   2 │   X   │  /   │ -10s │ +10s │ -1s │ +1s │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   3 │   /   │   X  │ -10h │ +10h │ -1h │ +1h │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   4 │ -10mn │ faib │  X   │  /   │  /  │  /  │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   5 │ +10mn │ fort │  /   │  X   │  /  │  /  │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   6 │ -1mn  │ /Son │  /   │  /   │  X  │  /  │
//   ──┼───────┼──────┼──────┼──────┼─────┼─────┤
//   7 │ +1mn  │ Son  │  /   │  /   │  /  │  X  │
//   ──┴───────┴──────┴──────┴──────┴─────┴─────┘
{
  pinMode(abscisse,OUTPUT); digitalWrite(abscisse, LOW);
  if (digitalRead(ordonnee)==LOW) // Bouton appuyé
  {
    if (abscisse != 3) correction += valeur;
    else
    {
      if ((ordonnee == 4) && (lumiere > 1)) lumiere /= 2; // Diminution de l'éclairage exponentiel
      if ((ordonnee == 5) && (lumiere < 1500)) lumiere *= 2; // Augmentation de l'éclairage
    }
    delay(20); // Antirebond
    while (digitalRead(ordonnee)==LOW) // On attend le relâchement
    delay(20);
  }
  pinMode(abscisse,INPUT_PULLUP);
}


void loop()
{
  // Calcul de l'heure pour le format d'affichage
  tempsAfficheur = temps = (millis()/1000)+correction; // En secondes
  while (tempsAfficheur >= 86400L) tempsAfficheur -= 86400L;
  while (tempsAfficheur < 0) tempsAfficheur += 86400L;
  chrono[7] = (tempsAfficheur % 10) + '0';
  tempsAfficheur /= 10; // En 10s
  chrono[6] = (tempsAfficheur % 6) + '0';
  tempsAfficheur /= 6; // En mn
  chrono[4] = (tempsAfficheur % 10) + '0';
  tempsAfficheur /= 10; // En 10mn
  chrono[3] = (tempsAfficheur % 6) + '0';
  tempsAfficheur /= 6; // En h
  chrono[1] = (tempsAfficheur % 10) + '0';
  tempsAfficheur /= 10; // En 10h
  chrono[0] = tempsAfficheur + '0';


  // Lecture du pavé numérique
  change(4, 3, -36000L);
  change(6, 3, -3600);
  change(2, 4, -600); 
  change(2, 6, -60);
  change(4, 2, -10);
  change(6, 2, -1);
  change(7, 2, 1);
  change(5, 2, 10);
  change(2, 7, 60);
  change(2, 5, 600);
  change(7, 3, 3600);
  change(5, 3, 36000L);
  change(3, 5, 0);
  change(3, 4, 0);
  pinMode(3,OUTPUT); digitalWrite(3, LOW);
  if (digitalRead(7)==LOW)
  {
    allume = false;
    OUTPUT_DISABLE;
    tone(10, 220);
  }
  if (digitalRead(6)==LOW)
  {
    noTone(10);
    allume = true;
  }
  pinMode(3,INPUT_PULLUP);

  //Déroulement du jeu
  if (indiceDepart < 0xff) // On na pas fini
  if (prochain <= temps) // On va travailler sur l'événement prochain
  {
    affichageEnCours = departs[indiceDepart].mot;
    if (departs[indiceDepart].musique == 1) coucou();
      else if (departs[indiceDepart].musique == 2) byebye();
    prochain += departs[indiceDepart].duree;
    if ((departs[indiceDepart].duree) == 0)
    { // Fin du jeu
      indiceDepart = 0xFE;
      lumiere = memoireLumiere;
    }
    if (affichageEnCours == "RAY")
    { // Début du jeu, passage en lumère maxi
      memoireLumiere = lumiere;
      lumiere = 2000;
    }
    indiceDepart++; // Prêt à lire l'événement suivant
  }

  // Affichage
  if (affichageEnCours == "") affiche(chrono); else affiche(affichageEnCours);
}

La fonte de caractère est:

const byte font[125*7] PROGMEM = { 
    B00000, // espace
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00100, // !
    B00100,
    B00100,
    B00100,
    B00100,
    B00000,
    B00100,
    
    B01010, // "
    B01010,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00000, // #
    B01010,
    B11111,
    B01010,
    B11111,
    B01010,
    B00000,
    
    B00100, // $
    B11110,
    B00001,
    B01110,
    B10000,
    B01111,
    B00100,
    
    B10011, // %
    B10011,
    B01000,
    B00100,
    B00010,
    B11001,
    B11001,
    
    B00110, // &
    B01001,
    B01001,
    B00110,
    B00101,
    B01001,
    B10110,
    
    B00100, // '
    B00100,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B01000, // (
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    B01000,
    
    B00010, // )
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    B00010,
    
    B00000, // *
    B10101,
    B01110,
    B11111,
    B01110,
    B10101,
    B00000,

    B00000, // +
    B00100,
    B00100,
    B11111,
    B00100,
    B00100,
    B00000,
    
    B00000, // ,
    B00000,
    B00000,
    B00000,
    B00000,
    B00100,
    B00010,
    
    B00000, // -
    B00000,
    B00000,
    B01110,
    B00000,
    B00000,
    B00000,
    
    B00000, // .
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00100,
    
    B10000, // /
    B01000,
    B01000,
    B00100,
    B00010,
    B00010,
    B00001,
    
    B00110, // 0
    B01001,
    B01001,
    B01001,
    B01001,
    B01001,
    B00110,
    
    B00100, // 1
    B00110,
    B00100,
    B00100,
    B00100,
    B00100,
    B01110,
    
    B00110, // 2
    B01001,
    B01000,
    B00100,
    B00010,
    B00001,
    B01111,
    
    B00110, // 3
    B01001,
    B01000,
    B00110,
    B01000,
    B01001,
    B00110,
    
    B01001, // 4
    B01001,
    B01001,
    B01111,
    B01000,
    B01000,
    B01000,
    
    B01111, // 5
    B00001,
    B00001,
    B00111,
    B01000,
    B01001,
    B00110,
    
    B00110, // 6
    B01001,
    B00001,
    B00111,
    B01001,
    B01001,
    B00110,
    
    B01111, // 7
    B01000,
    B00100,
    B00100,
    B00010,
    B00010,
    B00010,
    
    B00110, // 8
    B01001,
    B01001,
    B00110,
    B01001,
    B01001,
    B00110,
    
    B00110, // 9
    B01001,
    B01001,
    B01110,
    B01000,
    B01001,
    B00110,
    
    B00000, // :
    B00000,
    B00000,
    B00100,
    B00000,
    B00000,
    B00100,
    
    B00000, // ;
    B00000,
    B00000,
    B00100,
    B00000,
    B00100,
    B00010,
    
    B10000, // <
    B01000,
    B00100,
    B00010,
    B00100,
    B01000,
    B10000,
    
    B00000, // =
    B00000,
    B00000,
    B11111,
    B00000,
    B11111,
    B00000,
    
    B00010, // >
    B00100,
    B01000,
    B10000,
    B01000,
    B00100,
    B00010,
    
    B01110, // ?
    B10001,
    B10000,
    B01000,
    B00100,
    B00000,
    B00100,
    
    B01110, // @
    B10001,
    B11101,
    B10101,
    B11101,
    B00001,
    B11110,
    
    B01110, // A
    B10001,
    B10001,
    B11111,
    B10001,
    B10001,
    B10001,
    
    B01111, // B
    B10001,
    B10001,
    B01111,
    B10001,
    B10001,
    B01111,
    
    B01110, // C
    B10001,
    B00001,
    B00001,
    B00001,
    B10001,
    B01110,
    
    B01111, // D
    B10001,
    B10001,
    B10001,
    B10001,
    B10001,
    B01111,
    
    B11111, // E
    B00001,
    B00001,
    B01111,
    B00001,
    B00001,
    B11111,
    
    B11111, // F
    B00001,
    B00001,
    B01111,
    B00001,
    B00001,
    B00001,
    
    B01110, // G
    B10001,
    B00001,
    B11001,
    B10001,
    B10001,
    B01110,
    
    B10001, // H
    B10001,
    B10001,
    B11111,
    B10001,
    B10001,
    B10001,
    
    B01110, // I
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    B01110,
    
    B11110, // J
    B10000,
    B10000,
    B10000,
    B10000,
    B10001,
    B01110,
    
    B10001, // K
    B01001,
    B00101,
    B00011,
    B00101,
    B01001,
    B10001,
    
    B00001, // L
    B00001,
    B00001,
    B00001,
    B00001,
    B00001,
    B11111,
    
    B10001, // M
    B11011,
    B10101,
    B10001,
    B10001,
    B10001,
    B10001,
    
    B10001, // N
    B10001,
    B10011,
    B10101,
    B11001,
    B10001,
    B10001,
    
    B01110, // O
    B10001,
    B10001,
    B10001,
    B10001,
    B10001,
    B01110,
    
    B01111, // P
    B10001,
    B10001,
    B01111,
    B00001,
    B00001,
    B00001,
    
    B01110, // Q
    B10001,
    B10001,
    B10001,
    B10001,
    B01001,
    B10110,
    
    B01111, // R
    B10001,
    B10001,
    B01111,
    B10001,
    B10001,
    B10001,
    
    B01110, // S
    B10001,
    B00001,
    B01110,
    B10000,
    B10001,
    B01110,
    
    B11111, // T
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    
    B10001, // U
    B10001,
    B10001,
    B10001,
    B10001,
    B10001,
    B01110,
    
    B10001, // V
    B10001,
    B10001,
    B01010,
    B01010,
    B00100,
    B00100,
    
    B10001, // W
    B10001,
    B10001,
    B10101,
    B10101,
    B11011,
    B10001,
    
    B10001, // X
    B10001,
    B01010,
    B00100,
    B01010,
    B10001,
    B10001,
    
    B10001, // B
    B10001,
    B01010,
    B00100,
    B00100,
    B00100,
    B00100,
    
    B11111, // Z
    B10000,
    B01000,
    B00100,
    B00010,
    B00001,
    B11111,
    
    B01110, // [
    B00010,
    B00010,
    B00010,
    B00010,
    B00010,
    B01110,
    
    B00001, // barre oblique inverse
    B00010,
    B00010,
    B00100,
    B01000,
    B01000,
    B10000,
    
    B01110, // ]
    B01000,
    B01000,
    B01000,
    B01000,
    B01000,
    B01110,
    
    B00100, // ^
    B01010,
    B10001,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00000, // _
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B11111,
    
    B00010, // '
    B00100,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00000, // a
    B00000,
    B01110,
    B10000,
    B11110,
    B10001,
    B11110,
    
    B00001, // b
    B00001,
    B01111,
    B10001,
    B10001,
    B10001,
    B01111,
    
    B00000, // c
    B00000,
    B01110,
    B10001,
    B00001,
    B10001,
    B01110,
    
    B10000, // d
    B10000,
    B11110,
    B10001,
    B10001,
    B10001,
    B11110,
    
    B00000, // e
    B00000,
    B01110,
    B10001,
    B01111,
    B00001,
    B11110,
    
    B01100, // f
    B10010,
    B00010,
    B00111,
    B00010,
    B00010,
    B00010,
    
    B00000, // g
    B01110,
    B10001,
    B10001,
    B11110,
    B10000,
    B01110,
    
    B00001, // h
    B00001,
    B01111,
    B10001,
    B10001,
    B10001,
    B10001,
    
    B00100, // i
    B00000,
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    
    B01000, // j
    B00000,
    B01000,
    B01000,
    B01000,
    B01001,
    B00110,
    
    B00001, // k
    B00001,
    B10001,
    B01001,
    B00111,
    B01001,
    B10001,
    
    B00100, // l
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    B01000,
    
    B00000, // m
    B00000,
    B01111,
    B10101,
    B10101,
    B10101,
    B10101,
    
    B00000, // n
    B00000,
    B01111,
    B10001,
    B10001,
    B10001,
    B10001,
    
    B00000, // o
    B00000,
    B01110,
    B10001,
    B10001,
    B10001,
    B01110,
    
    B00000, // p
    B00000,
    B01111,
    B10001,
    B01111,
    B00001,
    B00001,
    
    B00000, // q
    B00000,
    B11110,
    B10001,
    B11110,
    B10000,
    B10000,
    
    B00000, // r
    B00000,
    B11101,
    B00011,
    B00001,
    B00001,
    B00001,
    
    B00000, // s
    B00000,
    B11110,
    B00001,
    B01110,
    B10000,
    B01111,
    
    B00010, // t
    B00010,
    B00111,
    B00010,
    B00010,
    B10010,
    B01100,
    
    B00000, // u
    B00000,
    B10001,
    B10001,
    B10001,
    B10001,
    B11110,
    
    B00000, // v
    B00000,
    B10001,
    B10001,
    B01010,
    B01010,
    B00100,
    
    B00000, // w
    B00000,
    B10101,
    B10101,
    B10101,
    B10101,
    B01010,
    
    B00000, // x
    B00000,
    B10001,
    B01010,
    B00100,
    B01010,
    B10001,
    
    B00000, // B
    B00000,
    B10001,
    B10001,
    B11110,
    B10000,
    B01110,
    
    B00000, // z
    B00000,
    B11111,
    B01000,
    B00100,
    B00010,
    B11111,
    
    B11000, // {
    B00100,
    B00100,
    B00010,
    B00100,
    B00100,
    B11000,
    
    B00100, // |
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    
    B00011, // }
    B00100,
    B00100,
    B01000,
    B00100,
    B00100,
    B00011,
    
    B00000, // ~
    B00000,
    B00010,
    B10101,
    B01000,
    B00000,
    B00000,
    
    B00000, // XXXXX
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00010, // à
    B00100,
    B01110,
    B10000,
    B11110,
    B10001,
    B11110,
    
    B01000, // á
    B00100,
    B01110,
    B10000,
    B11110,
    B10001,
    B11110,
    
    B00100, // â
    B01010,
    B01110,
    B10000,
    B11110,
    B10001,
    B11110,
    
    B00000, // XXXXX
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00000, // XXXXX
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00000, // XXXXX
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00000, // XXXXX
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00000, // ç
    B11110,
    B00001,
    B00001,
    B11110,
    B01000,
    B00110,
    
    B00010, // è
    B00100,
    B01110,
    B10001,
    B01111,
    B00001,
    B11110,
    
    B01000, // é
    B00100,
    B01110,
    B10001,
    B01111,
    B00001,
    B11110,
    
    B00100, // ê
    B01010,
    B01110,
    B10001,
    B01111,
    B00001,
    B11110,
    
    B10001, // ë
    B00000,
    B01110,
    B10001,
    B01111,
    B00001,
    B11110,
    
    B01110, // €
    B10001,
    B00111,
    B00001,
    B00111,
    B10001,
    B01110,
    
    B00000, // XXXXX
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00100, // î
    B01010,
    B00000,
    B00100,
    B00100,
    B00100,
    B00100,
    
    B10001, // ï
    B00000,
    B00100,
    B00100,
    B00100,
    B00100,
    B00100,
    
    B00100, // °
    B01010,
    B00100,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00100, // ±
    B00100,
    B11111,
    B00100,
    B00100,
    B00000,
    B11111,
    
    B00010, // ò
    B00100,
    B01110,
    B10001,
    B10001,
    B10001,
    B01110,
    
    B01000, // ó
    B00100,
    B01110,
    B10001,
    B10001,
    B10001,
    B01110,
    
    B00100, // ô
    B01010,
    B01110,
    B10001,
    B10001,
    B10001,
    B01110,
    
    B00000, // µ
    B00000,
    B10001,
    B10001,
    B01111,
    B00001,
    B00001,
    
    B10001, // ö
    B00000,
    B01110,
    B10001,
    B10001,
    B10001,
    B01110,
    
    B00000, // ÷
    B00100,
    B00000,
    B11111,
    B00000,
    B00100,
    B00000,
    
    B00000, // XXXXX
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    
    B00010, // ù
    B00100,
    B10001,
    B10001,
    B10001,
    B10001,
    B11110,
    
    B01000, // ú
    B00100,
    B10001,
    B10001,
    B10001,
    B10001,
    B11110,
    
    B00100, // û
    B01010,
    B10001,
    B10001,
    B10001,
    B10001,
    B11110,
    
    B10001, // ü
    B00000,
    B10001,
    B10001,
    B10001,
    B10001,
    B11110
};

Comme il a fallu faire vite, c'est écrit à l'arrache, sans économies. Il devrait être possible d'utiliser efficacement le SPI, mais j'ai eu la flegme de regarder les registres. L'écriture par la fonction affiche() centre le texte, et un afficheur pour moi c'est 4 digits. Un digit c'est 5 colonnes, 4 digits, c'est 20 bits à passer, un registre à décalage, c'est 8 bits, il en faut 3 et 4 bits inutiles sont donc à décaler.

 

 

 

Conclusion: vous n'aurez sans doute pas le même afficheur, mais je vous assure que l'idée de l'animation est bonne. Personne quasiment ne compte ses points, cela n'a d'ailleurs pas d'intérêt.
Prendre un autre afficheur, un autre programme et une autre carte est encouragé, il n'y a pas de droits d'auteur. Il vous reste un peu moins d'un an pour le faire.

1 Like

Pour la vidéo, je ne sais pas encore comment faire, pour l'insérer, mais le lien fonctionne:
http://arduino.dansetrad.fr/Decompte/Decompte.mp4 Remis dans le post #1

Super idée

:+1:

Merci également pour ce schéma avec des symboles aux normes I.E.C, des symboles qui ont ( avaient ?) l'avantage d'être construits pour exprimer le fonctionnement des composants :slightly_smiling_face:

http://genelec.santonum.free.fr/_fichiers/s1-Electronique/s13-Logique-cablee/Docum-Norme-IEC-Logique.i1342.pdf

1 Like

C'est presque le plus difficile à trouver. Plus que le schéma.

On peut être vieux et apprécier les nouveautés. Un schéma aux nouvelles normes actuelles se passe de tables de vérité, de doc...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.