.. note:: Bonjour, bienvenue dans la communauté SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts sur Facebook ! Plongez plus profondément dans Raspberry Pi, Arduino et ESP32 avec d'autres passionnés. **Pourquoi nous rejoindre ?** - **Support d’experts** : Résolvez les problèmes après-vente et les défis techniques avec l’aide de notre communauté et de notre équipe. - **Apprendre & Partager** : Échangez des conseils et tutoriels pour améliorer vos compétences. - **Aperçus exclusifs** : Obtenez un accès anticipé aux nouvelles annonces de produits et aux avant-premières. - **Réductions spéciales** : Profitez de réductions exclusives sur nos derniers produits. - **Promotions festives et concours** : Participez à des concours et promotions lors des fêtes. 👉 Prêt à explorer et créer avec nous ? Cliquez sur [|link_sf_facebook|] et rejoignez-nous dès aujourd’hui ! .. _2.2.2_c_mcp3008: 2.2.2 Thermistance (MCP3008) ============================ .. note:: .. image:: img/mcp3008_and_adc0834.jpg :width: 25% :align: left Selon la version de votre kit, identifiez si vous disposez de **ADC0834** ou **MCP3008** et passez à la section correspondante. Introduction ------------ Tout comme une photorésistance peut détecter la lumière, une thermistance est un composant électronique sensible à la température qui peut être utilisée pour réaliser des fonctions de contrôle thermique, comme un avertisseur de chaleur. Composants requis ----------------- Dans ce projet, nous avons besoin des composants suivants. .. image:: img/list2_2.2.2_thermistor.png Principe -------- Une thermistance est une résistance sensible à la température qui présente une variation précise et prévisible de sa résistance en fonction de petites variations de température. L’ampleur de cette variation dépend de sa composition spécifique. Les thermistances font partie d’un groupe plus large de composants passifs. Contrairement aux composants actifs, les dispositifs passifs ne peuvent pas fournir de gain de puissance ni d’amplification à un circuit. La thermistance est un élément sensible, et elle existe en deux types : à coefficient de température négatif (CTN ou NTC en anglais) et à coefficient de température positif (CTP ou PTC en anglais). Sa résistance varie considérablement avec la température. La résistance d’une CTP augmente avec la température, tandis que pour une CTN, c’est l’inverse. Dans cette expérience, nous utilisons une CTN. .. image:: img/image325.png Le principe est que la résistance d’une thermistance CTN change avec la température de l’environnement. Elle détecte la température en temps réel. Quand la température augmente, la résistance diminue. La tension est alors convertie en données numériques par l’adaptateur A/N (analogique/numérique). La température en degrés Celsius ou Fahrenheit est affichée via un programme. Dans cette expérience, une thermistance et une résistance de tirage (pull-up) de 10 kΩ sont utilisées. Chaque thermistance possède une résistance nominale mesurée à 25 °C, ici de 10 kΩ. Voici la relation entre la résistance et la température : R\ :sub:`T` = R\ :sub:`N` exp\ :sup:`B(1/TK – 1/TN)` **R\ T** est la résistance de la thermistance CTN à la température **T\ K**. **R\ N** est la résistance de la thermistance CTN à la température nominale **T\ N**. Ici, **R\ N** vaut 10 kΩ. **T\ K** est la température en Kelvin, en K. **T\ K** = 273,15 + température en °C. **T\ N** est la température nominale en Kelvin, ici 273,15 + 25. **B** (beta) est la constante de matériau de la thermistance CTN, aussi appelée indice de sensibilité thermique, ici de valeur 3950. **exp** est l’abréviation d’exponentielle, et la base e est un nombre naturel valant environ 2,7. En transformant cette formule, on obtient : T\ :sub:`K` = 1 / (ln(R\ :sub:`T` / R\ :sub:`N`) / B + 1 / T\ :sub:`N`) Ce qui permet de calculer la température en Kelvin, et donc en Celsius en soustrayant 273,15. Cette relation est empirique et précise uniquement lorsque la température et la résistance se trouvent dans la plage de mesure efficace. Schéma de câblage ----------------- .. list-table:: :widths: 30 30 30 30 :header-rows: 1 * - Nom sur la carte T - Physique - WiringPi - BCM * - SPICE0 - pin24 - 10 - 8 * - SPIMOSI - pin19 - 12 - 10 * - SPIMISO - pin21 - 13 - 9 * - SPISCLK - pin23 - 14 - 11 .. image:: img/schematic_2.2.2_thermistor_mcp3008.png Procédures expérimentales ------------------------- **Étape 1 :** Construire le circuit. .. image:: img/july24_2.2.2_thermistor_mcp3008.png Pour les utilisateurs du langage C ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Étape 2 :** Accédez au répertoire contenant le code. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/c/2.2.2-2/ **Étape 3 :** Compilez le code. .. raw:: html .. code-block:: gcc 2.2.2_Thermistor.c -o Thermistor -lwiringPi -lm .. note:: -lm sert à charger la bibliothèque mathématique. Ne l’omettez pas, sinon vous obtiendrez une erreur. **Étape 4 :** Exécutez le fichier compilé. .. raw:: html .. code-block:: ./Thermistor Une fois le code lancé, la thermistance détectera la température ambiante qui sera affichée à l’écran après calcul du programme. .. note:: Si cela ne fonctionne pas après exécution, ou si un message d’erreur apparaît : « wiringPi.h: No such file or directory », veuillez vous référer à :ref:`install_wiringpi`. **Code** .. code-block:: c #include #include #include #include #define SPI_CHANNEL 0 // CE0 #define SPI_SPEED 1000000 // 1MHz int read_ADC(int channel) { if (channel < 0 || channel > 7) return -1; unsigned char buffer[3]; buffer[0] = 1; // Bit de démarrage buffer[1] = (8 + channel) << 4; // Mode à entrée unique + canal buffer[2] = 0; wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3); int value = ((buffer[1] & 3) << 8) | buffer[2]; return value; } int main(void) { int analogVal; double Vr, Rt, temp, cel, Fah; if (wiringPiSetup() == -1) { printf("Échec de l’initialisation de wiringPi !\n"); return 1; } if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) { printf("Échec de l’initialisation SPI !\n"); return 1; } while (1) { analogVal = read_ADC(0); // Lecture sur CH0 // MCP3008 est un CAN 10 bits (0–1023) Vr = 3.3 * analogVal / 1023.0; // Vref supposé = 3,3V Rt = 10000.0 * Vr / (3.3 - Vr); // Diviseur de tension, résistance 10 kΩ temp = 1 / ((log(Rt / 10000.0) / 3950.0) + (1 / (273.15 + 25.0))); cel = temp - 273.15; Fah = cel * 1.8 + 32; printf("Celsius : %.2f C Fahrenheit : %.2f F\n", cel, Fah); delay(1000); } return 0; } **Explication du code** .. code-block:: c #include #include #include #include Ces en-têtes incluent les bibliothèques pour le contrôle GPIO (``wiringPi.h``), la communication SPI (``wiringPiSPI.h``), les opérations d’E/S standards (``stdio.h``) et les fonctions mathématiques (``math.h``) en C. .. code-block:: c #define SPI_CHANNEL 0 #define SPI_SPEED 1000000 Définit les constantes pour le canal SPI et la vitesse de communication SPI. Ici, le canal SPI 0 (CE0) et une fréquence d’horloge de 1 MHz sont utilisés. .. code-block:: c int read_ADC(int channel) Cette fonction lit les données analogiques d’un canal spécifique du MCP3008. .. code-block:: c buffer[0] = 1; buffer[1] = (8 + channel) << 4; buffer[2] = 0; Ces lignes préparent la commande SPI selon le protocole MCP3008 : un bit de démarrage, la configuration pour le mode à entrée unique, et le numéro du canal. .. code-block:: c wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3); Envoie la commande SPI et reçoit les données 10 bits du MCP3008. .. code-block:: c int value = ((buffer[1] & 3) << 8) | buffer[2]; Extrait et combine la valeur sur 10 bits renvoyée par le MCP3008. .. code-block:: c if (wiringPiSetup() == -1) { ... } if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) { ... } Ces lignes initialisent WiringPi et configurent le SPI. Si l’initialisation échoue, le programme s’arrête. .. code-block:: c analogVal = read_ADC(0); Lit le signal analogique sur le canal 0 du MCP3008, où est connectée la thermistance. .. code-block:: c Vr = 3.3 * analogVal / 1023.0; Convertit la valeur numérique du CAN en tension analogique. La plage du CAN est de 0–1023 avec une référence de 3,3V. .. code-block:: c Rt = 10000.0 * Vr / (3.3 - Vr); Calcule la résistance de la thermistance en utilisant la formule du diviseur de tension (avec une résistance série de 10 kΩ). .. code-block:: c temp = 1 / ((log(Rt / 10000.0) / 3950.0) + (1 / (273.15 + 25.0))); Utilise l’équation B pour convertir la résistance en température Kelvin. Formule : **T(K) = 1 / [ln(Rt/R₀)/B + 1/T₀]** - R₀ = 10 kΩ - B = 3950 - T₀ = 25°C = 298,15K .. code-block:: c cel = temp - 273.15; Convertit la température de Kelvin en degrés Celsius. .. code-block:: c Fah = cel * 1.8 + 32; Convertit la température Celsius en Fahrenheit. .. code-block:: c printf("Celsius : %.2f C Fahrenheit : %.2f F\n", cel, Fah); Affiche la température en Celsius et en Fahrenheit avec deux décimales de précision. Pour les utilisateurs du langage Python ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Étape 2 :** Configurez l’interface SPI et installez la bibliothèque ``spidev`` (voir :ref:`spi_configuration` pour des instructions détaillées). Si vous avez déjà effectué ces étapes, passez à la suivante. **Étape 3 :** Accédez au répertoire contenant le code. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/python **Étape 4 :** Exécutez le fichier Python. .. raw:: html .. code-block:: sudo python3 2.2.2-2_thermistor.py Une fois le code lancé, la thermistance détecte la température ambiante qui sera affichée à l’écran après calcul du programme. .. warning:: Si un message d’erreur apparaît : ``RuntimeError: Cannot determine SOC peripheral base address``, veuillez vous référer à :ref:`faq_soc`. **Code** .. note:: Vous pouvez **Modifier/Réinitialiser/Copier/Exécuter/Arrêter** le code ci-dessous. Mais avant cela, vous devez vous placer dans le répertoire source comme ``davinci-kit-for-raspberry-pi/python``. Après modification, vous pouvez exécuter le code directement pour voir le résultat. .. raw:: html .. code-block:: python #!/usr/bin/env python3 # -*- coding: utf-8 -*- import spidev import time import math import RPi.GPIO as GPIO # Définir le mode GPIO GPIO.setmode(GPIO.BCM) # Initialiser SPI pour MCP3008 (Bus 0, CE0) spi = spidev.SpiDev() spi.open(0, 0) # Bus 0, Périphérique 0 (CE0) spi.max_speed_hz = 1000000 # 1 MHz def read_adc(channel): """ Lire la valeur analogique d’un canal du MCP3008 (0–7) """ if channel < 0 or channel > 7: return -1 adc = spi.xfer2([1, (8 + channel) << 4, 0]) value = ((adc[1] & 0x03) << 8) | adc[2] return value try: while True: # Lire la valeur analogique sur CH0 du MCP3008 analogVal = read_adc(0) # Convertir en tension (Vref supposée = 3,3V) Vr = 3.3 * analogVal / 1023.0 # Calculer la résistance de la thermistance (R2 = 10 kΩ dans le diviseur) Rt = 10000.0 * Vr / (3.3 - Vr) # Calcul de Steinhart–Hart tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0))) # Conversion en Celsius et Fahrenheit Cel = tempK - 273.15 Fah = Cel * 1.8 + 32 # Afficher le résultat print('Celsius : %.2f °C Fahrenheit : %.2f °F' % (Cel, Fah)) time.sleep(0.2) except KeyboardInterrupt: pass finally: spi.close() GPIO.cleanup() **Explication du code** #. Cette section importe les bibliothèques nécessaires : - ``spidev`` pour la communication SPI avec le MCP3008 - ``time`` pour gérer les délais - ``math`` pour les calculs logarithmiques dans la formule de Steinhart–Hart - ``RPi.GPIO`` pour initialiser et nettoyer les GPIO (ajouté pour une complétude structurelle) .. code-block:: python #!/usr/bin/env python3 # -*- coding: utf-8 -*- import spidev import time import math import RPi.GPIO as GPIO #. Initialise le mode GPIO en BCM et configure l’interface SPI sur le bus 0 et le périphérique 0 (CE0), avec une vitesse de 1 MHz. .. code-block:: python # Définir le mode GPIO GPIO.setmode(GPIO.BCM) # Initialiser SPI pour MCP3008 (Bus 0, CE0) spi = spidev.SpiDev() spi.open(0, 0) # Bus 0, Périphérique 0 (CE0) spi.max_speed_hz = 1000000 # 1 MHz #. Définit une fonction ``read_adc(channel)`` pour lire la valeur analogique d’un canal donné (0–7) du MCP3008. Envoie une commande SPI de 3 octets et reçoit un résultat analogique 10 bits (0–1023). .. code-block:: python def read_adc(channel): """ Lire la valeur analogique d’un canal du MCP3008 (0–7) """ if channel < 0 or channel > 7: return -1 adc = spi.xfer2([1, (8 + channel) << 4, 0]) value = ((adc[1] & 0x03) << 8) | adc[2] return value #. Boucle principale : lit la tension depuis une thermistance connectée au canal 0, calcule sa résistance, puis applique l’équation de Steinhart–Hart pour obtenir la température en °C et °F. Les valeurs sont affichées toutes les 0,2 secondes. .. code-block:: python try: while True: # Lire la valeur analogique sur CH0 du MCP3008 analogVal = read_adc(0) # Convertir en tension (Vref supposée = 3,3V) Vr = 3.3 * analogVal / 1023.0 # Calculer la résistance de la thermistance (R2 = 10 kΩ dans le diviseur) Rt = 10000.0 * Vr / (3.3 - Vr) # Calcul de Steinhart–Hart tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0))) # Conversion en Celsius et Fahrenheit Cel = tempK - 273.15 Fah = Cel * 1.8 + 32 # Afficher le résultat print('Celsius : %.2f °C Fahrenheit : %.2f °F' % (Cel, Fah)) time.sleep(0.2) #. Le bloc ``finally`` garantit un arrêt propre : fermeture de l’interface SPI et nettoyage des GPIO pour libérer toutes les ressources matérielles. .. code-block:: python except KeyboardInterrupt: pass finally: spi.close() GPIO.cleanup()