Table des matières

Ajouter des entrées analogiques avec un MCP3008 et lire la valeur d'un potentiomètre

Le Raspberry pi est doté des GPIO, capables de servir d'entrées ou de sorties 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.

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 :  câblage du MCP3008 au raspberry pi par le bus SPI. Télécharger le schéma de câblage du MCP3008 vers le Raspberry pi en PDF

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 (2eme en haut à droite) du MCP3008, 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:

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 :  Schéma de câblage d'un MCP3008 connecté au Raspberry Pi et à un potentiomètre Télécharger le schéma de câblage du MCP3008 et du potentiomètre en PDF

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 code1), que voici :

adcRead.py
#!/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. On citera par exemple des capteurs simples pour lesquels nous avons des tutoriels :