Le Raspberry Pi n’a pas d’entrées analogiques intégrées, ce qui signifie qu’il est un peu pénible d’utiliser la plupart des capteurs disponibles. Je voulais mettre à jour mon système de sécurité de garage avec la possibilité d’utiliser plus de capteurs, j’ai donc décidé de rechercher un moyen simple et peu coûteux de le faire. Le MCP3008 était la réponse.
Le MCP3008 est un convertisseur analogique-numérique (CAN) à 8 canaux 10 bits. Il est bon marché, facile à connecter et ne nécessite aucun composant supplémentaire. Il utilise le protocole de bus SPI qui est pris en charge par l’en-tête GPIO du Pi.
Cet article explique comment utiliser un appareil MCP3008 pour fournir 8 entrées analogiques que vous pouvez utiliser avec une gamme de capteurs. Dans l’exemple de circuit ci-dessous, j’utilise mon MCP3008 pour lire un capteur de température et de lumière.
Voici les bits que j’ai utilisé :
- Raspberry Pi
- MCP3008 CAN 8 canaux
- Résistance dépendante de la lumière (LDR)
- Capteur de température TMP36
- Résistance de 10 Kohms
La première étape consiste à activer l’interface SPI sur le Pi qui est généralement désactivée par défaut.
Veuillez suivre mon article Activation de l’interface SPI sur le Raspberry Pi pour configurer SPI et installer le wrapper SPI Python.
Circuit
La liste suivante montre comment le MCP3008 peut être connecté. Il nécessite 4 broches GPIO sur l’en-tête Pi P1.
VDD 3.3V VREF 3.3V AGND GROUND CLK GPIO11 (P1-23) DOUT GPIO9 (P1-21) DIN GPIO10 (P1-19) CS GPIO8 (P1-24) DGND GROUND
Les broches CH0-CH7 sont les 8 entrées analogiques.
Voici mon circuit de maquette :
Il utilise CH0 pour le capteur de lumière et CH1 pour le capteur de température TMP36. Les 6 autres entrées sont libres.
Voici une photo de mon circuit de test sur un petit morceau de maquette :
Résistance dépendante de la lumière
J’ai choisi une belle LDR trapue (NORPS-12, Fiche de données). Sous un éclairage normal, sa résistance est d’environ 10Kohm tandis que dans l’obscurité, elle passe à plus de 2Mohm.
Lorsqu’il y a beaucoup de lumière, le LDR a une faible résistance, ce qui entraîne une chute de la tension de sortie vers 0V.
Lorsqu’il fait sombre, la résistance LDR augmente, ce qui entraîne une augmentation de la tension de sortie vers 3,3 V.
Capteur de température TMP36
Le capteur de température TMP36 est un appareil à 3 broches (Fiche de données). Vous pouvez l’alimenter avec 3,3 V et la broche Vout du milieu fournira une tension proportionnelle à la température.
Une température de 25 degrés C se traduira par une sortie de 0,750 V. Chaque degré donne une tension de sortie de 10 mV.
Donc 0 degré donnera 0,5V et 100 degrés donneront 1,5V.
Lire les données à l’aide d’un script Python
L’ADC est de 10 bits, il peut donc signaler une plage de nombres de 0 à 1023 (2 à la puissance 10). Une lecture de 0 signifie que l’entrée est de 0V et une lecture de 1023 signifie que l’entrée est de 3,3V. Notre plage 0-3,3 V équivaudrait à une plage de température de -50 à 280 degrés C en utilisant le TMP36.
Pour lire les données j’ai utilisé ce script Python :
#!/usr/bin/python import spidev import time import os # Open SPI bus spi = spidev.SpiDev() spi.open(0,0) spi.max_speed_hz=1000000 # Function to read SPI data from MCP3008 chip # Channel must be an integer 0-7 def ReadChannel(channel): adc = spi.xfer2([1,(8+channel)<<4,0]) data = ((adc[1]&3) << 8) + adc[2] return data # Function to convert data to voltage level, # rounded to specified number of decimal places. def ConvertVolts(data,places): volts = (data * 3.3) / float(1023) volts = round(volts,places) return volts # Function to calculate temperature from # TMP36 data, rounded to specified # number of decimal places. def ConvertTemp(data,places): # ADC Value # (approx) Temp Volts # 0 -50 0.00 # 78 -25 0.25 # 155 0 0.50 # 233 25 0.75 # 310 50 1.00 # 465 100 1.50 # 775 200 2.50 # 1023 280 3.30 temp = ((data * 330)/float(1023))-50 temp = round(temp,places) return temp # Define sensor channels light_channel = 0 temp_channel = 1 # Define delay between readings delay = 5 while True: # Read the light sensor data light_level = ReadChannel(light_channel) light_volts = ConvertVolts(light_level,2) # Read the temperature sensor data temp_level = ReadChannel(temp_channel) temp_volts = ConvertVolts(temp_level,2) temp = ConvertTemp(temp_level,2) # Print out results print "--------------------------------------------" print("Light: {} ({}V)".format(light_level,light_volts)) print("Temp : {} ({}V) {} deg C".format(temp_level,temp_volts,temp)) # Wait before repeating loop time.sleep(delay)
Voici une capture d’écran de la sortie :
Vous pouvez télécharger ce script directement sur votre Pi en utilisant :
wget https://bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/mcp3008/mcp3008_tmp36.py
Il peut alors être exécuté en utilisant :
sudo python mcp3008_tmp36.py
Alternativement, si vous êtes un fan de Git, vous pouvez cloner mon dépôt de scripts divers Raspberry Pi en utilisant :
git clone https://bitbucket.org/MattHawkinsUK/rpispy-misc.git
Explication supplémentaire de spi.xfer2
Beaucoup de gens ont posé des questions sur la ligne spi.xfer2. Cela envoie 3 octets à l’appareil. Le premier octet est 1 qui est égal à 0000001 en binaire.
« 8+canal » est 00001000 en binaire (où le canal est 0). « <<4" décale ces bits vers la gauche, ce qui donne 10000000. Le dernier octet est 0 qui est 00000000 en binaire.
Donc « spi.xfer2([1,(8+channel)<<4,0]) » envoie 00000000 10000000 00000000 à l’appareil. L’appareil renvoie alors 3 octets en réponse. La ligne « data= » extrait 10 bits de cette réponse et cela représente la mesure.
La raison exacte pour laquelle vous faites ce qui précède est expliquée dans la fiche technique, mais cela sort du cadre de cet article.
Plus d’information
Si vous souhaitez plus d’informations techniques sur l’appareil, veuillez consulter le fiche technique officielle Microchip MCP3008. Si vous voulez en savoir plus sur le bus SPI, jetez un œil à la Page Wikipédia du bus d’interface périphérique série.