Les ordinateurs embarqués sous le système d’exploitation Linux sont massivement présents dans les technologies modernes (transports, multimédia, téléphonie mobile, appareils photos …).
L’ordinateur Raspberry PI constitue un support d’apprentissage performant, très bon marché et disposant d’une forte communauté sur le net. Il possède des entrées/sorties puissantes permettant une connexion avec le monde physique par l’intermédiaire de capteurs et d’actionneurs.
L’objectif de ce TP est de réaliser une rapide prise en main d’un système embarqué au travers d’un ordinateur Raspberry PI qui sera largement utilisée en projet et d’effectuer un tour d’horizon des pratiques de mise en œuvre et de développement.
Présentation de l’activité
Objectifs
Se remémorer :
-
les bases de la programmation objet en C++ :
-
Déclaration/Implémentation d’une classe
-
Instanciation d’une classe (→ constructeur)
-
Associations entre classes
-
-
les bases du formalisme UML
-
les principes de la cross-compilation
Apprendre :
-
les principes de la cross-compilation
-
la manipulation du bus i2c du Raspberry pi
Mettre en oeuvre :
-
un afficheur LCD RGB i2c
-
? un capteur de température i2c ?
Durée
-
Entre 8h et 10h
Ressources
Matériel(s) :
-
1 PC avec système d’exploitation Linux
-
1 Raspberry Pi avec OS Débian
-
1 afficheur LCD RGB i2c JHD1313M1 de Grove
-
? 1 capteur de température i2c ?
Logiciel(s) :
-
cross-compilateur
arm-linux-gnueabihf-g++
Documentation :
-
Cours de Mr Antoine sur la programmation objet de 1ière année (disponible sur Chamilo).
-
Sites de référence sur C/C++ :
-
cplusplus.com
-
cppreference.com
-
…
-
Pré-requis
-
Notions sur le formalisme UML (représentation d’une classe et des relations)
-
Maîtrise du langage C (séquences, tests, boucles, variables, fonctions, paramètres, compilation multi-fichiers)
-
Maîtrise de la gestion des fichiers sur un système déporté (ssh, scp, Dolphin, …)
-
Maîtrise de la cross-compilation pour processeurs à architecture ARM
Compte rendu
Il sera constitué :
-
des réponses aux questions en veillant à soigner la rédaction
-
des programmes source commentés
1. Présentation
Le Raspberry Pi dispose de deux interfaces i2c. Le bus numéro 0 qui était accessible à travers le connecteur P5 sur le modèle B a disparu depuis le modèle B+. De plus, ce connecteur étant présent sous forme de simples trous cuivrés, il était donc nécessaire de venir y souder des broches pour pouvoir l’utiliser. Les signaux du bus 0 sont toujours présents – mais pas très accessibles – sur les connecteurs J3 (camera) et J4 (display).
2. Le bus I2C sur le Raspberry pi
2.1 L’accès au bus I2C
Nous allons nous intéresser au second bus, accessible via le port d’extension P1, sur deux broches (que l’on peut également employer pour des entrées/sorties GPIO) identiques quel que soit le modèle de Raspberry. Il s’agit de la broche 3 (signal SDA) et de la broche 5 (signal SCL).
Exercice 1
Rappelez à quoi servent ses deux signaux.
2.1 Activation du bus I2C sur le Raspberry
Le protocole i2c est supporté par le noyau Linux depuis sa version 2.4. De nombreux périphériques sont reconnus par le kernel, notamment dans le sous-système Hwmon (Hardware Monitor).
L’accès depuis l’espace utilisateur est facilité par le module i2c-dev
qui rend les bus i2c visibles dans le répertoire /dev
sous forme de fichiers spéciaux représentant des périphériques en mode caractère.
Exercice 2
-
Activez la prise en charge du bus I2C sur le Raspberry :
$ sudo raspi-config
→ Advanced options → I2C → Enabled (tout accepter).
OU
-
Supprimez du fichier
/etc/modprobe.d/raspi-blacklist.conf
les référence à l’I2C -
Ajoutez i2c aux modules à charger
$ echo i2c-dev >> /etc/modules
Normalement, les modules sont déja installés mais blacklistés. Cependant, dans certains cas, il peut être nécessaire de les installer manuellement : i2c_bcm2708 et i2c-dev |
-
Vérifiez la prise charge du bus I2C, identifiez la vitesse de transmission sur le bus :
$ dmesg | grep i2c
-
Identifiez le(s) bus i2c-c disponible(nt) :
$ ls /dev/i2c*
2.1 Installation des outils de gestion du bus i2c
Exercice 3
-
Installez les outils de gestion du bus i2c
$ sudo apt-get install i2c-tools
-
Détectez des esclaves sur le bus :
$ i2cdetect –y 1
-y pour répondre automatiquement yes et 1 pour le numéro de périphérique i2c |
Les commandes i2cset et i2cget permettent respectivement d’écrire et de lire sur le bus i2c.
|
3. Gestion d’un afficheur LCD RGB i2c
L’afficheur à gérer est un JHD1313M1 de chez Grove. Il est en fait composé d’un afficheur LCD basé sur le HD44780 d’Hitachi et d’un contrôleur du rétro-éclairage (RGB) PCA9633 de NXP Semiconductors. Il possède donc 2 adresses i2c :
-
LCD : 0x3e
-
RGB : 0x62
3.1 Par l’invite de commandes
Exercice 4
-
Connectez l’afficheur au connecteur de la carte Raspberry pi.
l’afficheur nécessite une tension de 5V pour fonctionner correctement. |
-
Vérifiez la présence de l’afficheur sur le bus i2c.
La commande i2cset s’utilise de la manière suivante :
|
-
Procédez à la séquence d’initialisation de l’afficheur :
i2cset -y 1 0x3E 0x80 0x3C
i2cset -y 1 0x3E 0x80 0x0C
i2cset -y 1 0x3E 0x80 0x01
i2cset -y 1 0x3E 0x80 0x06
i2cset -y 1 0x62 0x00 0x00
i2cset -y 1 0x62 0x08 0xFF
i2cset -y 1 0x62 0x01 0x20
i2cset -y 1 0x62 0x04 0x00
i2cset -y 1 0x62 0x03 0x00
i2cset -y 1 0x62 0x02 0xFF
i2cset -y 1 0x3E 0x40 0x31
i2cset -y 1 0x3E 0x40 0x32
i2cset -y 1 0x3E 0x40 0x33
-
Identifiez les instructions passées à l’afficheur LCD (adresse i2c 0x3E) et au contrôleur de rétro-éclairage (adresse i2c 0x62):
-
Identifiez les registres de gestions des couleurs du contrôleur de rétro-éclairage.
-
Configurez le rétro-éclairage pour qu’il clignote à une fréquence de 1Hz avec un rapport cyclique de 50%.
3.2 Visualisation d’une trame i2c
Le bus i2c (Inter Integrated Circuit) fait partie des bus série : 3 fils pour faire tout passer. Il a été développé au début des années 1980, par Philips pour minimiser les liaisons entre les circuits intégrés numériques de ses produits (Téléviseurs, éléments HiFi, magnétoscopes, …). |
Exercice 4
-
A tour de rôle, vous vous rendrez sur le poste dédié à l’utilisation de l’analyseur de protocole Saelae
-
Exécutez le logiciel Logic qui permet de piloter l’analyseur Saelae
-
Paramétrez l’analyseur logique, connectez 2 de ses sondes aux broches SDA et SCL du Raspberry Pi et lancez une acquisition avec analyse du protocole i2c.
-
Envoyez la commande
i2cset -y 1 0x3E 0x40 0x31
-
Analysez les trames obtenues et vérifiez qu’elles sont conformes au standard i2c
-
Vitesse de transfert (fréquence de SCL)
-
Condition de départ (START) et condition d’arrêt (STOP)
-
Adresse de l’esclave
-
Type d’opération (lecture/écriture)
-
Adresse du registre visé
-
Valeur de la donnée
-
bits ACK
-
3.3 Programmation C++
Vous allez écrire un programme permettant d’afficher un message sur votre afficheur en vous appuyant sur la librairie rgb_lcd
de gestion de cet afficheur.
Mais il nous faut avant tout pouvoir utiliser le bus i2c. La librairie `BCM2835`que nous avons utilisé dans le précédent TP fournie des fonctions de gestions du bus :
Exercice 5
-
Codez le programme de test suivant :
/**************************
* Test du rétro-éclairage
*
* i2cset -y 1 0x62 0x00 0x00
* i2cset -y 1 0x62 0x08 0xFF
* i2cset -y 1 0x62 0x01 0x20
* i2cset -y 1 0x62 0x04 0x00
* i2cset -y 1 0x62 0x03 0x00
* i2cset -y 1 0x62 0x02 0xFF
*
******************************/
#include <bcm2835.h>
#include <iostream>
using namespace std;
int main()
{
char buf[1];
if (!bcm2835_init())return 1;
bcm2835_i2c_begin(); //Start I2C operations.
cout << "Start I2C operations : ok" << endl;
bcm2835_i2c_setSlaveAddress(0x62); //I2C address
cout << "I2C address : ok" << endl;
bcm2835_i2c_set_baudrate(10000); //10k baudrate
cout << "Baudrate : ok" << endl;
buf[0] = 0x00;
buf[1] = 0x00;
bcm2835_i2c_write(buf,2);
buf[0] = 0x08;
buf[1] = 0xFF;
bcm2835_i2c_write(buf,2);
buf[0] = 0x01;
buf[1] = 0x20;
bcm2835_i2c_write(buf,2);
buf[0] = 0x02;
buf[1] = 0xFF;
bcm2835_i2c_write(buf,2);
buf[0] = 0x03;
buf[1] = 0xFF;
bcm2835_i2c_write(buf,2);
buf[0] = 0x04;
buf[1] = 0;
bcm2835_i2c_write(buf,2);
bcm2835_i2c_end();
bcm2835_close();
return 0;
}
-
Donnez les définitions des fonctions suivantes :
-
bcm2835_init()
-
bcm2835_i2c_begin()
-
bcm2835_i2c_setSlaveAddress(0x62)
-
bcm2835_i2c_set_baudrate(10000)
-
bcm2835_i2c_write(buf,2)
-
bcm2835_i2c_end()
-
bcm2835_close()
-
Reportez vous à la documentation de la librairie BCM2835 |
La classe rgb_lcd
permet de gérer l’afficheur et le rétro-éclairage.
Exercice 6
-
Identifiez la méthode qui réalise l’initialisation de l’afficheur et montrez qu’elle est conforme à la séquence d’initialisation décrite par le fabricant.
-
Identifiez la méthode qui permet de gérer la couleur du rétro-éclairage.
-
Identifiez la méthode qui permet d’afficher des caractères sur l’afficheur.
-
Complétez les définitions du fichier d’entête
rgb_lcd.h
en remplaçant les "?" par les bonnes adresses :
// Device I2C Adrress
#define LCD_ADDRESS ????
#define RGB_ADDRESS ????
// color define
...
// RGB Registers
#define REG_RED ????
#define REG_GREEN ????
#define REG_BLUE ????
#define REG_MODE1 ????
#define REG_MODE2 ????
#define REG_OUTPUT ????
-
Quels objets de la classe
Ci2cBcm2835
permettent l’accès au bus i2c ? -
Codez la classe
Ci2cBcm2835
qui définie par le diagramme de classe ci-dessous :
Exercice 7
-
Codez le programme principal
mainLcd.cpp
qui répond à l’algorithme suivant :
Début
Instancier un objet de la classe `rgb_lcd`
Initialiser l'afficheur (16 caratères, 2 lignes)
Configurer le rétro-éclairage en bleu
Placer le curseur au caractère 5 de la première ligne
Ecrire _"Bonjour"_
Placer le curseur au caractère 1 de la seconde ligne
Ecrire _"Afficheur i2c"_
Attendre 5 secondes
Effacer l'écran
Configurer le rétro-éclairage en blanc
Placer le curseur au caractère 0 de la première ligne
Ecrire _"OH"_
Placer le curseur au caractère 0 de la seconde ligne
Ecrire _"YES !!!"_
Tant que 1
Décaler l'affichage vers la droite
Attendre 250 ms
Fin tant que
Fin
-
proposez une séquence personnelle d’affichage en jouant avec les couleurs et le clignotement du rétro-éclairage, des décalages vers la droite ou la gauche du texte à l’écran.
4. Conclusion
Le bus de données i2c permet d’échanger des données numériques entre un capteur (ou un actionneur) et un mini-PC tel que le Raspberry Pi. Le bus i2c est très répandu également sur les micro-contrôleurs (Arduino, ESP8266, ESP32). Par défaut, le bus i2c n’est pas activé sur la distribution Raspbian.
Les outils de diagnostic et de gestion en ligne de commandes sont très utiles.
La librairie BCM2835 fournie les fonctions nécessaires à la gestion du bus dans un programme C/C++