jeudi 20 mars 2014

Lecture de capteurs analogiques sur le Raspberry Pi

Article mis à jour le 2 mars 2020: modification au script, qui ne fonctionnait plus convenablement.

Lors d'une récente rubrique, nous avons appris comment utiliser les broches GPIO du Raspberry Pi pour lire des signaux numériques.  Toutefois, contrairement à l'Arduino, le Raspberry Pi ne comporte pas la moindre entrée analogique.  Et pourtant, lire un signal analogique (provenant d'un potentiomètre, d'une photorésistance, d'une thermistance, etc.), ça peut être drôlement pratique...

Évidemment, il existe une solution à ce problème: l'utilisation d'un convertisseur numérique-analogique externe (ou ADC, pour analog to digital converter).  J'ai utilisé le MCP3008 de Microchip, qui est un ADC à 8 canaux, ce qui signifie que vous pouvez y brancher pas moins de 8 capteurs analogiques simultanément (si vos besoins sont plus modestes, vous pouvez vous rabattre sur le MCP3004, qui ne comporte que 4 canaux).

Le rôle du MCP3008 sera donc de transmettre au Raspberry Pi  un signal numérique entre 0 et 1023 qui sera la traduction du signal analogique (qui, lui, peut prendre n'importe quelle valeur située entre 0 et 3,3 V).

Interface SPI matérielle ou logicielle?

Puisque que le MCP3008 utilise le protocole SPI, nous avons le choix entre une approche matérielle (hardware SPI) ou logicielle (bit banged SPI).  L'approche logicielle consiste à gérer nous-mêmes le signal d'horloge et le chip select  à l'intérieur de notre script.  C'est un peu plus lent que le "hardware SPI", et ça nécessite des scripts un peu plus complexes.  Par contre, on peut utiliser n'importe quelle broche GPIO.  Pour un exemple de ce type, vous pouvez consulter l'adaptation que Dominique Meurisse de MC Hobby a faite du tutoriel d'Adafruit.

J'ai plutôt opté pour l'utilisation de l'interface SPI matérielle du Raspberry Pi:   ça facilite le codage, mais nous sommes obligés d'utiliser les broches GPIO qui sont dédiées au SPI (CE0, CE1, MOSI, MISO et SCLK):


Activation du protocole SPI

Par défaut, le protocole SPI est désactivé sur votre Raspberry Pi. Pour l'activer, vous devez ouvrir "Configuration du Raspberry Pi", dans la section "Préférences" du menu.


Dans l'onglet "Interfaces", vous activer "SPI" et vous redémarrez votre Raspberry Pi.




Le circuit

Le schéma ci-contre, issu de la fiche technique, montre le brochage du MCP3008.  Les 8 entrées analogiques sont alignées du côté gauche. Le côté droit comporte l'alimentation (VDD), la tension de référence (VREF), la masse du signal analogique (AGND) et celle du signal numérique (DGND), l'horloge (CLK), la sortie des données numériques vers le Raspberry Pi (DOUT) et l'entrée des données numériques en provenance du Raspberry Pi (DIN), le "chip select" (CS/SHDN) qui doit être au niveau logique bas pour que l'ADC soit actif.

Comme d'habitude, si votre capteur analogique est une résistance variable, vous la placez en série avec une résistance fixe afin que le signal acheminé à l'entrée analogique soit une tension variable:

Puisque je voulais seulement explorer les possibilités de mesurer des valeurs analogiques, j'ai utilisé deux potentiomètres reliés respectivement au canal 0 (pin 1) et au canal 1 (pin 2) du MCP3008 (c'est plus simple de tourner le bouton d'un potentiomètre que de changer la température dans l'environnement d'une thermistance...).


Les connexions entre le MCP3008 et le Raspberry Pi sont les suivantes:

MCP3008 VDD (broche 16)   →  Raspberry 3,3 V
MCP3008 VREF (broche5)   →  Raspberry 3,3 V
MCP3008 AGND (broche 14)  →;  Raspberry GND
MCP3008 CLK (broche 13)   →  Raspberry SCLK
MCP3008 DOUT (broche 12)   →  Raspberry MISO
MCP3008 DIN (broche 11)   →  Raspberry MOSI
MCP3008 CS (broche 10)   →  Raspberry CE0
MCP3008 DGND (broche 9)  →   Raspberry GND

Le code

Comme vous pouvez le constater, la routine ReadChannel se charge, en trois lignes de code, de toute la communication entre le Raspberry Pi et le MCP3008.   À partir du moment où vous l'incluez dans votre script, le reste n'est guère plus compliqué qu'utiliser AnalogRead avec Arduino.



Référence

Je n'ai pas trouvé ça tout seul!   Un article du blog Raspberry-Spy m'a été très utile.

Yves Pelletier (Twitter:  @ElectroAmateur)

10 commentaires:

  1. Salut, et merci pour le tuto !!

    Quand tu parles de la différence approche logicielle et matérielle, est-ce que tu sous entends que l'on peut mettre plus de 3 périphériques en SPI ?
    Mchobby, sur son topic du Pi-TFT dit que l'on ne peut pas mettre d'autres périphériques SPI en plus du Pi-TFT, parce que les deux canaux SPI sont occupés.

    Mais est-ce que cela signifique que dans ce cas là, l'écran occupe tout le SPI matériel, mais que l'on peut encore mettre une mcp3008 en SPI logicielle, en reconfigurant des pins du RPI ?


    Merci pour ton aide !

    RépondreSupprimer
    Réponses
    1. Je n'ai malheureusement pas la réponse à cette question...

      Supprimer
  2. Heu, et si on fait chuter la résistance du potar à zéro, y a t-il un court-circuit ? Et quelle est la valeur de cette résistance ?

    RépondreSupprimer
    Réponses
    1. Non, il n'y aura pas de court-circuit puisque la résistance totale du potentiomètre demeure constante peu importe la position du curseur (on peut considérer le potentiomètre comme une combinaison de deux résistances variables en série, dont la somme demeure constante: pendant qu'une des résistances augmente, l'autre diminue). Pour ce qui est de la valeur, vous utilisez ce que vous avez en main, les résultats seront les mêmes de toute façon.

      Supprimer
  3. Merci beaucoup de cette réponse immédiate !
    Donc je vais me lancer dans tout ça dès que j'aurai le matériel.
    Pouvez vous juste me dire quel potentiomètre acheter ?

    RépondreSupprimer
    Réponses
    1. Ça pourrait être, par exemple, un potentiomètre de 10 kiloohms.

      Supprimer
    2. Merci pour votre aide.

      Supprimer
  4. Dommage que le module spidev ne marche pas dans Python 3. :(

    RépondreSupprimer
    Réponses
    1. Merci pour l'info. C'est dommage, toutes ces incompatibilités entre Python 2 et 3.

      Supprimer
  5. impossible de le faire fonctionner avant d'ajouter "spi.max_speed_hz=1000000" juste après l'ouverture du canal SPI.
    Si ça peut aider

    RépondreSupprimer