NOMS : Date :
Objectifs :
– Mesurer une température sur une carte Raspberry Pi avec un capteur électronique communicant sur le bus I2C.
Compétences abordées
:
Concevoir C3.4 : Valider le choix d'une architecture matérielle/logicielle
Réaliser C4.3 : Analyser la structure logicielle. Procéder aux modifications logicielles C4.5 : Tester et valider un matériel
Installer C5.2 : Exécuter des mesures et tests appropriés.
Savoirs abordés
:
Savoir Description
S3.1. Modélisation orientée objet Objets, classes.
Constructeurs, destructeurs.
S4.1. Principes de base Représentation et codage des informations
Organisation des programmes : point d’entrée et arguments de la ligne de commande, prototypes, fonctions, paramètres, valeur de retour
S4.2. Algorithmique Structures fondamentales : enchaînements, alternatives, itérations, etc.
Bibliothèque standard (ANSI C) S4.3. Structure et gestion des
données Structures de données et méthodes d’accès directe et/ou indirecte : tableau
S4.4. Programmation procédurale Transcription d’algorithmes (« comment ») en pseudo-langage et/ou en langage C
S4.6. Programmation orientée objet (Support : C++) Instanciation d'objets [new, delete, etc.)
S4.7. Langages de programmation C++
S7.1. Concepts fondamentaux de la transmission Codage, débit binaire
S7.6. Réseaux locaux industriels I2C.
S8.1 Instruments de mesure Analyseur logique
Moyens :
– Carte Raspberry pi avec configuration minimale
→ Bus I2C en service,
→ librairie BCM2835 installée,
→ logiciel « gedit » installé.
– Capteur DS1621 (x2) + mini breadboard + fils.
– Analyseur logique Saleae ou Ikalogic ScanaQuad.
– Ordinateur disposant du logiciel Fritzing.
Conditions :
– Travail en binôme.
– Durée : 1 séance de 4H
– Compte rendu remis en fin de séance.
Prérequis :
Mise en situation
Les objectifs de ce TP sont :
• d'analyser la documentation d'un capteur de température communicant sur le bus I2C.
• de mettre en service le bus I2C sur la carte Raspberry Pi.
• de proposer un schéma de câblage rapide pour effectuer des essais sur une carte Raspberry Pi.
Capteur de température DS1621
La documentation du composant figure sur le site.
1 Quelle est la plage des températures mesurables par le capteur ? → 2 Dans quelle plage de tension peut fonctionner le circuit ? →
3 De quelles tensions d'alimentation dispose la carte Raspberry Pi ? → Sur le site figure le schéma structurel de la carte Rpi2B.
4 Des résistances de pull up sont nécessaires entre les broches SDA et SCL (bus I2C) et la tension d'alimentation. Rappeler leur rôle.
→
5 Les résistances de pull-up sont-elles déjà implantées sur la carte (dans ce cas indiquez leur valeur et sur quel schéma elles figurent) ou faut-il les câbler en même temps que le capteur de température (dans ce cas proposer une valeur) ?
→
6 Quelle(s) alimentation(s) de la carte Rpi est-il possible d'utiliser pour alimenter le DS1621 ? →
A-t-on réellement le choix dans le cas présent ? → 7 Le bus I2C est-il en service par défaut sur la carte ? →
8 Quelle est l'adresse de base, au format 7 bits du circuit DS1621 sur le bus I2C ?
→
9 A quoi servent les broches A0, A1 et A2 ? →
À quel niveau logique faut-il les positionner si l'on souhaite conserver l'adresse I2C de base ? →
10 Quel est le rôle de la broche "Tout" (la réponse ne doit pas se limiter à donner le nom de la broche).
→
11 Quelle est la précision du capteur ? → 12 Quel est le format des données ? →
Mise en service du bus I2C sur Rpi et installation de la librairie BCM2835
13 Si le bus I2C n'a pas été mis en service lors de la configuration de l'OS, le mettre en service en passant par le menu de configuration. Méthode indiquée dans l’onglet « Bus I2C sur Raspberry Pi ».
14 La librairie « bcm2835 » doit être installée sur la carte, si ce n'est pas le cas consulter les informations sur le site pour l'installer.
A noter : un fichier bcm2835.cpp sera fourni avec les fichiers des programmes à analyser et compléter, de façon à pouvoir programmer en C++ (C orienté objet).
Schéma de câblage rapide de l'association Rpi ↔ DS1621
Le logiciel Fritzing permet d'effectuer un schéma du câblage rapide (très pratique pour documenter les phases de mise au point) à réaliser entre la carte Rpi et le DS1621, le capteur étant monté sur un mini-breadboard.
15 Effectuez la saisie du schéma avec le logiciel Fritzing en utilisant si nécessaire le document d'aide .pdf figurant sur le site, et/ou la vidéo indiquant les commandes de base.
Le schéma devra permettre de faire fonctionner le capteur, celui-ci étant alimenté par la carte Rpi 2 et devant fonctionner à son adresse par défaut.
La saisie du schéma doit donc tenir compte de l'analyse précédente du capteur.
L'exportation d'une image du schéma au format .jpg sera à insérer dans le compte-rendu du TP (fichier LibreOffice).
Faire vérifier le schéma de câblage 16 Effectuez le câblage réel, à l'identique du schéma que vous venez de saisir. Prévoir de
laisser suffisamment de place pour un second circuit sur le même support.
Faire vérifier le câblage avant toute mise sous tension.
17 La commande « i2cdetect -y 1 » permet de connaître l'adresse I2C des circuits présents sur le bus. Lancez cette commande. Quelle est l'adresse du circuit DS1621 ?
→
18 Modifiez momentanément l'adresse (en changeant le câblage de l'une des Chip Address Input du circuit) pour vérifier que cette modification est bien prise en compte.
Mesure de température, par programmation en C et affichage en mode console Le programme du Document ANNEXE 1 est téléchargeable sur le site.
A noter : ce programme ne gère pas les températures négatives.
19 Récupérez le fichier, et le stocker dans un dossier « TP_DS1621 » dans votre sous- répertoire de travail sur la carte Rpi2. Renommez-le « DS1621_V1_votre_nom.cpp ».
Compilez le programme ( !! penser à adapter la ligne de compilation) et vérifiez son bon fonctionnement. Une vidéo illustrant le résultat attendu figure sur le site (Vidéo 1).
Sur le site figure un lien vers la documentation I2C de la librairie bcm2835. Utiliser ces informations et la documentation du DS1621 pour répondre aux questions qui suivent.
20 Utiliser l'analyseur logique pour visualiser les signaux SDA et SCL. Vérifier que la mesure affichée sur la console est cohérente avec les données visualisées (adresse I2C du circuit, commandes envoyées au DS1621, valeurs retournées).
→
Quelle est la vitesse de transmission sur le bus ? →
Effectuer une capture qui illustrera le compte rendu (après inversion des couleurs si nécessaire). 21 Le programme utilise un tableau de valeurs pour stocker les données à sortir (de la carte
Rpi vers le capteur), et un autre tableau pour les données lues (DS1621 vers Rpi).
Indiquer le nom respectif de chacun de ces tableaux.
→ →
22 L'une des lignes du programme est intentionnellement en commentaire, la mettre en service (enlever le commentaire, compiler et lancer l'exécutable) et visualiser les informations brutes récupérées par la carte Rpi lors de la mesure. On en déduit que :
• l'essentiel de la mesure effectuée par le DS1621 est envoyé sur le 1er ou le 2ème byte des données ?
→
• Dans le tableau de réception quelle est la case correspondante ? → Remettre la ligne en commentaire.
23 Complétez les commentaires du Document ANNEXE 1.
24 Le DS1621 est-il configuré en mode « 1 Shot » ou « conversion en continu » ?
→
A partir de la documentation (bas de page 4 et haut de page 5) indiquer l'intérêt du mode
« 1 Shot »
→
25 Sauvegarder le fichier « DS1621_V1_votre_nom.cpp » en
« DS1621_V2_votre_nom.cpp ». Dans ce nouveau fichier, en vous inspirant du sous- programme « init_I2c_bcm2835() », créer une fonction appelée « modeContinu() » qui initialise le DS1621 en mode mesure de température en continu, et une fonction appelée
« startConvertT() » qui lance la conversion.
Faire constater le bon fonctionnement Utilisation d'une classe « Cap_DS1621 »
La création d'une classe et des méthodes associées vont permettre l'utilisation de méthodes pour configurer un ou plusieurs capteurs, faire des mesures et afficher les résultats.
26 Télécharger le fichier DS1621_v3.zip depuis le site. (La version papier figure en Annexes 2, 3 et 4). Le désarchiver dans votre dossier pour ce TP, sauvegarder le fichier DS1621_V3.cpp en DS1621_V3_votre_nom.cpp, effectuer la compilation et lancer l'exécution.
27 Analyser les différents fichiers. Surligner le constructeur d'objets de type Cap_DS1621.
Pourquoi un destructeur n'est-il pas indispensable dans le cas présent ?
→
28 Faire évoluer le programme de telle sorte que d’une part le capteur se voit attribuer un numéro grâce à la méthode « set_numeroCapteur() » ; et que d’autre part l'affichage de la température mesurée devienne une méthode appelée « afficheMesure » dans laquelle le numéro du capteur apparaisse également. Les fichiers « capt_DS1621.h » et
« capt_DS1621.cpp » devront bien sûr évoluer.
Faire constater le bon fonctionnement 29 Câbler un second capteur, dont l'adresse sur le bus succédera à celle du premier capteur.
Faire vérifier le câblage 30 Indiquer la méthode pour vérifier que les 2 capteurs sont bien présents sur le bus à des
adresses différentes.
→
31 Sauvegarder le fichier DS1621_V3_votre_nom.cpp en DS1621_V4_votre_nom.cpp. Dans ce nouveau fichier instancier un second capteur appelé « Capt2 » et faire en sorte que la mesure de température de ces 2 capteurs se succède sur la console.
Faire constater le bon fonctionnement 32 Les fichiers des différents programmes modifiés et du schéma Fritzing sont à rendre en
fin de séance.
Document ANNEXE 1 : Programme DS1621_V1.cpp
// Mesure de temperature avec DS1621 // Fichier DS1621_V1.cpp
#include <iostream>
#include <bcm2835.h>
using namespace std;
#define clk_div BCM2835_I2C_CLOCK_DIVIDER_2500 // g++ DS1621_V1.cpp -l bcm2835.cpp -o DS1621_V1 void init_I2c_bcm2835()
{
if (!bcm2835_init()) {
printf("bcm2835_init failed. Are you running as root??\n");}
if (!bcm2835_i2c_begin()) {
printf("bcm2835_i2c_begin failed. Are you running as root??\n"); }
bcm2835_i2c_setClockDivider(clk_div); // Division de l'horloge Rpi pour obtenir une vitesse de 100KHz }
int main(void) {
double mesure;
unsigned int slave_address=0x48; // Adresse du DS1621 char i2cOut[3]; // Tableau des données I2C à sortir char i2cIn[2]; // Tableau des données I2C entrées init_I2c_bcm2835();
bcm2835_i2c_setSlaveAddress(slave_address); // Affectation de l'adresse de l'esclave i2cOut[0] = 0xAC;
i2cOut[1] = 0x00;
bcm2835_i2c_write(i2cOut, 2); // Commenter i2cOut[0] = 0xEE;
bcm2835_i2c_write(i2cOut, 1); // Commenter
delay(1000); // 1 seconde avant première lecture
while(1) {
i2cOut[0] = 0xAA; // Commenter
bcm2835_i2c_write(i2cOut,1); // Commenter bcm2835_i2c_read(i2cIn,2);
//cout<<"i2cIn[0] = "<< (int)i2cIn[0]<< " i2cIn[1] = "<< (int)i2cIn[1]<<endl;
if (i2cIn[1]!=0) mesure = (double)i2cIn[0] + 0.5; // Commenter else mesure = (double)i2cIn[0];
cout<<"Temperature du DS1621 : "<<mesure<<" deg."<<endl;
delay(1000); // 1 seconde entre chaque conversion
}
bcm2835_close();
return 0;
Document ANNEXE 2 : Fichier Capt_DS1621.h
#pragma once class Cap_DS1621 {double mesure;
unsigned int adresseI2c;
public:
Cap_DS1621();
void set_adresseI2c(const unsigned int &);
double mesureTemperature();
void modeContinu();
void startConvertT();
};
Document ANNEXE 3 : Fichier Capt_DS1621.cpp
#include "Cap_DS1621.h"
#include <bcm2835.h>
Cap_DS1621::Cap_DS1621() {adresseI2c=0;
mesure=0;
}
void Cap_DS1621::set_adresseI2c(const unsigned int & val) {adresseI2c=val;
}
double Cap_DS1621::mesureTemperature() {bcm2835_i2c_setSlaveAddress(adresseI2c);
char i2cOut[1];
char i2cIn[2];
i2cOut[0] = 0xAA;
bcm2835_i2c_write(i2cOut,1);
bcm2835_i2c_read(i2cIn,2);
//cout<<"i2cIn[0] = "<< (int)i2cIn[0]<< " i2cIn[1] = "<< (int)i2cIn[1]<<endl;
if (i2cIn[1]!=0) mesure = (double)i2cIn[0] + 0.5;
else mesure = (double)i2cIn[0];
return mesure;
}
void Cap_DS1621::modeContinu()
{bcm2835_i2c_setSlaveAddress(adresseI2c);
char i2cOut[2]; // Tableau des données I2C à sortir i2cOut[0] = 0xAC;
{bcm2835_i2c_setSlaveAddress(adresseI2c);
char i2cOut[1];
i2cOut[0] = 0xEE;
bcm2835_i2c_write(i2cOut, 1);
};
Document ANNEXE 4 : Programme DS1621_V3.cpp
// Mesure de temperature avec DS1621
#include <iostream>
#include <bcm2835.h>
#include "Cap_DS1621.h"
//#include <wiringPi.h>
//#include <wiringPiI2C.h> // bibliothèque pour la gestion de l'I2C using namespace std;
#define clk_div BCM2835_I2C_CLOCK_DIVIDER_2500
// g++ Cap_DS1621.cpp DS1621_V3.cpp -l bcm2835.cpp -o DS1621_V3 void init_I2c_bcm2835()
{ if (!bcm2835_init())
{
printf("bcm2835_init failed. Are you running as root??\n");
}
if (!bcm2835_i2c_begin())
{
printf("bcm2835_i2c_begin failed. Are you running as root??\n");
}
bcm2835_i2c_setClockDivider(clk_div); // Horloge I2C de 100KHz }
int main(void)
{ init_I2c_bcm2835();
char i2cOut[3]; // Tableau des données I2C à sortir char i2cIn[2]; // Tableau des données I2C entrées Cap_DS1621 Capt1; // Instanciation d'un capteur DS1621 Capt1.set_adresseI2c(0x48);
Capt1.modeContinu();
Capt1.startConvertT();
delay(1000); // 1 seconde avant première lecture
while(1) {
cout<<"Temperature du DS1621 Capt1 : "<<Capt1.mesureTemperature()<<" deg."<<endl;
delay(1000); // 1 seconde entre chaque conversion
}
bcm2835_close();
return 0;
}