01 - Écran LED (Afficheur digital)

@joekakone

Joseph Konka @joekakone

03/03/2026 · 14 min

Concevez un simulateur d'écran LED et d'afficheur digital 7 segments en langage C. Maîtrisez le rendu horizontal ligne par ligne à partir de matrices de caractères ASCII.

Projet 01 : Écran LED (Afficheur digital en ASCII)#

Dans les systèmes embarqués, les automates industriels et les réveils digitaux, les nombres sont fréquemment restitués par des afficheurs à 7 segments ou des matrices de diodes électroluminescentes (LED).

L'objectif de ce projet est de concevoir un simulateur complet d'écran digital en console capable de convertir n'importe quel nombre ou horodatage saisi par l'utilisateur en un affichage LED géant en ASCII.


1. Analyse du problème et contrainte du terminal#

Le défi de l'affichage horizontal#

Dans une console texte, le flux de sortie (stdout) fonctionne de manière strictement séquentielle de haut en bas et de gauche à droite. Une fois qu'un saut de ligne \n est envoyé à l'écran, il est impossible de revenir en arrière pour compléter une ligne précédente.

Si nous souhaitons afficher le nombre 2026, nous ne pouvons pas simplement afficher le chiffre 2 en entier, puis le chiffre 0, etc. Nous devons impérativement : 1. Afficher la Ligne 0 de tous les chiffres côte à côte, suivie de \n. 2. Afficher la Ligne 1 de tous les chiffres côte à côte, suivie de \n. 3. Répéter cette opération pour les 5 lignes de la matrice.

Ligne 0:  ###   ###   ###   ###
Ligne 1:    #   # #     #   #  
Ligne 2:  ###   # #   ###   ###
Ligne 3:  #     # #   #     # #
Ligne 4:  ###   ###   ###   ###
           2     0     2     6

2. Modélisation géométrique des chiffres (\(5 \times 3\))#

Chaque chiffre de 0 à 9 est inscrit dans une grille de 5 lignes de hauteur par 3 colonnes de largeur :

Chiffre Ligne 0 Ligne 1 Ligne 2 Ligne 3 Ligne 4
0 ### # # # # # # ###
1 # # # # #
2 ### # ### # ###
3 ### # ### # ###
4 # # # # ### # #
5 ### # ### # ###
6 ### # ### # # ###
7 ### # # # #
8 ### # # ### # # ###
9 ### # # ### # ###

Nous intégrerons également les caractères spéciaux courants : - Le signe négatif - (barre centrale) - Les deux-points : (deux diodes verticales pour les horloges) - L'espace ' ' (séparateur neutre)


3. Architecture logicielle#

