.. note::
Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook!
Tauchen Sie tiefer in Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten ein.
**Warum beitreten?**
- **Expertenunterstützung**: Lösen Sie nach dem Kauf auftretende Probleme und technische Herausforderungen mit Hilfe unserer Community und unseres Teams.
- **Lernen & Teilen**: Tauschen Sie Tipps und Tutorials aus, um Ihre Fähigkeiten zu verbessern.
- **Exklusive Vorschauen**: Erhalten Sie frühzeitigen Zugriff auf neue Produktankündigungen und exklusive Einblicke.
- **Sonderrabatte**: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.
- **Festliche Aktionen und Verlosungen**: Nehmen Sie an Verlosungen und Feiertagsaktionen teil.
👉 Bereit, mit uns zu forschen und zu kreieren? Klicken Sie auf [|link_sf_facebook|] und treten Sie noch heute bei!
.. _4.1.10_py_pi5_mcp3008:
4.1.7 Intelligenter Ventilator (MCP3008)
=========================================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Abhängig von Ihrer Kit-Version identifizieren Sie bitte, ob Sie **ADC0834** oder **MCP3008** haben, und fahren Sie mit dem entsprechenden Abschnitt fort.
Einführung
-----------------
In diesem Projekt verwenden wir Motoren, Tasten und Thermistoren, um einen manuellen + automatischen intelligenten Ventilator zu bauen, dessen Windgeschwindigkeit einstellbar ist.
Benötigte Komponenten
------------------------------
In diesem Projekt benötigen wir die folgenden Komponenten.
.. image:: ../python_pi5/img/list2_Smart_Fan.png
:width: 800
:align: center
Es ist auf jeden Fall bequem, ein komplettes Kit zu kaufen, hier ist der Link:
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - Name
- ELEMENTE IN DIESEM KIT
- LINK
* - Raphael Kit
- 337
- |link_Raphael_kit|
Sie können diese Komponenten auch einzeln über die folgenden Links kaufen.
.. list-table::
:widths: 30 20
:header-rows: 1
* - KOMPONENTENBESCHREIBUNG
- 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_power_module`
- \-
* - :ref:`cpn_thermistor`
- |link_thermistor_buy|
* - :ref:`cpn_l293d`
- \-
* - :ref:`cpn_mcp3008`
- \-
* - :ref:`cpn_button`
- |link_button_buy|
* - :ref:`cpn_motor`
- |link_motor_buy|
Schaltplan
------------------------
============ ======== ======== ===
T-Board Name physical wiringPi BCM
SPICE0 Pin 24 10 8
SPIMOSI Pin 19 12 10
SPIMISO Pin 21 13 9
SPISCLK Pin 23 14 11
GPIO22 Pin 15 3 22
GPIO5 Pin 29 21 5
GPIO6 Pin 31 22 6
GPIO13 Pin 33 23 13
============ ======== ======== ===
.. image:: ../python_pi5/img/schematic_3.1.4_smart_fan_mcp3008.png
:align: center
:width: 800
Experimentelle Verfahren
-----------------------------
**Schritt 1:** Bauen Sie die Schaltung auf.
.. image:: ../python_pi5/img/july24_3.1.4_smart_fan_mcp3008.png
:width: 800
.. note::
Das Strommodul kann eine 9V-Batterie mit dem im Kit enthaltenen 9V-Batterieclip verwenden.
.. image:: ../python_pi5/img/4.1.10_smart_fan_battery.jpeg
:align: center
**Schritt 2:** Richten Sie die SPI-Schnittstelle ein und installieren Sie die ``spidev``-Bibliothek (siehe :ref:`spi_configuration` für detaillierte Anweisungen). Wenn Sie diese Schritte bereits abgeschlossen haben, können Sie diesen Schritt überspringen.
**Schritt 3:** Wechseln Sie in den Ordner mit dem Code.
.. raw:: html
.. code-block::
cd ~/raphael-kit/python-pi5
**Schritt 4:** Ausführen.
.. raw:: html
.. code-block::
sudo python3 4.1.10-2_SmartFan_zero.py
Sobald der Code ausgeführt wird, starten Sie den Ventilator durch Drücken des Knopfes. Bei jedem Druck wird die Geschwindigkeit um eine Stufe erhöht oder verringert. Es gibt **5** Geschwindigkeitsstufen: **0~4**. Wenn die 4. Stufe erreicht ist und Sie erneut drücken, stoppt der Ventilator mit **0** Windgeschwindigkeit.
Wenn sich die Temperatur um mehr als 2℃ ändert, erhöht oder verringert sich die Geschwindigkeit automatisch um eine Stufe.
Code
--------
.. note::
Sie können den untenstehenden Code **Ändern/Zurücksetzen/Kopieren/Ausführen/Stoppen**.
Vorher müssen Sie jedoch zum Quellcodepfad wie ``raphael-kit/python-pi5`` wechseln.
Nach dem Ändern des Codes können Sie ihn direkt ausführen, um das Ergebnis zu sehen.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import Motor, Button
from time import sleep
import spidev
import math
# Initialisiere SPI für MCP3008
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0 (GPIO8 / physical pin 24)
spi.max_speed_hz = 1000000 # 1 MHz
# Initialisiere GPIO-Pins für den Knopf und die Motorsteuerung
BtnPin = Button(22) # GPIO22 (physikalischer Pin 15)
motor = Motor(forward=5, backward=6, enable=13) # GPIO5, GPIO6, GPIO13
# Initialisiere Variablen zur Verfolgung der Motorgeschwindigkeit und Temperatur
level = 0
currentTemp = 0
markTemp = 0
def read_adc(channel):
"""
Liest den analogen Wert vom MCP3008-Kanal (0–7).
"""
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
def temperature():
"""
Liest und berechnet die aktuelle Temperatur vom Sensor.
Rückgabe:
float: Die aktuelle Temperatur in Grad Celsius.
"""
analogVal = read_adc(0) # Thermistor an CH0 angeschlossen
Vr = 3.3 * analogVal / 1023.0 # Für 3,3V-System
Rt = 10000.0 * Vr / (3.3 - Vr)
temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
Cel = temp - 273.15
return Cel
def motor_run(level):
"""
Passt die Motordrehzahl basierend auf der angegebenen Stufe an.
Argumente:
level (int): gewünschte Motordrehzahlstufe.
Rückgabe:
int: Angepasste Motordrehzahlstufe.
"""
if level == 0:
motor.stop()
return 0
if level >= 4:
level = 4
motor.forward(speed=float(level / 4))
return level
def changeLevel():
"""
Ändert die Motordrehzahlstufe, wenn die Taste gedrückt wird, und aktualisiert die Referenztemperatur.
"""
global level, currentTemp, markTemp
print("Button gedrückt")
level = (level + 1) % 5
markTemp = currentTemp
# Verknüpfe die Tastenereignisfunktion
BtnPin.when_pressed = changeLevel
def main():
"""
Hauptfunktion zur kontinuierlichen Überwachung und Reaktion auf Temperaturänderungen.
"""
global level, currentTemp, markTemp
markTemp = temperature()
while True:
currentTemp = temperature()
if level != 0:
if currentTemp - markTemp <= -2:
level -= 1
markTemp = currentTemp
elif currentTemp - markTemp >= 2:
if level < 4:
level += 1
markTemp = currentTemp
level = motor_run(level)
sleep(0.2)
try:
main()
except KeyboardInterrupt:
motor.stop()
spi.close()
Code-Erklärung
---------------------
#. Importiert Bibliotheken für Motor- und Tastensteuerung, SPI-Kommunikation mit MCP3008 und mathematische Berechnungen. Die ``gpiozero``-Bibliothek wird zur Steuerung von GPIO-Geräten verwendet, ``spidev`` für die SPI-Kommunikation mit dem MCP3008-ADC und ``math`` für Temperaturberechnungen.
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import Motor, Button
from time import sleep
import spidev
import math
#. Initialisiert die SPI-Kommunikation auf Bus 0, Gerät 0 (CE0), der mit dem MCP3008-ADC-Chip verbunden ist.
.. code-block:: python
# Initialize SPI for MCP3008
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0 (GPIO8 / physical pin 24)
spi.max_speed_hz = 1000000 # 1 MHz
#. Richtet GPIO-Pin 22 als Tasten-Eingang ein und konfiguriert den Motor mit GPIO5 (vorwärts), GPIO6 (rückwärts) und GPIO13 (Enable). Deklariert außerdem globale Variablen zur Verfolgung von Motordrehzahlstufe und Temperatur.
.. code-block:: python
# Initialize GPIO pins for the button and motor control
BtnPin = Button(22) # GPIO22 (physical pin 15)
motor = Motor(forward=5, backward=6, enable=13) # GPIO5, GPIO6, GPIO13
# Initialize variables to track the motor speed level and temperatures
level = 0
currentTemp = 0
markTemp = 0
#. Definiert eine Funktion zum Lesen analoger Werte vom MCP3008 auf einem angegebenen Kanal über SPI. Der zurückgegebene Wert ist eine 10-Bit-Zahl (0–1023).
.. code-block:: python
def read_adc(channel):
"""
Reads analog value from MCP3008 channel (0–7).
"""
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 eine Funktion zum Lesen der Temperatur vom Thermistor, der an MCP3008-Kanal 0 angeschlossen ist. Sie wandelt den ADC-Wert in Spannung um, berechnet den Widerstand und konvertiert ihn anschließend mithilfe der Steinhart-Hart-Approximation in Grad Celsius.
.. code-block:: python
def temperature():
"""
Reads and calculates the current temperature from the sensor.
Returns:
float: The current temperature in Celsius.
"""
analogVal = read_adc(0) # Assuming thermistor connected to CH0
Vr = 3.3 * analogVal / 1023.0 # For 3.3V system
Rt = 10000.0 * Vr / (3.3 - Vr)
temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
Cel = temp - 273.15
return Cel
#. Eine Funktion zur Steuerung der Motordrehzahl basierend auf ``level`` (0–4). Der Motor stoppt bei Stufe 0, und bei Stufen 1–4 wird die PWM-Geschwindigkeit proportional eingestellt (z. B. Stufe 2 entspricht 50 % Geschwindigkeit).
.. code-block:: python
def motor_run(level):
"""
Adjusts the motor speed based on the specified level.
Args:
level (int): Desired motor speed level.
Returns:
int: Adjusted motor speed level.
"""
if level == 0:
motor.stop()
return 0
if level >= 4:
level = 4
motor.forward(speed=float(level / 4))
return level
#. Definiert eine Ereignisfunktion für die Taste, die die Motordrehzahlstufe zyklisch von 0 bis 4 erhöht und die Referenztemperatur aktualisiert.
.. code-block:: python
def changeLevel():
"""
Changes the motor speed level when the button is pressed and updates the reference temperature.
"""
global level, currentTemp, markTemp
print("Button pressed")
level = (level + 1) % 5
markTemp = currentTemp
# Bind the button press event to changeLevel function
BtnPin.when_pressed = changeLevel
#. Die Hauptlogik liest kontinuierlich die Temperatur und vergleicht sie mit einem Referenzwert (``markTemp``). Wenn die Temperaturdifferenz ±2 °C beträgt, wird die Motordrehzahl entsprechend angepasst. Der Motor wird in jedem Zyklus aktualisiert, und eine kurze Verzögerung verhindert schnelle Umschaltungen.
.. code-block:: python
def main():
"""
Main function to continuously monitor and respond to temperature changes.
"""
global level, currentTemp, markTemp
markTemp = temperature()
while True:
currentTemp = temperature()
if level != 0:
if currentTemp - markTemp <= -2:
level -= 1
markTemp = currentTemp
elif currentTemp - markTemp >= 2:
if level < 4:
level += 1
markTemp = currentTemp
level = motor_run(level)
sleep(0.2)
#. Führt die Hauptfunktion in einem Try-Except-Block aus und stellt sicher, dass der Motor gestoppt und die SPI-Verbindung sauber geschlossen wird, wenn das Programm mit Ctrl+C unterbrochen wird.
.. code-block:: python
# Run the main function and handle KeyboardInterrupt
try:
main()
except KeyboardInterrupt:
motor.stop()
spi.close()