TP01 : Prise en main et thermomètre numérique
Dans ce TP, après une rapide prise en main de la cible, nous réalisons un thermomètre qui affiche la température ambiante sur l’afficheur 7-segments et sur l’écran LCD.
Photo par Kaffeebart sur Unsplash
Objectifs du TP
Ce TP a pour but de vous familiariser avec l’environnement de développement et de réaliser un premier projet qui met en œuvre plusieurs bus de communication (I2C et SPI).
À la fin de ce TP, les étudiants :
- auront installé leur PC pour réaliser les TPs;
- sauront utiliser les outils de développement;
- connaîtront les règles de style à appliquer pour les TPs;
- sauront utiliser le CI/CD de gitlab pour vérifier le code;
- auront réalisé un test unitaire qui tourne sur une cible;
- auront mis en œuvre le concept de programmation orientée objet et auront implémenté des classes en C++;
- connaîtront les différents bus de communications pour les périphériques externes (I2C, SPI, UART)
- auront rédigé un journal de travail et déposé le PDF dans le dépôt git.
Les livrables sont :
- un projet git (tp01) dans votre groupe sur gitlab.forge.hefr.ch avec le code du TP et le code du programme de test;
- une configuration CI/CD de gitlab pour valider votre TP;
- un journal de travail déposé sur gitlab.
Temps accordé : 4 périodes de 45 minutes en classe + travail personnel à la maison
Délai
Le TP doit être rendu au plus tard 6 jours après la séance en classe à 23:59.
Prise en main de l’environnement de développement
Pour les TPs du cours Systèmes Embarqués 1, nous utilisons la même cible que pour les TPs du cours Architecture des Ordinateurs et la même bibliothèque STM32Cube pour la couche d’abstraction du matériel (HAL - Hardware Abstraction Layer).
- L’enseignant vous a assigné un projet sur gitlab.forge.hefr.ch (
embsys/2024-2025/sup/tp01/tp01<X>
). - Le projet à été créé à partir du projet starter-tp01. Prenez un moment pour étudier les fichiers de ce projet.
- Clonez le projet sur votre PC.
Attention
- Évitez d’avoir des espaces, des lettres accentuées ou des caractères spéciaux dans le path du projet sur votre PC.
- Assurez-vous d’avoir au moins 3GB de libre sur votre disque dur / SSD.
Assurez-vous que le projet starter compile bien sur votre machine et assurez-vous de pouvoir flasher la cible avec ce projet. Le nombre 42 devrait être affiché sur le 7-segments, la LED bleue devrait clignoter et l’écran LCD devrait afficher un message de bienvenue.
Note
Le projet starter-tp01 est un projet complet qui ne dépend que de STM32Cube.
Tout le code de l’écran et tous les drivers sont dans le dossier lib
. Prenez
le temps d’étudier tous les fichiers de ce projet (sauf lib/cmsis_rtos_v2
et
lib/FreeRTOS
que nous étudierons dès le prochain TP)
Utilisation du 7-segments
Dans le cours “Architecture des Ordinateurs”, vous avez utilisé le 7-segments avec l’interface de communication SPI.
- SCK (Serial ClocK) : le signal d’horloge émis par le contrôleur.
- SDO (Serial Data Out) : le signal de données émis par le contrôleur. Ce signal était parfois nommé MOSI (Master Out Slave In), mais les termes de master ou de slave ne sont plus politiquement corrects. La dénomination COPI (Controller Out Peripheral In) est parfois également utilisée.
- SDI (Serial Data In) : le signal de données reçues par le contrôleur. L’ancien nom était MISO (Master In Slave Out). La dénomination CIPO (Controller In Peripheral Out) est également utilisée.
- CS (Chip Select) : le signal de sélection du périphérique externe. Son ancien nom était SS (Slave Select).
Un contrôleur peut communiquer avec plusieurs périphériques, mais il a besoin d’un signal Chip Select par périphérique. Le microcontrôleur STM32F412 possède 5 contrôleurs SPI qui peuvent communiquer avec une horloge de maximum 50 MHz.
L’affichage 7-segments est contrôlé par un registre à décalage et le SPI est un très bon moyen d’envoyer les bits au registre à décalage.
Pour écrire dans le registre à décalage du 7-segments avec cette interface de communication, nous devons nous assurer d’utiliser les bons paramètres (vitesse d’horloge, polarité et phase).
À faire
Pour compléter l’interaction avec le registre à décalage, il faut encore manipuler le latch. Reprenez le code du cours “Architecture des Ordinateurs” et décrivez le rôle du latch
Illustrez l’envoi de 8 bits dans un registre à décallage avec un un diagramme temporel. Dessinez tous les signaux nécessaires.
Mesure et lecture de la température
Pour mesurer la température, nous utilisons une nouvelle “Click-Board” avec le capteur de température TMP102. Étudiez bien ce document pour savoir comment utiliser le capteur de température.
Configurez votre cible comme illustré ci-dessous :
Ce capteur utilise le bus I2C (Inter-Integrated Circuit). Il s’agit d’un protocole inventé par Philips Semiconductors en 1982 et qui est très utilisé dans les systèmes embarqués. Le bus I2C n’a besoin que de deux fils (en plus de la masse) pour communiquer et chaque périphérique est identifié par une adresse unique transmise également sur ces deux fils. Prenez le temps de parcourir la page Wikipédia pour plus de détails sur le protocole I2C.
Questions
- Quelle est la vitesse de transmission du bus I2C ?
- Quels sont les avantages et les inconvénients du bus I2C par rapport au bus SPI ?
- Est-ce que le bus I2C est synchrone ou asynchrone ?
- Est-ce que le bus I2C fonctionne en “simplex”, “full-duplex” ou en “half-duplex” ?
L’utilisation de I2C avec STM32Cube est décrite dans le chapitre 36 (HAL I2C Generic Driver / page 482) du manuel UM1725 : “Description of STM32F4 HAL and low-layer drivers”. Étudiez ce chapitre et en particulier la section 36.2.1 pour savoir comment utiliser le pilote.
Notez que le point 2.a) (Enable the I2Cx interface clock) est implémenté
dans le constructeur de la classe ArduinoShield
et 2.b) (I2C pins configuration) est implémenté dans la méthode MspInitI2c()
de cette même classe ArduinoShield
. Étudiez le code de constructeur et de
cette méthode.
Les points 2.c) et 2.d) ne sont pas nécessaires pour notre projet.
Pour le point 3), vous devez impérativement configurer la vitesse (ClockSpeed
)
et la taille de l’adresse (AddressingMode
). Pour la vitesse, vous pouvez utiliser
100 kHz et le mode d’adressage pour notre I2C est sur 7 bits.
Pour le point 6), étudiez le mode Polling mode IO operation. C’est le plus simple et c’est celui que nous utiliserons ici.
À faire
Modifiez le programme principal pour qu’il énumère tous les périphériques
I2C visibles. Écrivez une fonction void ScanI2C(I2C_TypeDef* i2c)
qui
teste toutes les adresses entre 1 et 127 (y compris) et qui affiche un message sur la console pour
toutes les adresses découvertes. Pour savoir si un périphérique répond, utilisez
la fonction HAL_I2C_IsDeviceReady
.
Appelez la méthode ScanI2C
ainsi:
ArduinoShield* shield = ArduinoShield::GetInstance();
shield->MspInitI2c();
ScanI2C(shield->GetI2C());
Assurez-vous que votre programme trouve bien le thermomètre.
À faire
Implémentez une classe Thermo3
avec l’interface suivante :
class Thermo3 {
public:
Thermo3(I2C_TypeDef* i2c, uint16_t address);
~Thermo3();
float GetTemperature();
};
Ajoutez des attributs et des méthodes privées si nécessaire.
Important
Respectez les règles de style imposées pour ce cours!
Autres interfaces de communications
En plus du SPI et du I2C, les systèmes embarqués utilisent également des interfaces de communication comme le UART ou le CAN.
L’interface UART (Universal asynchronous receiver-transmitter) est un protocole de communication asynchrone (comme son nom l’indique) qui permet de communiquer sur de plus longues distances, mais avec un débit de données plus limité. Cette interface est souvent utilisée pour communiquer avec des modems, des modules WiFi ou des récepteurs GPS.
Étudiez les caractéristiques de l’interface UART sur Wikipédia et répondez aux questions suivantes :
Questions
- Quelle distance peut-on atteindre avec cette interface si on utilise la couche physique RS-485 ?
- Quels sont les avantages et les inconvénients l’interface UART par rapport au bus I2C et SPI ?
- Est-ce que l’interface UART fonctionne en “simplex”, “full-duplex” ou en “half-duplex” ?
- Où trouver la documentation pour utiliser l’UART dans STM32Cube ?
Mini projet
Combinez maintenant le module d’affichage sur le 7-segments et le module de lecture de température pour créer un mini-projet qui affiche la température ambiante. Voici le cahier des charges.
- Le système doit lire la température une fois par seconde (sampling : 1 Hz)
- La température doit être affichée en degrés °C avec le plus de précision possible sur l’affichage 7-segments
- La température doit être affichée en degré °C avec une précision d’un dixième de degré sur l’affichage LCD.
- La police pour la température doit être la plus grande possible.
- L’écran LCD ne doit pas trop scintiller. En particulier, l’écran ne doit pas être redessiné si la température ne change pas. Et si elle change, ne redessinez que ce qui est nécessaire.
- Une LED clignote à chaque mesure de la température.
- Assurez-vous que les températures négatives soient bien traitées en refroidissant le capteur avec le spray froid KÄLTE 75.
- (Optionnel) Faites clignoter une LED différente en fonction de la température.
- (Optionnel) Affichez la température sur l’écran LCD avec une couleur différente en fonction de la température.
- (Optionnel) Affichez la température sous une forme non textuelle (par exemple une gauge ou un graphique).
- (Optionnel) Utilisez le Joystick pour changer les unités (°C, °F ou °K).
Tests et validations
Comme vous l’avez appris au cours “Architecture des Ordinateurs”, implémentez des tests unitaires pour vérifier que votre code fonctionne correctement. Vous pouvez simplement vérifier que la température ambiante soit “plausible” (par exemple entre 10 et 40°C) et que lors de deux mesures consécutives, la différence de température ne soit pas trop importante.
Testez aussi la fonction qui convertit les données “brutes” transmises par le thermomètre en nombre réel. Testez en particulier les cas limites, les valeurs extrêmes et les valeurs négatives.
Implémentez également le CI/CD et configurer votre projet pour que les tests unitaires tournent automatiquement dans l’infrastructure CI/CD de l’école. utilisez pour cela le tag embsys-thermo
dans le fichier .gitlab-ci.yml
:
test-job:
stage: test
tags:
- embsys-thermo
script:
- ...
À ne pas oublier
Gardez toujours en têtes les bonnes pratiques ainsi que les dix commandements du bon programmeur.
- Choisissez de bons noms pour les classes, les méthodes et les variables.
- Implémentez les bibliothèques avec un haut niveau d’abstraction pour pouvoir réutiliser les méthodes dans d’autres projets.
- Faites des “git commit” régulièrement avec de bons commentaires.
- Configurez le CI/CD de gitlab et testez automatiquement le plus de choses possibles.
- Implémentez des tests unitaires.
- Utilisez des assertions dans votre code pour le documenter et le rendre plus robuste.
Journal de travail
- Rédigez un rapport (journal de travail) avec les indications suivantes :
- Une page de titre avec au minimum :
- le nom et le logo officiel de l’école
- le nom du cours : Systèmes Embarqués 1
- le titre de votre document : “TP01 : Prise en main et thermomètre numérique”
- le numéro de votre groupe
- les noms des auteurs (vous) avec la classe dans laquelle vous êtes
- la date à laquelle vous avez terminé le rapport
- éventuellement la version du rapport
- Une introduction pour poser le contexte
- Un résumé des notions que vous avez apprises pendant ce TP en précisant si c’est
- non acquis
- acquis, mais encore à exercer
- parfaitement acquis
- Un résumé des points qui vous semblent importants et que vous devez retenir
- Les réponses aux questions.
- Le code source bien formaté et avec du “syntax highlighting” de votre code source.
- Une conclusion par laquelle vous donnez vos impressions sur le TP, ce que vous avez aimé, ce que vous avez moins aimé, et éventuellement des suggestions pour des changements. Indiquez également le nombre d’heures que vous avez passées, par personne, en dehors des heures de TP en classe.
Important
Déposez votre rapport dans un dossier /docs
de votre dépôt git
(tp01) avec le nom report01.pdf
(le chemin complet vers votre rapport est donc
/docs/report01.pdf
)