Bemerkung

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

3.1.8 Überhitzungsmonitor (MCP3008)

Bemerkung

../_images/mcp3008_and_adc0834.jpg

Je nach Kit-Version bitte prüfen, ob ADC0834 oder MCP3008 enthalten ist, und mit dem entsprechenden Abschnitt fortfahren.

Einführung

Vielleicht möchtest du ein Überhitzungs-Überwachungsgerät bauen, das in verschiedenen Situationen eingesetzt werden kann – z. B. in einer Fabrik, um bei einer Überhitzung der Schaltung einen Alarm auszulösen und die Maschine rechtzeitig automatisch abzuschalten. In diesem Projekt verwenden wir einen Thermistor, einen Joystick, einen Summer, eine LED und ein LCD, um ein intelligentes Temperaturüberwachungsgerät mit einstellbarem Grenzwert zu bauen.

Benötigte Komponenten

In diesem Projekt benötigen wir die folgenden Komponenten:

../_images/list2_Overheat_Monitor1.png

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

Pin15

3

22

GPIO23

Pin16

4

23

GPIO24

Pin18

5

24

SDA1

Pin 3

SCL1

Pin 5

../_images/schematic_over_monitor_mcp3008.png

Experimentelle Schritte

Schritt 1: Baue die Schaltung auf.

../_images/july24_3.1.8_overheat_monitor_mcp30081.png

Schritt 2: Richte die SPI-Schnittstelle ein und installiere die spidev-Bibliothek (siehe SPI-Konfiguration für detaillierte Anweisungen). Falls diese Schritte bereits erledigt sind, kannst du sie überspringen.

Schritt 3: Wechsle in den Ordner mit dem Code.

cd ~/davinci-kit-for-raspberry-pi/python-pi5

Schritt 4: Führe die Programmdatei aus.

sudo python3 3.1.8-2_OverheatMonitor_zero.py

Während der Code läuft, werden die aktuelle Temperatur und der hohe Temperaturgrenzwert 40 auf dem I2C LCD1602 angezeigt. Wenn die aktuelle Temperatur höher als der Grenzwert ist, werden der Summer und die LED eingeschaltet, um dich zu warnen.

Der Joystick dient hier dazu, den hohen Temperaturgrenzwert einzustellen. Das Bewegen des Joysticks in X- oder Y-Richtung passt den Grenzwert nach oben oder unten an. Durch erneutes Drücken des Joysticks wird der Grenzwert auf den Anfangswert zurückgesetzt.

Bemerkung

  • Falls der Fehler FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1' auftritt, siehe I²C-Konfiguration, um I²C zu aktivieren.

  • Falls der Fehler ModuleNotFoundError: No module named 'smbus2' auftritt, führe sudo apt install python3-smbus2 aus.

  • Falls der Fehler OSError: [Errno 121] Remote I/O error auftritt, ist das Modul falsch verdrahtet oder defekt.

  • Falls Code und Verdrahtung korrekt sind, aber das LCD dennoch nichts anzeigt, kann der Potentiometer auf der Rückseite zur Erhöhung des Kontrasts gedreht werden.

Warnung

Falls die Fehlermeldung RuntimeError: Cannot determine SOC peripheral base address erscheint, siehe Wenn gpiozero nicht funktioniert.

Code

Bemerkung

Du kannst den folgenden Code Ändern/Zurücksetzen/Kopieren/Ausführen/Stoppen. Vorher musst du jedoch in das Quellcode-Verzeichnis wechseln (z. B. davinci-kit-for-raspberry-pi/python). Nach einer Änderung kannst du den Code direkt ausführen, um den Effekt zu sehen.

#!/usr/bin/env python3

import LCD1602
from gpiozero import LED, Buzzer, Button
import spidev
import time
import math

# Joystick-Taste, Summer und LED initialisieren
Joy_BtnPin = Button(22)  # GPIO22, Pin15
buzzPin = Buzzer(23)     # GPIO23, Pin16
ledPin = LED(24)         # GPIO24, Pin18

# Anfangswert für obere Temperaturgrenze
upperTem = 40

# SPI für MCP3008 initialisieren (Bus 0, CE0 -> GPIO8 / Pin24)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000  # 1 MHz

# LCD initialisieren (I2C-Adresse 0x27, Hintergrundbeleuchtung an)
LCD1602.init(0x27, 1)

