.. note::
Bonjour et bienvenue dans la communauté SunFounder Raspberry Pi & Arduino & ESP32 sur Facebook ! Plongez plus profondément dans l’univers de Raspberry Pi, Arduino et ESP32 avec d’autres passionnés.
**Pourquoi rejoindre ?**
- **Support d’experts** : Résolvez vos problèmes après-vente et vos défis techniques avec l’aide de notre communauté et de notre équipe.
- **Apprendre et partager** : Échangez des astuces et des tutoriels pour améliorer vos compétences.
- **Aperçus exclusifs** : Accédez en avant-première aux annonces de nouveaux produits et aux aperçus.
- **Réductions spéciales** : Profitez de réductions exclusives sur nos derniers produits.
- **Promotions et concours festifs** : Participez à des concours et des promotions spéciales pour les fêtes.
👉 Prêt à explorer et créer avec nous ? Cliquez sur [|link_sf_facebook|] et rejoignez-nous dès aujourd’hui !
.. _2.1.6_c_mcp3008:
2.1.6 Joystick (MCP3008)
==========================
.. note::
.. image:: img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Selon la version de votre kit, identifiez si vous avez **ADC0834** ou **MCP3008** et suivez la section correspondante.
Introduction
--------------
Dans ce projet, nous allons apprendre comment fonctionne un joystick.
Nous allons manipuler le joystick et afficher les résultats à l’écran.
Composants requis
-------------------------------
Pour ce projet, nous avons besoin des composants suivants :
.. image:: img/image317-copy.png
Principe
---------
**Joystick**
Le principe de base d’un joystick est de traduire le mouvement d’un levier en information électronique que l’ordinateur peut traiter.
Pour transmettre toute la gamme de mouvements à l’ordinateur, un joystick doit mesurer la position du levier sur deux axes — l’axe X (gauche à droite) et l’axe Y (haut en bas). Comme en géométrie de base, les coordonnées X-Y indiquent précisément la position du levier.
Pour déterminer l’emplacement du levier, le système de contrôle du joystick surveille simplement la position de chaque axe. Le design analogique traditionnel d’un joystick fait cela à l’aide de deux potentiomètres, ou résistances variables.
Le joystick possède également une entrée numérique qui est activée lorsque l’on appuie sur le levier.
.. image:: img/image318.png
Schéma de câblage
-----------------
Lorsque les données du joystick sont lues, il existe des différences entre les axes :
les données des axes X et Y sont analogiques et nécessitent l’utilisation du MCP3008 pour convertir la valeur analogique en valeur numérique. Les données de l’axe Z sont numériques, vous pouvez donc les lire directement via un GPIO, ou aussi via l’ADC.
.. image:: img/schematic_2.1.9_joystick_mcp3008.png
Procédure expérimentale
-----------------------
**Étape 1 :** Montez le circuit.
.. image:: img/july24_2.1.9_joystick_mcp3008.png
Pour les utilisateurs du langage C
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Étape 2 :** Ouvrez le dossier du code.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/c/2.1.6-2/
**Étape 3 :** Compilez le code.
.. raw:: html
.. code-block::
gcc 2.1.6_Joystick.c -o joystick -lwiringPi
**Étape 4 :** Exécutez le fichier compilé.
.. raw:: html
.. code-block::
./joystick
Après exécution, déplacez le joystick : les valeurs correspondantes de X, Y et Btn s’affichent à l’écran.
.. note::
Si cela ne fonctionne pas après exécution, ou qu’un message d’erreur apparaît : « wiringPi.h: No such file or directory », veuillez vous référer à :ref:`install_wiringpi`.
**Code**
.. code-block:: c
#include
#include
#include
#define SPI_CHANNEL 0
#define SPI_SPEED 1000000 // 1 MHz
#define BtnPin 3 // WiringPi 3 = BCM GPIO22
// Lecture depuis le canal MCP3008 (0–7)
int read_ADC(int channel) {
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // Bit de démarrage
buffer[1] = (8 + channel) << 4; // Configuration canal
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int result = ((buffer[1] & 0x03) << 8) | buffer[2];
return result;
}
int main(void) {
if (wiringPiSetup() == -1) {
printf("Échec de l’initialisation de WiringPi !\n");
return 1;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("Échec de l’initialisation SPI !\n");
return 1;
}
pinMode(BtnPin, INPUT);
pullUpDnControl(BtnPin, PUD_UP);
while (1) {
int x_val = read_ADC(0); // VRX sur CH0
int y_val = read_ADC(1); // VRY sur CH1
int btn_val = digitalRead(BtnPin); // Bouton SW
printf("x = %d, y = %d, btn = %d\n", x_val, y_val, btn_val);
delay(100);
}
return 0;
}
**Explication du code**
1. Cette section initialise les bibliothèques nécessaires pour le GPIO et la communication SPI.
.. code-block:: c
#include
#include
#include
#define SPI_CHANNEL 0
#define SPI_SPEED 1000000 // 1 MHz
#define BtnPin 3 // WiringPi 3 = BCM GPIO22
2. La fonction `read_ADC()` lit les données analogiques depuis le MCP3008 via SPI sur un canal donné (0–7), puis renvoie un résultat ADC sur 10 bits.
.. code-block:: c
int read_ADC(int channel) {
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1;
buffer[1] = (8 + channel) << 4;
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int result = ((buffer[1] & 0x03) << 8) | buffer[2];
return result;
}
3. La fonction principale initialise WiringPi et l’interface SPI, configure le bouton du joystick, puis lit et affiche en continu les valeurs X, Y et bouton.
.. code-block:: c
int main(void) {
if (wiringPiSetup() == -1) {
printf("Échec de l’initialisation de WiringPi !\n");
return 1;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("Échec de l’initialisation SPI !\n");
return 1;
}
pinMode(BtnPin, INPUT);
pullUpDnControl(BtnPin, PUD_UP);
while (1) {
int x_val = read_ADC(0);
int y_val = read_ADC(1);
int btn_val = digitalRead(BtnPin);
printf("x = %d, y = %d, btn = %d\n", x_val, y_val, btn_val);
delay(100);
}
return 0;
}
Pour les utilisateurs Python
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Étape 2 :** Configurez l’interface SPI et installez la bibliothèque ``spidev`` (voir :ref:`spi_configuration` pour les instructions détaillées). Si vous avez déjà effectué ces étapes, vous pouvez les ignorer.
**Étape 3 :** Ouvrez le dossier du code.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/python
**Étape 4 :** Exécutez.
.. raw:: html
.. code-block::
sudo python3 2.1.6-2_Joystick.py
Après exécution, déplacez le joystick : les valeurs correspondantes de X, Y et Btn s’affichent à l’écran.
.. warning::
Si un message d’erreur « RuntimeError: Cannot determine SOC peripheral base address » apparaît, veuillez vous référer à :ref:`faq_soc`
**Code**
.. note::
Vous pouvez **Modifier/Réinitialiser/Copier/Exécuter/Arrêter** le code ci-dessous. Avant cela, assurez-vous d’être dans le répertoire source comme ``davinci-kit-for-raspberry-pi/python``. Après modification, vous pouvez l’exécuter directement pour voir le résultat.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
# Définir le GPIO pour le bouton du joystick (SW)
BTN_PIN = 22
GPIO.setmode(GPIO.BCM)
GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
spi = spidev.SpiDev()
spi.open(0, 0) # Bus SPI 0, CE0
spi.max_speed_hz = 1000000 # 1 MHz
def read_adc(channel):
"""
Lit la valeur analogique depuis le MCP3008 (canal 0–7)
:param channel: numéro de canal ADC (0–7)
:return: valeur entière sur 10 bits (0–1023)
"""
if channel < 0 or channel > 7:
return -1
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 0x03) << 8) | adc[2]
return value
try:
while True:
x_val = read_adc(1) # VRX sur CH1
y_val = read_adc(2) # VRY sur CH2
Btn_val = GPIO.input(BTN_PIN) # 0 = appuyé, 1 = relâché
print('X: %d Y: %d Btn: %d' % (x_val, y_val, Btn_val))
time.sleep(0.2)
except KeyboardInterrupt:
pass
finally:
spi.close()
GPIO.cleanup()
**Explication du code**
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
- ``RPi.GPIO`` gère les entrées/sorties GPIO (ici, le bouton du joystick).
- ``spidev`` communique avec le MCP3008 via SPI.
- ``time`` permet d’ajouter des délais.
.. code-block:: python
BTN_PIN = 22
GPIO.setmode(GPIO.BCM)
GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
Cette partie configure le bouton du joystick sur GPIO22 avec résistance pull-up, et initialise SPI sur le bus 0, CE0 à 1 MHz.
.. code-block:: python
def read_adc(channel):
if channel < 0 or channel > 7:
return -1
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 0x03) << 8) | adc[2]
return value
La fonction ``read_adc()`` lit les données analogiques sur le canal donné et renvoie une valeur de 0 à 1023.
.. code-block:: python
try:
while True:
x_val = read_adc(0) # VRX sur CH0
y_val = read_adc(1) # VRY sur CH1
Btn_val = GPIO.input(BTN_PIN)
print('X: %d Y: %d Btn: %d' % (x_val, y_val, Btn_val))
time.sleep(0.2)
except KeyboardInterrupt:
pass
finally:
spi.close()
GPIO.cleanup()
La boucle principale lit X/Y toutes les 200 ms et affiche aussi l’état du bouton (0 = appuyé, 1 = relâché).
En cas d’interruption clavier, les ressources SPI et GPIO sont correctement libérées.