Capteur SHT20

Généralités

Le capteur SHT20, présent sur la carte d’extension de la Raspberry Pi, est un capteur de température et d’humidité relative sur bus I2C.

La librairie bcm2835 prend en charge ce genre de communication à travers un certain nombre de fonctions.

🖮 Travail n° 1 Étude du bus I2C

  1. En s’appuyant sur cette présentation du bus I2C et la datasheet du SHT20 pdf, décoder les 2 trames suivantes capturées à l’aide du logiciel Waveforms depuis l’analyseur logique Analog Discovery 2 lors d’un même échange avec le capteur SHT20 (⇒ requête du maître vers le SHT20 puis réponse de ce dernier].

    sht trigger temp blurred
    Figure 1. Trame n°1
    sht read temp blurred
    Figure 2. Trame n°2

    Identifier notamment :

    • la condition de start

    • l’adresse 7 bits du composant I2C

    • le type d’opération (→ écriture ou lecture}

    • les valeurs des données

    • les accusés de réception

    • la condition de stop

    Utiliser un logiciel de retouche d’image pour marquer ces différents éléments et joindre l’image obtenue dans le compte-rendu.

  2. Toujours à l’aide de la datasheet du SHT20 pdf, déterminer en °C la valeur de la température retournée par le SHT20

  3. À l’aide de :

    déterminer le type de checksum utilisé dans la trame renvoyée par le capteur pour permettre de s’assurer de l’intégrité des données transmises — la valeur de la température dans le cas présent — et vérifier sa valeur en partant de l’hypothèse qu’il s’agit d’un CRC personnalisé et qu’il faut donc saisir ses caractéristiques dans le calculateur (→ champs "`Polynomial`", "`Initial value`" et "`Final Xor Value`".

    Parcourir la documentation du calculateur de CRC en ligne et notamment ce paragraphe link pour savoir comment saisir la représentation hexadécimale du polynôme générateur (→ champ “Polynomial”).

🖮 Travail n° 2 Acquisition SHT20 par programmation procédurale

Le code suivant suivant illustre comment utiliser les fonctions de la libraire bcm2835 pour acquérir et afficher la température (en °C).

Code source
sht20-cli-get-trh.cpp
/**
 * Lecture de la température (-> T°C) et
 * de l'humidité relative (-> HR%) depuis un capteur SHT2x
 * en utilisant la librairie libbcm2835.a
 *
 * Compilation :
 *    gcc -o sht20-cli-get-trh sht20-cli-get-trh.c -lbcm2835
 *
 * Utilisation :
 *    sudo ./sht20-cli-get-trh
 */
#include <iostream>
#include <iomanip>
#include <unistd.h>

#include <bcm2835.h>

using namespace std;

int main() {
    const uint8_t SHT20_ADDR = 0x40;
    const char TRIGGER_T_NO_HOLD = 0xf3;

    if(bcm2835_init() != 1) {
        cout << "Erreur initialisation librairie bcm2835" << endl;
    } else {
        if( bcm2835_i2c_begin() != 1) {
            cout << "Erreur initialisation bus I2C librairie bcm2835." << endl
                << "Programme exécuté sans `sudo` ?" << endl;
        } else {
            char cmd[ 1 ]; // commande i2c à envoyer au capteur
            char resp[ 3 ]; // réponse à la commande envoyée

            bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_2500);

            bcm2835_i2c_setSlaveAddress(SHT20_ADDR);

            // On lance l'acquisition de la T° en mode "no hold master"
            // (pas de clock streching)
            cout << "Acquisition T°C en cours..." << endl;
            cmd[ 0 ] = TRIGGER_T_NO_HOLD;
            if (bcm2835_i2c_write(cmd, 1) != BCM2835_I2C_REASON_OK) {
                cout << "Echec envoi commande acquisition T°C" << endl;
            } else {
                // On attend la fin de l'acquisition (85ms selon la datasheet)
                usleep(85000);
                // On lit la T° acquise
                if( bcm2835_i2c_read(resp, 3) != BCM2835_I2C_REASON_OK ) {
                    cout << "Echec lecture I2C de T°C" << endl;
                } else {
                    uint16_t rawTemperature;
                    rawTemperature = (resp[0 ] << 8) | (resp[ 1 ] & 0xfc);
                    float celsiusTemp = 172.72 * (rawTemperature / 65536.0) - 46.85;
                    cout << "=> T : " << fixed << setw( 5 )
                        << setprecision( 2 ) << setfill( '0' )
                        << celsiusTemp << " °C" << endl;
                }
            }

            // On lance l'acquisition de la HR% en mode "no hold master"
            // (pas de clock streching)

            // A COMPLÉTER

        }
        bcm2835_close();
    }
}
  1. Étudier le code source en faisant particulièrement attention à la façon dont :

    • on traite les erreurs éventuelles retournées par les fonctions de la librairie bcm2835 (→ if…​else imbriqués)

    • on utilise les opérateurs bit à bit (→ décalage, ET) pour concaténer les 2 octets retournés par le SHT20 pour en faire une valeur sur 16 bits.

    • on affiche le résultat avec cout en utilisant des “manipulateurs” C++ pour spécifier le format d’affichage (→ fixed, setw() …​)

  2. Indiquer l’instruction que vous auriez dû taper en langage C avec la fonction printf() pour obtenir le même affichage.

  3. Compléter le code pour faire l’acquisition de l’humidité relative puis l’afficher sachant que la commande à envoyer au SHT20 est bien sûr différente que celle pour la température et que le délai d’attente est également différent. Voir la datasheet pour obtenir ces valeurs.

    Résultat attendu
    pi@rpi-defrance:~ $ sudo ./sht20-cli-get-trh
    Acquisition T°C en cours...
    => T : 32.10 °C
    Acquisition HR% en cours...
    => HR : 33.92 %
    pi@rpi-defrance:~ $
  4. Installer le logiciel Waveforms sur Windows et utiliser l’analyseur logique Analog Discovery 2 pour réaliser/analyser des captures de trame I2C sur votre carte d’extension.

    analog discovery2 waveforms logo

    i2c test points

🖮 Travail n° 3 Classe SHT20

  1. Déclarer puis implémenter une classe SHT20 répondant à la spécification UML suivante :

    sht20 class
  2. Faire un programme C++ qui utilise cette classe pour arriver au même résultat qu’à l’exercice précédent (acquisition pui affichage de la température et de l’humidité relative)

🞄  🞄  🞄