Convertisseur analogique-numérique MCP3008

Convertisseur analogique-numérique MCP3008

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 breadboardjumper 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 :

Câblage du MCP3008

Câblage du MCP3008 vers le Raspberry pi

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 :

Câblage d'un potentiomètre et du MCP 3008 sur le Raspi

Câblage d’un potentiomètre et du MCP 3008 sur le Raspberry pi

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:

Réseaux sociaux