.. note::
Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauche tiefer in Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten ein.
**Warum beitreten?**
- **Expertenunterstützung**: Löse Probleme nach dem Kauf und technische Herausforderungen mit Hilfe unserer Community und unseres Teams.
- **Lernen & Teilen**: Tausche Tipps und Tutorials aus, um deine Fähigkeiten zu verbessern.
- **Exklusive Vorschauen**: Erhalte frühzeitigen Zugang zu neuen Produktankündigungen und Vorschauen.
- **Sonderrabatte**: Genieße exklusive Rabatte auf unsere neuesten Produkte.
- **Festliche Aktionen und Gewinnspiele**: Nimm an Gewinnspielen und Feiertagsaktionen teil.
👉 Bereit, mit uns zu erkunden und zu kreieren? Klicke [|link_sf_facebook|] und tritt noch heute bei!
.. _2.1.9_py_mcp3008:
2.1.9 Joystick (MCP3008)
=========================
Einführung
----------
In diesem Projekt lernen wir, wie ein Joystick funktioniert. Wir bewegen den Joystick und zeigen die Ergebnisse auf dem Bildschirm an.
Benötigte Komponenten
---------------------
Für dieses Projekt benötigen wir die folgenden Komponenten.
.. image:: ../img/image317 - Copy.png
Es ist auf jeden Fall praktisch, ein komplettes Kit zu kaufen. Hier ist der Link:
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - Name
- ARTIKEL IN DIESEM KIT
- LINK
* - Raphael Kit
- 337
- |link_Raphael_kit|
Du kannst sie auch separat über die folgenden Links kaufen.
.. list-table::
:widths: 30 20
:header-rows: 1
* - KOMPONENTENVORSTELLUNG
- KAUFLINK
* - :ref:`cpn_gpio_board`
- |link_gpio_board_buy|
* - :ref:`cpn_breadboard`
- |link_breadboard_buy|
* - :ref:`cpn_wires`
- |link_wires_buy|
* - :ref:`cpn_resistor`
- |link_resistor_buy|
* - :ref:`cpn_joystick`
- \-
* - :ref:`cpn_mcp3008`
- \-
Schaltplan
----------
Beim Auslesen der Joystick-Daten gibt es Unterschiede zwischen den Achsen: Die Daten der X- und Y-Achse sind analog und müssen über den MCP3008 in digitale Werte umgewandelt werden. Die Daten der Z-Achse sind digital und können direkt über den GPIO ausgelesen werden, können aber auch über den ADC gelesen werden.
.. .. image:: ../img/2.1.9_joystick_schematic_1.png
* - T-Board-Name
- physical
- WiringPi
- BCM
* - SPICE0
- pin24
- 10
- 8
* - SPIMOSI
- pin19
- 12
- 10
* - SPIMISO
- pin21
- 13
- 9
* - SPISCLK
- pin23
- 14
- 11
* - GPIO22
- pin15
- 3
- 22
.. image:: ../img/schematic_2.1.9_joystick_mcp3008.png
Experimentelle Schritte
-----------------------
**Schritt 1:** Baue die Schaltung auf.
.. image:: ../img/july24_2.1.9_joystick_mcp3008.png
**Schritt 2:** Richte die SPI-Schnittstelle ein und installiere die ``spidev``-Bibliothek (siehe :ref:`spi_configuration` für detaillierte Anweisungen). Wenn du diese Schritte bereits abgeschlossen hast, kannst du diesen Schritt überspringen.
**Schritt 3:** Wechsle in den Code-Ordner.
.. raw:: html
.. code-block::
cd ~/raphael-kit/python
**Schritt 4:** Führe den Code aus.
.. raw:: html
.. code-block::
sudo python3 2.1.9-2_Joystick.py
Nachdem der Code ausgeführt wird, bewege den Joystick, und die entsprechenden Werte von x, y und Btn werden auf dem Bildschirm angezeigt.
.. warning::
Wenn die Fehlermeldung ``RuntimeError: Cannot determine SOC peripheral base address`` erscheint, siehe :ref:`faq_soc`
**Code**
.. note::
Du kannst den untenstehenden Code **Bearbeiten/Zurücksetzen/Kopieren/Ausführen/Stoppen**. Gehe zuvor in das Quellcodeverzeichnis wie ``raphael-kit/python``. Nach Änderungen kannst du den Code direkt ausführen, um das Ergebnis zu sehen.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
# GPIO-Pin für den Joystick-Button (SW-Pin)
BTN_PIN = 22
# GPIO-Modus festlegen
GPIO.setmode(GPIO.BCM)
GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # interner Pull-up
# SPI-Kommunikation mit MCP3008 initialisieren
spi = spidev.SpiDev()
spi.open(0, 0) # SPI-Bus 0, CE0
spi.max_speed_hz = 1000000 # 1 MHz
def read_adc(channel):
"""
Liest den analogen Wert vom angegebenen MCP3008-Kanal (0–7)
:param channel: ADC-Kanalnummer (0–7)
:return: 10-Bit-Integerwert (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:
# Hauptschleife zum Lesen und Ausgeben der Joystick-Werte und des Button-Status
while True:
# Lese X- und Y-Werte von den MCP3008-Kanälen 1 und 2
x_val = read_adc(1) # Joystick VRX an CH1
y_val = read_adc(2) # Joystick VRY an CH2
# Lese den Zustand des Joystick-Buttons (SW)
Btn_val = GPIO.input(BTN_PIN) # 0 = gedrückt, 1 = losgelassen
# Werte ausgeben
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()
**Code-Erklärung**
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
Dieser Abschnitt importiert die benötigten Bibliotheken:
- ``RPi.GPIO`` wird verwendet, um GPIO-Eingaben (Joystick-Button) zu verarbeiten.
- ``spidev`` wird verwendet, um mit dem MCP3008-ADC-Chip über SPI zu kommunizieren.
- ``time`` wird verwendet, um Verzögerungen zwischen den Messungen einzufügen.
.. code-block:: python
# GPIO-Pin für den Joystick-Button (SW-Pin)
BTN_PIN = 22
# GPIO-Modus festlegen
GPIO.setmode(GPIO.BCM)
GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# SPI-Kommunikation mit MCP3008 initialisieren
spi = spidev.SpiDev()
spi.open(0, 0) # SPI-Bus 0, CE0
spi.max_speed_hz = 1000000
Dieser Block setzt den GPIO-Modus auf ``BCM``, initialisiert den Joystick-Button-Eingang auf GPIO22 mit einem Pull-up-Widerstand und konfiguriert die SPI-Schnittstelle mit MCP3008 unter Verwendung von Bus 0 und Chip Enable 0 (CE0) bei 1 MHz.
.. code-block:: python
def read_adc(channel):
"""
Liest den analogen Wert vom angegebenen MCP3008-Kanal (0–7)
:param channel: ADC-Kanalnummer (0–7)
:return: 10-Bit-Integerwert (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
Definiert die Funktion ``read_adc()``, um analoge Daten von einem bestimmten MCP3008-Kanal zu lesen. Es werden drei Bytes über SPI gesendet, und die Antwort wird interpretiert, um einen 10-Bit-Wert von 0 bis 1023 zurückzugeben.
.. code-block:: python
try:
# Hauptschleife zum Lesen und Ausgeben der Joystick-Werte und des Button-Status
while True:
# Lese X- und Y-Werte von den MCP3008-Kanälen 0 und 1
x_val = read_adc(0) # Joystick VRX an CH0
y_val = read_adc(1) # Joystick VRY an CH1
# Lese den Zustand des Joystick-Buttons (SW)
Btn_val = GPIO.input(BTN_PIN) # 0 = gedrückt, 1 = losgelassen
# Werte ausgeben
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()
Diese Hauptschleife liest und gibt die X/Y-Positionen des Joysticks und den Zustand des Buttons alle 200 ms aus. Wenn das Skript über die Tastatur (Strg+C) unterbrochen wird, werden SPI und GPIO ordnungsgemäß bereinigt.