flowchart TD
    A[Chaine en entree ex: '2026'] --> B[Validation des caracteres]
    B --> C[Boucle externe : Lignes de 0 a 4]
    C --> D[Boucle interne : Chaque caractere de la chaine]
    D --> E[Extraction du sous-motif de 3 colonnes]
    E --> F[Impression du motif + espace d'espacement]
    F --> G[Saut de ligne terminal \\n]

Nous stockerons les motifs des 10 chiffres dans un tableau tridimensionnel constant : const char MOTIFS_CHIFFRES[10][5][4]


4. Implémentation complète en langage C#

Voici le code source intégral, documenté et conforme aux standards C99 :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

#define HAUTEUR 5
#define LARGEUR 3

// Dictionnaire matriciel des chiffres 0 à 9
// Dimensions : 10 chiffres, 5 lignes, 4 caractères (3 + '\0')
static const char MOTIFS[10][HAUTEUR][LARGEUR + 1] = {
    {
        "###",
        "# #",
        "# #",
        "# #",
        "###"
    }, // 0
    {
        "  #",
        "  #",
        "  #",
        "  #",
        "  #"
    }, // 1
    {
        "###",
        "  #",
        "###",
        "#  ",
        "###"
    }, // 2
    {
        "###",
        "  #",
        "###",
        "  #",
        "###"
    }, // 3
    {
        "# #",
        "# #",
        "###",
        "  #",
        "  #"
    }, // 4
    {
        "###",
        "#  ",
        "###",
        "  #",
        "###"
    }, // 5
    {
        "###",
        "#  ",
        "###",
        "# #",
        "###"
    }, // 6
    {
        "###",
        "  #",
        "  #",
        "  #",
        "  #"
    }, // 7
    {
        "###",
        "# #",
        "###",
        "# #",
        "###"
    }, // 8
    {
        "###",
        "# #",
        "###",
        "  #",
        "###"
    }  // 9
};

// Renvoie la ligne demandée pour un caractère donné
const char *ObtenirTranche(char c, int ligne)
{
    if (isdigit((unsigned char)c))
    {
        return MOTIFS[c - '0'][ligne];
    }

    // Caractères spéciaux
    switch (c)
    {
        case '-':
            return (ligne == 2) ? "###" : "   ";
        case ':':
            return (ligne == 1 || ligne == 3) ? " # " : "   ";
        case '.':
            return (ligne == 4) ? " # " : "   ";
        case ' ':
        default:
            return "   ";
    }
}

// Affiche la chaîne complète horizontalement sur l'écran LED
void AfficherEcranLED(const char *texte)
{
    if (texte == NULL || strlen(texte) == 0)
    {
        return;
    }

    size_t longueur = strlen(texte);

    // Bordure supérieure
    printf("+");
    for (size_t i = 0; i < longueur * (LARGEUR + 1) + 1; i++) printf("-");
    printf("+\n");

    // Rendu ligne par ligne (de haut en bas)
    for (int ligne = 0; ligne < HAUTEUR; ligne++)
    {
        printf("| ");
        for (size_t i = 0; i < longueur; i++)
        {
            printf("%s ", ObtenirTranche(texte[i], ligne));
        }
        printf("|\n");
    }

    // Bordure inférieure
    printf("+");
    for (size_t i = 0; i < longueur * (LARGEUR + 1) + 1; i++) printf("-");
    printf("+\n\n");
}

// Mode Horloge Digitale en temps réel
void AfficherHorloge(void)
{
    time_t maintenant = time(NULL);
    struct tm *temps = localtime(&maintenant);

    char buffer[16];
    strftime(buffer, sizeof(buffer), "%H:%M:%S", temps);

    printf(">>> HORLOGE DIGITALE COURANTE : %s <<<\n", buffer);
    AfficherEcranLED(buffer);
}

int main(void)
{
    printf("===================================================\n");
    printf("   ALGOJUNGLE - SIMULATEUR D'ECRAN LED 7 SEGMENTS  \n");
    printf("===================================================\n\n");

    // Démonstration 1 : Affichage de l'année
    printf("Affichage de l'annee 2026 :\n");
    AfficherEcranLED("2026");

    // Démonstration 2 : Valeur négative avec décimale
    printf("Affichage d'une temperature : -14.5 C\n");
    AfficherEcranLED("-14.5");

    // Démonstration 3 : Horloge
    AfficherHorloge();

    // Mode interactif
    char saisie[64];
    printf("Entrez un nombre ou un texte a afficher (ou 'q' pour quitter) :\n>>> ");
    if (fgets(saisie, sizeof(saisie), stdin) != NULL)
    {
        saisie[strcspn(saisie, "\r\n")] = '\0';
        if (strcmp(saisie, "q") != 0 && strlen(saisie) > 0)
        {
            printf("\nRendu de votre saisie :\n");
            AfficherEcranLED(saisie);
        }
    }

    return EXIT_SUCCESS;
}

5. Analyse de la complexité et optimisations#

  • Complexité temporelle : Pour une chaîne de \(N\) caractères et une matrice de hauteur \(H=5\), l'algorithme effectue exactement \(H \times N\) itérations. La complexité est donc en \(\mathcal{O}(N)\), ce qui est optimal.
  • Complexité spatiale : L'espace mémoire occupé par le tableau MOTIFS est constant : \(10 \times 5 \times 4 = 200\) octets en mémoire statique .rodata.
  • Indépendance vis-à-vis du terminal : Cette approche ne nécessite aucune bibliothèque spécifique à un OS (comme conio.h ou windows.h) et s'exécute de façon identique sous Linux, macOS et Windows.

6. Extensions suggérées#

Pour aller plus loin, vous pouvez implémenter : 1. Une option de mise à l'échelle (scaling) permettant de doubler la taille des segments (ex: segments de 2 caractères de large sur 2 lignes de haut). 2. Un affichage dynamique d'un compte à rebours avec rafraîchissement d'écran en utilisant la séquence d'échappement ANSI \033[H\033[J et usleep().

Commentaires

Inscrivez-vous à une formation complète

Voir le catalogue