Objectifs pédagogiques
Les principaux objectifs de ce sujet de travaux pratiques sont :
- de découvrir le paradigme de la programmation procédurale (cf. le chap. C1‑I ), autrement dit de créer pas à pas un programme décomposé en fonctions ;
- de découvrir l'usage des variables locales statiques.
Les exercices sont aussi l'occasion de consolider la pratique des éléments de langage mis en œuvre aux TP précédents, en particulier la manipulation des variables de type byte, la génération de nombres pseudo‑aléatoires et la composition d'appels de fonctions.
Pour traiter ce sujet de TP, il est recommandé d'avoir étudié les chapitres C4‑I à C4‑III du cours. Des renvois aux principaux éléments de connaissance requis sont indiqués au fur et à mesure des questions.
Mise en situation
Spécifications matérielles générales
Tous les exercices sont à traiter dans l'environnement de simulation en ligne Tinkercad , en implémentant préalablement le montage électronique en figure ci‑contre, qui comprend les composants listés ci‑dessous :
- Une pile « bouton » CR2032 de tension nominale 3 V assure l'alimentation embarquée du montage.
- Une platine d'essai (breadboard) de très petite taille (« mini‑plaquette ») suffit.
- Un microcontrôleur Atmel ATTiny 85 (cf. chap C1‑III ) remplace avantageusement une carte Arduino avec un encombrement minimal. Sa broche PB5 est laissée non connectée pour générer un nombre aléatoire par lecture analogique de la tension générée par le champ électromagnétique ambiant.
- Sept led bleues (numérotées de 1 à 7) sont disposées selon le motif générique commun aux six faces d'un dé à jouer. À l'exception de la led centrale (nº 7), elles sont pilotables par pairs (en effet, à titre d'exemple, les led nº 1 & 6 sont toujours allumées ensembles). Elles sont donc raccordées aux broches PB0 à PB3 du microcontrôleur via un résistor de limitation de courant, conformément aux spécifications ci‑dessous :
- les led d'angle nº 1 et 6, en parallèle, à la broche PB0, via un résistor de 22 Ω ;
- les led latérales nº 2 et 5, en parallèle, à la broche PB1, via un résistor de 22 Ω ;
- les led d'angle nº 3 et 4, en parallèle, à la broche PB2, via un résistor de 22 Ω ;
- la led centrale nº 7, seule, à la broche PB3, via un résistor de 47 Ω ;
- la tension délivrée par la pile est très basse (3 V, voire moins lorsqu'elle s'use) ;
- les led bleues ont une tension directe élevée (typiquement, 2,5 V).
- Un détecteur d'inclinaison SW200D (dual ball tilt switch) joue le rôle de déclencheur d'un lancé de dé. Il est alimenté par la tension de la pile et câblé en logique positive (cf. chap. C2‑VIII , c'est‑à‑dire raccordé à la broche PB4 du microcontrôleur avec un résistor de pull‑down (vers la borne « − » de la pile) de 2 kΩ.
Depuis 2025, la simulation de l'ATTiny 85 sur Tinkercad n'est pas satisfaisante (les programmes ne s'exécutent pas conformément à leur algorithme). Il est donc vivement recommandé d'utiliser une plateforme alternative comme, par exemple, Wokwi (cf. chap. C1‑III ).
Il suffit de réaliser un montage similaire, représenté sur la figure ci‑contre, avec les deux différences suivantes :
- Il n'y a pas d'alimentation (Wokwi ne simule pas les aspects électriques) :
- Le détecteur d'inclinaison est remplacé par un simple bouton‑poussoir.
Pour mémoire, le montage peut être récupéré et sauvegardé sous la forme d'un fichier .json (cf. l'onglet diagram).
Spécifications logicielles générales
Le gadget en photo ci‑contre est un dé électronique (modèle en kit). Son fonctionnement consiste à animer les led pour simuler un dé à six faces qui roule pour finalement présenter sa face du dessus, « fruit » du hasard. Pour plus de détails, on peut consulter la vidéo Y présentant une solution DIY de ce gadget.
Les spécifications logicielles pour le programme d'animation final du dé sont les suivantes :
- Chaque roulement de dé est déclenché sur front montant sur le signal du détecteur d'inclinaison.
- Un roulement du dé est simulé par une séquence d'affichage de 10 faces du dé, toutes tirées au hasard et chacune restant affichée durant une durée croissante par incréments de 100 ms, qui est aussi la durée d'affichage de la première face de la séquence.
- Dans une séquence, deux faces consécutives doivent nécessairement être adjacentes sur un dé c'est‑à‑dire, ni identiques, ni opposées – cf. le patron d'un dé sur la figure.
- La dernière face de la séquence doit rester affichée tant que le dé n'est pas « relancé », et au moins deux secondes avant le début d'une nouvelle séquence.
- Une séquence ne peut pas être interrompue par un nouveau déclenchement du détecteur d'inclinaison. Elle doit obligatoirement être exécutée jusqu'à son terme.
Travail demandé
Il est recommandé de traiter les exercices dans l'ordre.
Préalablement, dans un nouveau circuit sous Tinkercad :
- effectuer le câblage de la partie matérielle conformément à la figure ci‑dessus ;
- vérifier le câblage par branchements directs temporaires, typiquement en reliant les sorties led au potentiel de référence 3V de la pile.
Pour coder les programmes, il est vivement recommandé de ne pas travailler directement dans Tinkercad, mais d'utiliser un éditeur de code externe comme VS Code, à paramétrer pour obtenir une coloration syntaxique adaptée au langage C++ (cf. chap. C2‑X ).
On s'efforcera de respecter les règles de bonnes pratiques de codage, notamment pour le nommage des données, l'indentation et l'aération du code (cf. chap. C2‑X ).
- Au fur et à mesure, enregistrer chaque fichier source en le nommant conformément à la numérotation des exercices, c'est‑à‑dire par exemple :
Ct41_exNvX.ino
où N est le numéro de l'exercice et X la version du programme. - Tous ces fichiers doivent être regroupés dans un répertoire d'exercices nommé par exemple
TP_C4-1, lui‑même placé dans le répertoire principal de programmationPROG_C, lui‑même placé dans répertoire personnel d'étudiant.
Remarque. Comme on n'expérimente pas ici avec une véritable carte Arduino, il n'est pas indispensable de créer un répertoire de projet distinct pour chaque programme.
Enfin, pour tester le bon fonctionnement de chaque programme, procéder par copier‑coller dans la fenêtre d'édition de Tinkercad. En cas de modifications ponctuelles de mise au point, ne pas oublier d'effectuer un copier‑coller inverse dans l'éditeur de code et d'enregistrer les modifications.
Répondre aux questions supplémentaires sur feuille ou cahier.
Consignes de codage
Au début de chaque programme, selon les besoins, définir des pseudo‑constantes (cf. chap. C4‑III ) pour nommer :
- les numéros de broche en fonction de leur utilisation (procéder de la même manière que pour traiter les sujets de TP C2‑2 et C3‑I , c'est‑à‑dire en définissant seulement la première et la dernière broche de pilotage des led) ;
- les valeurs des délais dans une séquence – cf. les spécifications générales B et E supra.
- Fonction de configuration et initialisation des broches
- convertir le nombre en un octet dont les 4 bits de poids faibles représentant respectivement les groupes de led à allumer (valeur
1) ou éteindre (valeur0) reliées aux brochesPB0àPB3du microcontrôleur ; - recopier les bits de cet octets sur le port de sortie du microcontrôleur pour afficher la face de dé voulue.
- Fonction de transcodage du nombre à afficher
- Coder la fonction
transcodeNumberqui transcode la valeur numérique d'une face de dé en un quartet de sorties logiques conformément au montage du système. Cette fonction doit : - prendre pour argument un nombre entier
numbercompris entre1et6; - retourne comme valeur un octet de sortie (de type
byte) dont le quartet de poids faible (les bits de rang 0 à 3) indiquent le niveau logique à écrire respectivement sur les 4 broches PB0 à PB3 du microcontrôleur pour afficher la face du dé correspondant au nombre pris comme argument. - Fonction d'affichage de la face du dé
- Coder la fonction
displayDiceFacequi affiche les faces de dé en « recopiant » sur les broches des led les valeurs des bits d'un octet de sortie de la fonctiontranscodeNumber. Sans valeur retournée (c'est‑à‑dire de typevoid), la fonctiondisplayDiceFace: - prend pour argument un octet nommé
pinBytedont les valeurs0ou1des bits du quartet de poids faible codent respectivement les niveaux logiquesLOWouHIGHà écrire sur les 4 sorties PB0 à PB3 du microcontrôleur ; - écrit physiquement ces niveaux logiques de sorties (cf. chap. C2‑VIII ).
- Dans la fonction
setup, coder temporairement un jeu d'essai de cette fonction, en affichant sur les led la succession des 16 combinaisons de valeurs du quartet de poids faible (0b0000à0b1111) de l'octetpinByteargument de la fonctiondisplayDiceFace, même si 10 de ces combinaisons ne correspondent à aucune face de dé. - Programme d'affichage d'une séquence ordonnée de faces
- Fonction de génération d'une face de dé aléatoire
- Coder une fonction
initRandomSeriequi, sans arguments ni valeur retournée, initialise la série de nombres pseudo‑aléatoires (cf. chap. C3‑II ) pour générer des nombres aléatoires toujours différents, d'une exécution à l'autre du programme. - * Coder une fonction
generateNewFaceNumber, sans argument, qui retourne comme valeur un nouveau nombre aléatoire entier qui est tiré entre1et6et qui respecte la condition d'adjacence avec le nombre aléatoire précédemment affiché comme face de dé (cf. la spécification logicielle C supra). - Dans la fonction
loop, coder un programme d'essai qui appelle la composition des fonctionsgenerateNewFaceNumber,transcodeNumberetdisplayDiceFacepour afficher en boucle des faces de dé aléatoires (successivement adjacentes), chacune restant visible une seconde. - Fonction de détection de déclenchement du détecteur d'inclinaison
- Coder une fonction
isSequenceTriggered, sans argument, qui détecte les déclenchements du détecteur d'inclinaison, autrement dit qui retourne la valeur booléenne1en cas de front montant sur le signal du détecteur d'inclinaison, sinon la valeur0. - Coder un programme d'essai de la fonction
isSequenceTriggeredqui affiche durant une seconde la face ⚀ du dé à chaque front montant sur le signal du détecteur d'inclinaison, sachant que : - durant l'affichage, d'éventuels fronts montants ultérieurs à celui qui a déclenché l'affichage doivent être ignorés ;
- une fois que la durée est écoulée, la face doit s'éteindre (jusqu'au prochain front montant).
- Programme d'affichage d'une séquence aléatoire
- Coder un programme qui, à chaque front montant sur le signal du détecteur d'inclinaison affiche sur les led, une séquence aléatoires de 10 faces de dé successivement adjacentes, chacune restant affichée ½ seconde, sauf la dernière qui doit rester affichée jusqu'au prochain front montant.
- Modifier le programme précédent pour que la durée d'affichage des faces soit de plus en plus longue au cours de la séquence, conformément aux spécifications logicielles B et D supra.
loop (pas encore codée), coder une fonction initPins qui, sans arguments ni valeur retournée (c'est‑à‑dire de type void – cf. chap. C4‑I ), configure toutes les broches connectées du microcontrôleur et initialise les sorties au repos. for que l'on code usuellement dans la fonction setup pour configurer les broches.) Dans une logique de programmation procédurale (cf. le chap. C1‑I ), on va d'abord décomposer l'affichage d'une face de dé (codée par un nombre compris entre 1 et 6) comme un enchaînement d'appels de deux fonctions transcodeNumber et displayDiceFace qui vont, dans l'ordre :
Cet enchaînement d'appels (cf. le cours, chap. C4‑I W) correspond au schéma‑bloc représenté ci‑dessous.
0b0000. number vaut 3, la fonction retourne l'octet 0b1100 pour mettre au niveau logique HIGH les sorties PB2 (led nº 3 et 4) et PB3 (led nº 7) formant la face ⚂ du dé (cf. la figure ci‑dessus). loop une boucle for dans laquelle on appelle la composition des fonctions transcodeNumber et displayDiceFace pour afficher sur les led la séquence ordonnée de toutes les faces de dé de ⚀ à ⚅, avec une durée d'affichage d'une seconde pour chacune. setup. previousDisplayedNumber (cf. chap. C4‑II ).
previousSwitchLevel et currentSwitchLevel, initialisées toutes les deux à la valeur LOW puisque le détecteur est câblé en logique positive. Ces deux variables mémoriseront respectivement les valeurs antérieure et courantes lues sur la broche du détecteur d'inclinaison et permettront ainsi d'exprimer l'occurrence d'un front montant.