.. note::
Hallo und 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 Verlosungen**: Nimm an Verlosungen und Feiertagsaktionen teil.
👉 Bereit, mit uns zu entdecken und zu erschaffen? Klicke auf [|link_sf_facebook|] und tritt noch heute bei!
.. _3.1.4_py_pi5_mcp3008:
3.1.4 Intelligenter Ventilator (MCP3008)
========================================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Je nach Kit-Version bitte prüfen, ob **ADC0834** oder **MCP3008** enthalten ist, und mit dem entsprechenden Abschnitt fortfahren.
Einführung
----------
In diesem Projekt werden wir Motoren, Tasten und Thermistoren verwenden,
um einen manuellen + automatischen intelligenten Ventilator mit einstellbarer Windgeschwindigkeit zu bauen.
Benötigte Komponenten
----------------------
In diesem Projekt benötigen wir die folgenden Komponenten.
.. image:: ../python_pi5/img/list2_Smart_Fan.png
:width: 800
:align: center
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 Schritte
------------------------
**Schritt 1:** Baue die Schaltung auf.
.. image:: ../python_pi5/img/july24_3.1.4_smart_fan_mcp3008.png
:width: 800
.. note::
Das Strommodul kann mit einer 9V-Batterie und dem im Kit enthaltenen 9V-Batterieclip betrieben werden.
.. image:: ../python_pi5/img/4.1.10_smart_fan_battery.jpeg
:align: center
**Schritt 2:** Richte die SPI-Schnittstelle ein und installiere die ``spidev``-Bibliothek (siehe :ref:`spi_configuration` für detaillierte Anweisungen). Falls diese Schritte bereits erledigt sind, kannst du sie überspringen.
**Schritt 3:** Wechsle in den Ordner mit dem Code.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/python-pi5
**Schritt 4:** Ausführen.
.. raw:: html
.. code-block::
sudo python3 3.1.4-2_SmartFan_zero.py
Wenn der Code läuft, starte den Ventilator durch Drücken der Taste.
Jedes Mal, wenn du drückst, wird die Geschwindigkeit um eine Stufe erhöht oder verringert.
Es gibt **5** Geschwindigkeitsstufen: **0~4**.
Wenn die 4\ :sup:`te` Stufe eingestellt ist und du erneut drückst, stoppt der Ventilator mit einer Windgeschwindigkeit von **0**.
Sobald die Temperatur um mehr als 2℃ steigt oder fällt, erhöht oder verringert sich die Geschwindigkeit automatisch um eine Stufe.
Code
----
.. note::
Du kannst den folgenden Code **Ändern/Zurücksetzen/Kopieren/Ausführen/Stoppen**.
Vorher musst du jedoch in das Quellcode-Verzeichnis (z. B. ``davinci-kit-for-raspberry-pi/python-pi5``) wechseln.
Nach einer Änderung kannst du den Code direkt ausführen, um den Effekt zu sehen.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import Motor, Button
from time import sleep
import spidev
import math
# SPI für MCP3008 initialisieren
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0 (GPIO8 / physikalischer Pin 24)
spi.max_speed_hz = 1000000 # 1 MHz
# GPIO-Pins für Taste und Motorsteuerung initialisieren
BtnPin = Button(22) # GPIO22 (physikalischer Pin 15)
motor = Motor(forward=5, backward=6, enable=13) # GPIO5, GPIO6, GPIO13
# Variablen für Geschwindigkeitsstufe 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: Aktuelle Temperatur in Celsius.
"""
analogVal = read_adc(0) # Thermistor an CH0
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):
"""
Stellt die Motorgeschwindigkeit basierend auf der angegebenen Stufe ein.
Argumente:
level (int): Gewünschte Motorgeschwindigkeitsstufe.
Rückgabe:
int: Angepasste Motorgeschwindigkeitsstufe.
"""
if level == 0:
motor.stop()
return 0
if level >= 4:
level = 4
motor.forward(speed=float(level / 4))
return level
def changeLevel():
"""
Ändert die Motorgeschwindigkeitsstufe bei Tastendruck und aktualisiert die Referenztemperatur.
"""
global level, currentTemp, markTemp
print("Taste gedrückt")
level = (level + 1) % 5
markTemp = currentTemp
# Taste mit changeLevel-Funktion verknüpfen
BtnPin.when_pressed = changeLevel
def main():
"""
Hauptfunktion zur kontinuierlichen Temperaturüberwachung und Anpassung der Motorgeschwindigkeit.
"""
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)
# Hauptfunktion ausführen und bei Tastenkombination Strg+C sauber beenden
try:
main()
except KeyboardInterrupt:
motor.stop()
spi.close()
Code-Erklärung
--------------
#. Importiert Bibliotheken zur Steuerung von Motor und Taste, für die SPI-Kommunikation mit MCP3008 sowie mathematische Berechnungen.
``gpiozero`` steuert die GPIO-Geräte, ``spidev`` die SPI-Kommunikation mit dem MCP3008-ADC, und ``math`` wird für Temperaturberechnungen aus Widerstandswerten verwendet.
.. code-block:: python
from gpiozero import Motor, Button
from time import sleep
import spidev
import math
#. Initialisiert die SPI-Kommunikation auf Bus 0, Gerät 0 (CE0) für den MCP3008-ADC.
.. code-block:: python
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
#. Richtet GPIO-Pin 22 als Taste ein und konfiguriert den Motor mit GPIO5 (vorwärts), GPIO6 (rückwärts) und GPIO13 (Enable).
Legt außerdem Variablen zur Verfolgung der Geschwindigkeitsstufe und Temperatur fest.
.. code-block:: python
BtnPin = Button(22)
motor = Motor(forward=5, backward=6, enable=13)
level = 0
currentTemp = 0
markTemp = 0
#. Funktion zum Auslesen eines analogen Wertes (0–1023) vom MCP3008 über SPI.
.. 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
#. Funktion zum Messen der Temperatur über den Thermistor an CH0.
Wandelt den ADC-Wert in Spannung um, berechnet den Widerstand und dann die Temperatur in °C (Steinhart-Hart).
.. code-block:: python
def temperature():
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0
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
#. Funktion zur Einstellung der Motorgeschwindigkeit basierend auf ``level`` (0–4).
Bei 0 stoppt der Motor, bei 1–4 wird die PWM-Geschwindigkeit proportional gesetzt.
.. code-block:: python
def motor_run(level):
if level == 0:
motor.stop()
return 0
if level >= 4:
level = 4
motor.forward(speed=float(level / 4))
return level
#. Event-Handler für Tastendruck: erhöht die Geschwindigkeitsstufe zyklisch von 0 bis 4 und aktualisiert die Referenztemperatur.
.. code-block:: python
def changeLevel():
global level, currentTemp, markTemp
level = (level + 1) % 5
markTemp = currentTemp
BtnPin.when_pressed = changeLevel
#. Hauptschleife: überwacht kontinuierlich die Temperatur.
Bei ±2°C Abweichung zur Referenz wird die Geschwindigkeitsstufe automatisch angepasst.
.. code-block:: python
def main():
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 aus und beendet Motor & SPI sauber bei Strg+C.
.. code-block:: python
try:
main()
except KeyboardInterrupt:
motor.stop()
spi.close()