Bemerkung

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 [hier] und tritt noch heute bei!

4.1.10 Intelligenter Ventilator (MCP3008)

Bemerkung

../_images/mcp3008_and_adc0834.jpg

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.

../_images/list2_Smart_Fan.png

Es ist auf jeden Fall praktisch, ein komplettes Kit zu kaufen. Hier ist der Link:

Name

ENTHALTENE ARTIKEL

LINK

Raphael Kit

337

Raphael Kit

Du kannst die Komponenten auch einzeln über die folgenden Links kaufen.

KOMPONENTENBESCHREIBUNG

KAUFLINK

GPIO Extension Board

KAUFEN

Steckbrett

KAUFEN

Jumper-Kabel

KAUFEN

Widerstand

KAUFEN

Stromversorgungsmodul

-

Thermistor

KAUFEN

L293D

-

MCP3008

-

Taste

KAUFEN

Gleichstrommotor

KAUFEN

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

../_images/schematic_3.1.4_smart_fan_mcp3008.png

Experimentelle Schritte

Schritt 1: Baue die Schaltung auf.

../_images/july24_3.1.4_smart_fan_mcp3008.png

Bemerkung

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.

../_images/image118.jpeg

Schritt 2: Richte die SPI-Schnittstelle ein und installiere die spidev-Bibliothek (siehe SPI-Konfiguration 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.

cd ~/raphael-kit/python

Schritt 4: Führe den Code aus.

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

Bemerkung

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.

#!/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

  1. 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.

    import RPi.GPIO as GPIO
    import spidev
    import time
    import math
    
  2. GPIO-Pins einrichten:

    • Taster auf GPIO22 (interner Pull-Up),

    • Motorsteuerung über GPIO5 (vorwärts), GPIO6 (rückwärts) und GPIO13 (PWM).

    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)
    
  3. SPI-Kommunikation mit dem MCP3008 initialisieren (Bus 0, CE0) bei 1 MHz.

    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1000000
    
  4. Funktion read_adc() definiert, um einen 10-Bit-Analogwert (0–1023) vom angegebenen MCP3008-Kanal zu lesen.

    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
    
  5. Funktion temperature():

    • Analogspannung in Widerstand umrechnen,

    • Steinhart–Hart-Gleichung anwenden, um die Temperatur in °C zu berechnen.

    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
    
  6. Funktion motor_run():

    • Motor bei Stufe 0 stoppen,

    • Motor vorwärts laufen lassen bei Stufe 1–4 mit PWM 25 % bis 100 %.

    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
    
  7. changeLevel()-Callback bei Tastendruck:

    • Motorstufe zyklisch erhöhen (0 bis 4),

    • aktuelle Temperatur als Referenz speichern.

    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)
    
  8. main()-Schleife:

    • Temperaturänderung überwachen,

    • Bei -2 °C Stufe senken, bei +2 °C Stufe erhöhen,

    • Motorgeschwindigkeit entsprechend anpassen.

    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)
    
  9. Hauptfunktion starten und bei Strg+C aufräumen (Motor stoppen, GPIO und SPI freigeben).

    try:
        main()
    except KeyboardInterrupt:
        pass
    finally:
        pwm.stop()
        GPIO.cleanup()
        spi.close()