def read_adc(channel):
    """
    Liest den analogen Wert vom MCP3008 (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 get_joystick_value():
    """
    Liest die Joystick-Werte und gibt eine Änderungszahl je nach Joystick-Position zurück.
    """
    x_val = read_adc(1)
    y_val = read_adc(2)
    if x_val > 800:
        return 1
    elif x_val < 200:
        return -1
    elif y_val > 800:
        return -10
    elif y_val < 200:
        return 10
    else:
        return 0

def upper_tem_setting():
    """
    Passt die obere Temperaturgrenze an und zeigt sie auf dem LCD an.
    """
    global upperTem
    LCD1602.write(0, 0, 'Upper Adjust: ')
    change = int(get_joystick_value())
    upperTem += change
    strUpperTem = str(upperTem)
    LCD1602.write(0, 1, strUpperTem)
    LCD1602.write(len(strUpperTem), 1, '              ')
    time.sleep(0.1)

def temperature():
    """
    Liest die aktuelle Temperatur vom Sensor und gibt sie in Celsius zurück.
    """
    analogVal = read_adc(0)
    Vr = 3.3 * analogVal / 1023.0  # Spannung über dem Festwiderstand
    if Vr == 0:
        return 0  # Division durch Null vermeiden
    Rt = 10000.0 * Vr / (3.3 - Vr)  # Angepasste Formel
    temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
    Cel = temp - 273.15
    return round(Cel, 2)

def monitoring_temp():
    """
    Überwacht und zeigt die aktuelle Temperatur und die obere Temperaturgrenze an.
    Aktiviert Summer und LED, wenn die Temperatur die Obergrenze überschreitet.
    """
    global upperTem
    Cel = temperature()
    LCD1602.write(0, 0, 'Temp: ')
    LCD1602.write(0, 1, 'Upper: ')
    LCD1602.write(6, 0, str(Cel))
    LCD1602.write(7, 1, str(upperTem))
    time.sleep(0.1)
    if Cel >= upperTem:
        buzzPin.on()
        ledPin.on()
    else:
        buzzPin.off()
        ledPin.off()

# Hauptprogrammschleife
try:
    lastState = 1
    stage = 0
    while True:
        currentState = Joy_BtnPin.value
        if currentState == 1 and lastState == 0:
            stage = (stage + 1) % 2
            time.sleep(0.1)
            LCD1602.clear()
        lastState = currentState
        if stage == 1:
            upper_tem_setting()
        else:
            monitoring_temp()
except KeyboardInterrupt:
    LCD1602.clear()
    spi.close()

Code-Erklärung

  1. Importiert die benötigten Bibliotheken. LCD1602 für das LCD-Display über I²C, gpiozero für LED, Summer und Taste, spidev für die Kommunikation mit dem MCP3008, sowie time und math für Verzögerungen und Temperaturberechnungen.

    #!/usr/bin/env python3
    
    import LCD1602
    from gpiozero import LED, Buzzer, Button
    import spidev
    import time
    import math
    
  2. Initialisiert die Hardwarekomponenten:

    • Button(22) für die Joystick-Taste

    • Buzzer(23) und LED(24) als Ausgabesignale für hohe Temperatur

    Joy_BtnPin = Button(22)  # GPIO22, Pin15
    buzzPin = Buzzer(23)     # GPIO23, Pin16
    ledPin = LED(24)         # GPIO24, Pin18
    
  3. Setzt den Standard-Grenzwert für die obere Temperatur und initialisiert SPI sowie LCD1602.

    upperTem = 40
    
    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1000000
    
    LCD1602.init(0x27, 1)
    
  4. read_adc(channel) liest den analogen Wert (0–1023) vom MCP3008-Kanal.

    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. get_joystick_value() wertet die Joystick-Position (Kanäle 1 und 2) aus und gibt je nach Richtung Anpassungswerte zurück.

    def get_joystick_value():
        x_val = read_adc(1)
        y_val = read_adc(2)
        if x_val > 800:
            return 1
        elif x_val < 200:
            return -1
        elif y_val > 800:
            return -10
        elif y_val < 200:
            return 10
        else:
            return 0
    
  6. upper_tem_setting() passt den oberen Temperaturgrenzwert an und zeigt ihn auf dem LCD an.

    def upper_tem_setting():
        global upperTem
        LCD1602.write(0, 0, 'Upper Adjust: ')
        change = int(get_joystick_value())
        upperTem += change
        strUpperTem = str(upperTem)
        LCD1602.write(0, 1, strUpperTem)
        LCD1602.write(len(strUpperTem), 1, '              ')
        time.sleep(0.1)
    
  7. temperature() berechnet die Temperatur in °C anhand der Steinhart–Hart-Approximation.

    def temperature():
       """
       Reads the current temperature from the sensor and returns it in Celsius.
       """
       analogVal = read_adc(0)
       Vr = 3.3 * analogVal / 1023.0  # Voltage across the fixed resistor
       if Vr == 0:
             return 0  # Prevent division by zero
       Rt = 10000.0 * Vr / (3.3 - Vr)  # Adjusted formula: thermistor voltage is (3.3 - Vr)
       temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
       Cel = temp - 273.15
       return round(Cel, 2)
    
  8. monitoring_temp() überwacht die Temperatur, vergleicht sie mit dem Grenzwert, zeigt beide Werte an und schaltet Summer/LED ein, wenn der Grenzwert überschritten wird.

    def monitoring_temp():
        global upperTem
        Cel = temperature()
        LCD1602.write(0, 0, 'Temp: ')
        LCD1602.write(0, 1, 'Upper: ')
        LCD1602.write(6, 0, str(Cel))
        LCD1602.write(7, 1, str(upperTem))
        time.sleep(0.1)
        if Cel >= upperTem:
            buzzPin.on()
            ledPin.on()
        else:
            buzzPin.off()
            ledPin.off()
    
  9. Die Hauptschleife schaltet mit der Joystick-Taste zwischen Einstell- und Überwachungsmodus um.

    try:
        lastState = 1
        stage = 0
        while True:
            currentState = Joy_BtnPin.value
            if currentState == 1 and lastState == 0:
                stage = (stage + 1) % 2
                time.sleep(0.1)
                LCD1602.clear()
            lastState = currentState
            if stage == 1:
                upper_tem_setting()
            else:
                monitoring_temp()
    
  10. Bei Programmende werden LCD geleert und SPI-Verbindung geschlossen.

    except KeyboardInterrupt:
        LCD1602.clear()
        spi.close()