Le Raspberry pi est doté des GPIO, capables de servir d’entrées(tuto) ou de sorties(tuto) numériques. On peut donc lire des signaux logiques hauts ou bas (des 0 ou des 1). Il n’est en revanche pas possible de lire directement des valeurs analogiques. Pour cela, il faut utiliser un ADC, pour “Analog to Digital Converter”, ou convertisseur analogique vers numérique en français, dont le Raspberry Pi n’est pas doté. L’objet de ce tutoriel sera justement de connecter une puce, la MCP3008, au Raspberry pi via le bus SPI pour ajouter huit entrées analogiques. A titre d’exemple, nous nous servirons de ces entrées pour pouvoir effectuer la lecture des valeurs d’un capteur simple : le potentiomètre. Il est toujours possible d’accéder à la liste des tutoriels sur le Raspberry pi sur le wiki.
N’hésitez pas à consulter la version wiki de cet article, plus confortable avec des liens supplémentaires.
Prérequis
Pour ce tutoriel, nous aurons besoin d’un Raspberry Pi (A, A+, B, B+) configuré, d’une breadboard, de câbles pour breadboard “jumper wire”, d’une puce MCP3008 au format DIP, et de capteurs analogiques pour tester le tout, à savoir un potentiomètre pour cet exemple. Pour pouvoir réaliser ce montage, il est préférable de savoir utiliser les GPIO du Raspberry pi comme entrée.
Installation du MCP3008
Avant toute chose, il faut déterminer le “haut” de la puce. Si vous tenez la puce face à vous, les pattes s’éloignant de vous, vous verrez sur le dessus de la puce une petite encoche en forme de demi lune. Elle sert à marquer le haut de la puce. On cherchera à reproduire le câblage suivant :
La première étape sera simplement d’alimenter le circuit. pour cela, on connectera le Vdd, qui est la broche 16 (première broche en haut à droite, en rouge sur le schéma) au 3.3V du Raspberry (broche P1-01, en haut à gauche, lorsque la carte SD est vers le haut). Les broches 14 (Agnd, 3eme en haut à droite) et 9 (Dgnd, 8eme broche en partant du haut, colonne de droite) du MCP3008 sont la masse des signaux analogiques et numériques, et seront connectées à la masse du Raspberry pi : la broche P1-06 (3eme en partant du haut, à droite). Il s’agira des fils noirs sur notre schéma. Il faudra ensuite connecter le Vref de notre CI, qui donnera la tension de référence des signaux logiques, au 3.3V du Raspberry. Il s’agit de la broche 15 du MCP3008 (2eme en haut à droite), que vous connecterez au même 3.3V que plus haut (fil rouge sur le schéma). Nous connecterons maintenant 4 broches GPIO de notre Raspberry aux broches CLK, Dout, Din et CS du MCP3008:
-
La broche CLK est la 4eme à droite en partant du haut. Nous la connecterons au GPIO18 du Raspberry Pi. C’est le fil vert sur le schéma;
-
La broche Dout est juste en dessous, la 5eme à droite en partant du haut. Connectons la au GPIO23. (fil gris);
-
La broche Din est celle du dessous, la 6eme à droite en partant du haut. Elle pourra aller en GPIO24. (fil jaune);
-
La broche CD est encore en dessous, la 7eme à droite, en partant du haut. On la connecte au GPIO25. (fil bleu).
On pourra utiliser d’autres GPIO que les 4 utilisés ici, il suffira alors d’ajuster les variables correspondantes dans le code que nous verrons plus bas.
A cette étape, notre MCP3008 est connecté au Raspberry. Toutes les broches de gauche du circuit sont des entrées analogiques que nous pourrons utiliser.
Analyse de la position d’un potentiomètre
Le “capteur” le plus simple que nous pouvons utiliser immédiatement est un potentiomètre. pour s’en servir, il faudra brancher la première patte du potentiomètre sur le 3.3V(fil rouge en bas), la patte centrale sur une des entrées analogiques (par exemple la broche 1, fil marron), et enfin la dernière patte ira à la masse (fil noir). On obtiendra le montage suivant :
Programme en Python
Maintenant que notre montage est assemblé, nous pouvons nous intéresser au code. Je me suis basé pour ce code sur l’exemple/tutoriel sur le MCP3008 fourni par Adafruit, et j’ai simplifié quelque peu le code original, que dont voici ma version modifiée :
#!/usr/bin/env python import time import os import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) #fonction lisant les donnees SPI de la puce MCP3008, parmi 8 entrees, de 0 a 7 def readadc(adcnum, clockpin, mosipin, misopin, cspin): if ((adcnum > 7) or (adcnum < 0)): return -1 GPIO.output(cspin, True) GPIO.output(clockpin, False) # start clock low GPIO.output(cspin, False) # bring CS low commandout = adcnum commandout |= 0x18 # start bit + single-ended bit commandout <<= 3 # we only need to send 5 bits here for i in range(5): if (commandout & 0x80): GPIO.output(mosipin, True) else: GPIO.output(mosipin, False) commandout <<= 1 GPIO.output(clockpin, True) GPIO.output(clockpin, False) adcout = 0 # read in one empty bit, one null bit and 10 ADC bits for i in range(12): GPIO.output(clockpin, True) GPIO.output(clockpin, False) adcout <<= 1 if (GPIO.input(misopin)): adcout |= 0x1 GPIO.output(cspin, True) adcout /= 2 # first bit is 'null' so drop it return adcout # ces numeros de pins GPIO doivent etre modifies pour correspondre aux broches utilisées si vous avez utilisé un autre câblage que celui du tutoriel. SPICLK = 18 SPIMISO = 23 SPIMOSI = 24 SPICS = 25 # definition de l'interface SPI GPIO.setup(SPIMOSI, GPIO.OUT) GPIO.setup(SPIMISO, GPIO.IN) GPIO.setup(SPICLK, GPIO.OUT) GPIO.setup(SPICS, GPIO.OUT) #definition du ADC utilise (broche du MCP3008). Cette valeur peut aller de 0 à 7. adcnum = 0 # Lecture de la valeur brute du capteur read_adc0 = readadc(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS) # conversion de la valeur brute lue en milivolts = ADC * ( 3300 / 1024 ) millivolts = read_adc0 * ( 3300.0 / 1024.0) print "\tvaleur brute : %s" % read_adc0 print "\ttension : %s millivolts" % millivolts
Ce code nous permet de lire la valeur de n’importe laquelle des 8 entrées, il suffira pour cela de changer la valeur de la variable adcnum, pour la faire varier entre 0 et 7 pour lire les entrées 1 à 8. Il est de même possible de lire plusieurs entrées dans le même programme.
Conclusion
Au prix de 4 GPIO, nous ajoutons ainsi 8 entrées analogiques au Raspberry Pi. Toutefois, puisqu’il s’agit du bus SPI, il est techniquement possible d’utiliser ces mêmes broches pour d’autres périphériques, au prix d’un GPIO de plus par périphérique SPI ajouté en plus du premier.
Cette puce permettra dans tous les cas de combler l’absence de convertisseur analogique vers numérique sur le Raspberry pi, permettant ainsi de lire toute une gamme de capteurs afin par exemple de mesurer la luminosité ambiante avec une photorésistance. On pourra également mesurer la distance d’un objet en face du Raspberry pi à l’aide d’un capteur infrarouge, qui pourra nous servir à fabriquer un robot comme R.Cerda basé sur le Raspberry Pi.
Pour aller plus loin, voici quelques des tutoriels sur le wiki:
Bonjour,
j’ai essayer votre programme mais il ne fonctionne pas quand je le lance il me dit que la syntaxe est incorrect
“if ((adcnum > 7) or (adcnum < 0)):”
le “:” de cette ligne de code sont surligner en rouge pouvez vous m’aider s’il vous plait?
bonjour
je suis interesse a developer des mesures sortie cellule
photovoltaique pour mesurer linpact de lumiere entrente et manque de lumiere sur chaque point de la plaque
une etude similaire ala votre ,
ma question vu le signal faible et a pente raide , et aparissition de forte signale , je doit prendre des precautions pour ce qui suit
1_ mesure de courant ou tension
2_comment eviter le retour de signal de la batterie et eviter ainsi l’interference
3_architecture de la carte entree pour differente situation a savoir
signal fort , faible , surtention , overcurrent , , hysteresis , et attaque de processor des valeures mesurees et aquise sur des registres et memoires
block de valeures de reference et signaler par interface a host de la situationet dans le temts
a plus
J’ai mis à jour l’article et le code, il ne devrait plus y avoir de problème de syntaxe (ils étaient dus à la façon de poster le code). N’hésitez pas à consulter la version wiki de cet article.
[…] un MCP3008, que nous utiliserons avec le Raspberry pi, la résistance d’entrée maximale tolérée variera entre 1 et 10 Kilo ohms, comme on peut […]
[…] Nous avons un tutoriel sur la connexion et l’utilisation du MCP3008, avec des exemples pratiques et le co…. […]
[…] d’une sonde numérique (pas besoin de convertisseur analogique-numérique tel que le MCP3008) qui est assez précise (±0.5°C sur la plage -10°C – 85°C), raisonnablement facile à […]
[…] Ce code sera à intégrer avec le votre. Vu sur nagashur. […]
[…] explications plus complètes sont disponible sur le blog nagashur.com qui m’a beaucoup […]
[…] explications plus complètes sont disponible sur le blog nagashur.com qui m’a beaucoup […]
Est-ce possible d’utiliser le même procéder avec une PI face Digital?
Bonjour
Pourquoi ne pas avoir utiliser le bus SPI du Raspberry?
[…] http://nagashur.com/blog/2013/01/13/lire-des-entrees-analogiques-sur-un-raspberry-avec-un-circuit-ad… https://f-leb.developpez.com/tutoriels/raspberry-pi/conv-analogique-numerique/ […]
[…] of large graphs can be very challenging because the huge amount of data causes a high I/O latency. Ponts analogiques. Convertisseur analogique-> numérique MCP3008 Le Raspberry pi dispose de broches GPIO pouvant […]
Merci
La version wiki a fonctionné.
Merci beaucoup
[…] associant entre eux des nœuds (ou sommets) par des relations. Property graphs. Graph. Graph. Lire des entrées analogiques sur un Raspberry avec un circuit ADC : le MCP3008 – Slog. Convertisseur analogique-> numérique MCP3008 Le Raspberry pi dispose de broches GPIO pouvant […]