Différences entre versions de « Rasp-Hack-PiAnalog »

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche
 
(23 versions intermédiaires par le même utilisateur non affichées)
Ligne 7 : Ligne 7 :
  
 
Voici une liste de quelques entrées analogiques qui peuvent être lue avec ce montage:
 
Voici une liste de quelques entrées analogiques qui peuvent être lue avec ce montage:
* Un [http://mchobby.be/PrestaShop/product.php?id_product=33 potentiomètre]
+
* Un {{pl|33|potentiomètre}}
* Une [http://mchobby.be/PrestaShop/product.php?id_product=58 Photorésistance]
+
* Une {{pl|58|Photorésistance}}
* Un FSR (résistance sensible à la force) voir [http://mchobby.be/PrestaShop/product.php?id_product=110 notre FSR] et [http://mchobby.be/PrestaShop/product.php?id_product=111 Flex Sensor].
+
* Un FSR (résistance sensible à la force) voir {{pl|110|notre FSR}} et {{pl|111|Flex Sensor}}.
* Un senseur de température comme [http://mchobby.be/PrestaShop/product.php?id_product=59 le TMP36]
+
* Un senseur de température comme {{pl|59|le TMP36}}
* Un [http://mchobby.be/PrestaShop/product.php?id_product=126 joystick 2 axes]
+
* Un {{pl|126|joystick 2 axes}}
  
 
Ce guide utilise un potentiomètre pour controler le volume d'un MP3 en cours de de lecture, mais ce code peut être utilisé comme base pour n'importe quelle lecture analogique.
 
Ce guide utilise un potentiomètre pour controler le volume d'un MP3 en cours de de lecture, mais ce code peut être utilisé comme base pour n'importe quelle lecture analogique.
  
Le [http://mchobby.be/PrestaShop/product.php?id_product=160 Pi Cobbler d'AdaFruit] (disponible chez MC Hobby) est utiliser pour faciliter le montage.
+
Le {{link-product-picobbler}} ou un {{link-product-picobblerplus}} (disponible chez MC Hobby) est utiliser pour faciliter le montage.
 +
 
 +
=== Pi-Cobbler ou Pi-Cobbler-Plus? ===
 +
 
 +
{{picobbler-compatibility}}
  
 
== Prérequis ==
 
== Prérequis ==
Assurez-vous d'avoir [http://mchobby.be/wiki/index.php?title=RaspberryPi-Accueil#Pr.C3.A9paration_pour_Python mis votre environnement Python à jour].
+
Assurez-vous d'avoir [[RaspberryPi-Accueil#Pr.C3.A9paration_pour_Python|mis votre environnement Python à jour]].
 +
 
 +
La base de cet exemple affiche la valeur du potentiomètre sur le terminal.
 +
 
 +
En fin d'exemple, il vous sera proposé un second script (sur le site d'AdaFruit) dont le but est de contrôler le volume sonore depuis le potentiomètre.
 +
Si vous désirez tester ce script, il sera nécessaire d'installer mpg321<br />
 +
 
 +
<nowiki>sudo apt-get install mpg321</nowiki>
 +
 
 +
Si vous rencontrez des problèmes d'installation, vous pouvez jeter un oeil sur notre article consacré à [http://arduino103.blogspot.be/2012/11/rapsberry-installer-mpg321-sur-debian.html l'installation de mpg321 et le rendu sonore sur un moniteur].
  
 
== Matériel ==
 
== Matériel ==
* Un [http://mchobby.be/PrestaShop/product.php?id_product=160 Pi-Cobbler] (disponible chez MCHobby)
+
* Un {{pl|160|Pi-Cobbler}} (disponible chez MCHobby)
* Un [http://mchobby.be/PrestaShop/product.php?id_product=33 potentiomètre]
+
* Un {{pl|33|potentiomètre}}
* Un [http://mchobby.be/PrestaShop/product.php?id_product=170 MCP3008 ADC] (Convertisseur Analogique Digital) modèle DIP.
+
* Un {{pl|170|MCP3008 ADC}} (Convertisseur Analogique Digital) modèle DIP.
* Un [http://mchobby.be/PrestaShop/product.php?id_product=141 Rapsberry]
+
* Un {{pl|141|Rapsberry}}
* Du [http://mchobby.be/PrestaShop/product.php?id_product=34 fil de prototypage pour breadboard]
+
* Du {{pl|34|fil de prototypage pour breadboard}}
* Un [http://mchobby.be/PrestaShop/search.php?orderby=position&orderway=desc&search_query=breadboard&submit_search=Rechercher breadboard] (demi ou grande taille).
+
* Un {{sl|breadboard|breadboard}} (demi ou grande taille).
  
 
== Pourquoi avons nous besoin d'un ADC? ==
 
== Pourquoi avons nous besoin d'un ADC? ==
 
ADC signifie "Analog to Digital Converter" autrement dit "Convertisseur Analogique vers Digital".
 
ADC signifie "Analog to Digital Converter" autrement dit "Convertisseur Analogique vers Digital".
  
The Raspberry Pi computer does not have a way to read analog inputs. It's a digital-only computer. Compare this to the Arduino, AVR or PIC microcontrollers that often have 6 or more analog inputs! Analog inputs are handy because many sensors are analog outputs, so we need a way to make the Pi analog-friendly.
+
Le Raspberry Pi ne dispose pas de moyen matériel pour lire une entrée analogique. Le Raspberry est purement digital a contrario des Arduino, AVR ou microcontroleur qui eux disposent souvent de 6 entrées analogiques ou plus!  
 +
 
 +
Les entrées analogiques sont vraiment pratiques parce que beaucoup de senseur utilisent des sorties analogiques, il est donc important de faire en sorte que le Raspberry soit aussi capable de faire des lectures analogiques.
  
We'll do that by wiring up an [http://mchobby.be/PrestaShop/product.php?id_product=170 MCP3008 chip] to it. The [http://mchobby.be/PrestaShop/product.php?id_product=170 MCP3008] acts like a 'bridge' between digital and analog. It has 8 analog inputs and the Pi can query it using 4 digital pins. That makes it a perfect addition to the Pi for integrating simple sensors like photocells, FSRs or potentiometers, thermistors, etc.!
+
Cela est rendu possible en raccordant une {{pl|170|puce MCP3008}} sur notre Pi. The {{pl|170|MCP3008}} agit comme un "pont" entre le monde digital et analogique. Il dispose de 8 entrées analogiques que le Pi peut "lire" en utilisant 4 pins digitales. Le MCP3008 est donc un ajout idéal pour permettre au Pi de lire des senseurs simples comme des photorésistance, des senseurs de forces, des potentiomètres ou des résistances sensibles à la chaleur, etc!
  
Lets check the [http://www.mchobby.be/data-files/datasheet/MCP3008.pdf datasheet of the MCP3008 chip]. On the first page in the lower right corner there's a pinout diagram showing the names of the pins
+
En jetant un oeil sur la [http://df.mchobby.be/datasheet/MCP3008.pdf fiche technique du MCP3008], la première page présente le diagramme de brochage du MCP3008 avec le nom des différentes broches.  
  
 
[[Fichier:MCP3008.jpg]]
 
[[Fichier:MCP3008.jpg]]
  
 
== Montage ==
 
== Montage ==
Voici le détail du montage
 
  
[[Fichier:Pi-MCP3008-Analog.jpg]]
+
=== Détails du montage ===
 +
 
 +
Pour pouvoir lire des données analogiques nous devons utiliser les broches suivantes pour alimenter la puce MCP3008:
 +
* VDD (alimentation),
 +
* DGND (digital ground, masse digitale).
 +
 
 +
Nous avons aussi besoin de 4 broches/pins pour les données 'SPI':
 +
* DOUT: broche "Data Out", sortie de donnée de la puce MCP3008,
 +
* CLK : broche "Clock" pour le signal d'horloge,
 +
* DIN : broche "Data In", entrée des données dans la puce MCP3008, données provenant du Raspberry Pi, 
 +
* /CS : broche "Chip Select", qui permet d'activer la puce. 
 +
 
 +
Et bien entendu, pour finir, la source de donnée analogique. Nous allons utiliser un potentiomètre de 10k.
 +
 
 +
Le MCP3008 a quelques broches complémentaires qui doivent aussi être connectées:
 +
* AGND: (analog ground, masse analogique), broche quelque-fois utilisées dans les montages de précision... ce qui n'est pas le cas de cet exemple.<br />Nous raccordons AGND à GND (la masse).
 +
* VREF: tension de référence. Utilisée pour changer l'échelle de mesure de la tension.<br />Comme nous désirons une mesure sur l'échelle complete, nous raccordons VREF à 3.3V.
 +
 
 +
=== Diagramme ===
 +
Vous trouverez ci-dessous le diagramme de raccordement.
 +
 
 +
Connectez la broche 3.3V du cobbler sur le rail d'alimentation de gauche (le rouge) et la broche GND du cobbler sur le rail d'alimentation à droite (le bleu).
 +
 
 +
Connectez les broches suivantes sur la puce MCP:
 +
 
 +
* MCP3008 VDD -> 3.3V (rouge)
 +
* MCP3008 VREF -> 3.3V (rouge)
 +
* MCP3008 AGND -> GND (noir)
 +
* MCP3008 CLK -> #18 (orange)
 +
* MCP3008 DOUT -> #23 (jaune)
 +
* MCP3008 DIN -> #24 (bleu)
 +
* MCP3008 CS -> #25 (violet)
 +
* MCP3008 DGND -> GND (noir)
 +
 
 +
Raccordez ensuite le potentiomètre:
 +
*  Broche No 1 (gauche) sur la masse/GND (NOIR),
 +
*  Broche No 2 (milieu) branchée sur la broche CH0 du MCP3008 avec un fil gris.<br />CH0 est l'abréviation anglaise de "Channel 0" signifiant "Canal ''analogique'' 0".
 +
* Broche No 3 (celle de droite) connectées à 3.3V (rail rouge)
 +
 
 +
[[Fichier:Pi-MCP3008-Wiring.jpg]]
  
 
Source: AdaFruit.com
 
Source: AdaFruit.com
 +
 +
=== Raspberry et SPI ===
 +
Les utilisateurs avancés de Raspberry PI aurons certainement déjà notés que le Raspberry PI dispose d'une interface SPI matérielle.
 +
 +
Cette interface matérielle est identifiable sur le Cobbler aux broches identifiées par MISO/MOSI/SCLK/CE0/CE1. Une interface SPI matérielle est super rapide mais malheureusement elle n'est pas prise en charge par toutes les distributions.
 +
 +
C'est pour cette raison que notre exemple met oeuvre une interface SPI logicielle. C'est le programme qui contrôle les broches relatives à l'interface SPI, les bits et le protocole. Comme le protocole SPI est assez simple, le code mis en oeuvre n'est pas trop long.
 +
 +
Le principal avantage de cette approche logicielle c'est que le protocole SPI peut être utilisé avec n'importe quelles broches GPIO du Raspberry Pi.
  
 
== Code ==
 
== Code ==
Ligne 51 : Ligne 113 :
 
  <nowiki>#!/usr/bin/env python
 
  <nowiki>#!/usr/bin/env python
 
# -*- coding: latin-1 -*-
 
# -*- coding: latin-1 -*-
 +
 +
import time
 +
import RPi.GPIO as GPIO
 +
 +
GPIO.setmode( GPIO.BCM )
 +
DEBUG = 1
 +
 +
# Lit les données SPI d'une puce MCP3008, 8 canaux disponibles (adcnum de 0 à 7)
 +
def readadc( adcnum, clockpin, mosipin, misopin, cspin ):
 +
        if( (adcnum > 7) or (adcnum < 0)):
 +
                return -1
 +
 +
        GPIO.output( cspin, True )
 +
 +
        GPIO.output( clockpin, False ) # met Clock à Low
 +
        GPIO.output( cspin, False )    # met CS à Low (active le module MCP3008)
 +
 +
        commandout = adcnum # numéro de channel
 +
        commandout |= 0x18  # OR pour ajouter Start bit + signle-ended bit
 +
                            # 0x18 = 24d = 00011000b
 +
        commandout <<=3    # décalage de 3 bits à gauche
 +
 +
        # Envoi des Bits sur le bus SPI
 +
        for i in range(5):
 +
                # faire un AND pour determiner l'état du bit de poids le plus
 +
                # fort (0x80 = 128d = 10000000b)
 +
                if( commandout & 0x80 ): # faire un AND pour déterminer l'état du bit
 +
                        GPIO.output( mosipin, True )
 +
                else:
 +
                        GPIO.output( mosipin, False )
 +
                commandout <<= 1 # décalage de 1 bit sur la gauche
 +
 +
                # Envoi du bit mosipin avec signal d'horloge
 +
                GPIO.output( clockpin, True )
 +
                GPIO.output( clockpin, False )
 +
 +
        # lecture des bits renvoyés par le MCP3008
 +
        # Lecture de 1  bit vide, 10 bits de données et un bit null
 +
        adcout = 0
 +
        for i in range(12):
 +
                # Signal d'horloge pour que le MCP3008 place un bit
 +
                GPIO.output( clockpin, True )
 +
                GPIO.output( clockpin, False )
 +
                # décalage de 1 bit vers la gauche
 +
                adcout <<= 1
 +
                # stockage du bit en fonction de la broche miso
 +
                if( GPIO.input(misopin)):
 +
                        adcout |= 0x1 # active le bit avec une opération OR
 +
 +
        # Mettre Chip Select à High (désactive le MCP3008)
 +
        GPIO.output( cspin, True )
 +
 +
        # Le tout premier bit (celui de poids le plus faible, le dernier lut)
 +
        # est null. Donc on l'elimine ce dernier bit en décalant vers la droite
 +
        adcout >>= 1
 +
 +
        return adcout
 +
 +
# Broches connectées sur l'interface SPI du MCP3008 depuis le Cobbler
 +
# (changer selon vos besoins)
 +
SPICLK = 18
 +
SPIMISO = 23
 +
SPIMOSI = 24
 +
SPICS = 25
 +
 +
# Initialisation de l'interface SPI
 +
GPIO.setup(SPIMOSI, GPIO.OUT)
 +
GPIO.setup(SPIMISO, GPIO.IN)
 +
GPIO.setup(SPICLK, GPIO.OUT)
 +
GPIO.setup(SPICS, GPIO.OUT)
 +
 +
# Potentiomètre 10KOhms raccordés sur le canal ADC #0
 +
potentiometer_adc = 0
 +
 +
while True:
 +
        # Lecture analogique, retourne une valeur entre 0 et 1023
 +
        # pour une valeur de tension entre 0 et VRef (3.3v)
 +
        trim_pot = readadc( potentiometer_adc, SPICLK, SPIMOSI, SPIMISO, SPICS )
 +
 +
        print( "Valeur: " + str( trim_pot ) )
 +
 +
        # convertir en tension
 +
        print( "tension: "+ str( (3.3*trim_pot)/1024 ) )
 +
 +
        # attendre une demi-seconde
 +
        time.sleep(0.5)
 +
</nowiki>
 +
 +
Ce qui produit le résultat suivant:
 +
 +
<nowiki>Valeur: 665
 +
tension: 2.14306640625
 +
Valeur: 666
 +
tension: 2.1462890625
 +
Valeur: 665
 +
tension: 2.14306640625
 +
Valeur: 668
 +
tension: 2.152734375
 +
Valeur: 665
 +
tension: 2.14306640625
 
</nowiki>
 
</nowiki>
  
Pour savoir comment télécharger et exécuter ce programme sur votre Py, nous vous proposons de prendre connaissance de notre premiers articles sur [[Rasp-Hack-LED|Raspberry Pi et LED]]  
+
Pour savoir comment télécharger et exécuter ce programme sur votre Py, nous vous proposons de prendre connaissance de notre premiers articles sur [[Rasp-Hack-LED|Raspberry Pi et LED]]
 +
 
 +
== Code - un petit complément ==
 +
En faisant des recherche sur le NET, je suis tombé sur [http://www.raspberrypi.org/forums/viewtopic.php?f=65&t=23404 cet article du Forum RaspberryPy.org] parlant justement de ce tuto.
 +
 
 +
Lorsque vous pressez CTRL+C pour arrêtez le programme, ce dernier s'arrête brutalement.
 +
 
 +
Si vous essayez de le redémarrer, vous obtenez le message d'erreur:
 +
<nowiki>./test.py:69: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
 +
  GPIO.setup(SPIMOSI, GPIO.OUT)
 +
./test.py:71: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
 +
  GPIO.setup(SPICLK, GPIO.OUT)
 +
./test.py:72: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
 +
  GPIO.setup(SPICS, GPIO.OUT)</nowiki>
 +
 
 +
C'est normal étant donné les circonstances... en effet, en quittant le programme brutalement, nous n'avons pas fait le nécessaire pour fermer notre connexion sur le GPIO.
 +
 
 +
La solution consiste à:
 +
# créer une fonction main() pour y placer le code de démonstration
 +
# exécuter la fonction mais dans un {try} {except} qui capture l'interruption clavier
 +
# clôturer notre accès sur le GPIO (faire un cleanup)
 +
 
 +
<nowiki>if __name__ == "__main__":
 +
    try:
 +
        main()
 +
    except KeyboardInterrupt:
 +
        gpio.cleanup()</nowiki>
 +
 
 +
Je vous invite à consulter l'[[http://www.raspberrypi.org/forums/viewtopic.php?f=65&t=23404 article sur le Forum] (merci les gars)
 +
 
 +
== Commande de volume ==
 +
AdaFruit propose un exemple plus avancé basé sur ce montage.
 +
 
 +
L'exemple propose de modifier le volume du son en fonction de la position du potentiomètre.
 +
 
 +
Cet exemple est disponible sur le site [http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi/script AdaFruit Learning System]
 +
 
 +
== Où acheter ==
 +
Tout le matériel nécessaire est disponible chez MCHobby.
 +
* {{pl|170|MCP3008}}
 +
* {{link-product-picobblerplus}}
 +
* {{link-product-piplus}}
 +
* {{link-product-pi2}}
 +
* {{link-product-pi3}}
 +
* {{link-product-picobbler}}
 +
* {{link-product-pi}}
 +
* Voir aussi la section [[Rasp-Hack-PiAnalog#Mat.C3.A9riel|matériel]] pour avoir les liens vers les différents articles.
  
Source: [http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi AdaFruit Learning System]
+
<hr ><small>
 +
Source: [http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi AdaFruit Learning System] par [http://www.adafruit.com www.adafruit.com] <br />
  
 +
Traduit par Meurisse D. pour [http://www.mchobby.be MCHobby.be]
 +
</small>
 
{{MCH-Accord}}
 
{{MCH-Accord}}
  
 
{{ADF-Accord}}
 
{{ADF-Accord}}

Version actuelle datée du 29 février 2016 à 17:05

Introduction

Apprendre comment lire une tension analogique à l'aide d'un Raspberry Pi pourrait être plus facile que vous ne le pensez!

MCP3008-PiDemo.jpg

Le Pi n'inclus pas de convertisseur Analogique/Digital mais un convertisseur ADC externe tel que le MCP3008 peut être utilisé avec du code Python pour faire une lecture analogique en utilisant le protocole SPI.

Voici une liste de quelques entrées analogiques qui peuvent être lue avec ce montage:

Ce guide utilise un potentiomètre pour controler le volume d'un MP3 en cours de de lecture, mais ce code peut être utilisé comme base pour n'importe quelle lecture analogique.

Le Pi-Cobbler ou un Pi-Cobbler PLUS (disponible chez MC Hobby) est utiliser pour faciliter le montage.

Pi-Cobbler ou Pi-Cobbler-Plus?

Avec l'arrivée du Raspberry Pi 3, Raspberry Pi-2 et Raspberry Pi-B PLUS, Raspberry Pi Zero W vient également un GPIO étendu de 40 broches rétro-compatible avec le GPIO des premières générations du Raspberry-Pi qui, lui, n'avait que 26 broches.

GPIO-Compatibility-00v3.jpg

La seule vraie différence réside dans la longueur du GPIO du modèle Pi-3, Pi-2 ou B+ qui contient des broches en plus... et le Pi-Cobbler PLUS qui à également grandi pour accueillir les broches en plus.

Avec l'apparition du Pi Zero, nous pouvons reparler de la correspondance des GPIO.

Pour notre plus grand bonheur, le GPIO du Pi Zero et du Pi 3 (ou Pi 2) sont identiques :) chouette.

RASP-PIZERO-Correspondance-GPIO v2.jpg
Cliquez pour agrandir

Prérequis

Assurez-vous d'avoir mis votre environnement Python à jour.

La base de cet exemple affiche la valeur du potentiomètre sur le terminal.

En fin d'exemple, il vous sera proposé un second script (sur le site d'AdaFruit) dont le but est de contrôler le volume sonore depuis le potentiomètre. Si vous désirez tester ce script, il sera nécessaire d'installer mpg321

sudo apt-get install mpg321

Si vous rencontrez des problèmes d'installation, vous pouvez jeter un oeil sur notre article consacré à l'installation de mpg321 et le rendu sonore sur un moniteur.

Matériel

Pourquoi avons nous besoin d'un ADC?

ADC signifie "Analog to Digital Converter" autrement dit "Convertisseur Analogique vers Digital".

Le Raspberry Pi ne dispose pas de moyen matériel pour lire une entrée analogique. Le Raspberry est purement digital a contrario des Arduino, AVR ou microcontroleur qui eux disposent souvent de 6 entrées analogiques ou plus!

Les entrées analogiques sont vraiment pratiques parce que beaucoup de senseur utilisent des sorties analogiques, il est donc important de faire en sorte que le Raspberry soit aussi capable de faire des lectures analogiques.

Cela est rendu possible en raccordant une puce MCP3008 sur notre Pi. The MCP3008 agit comme un "pont" entre le monde digital et analogique. Il dispose de 8 entrées analogiques que le Pi peut "lire" en utilisant 4 pins digitales. Le MCP3008 est donc un ajout idéal pour permettre au Pi de lire des senseurs simples comme des photorésistance, des senseurs de forces, des potentiomètres ou des résistances sensibles à la chaleur, etc!

En jetant un oeil sur la fiche technique du MCP3008, la première page présente le diagramme de brochage du MCP3008 avec le nom des différentes broches.

MCP3008.jpg

Montage

Détails du montage

Pour pouvoir lire des données analogiques nous devons utiliser les broches suivantes pour alimenter la puce MCP3008:

  • VDD (alimentation),
  • DGND (digital ground, masse digitale).

Nous avons aussi besoin de 4 broches/pins pour les données 'SPI':

  • DOUT: broche "Data Out", sortie de donnée de la puce MCP3008,
  • CLK : broche "Clock" pour le signal d'horloge,
  • DIN : broche "Data In", entrée des données dans la puce MCP3008, données provenant du Raspberry Pi,
  • /CS : broche "Chip Select", qui permet d'activer la puce.

Et bien entendu, pour finir, la source de donnée analogique. Nous allons utiliser un potentiomètre de 10k.

Le MCP3008 a quelques broches complémentaires qui doivent aussi être connectées:

  • AGND: (analog ground, masse analogique), broche quelque-fois utilisées dans les montages de précision... ce qui n'est pas le cas de cet exemple.
    Nous raccordons AGND à GND (la masse).
  • VREF: tension de référence. Utilisée pour changer l'échelle de mesure de la tension.
    Comme nous désirons une mesure sur l'échelle complete, nous raccordons VREF à 3.3V.

Diagramme

Vous trouverez ci-dessous le diagramme de raccordement.

Connectez la broche 3.3V du cobbler sur le rail d'alimentation de gauche (le rouge) et la broche GND du cobbler sur le rail d'alimentation à droite (le bleu).

Connectez les broches suivantes sur la puce MCP:

  • MCP3008 VDD -> 3.3V (rouge)
  • MCP3008 VREF -> 3.3V (rouge)
  • MCP3008 AGND -> GND (noir)
  • MCP3008 CLK -> #18 (orange)
  • MCP3008 DOUT -> #23 (jaune)
  • MCP3008 DIN -> #24 (bleu)
  • MCP3008 CS -> #25 (violet)
  • MCP3008 DGND -> GND (noir)

Raccordez ensuite le potentiomètre:

  • Broche No 1 (gauche) sur la masse/GND (NOIR),
  • Broche No 2 (milieu) branchée sur la broche CH0 du MCP3008 avec un fil gris.
    CH0 est l'abréviation anglaise de "Channel 0" signifiant "Canal analogique 0".
  • Broche No 3 (celle de droite) connectées à 3.3V (rail rouge)

Pi-MCP3008-Wiring.jpg

Source: AdaFruit.com

Raspberry et SPI

Les utilisateurs avancés de Raspberry PI aurons certainement déjà notés que le Raspberry PI dispose d'une interface SPI matérielle.

Cette interface matérielle est identifiable sur le Cobbler aux broches identifiées par MISO/MOSI/SCLK/CE0/CE1. Une interface SPI matérielle est super rapide mais malheureusement elle n'est pas prise en charge par toutes les distributions.

C'est pour cette raison que notre exemple met oeuvre une interface SPI logicielle. C'est le programme qui contrôle les broches relatives à l'interface SPI, les bits et le protocole. Comme le protocole SPI est assez simple, le code mis en oeuvre n'est pas trop long.

Le principal avantage de cette approche logicielle c'est que le protocole SPI peut être utilisé avec n'importe quelles broches GPIO du Raspberry Pi.

Code

Voici notre exemple Rasp-PiAnalog.py écrit en python.

#!/usr/bin/env python
# -*- coding: latin-1 -*-

import time
import RPi.GPIO as GPIO

GPIO.setmode( GPIO.BCM )
DEBUG = 1

# Lit les données SPI d'une puce MCP3008, 8 canaux disponibles (adcnum de 0 à 7)
def readadc( adcnum, clockpin, mosipin, misopin, cspin ):
        if( (adcnum > 7) or (adcnum < 0)):
                return -1

        GPIO.output( cspin, True )

        GPIO.output( clockpin, False ) # met Clock à Low
        GPIO.output( cspin, False )    # met CS à Low (active le module MCP3008)

        commandout = adcnum # numéro de channel
        commandout |= 0x18  # OR pour ajouter Start bit + signle-ended bit
                            # 0x18 = 24d = 00011000b
        commandout <<=3     # décalage de 3 bits à gauche

        # Envoi des Bits sur le bus SPI
        for i in range(5):
                # faire un AND pour determiner l'état du bit de poids le plus 
                # fort (0x80 = 128d = 10000000b)
                if( commandout & 0x80 ): # faire un AND pour déterminer l'état du bit
                        GPIO.output( mosipin, True )
                else:
                        GPIO.output( mosipin, False )
                commandout <<= 1 # décalage de 1 bit sur la gauche

                # Envoi du bit mosipin avec signal d'horloge
                GPIO.output( clockpin, True )
                GPIO.output( clockpin, False )

        # lecture des bits renvoyés par le MCP3008
        # Lecture de 1  bit vide, 10 bits de données et un bit null
        adcout = 0
        for i in range(12):
                # Signal d'horloge pour que le MCP3008 place un bit
                GPIO.output( clockpin, True )
                GPIO.output( clockpin, False )
                # décalage de 1 bit vers la gauche
                adcout <<= 1
                # stockage du bit en fonction de la broche miso
                if( GPIO.input(misopin)):
                        adcout |= 0x1 # active le bit avec une opération OR

        # Mettre Chip Select à High (désactive le MCP3008)
        GPIO.output( cspin, True )

        # Le tout premier bit (celui de poids le plus faible, le dernier lut)
        # est null. Donc on l'elimine ce dernier bit en décalant vers la droite
        adcout >>= 1

        return adcout

# Broches connectées sur l'interface SPI du MCP3008 depuis le Cobbler
# (changer selon vos besoins)
SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25

# Initialisation de l'interface SPI
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)

# Potentiomètre 10KOhms raccordés sur le canal ADC #0
potentiometer_adc = 0

while True:
        # Lecture analogique, retourne une valeur entre 0 et 1023 
        # pour une valeur de tension entre 0 et VRef (3.3v)
        trim_pot = readadc( potentiometer_adc, SPICLK, SPIMOSI, SPIMISO, SPICS )

        print( "Valeur: " + str( trim_pot ) )

        # convertir en tension
        print( "tension: "+ str( (3.3*trim_pot)/1024 ) )

        # attendre une demi-seconde
        time.sleep(0.5)

Ce qui produit le résultat suivant:

Valeur: 665
tension: 2.14306640625
Valeur: 666
tension: 2.1462890625
Valeur: 665
tension: 2.14306640625
Valeur: 668
tension: 2.152734375
Valeur: 665
tension: 2.14306640625

Pour savoir comment télécharger et exécuter ce programme sur votre Py, nous vous proposons de prendre connaissance de notre premiers articles sur Raspberry Pi et LED

Code - un petit complément

En faisant des recherche sur le NET, je suis tombé sur cet article du Forum RaspberryPy.org parlant justement de ce tuto.

Lorsque vous pressez CTRL+C pour arrêtez le programme, ce dernier s'arrête brutalement.

Si vous essayez de le redémarrer, vous obtenez le message d'erreur:

./test.py:69: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(SPIMOSI, GPIO.OUT)
./test.py:71: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(SPICLK, GPIO.OUT)
./test.py:72: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(SPICS, GPIO.OUT)

C'est normal étant donné les circonstances... en effet, en quittant le programme brutalement, nous n'avons pas fait le nécessaire pour fermer notre connexion sur le GPIO.

La solution consiste à:

  1. créer une fonction main() pour y placer le code de démonstration
  2. exécuter la fonction mais dans un {try} {except} qui capture l'interruption clavier
  3. clôturer notre accès sur le GPIO (faire un cleanup)
if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        gpio.cleanup()

Je vous invite à consulter l'[article sur le Forum (merci les gars)

Commande de volume

AdaFruit propose un exemple plus avancé basé sur ce montage.

L'exemple propose de modifier le volume du son en fonction de la position du potentiomètre.

Cet exemple est disponible sur le site AdaFruit Learning System

Où acheter

Tout le matériel nécessaire est disponible chez MCHobby.


Source: AdaFruit Learning System par www.adafruit.com

Traduit par Meurisse D. pour MCHobby.be Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : «  Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.

L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.

Traduit avec l'autorisation d'AdaFruit Industries - Translated with the permission from Adafruit Industries - www.adafruit.com