.. 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! .. _4.1.10_py_mcp3008: 4.1.10 Intelligenter Ventilator (MCP3008) ============================================================ .. note:: .. image:: ../img/mcp3008_and_adc0834.jpg :width: 25% :align: left Je nach deiner Kit-Version überprüfe bitte, ob du **ADC0834** oder **MCP3008** hast, und fahre mit dem entsprechenden Abschnitt fort. Einführung ---------- In diesem Projekt verwenden wir Motoren, Taster und Thermistoren, um einen manuellen + automatischen intelligenten Ventilator zu bauen, dessen Windgeschwindigkeit einstellbar ist. Benötigte Komponenten --------------------- Für dieses Projekt benötigen wir die folgenden Komponenten. .. image:: ../img/list2_Smart_Fan.png :width: 800 :align: center 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 - ENTHALTENE ARTIKEL - LINK * - Raphael Kit - 337 - |link_Raphael_kit| Du kannst die 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:: ../img/schematic_3.1.4_smart_fan_mcp3008.png :align: center Experimentelle Schritte ----------------------- **Schritt 1:** Baue die Schaltung auf. .. image:: ../img/july24_3.1.4_smart_fan_mcp3008.png .. note:: Das Netzmodul kann mit einer 9V-Batterie und dem 9V-Batterieanschluss aus dem Kit betrieben werden. Stecke den Jumper des Netzmoduls in die 5V-Stromschienen des Breadboards. .. image:: ../img/image118.jpeg :align: center **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 Ordner mit dem Code. .. raw:: html .. code-block:: cd ~/raphael-kit/python **Schritt 4:** Führe den Code aus. .. raw:: html .. code-block:: sudo python3 4.1.10-2_SmartFan.py Während der Code läuft, starte den Ventilator, indem du den Knopf drückst. Bei jedem Drücken wird eine Geschwindigkeitsstufe hoch- oder runtergeschaltet. Es gibt **5** Geschwindigkeitsstufen: **0~4**. Wenn die 4. Stufe erreicht ist und der Knopf erneut gedrückt wird, stoppt der Ventilator bei Windstufe **0**. Sobald sich die Temperatur um mehr als 2 °C ändert, wird die Geschwindigkeit automatisch um eine Stufe erhöht oder verringert. Code ---- .. note:: Du kannst den untenstehenden Code **Bearbeiten/Zurücksetzen/Kopieren/Ausführen/Stoppen**. Wechsle vorher in den Quellcodepfad wie ``raphael-kit/python``. Nach dem Ändern 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 import math # Pin-Konfiguration BTN_PIN = 22 # Taster MOTOR_IN1 = 5 # Motor vorwärts MOTOR_IN2 = 6 # Motor rückwärts MOTOR_EN = 13 # PWM-Pin # GPIO einrichten GPIO.setmode(GPIO.BCM) GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(MOTOR_IN1, GPIO.OUT) GPIO.setup(MOTOR_IN2, GPIO.OUT) GPIO.setup(MOTOR_EN, GPIO.OUT) # PWM für Motorsteuerung pwm = GPIO.PWM(MOTOR_EN, 1000) # 1kHz pwm.start(0) # SPI initialisieren (MCP3008) spi = spidev.SpiDev() spi.open(0, 0) # Bus 0, CE0 spi.max_speed_hz = 1000000 # 1 MHz # Globale Variablen level = 0 currentTemp = 0 markTemp = 0 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 def temperature(): analogVal = read_adc(0) Vr = 3.3 * analogVal / 1023.0 Rt = 10000.0 * Vr / (3.3 - Vr) tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0))) Cel = tempK - 273.15 return Cel def motor_run(level): if level == 0: GPIO.output(MOTOR_IN1, GPIO.LOW) GPIO.output(MOTOR_IN2, GPIO.LOW) pwm.ChangeDutyCycle(0) return 0 if level >= 4: level = 4 GPIO.output(MOTOR_IN1, GPIO.HIGH) GPIO.output(MOTOR_IN2, GPIO.LOW) pwm.ChangeDutyCycle(level * 25) # 25%–100% return level def changeLevel(channel): global level, currentTemp, markTemp print("Button pressed") level = (level + 1) % 5 markTemp = currentTemp # Ereigniserkennung für Taster GPIO.add_event_detect(BTN_PIN, GPIO.FALLING, callback=changeLevel, bouncetime=300) 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) time.sleep(0.2) try: main() except KeyboardInterrupt: pass finally: pwm.stop() GPIO.cleanup() spi.close() Code-Erklärung -------------- #. Benötigte Module importieren: - ``RPi.GPIO`` für die Steuerung von GPIO (Taster und Motor), - ``spidev`` für die Kommunikation mit MCP3008, - ``time`` für Verzögerungen, - ``math`` für Temperaturberechnungen. .. code-block:: python import RPi.GPIO as GPIO import spidev import time import math #. GPIO-Pins einrichten: - Taster auf GPIO22 (interner Pull-Up), - Motorsteuerung über GPIO5 (vorwärts), GPIO6 (rückwärts) und GPIO13 (PWM). .. code-block:: python BTN_PIN = 22 MOTOR_IN1 = 5 MOTOR_IN2 = 6 MOTOR_EN = 13 GPIO.setmode(GPIO.BCM) GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(MOTOR_IN1, GPIO.OUT) GPIO.setup(MOTOR_IN2, GPIO.OUT) GPIO.setup(MOTOR_EN, GPIO.OUT) pwm = GPIO.PWM(MOTOR_EN, 1000) pwm.start(0) #. SPI-Kommunikation mit dem MCP3008 initialisieren (Bus 0, CE0) bei 1 MHz. .. code-block:: python spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000 #. Funktion ``read_adc()`` definiert, um einen 10-Bit-Analogwert (0–1023) vom angegebenen MCP3008-Kanal zu lesen. .. 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 ``temperature()``: - Analogspannung in Widerstand umrechnen, - Steinhart–Hart-Gleichung anwenden, um die Temperatur in °C zu berechnen. .. code-block:: python def temperature(): analogVal = read_adc(0) Vr = 3.3 * analogVal / 1023.0 Rt = 10000.0 * Vr / (3.3 - Vr) tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0))) Cel = tempK - 273.15 return Cel #. Funktion ``motor_run()``: - Motor bei Stufe 0 stoppen, - Motor vorwärts laufen lassen bei Stufe 1–4 mit PWM 25 % bis 100 %. .. code-block:: python def motor_run(level): if level == 0: GPIO.output(MOTOR_IN1, GPIO.LOW) GPIO.output(MOTOR_IN2, GPIO.LOW) pwm.ChangeDutyCycle(0) return 0 if level >= 4: level = 4 GPIO.output(MOTOR_IN1, GPIO.HIGH) GPIO.output(MOTOR_IN2, GPIO.LOW) pwm.ChangeDutyCycle(level * 25) return level #. ``changeLevel()``-Callback bei Tastendruck: - Motorstufe zyklisch erhöhen (0 bis 4), - aktuelle Temperatur als Referenz speichern. .. code-block:: python def changeLevel(channel): global level, currentTemp, markTemp print("Button pressed") level = (level + 1) % 5 markTemp = currentTemp GPIO.add_event_detect(BTN_PIN, GPIO.FALLING, callback=changeLevel, bouncetime=300) #. ``main()``-Schleife: - Temperaturänderung überwachen, - Bei -2 °C Stufe senken, bei +2 °C Stufe erhöhen, - Motorgeschwindigkeit entsprechend anpassen. .. 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) time.sleep(0.2) #. Hauptfunktion starten und bei Strg+C aufräumen (Motor stoppen, GPIO und SPI freigeben). .. code-block:: python try: main() except KeyboardInterrupt: pass finally: pwm.stop() GPIO.cleanup() spi.close()