.. 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.8_py_pi5_mcp3008: 3.1.8 Überhitzungsmonitor (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 ---------- 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: .. image:: ../python_pi5/img/list2_Overheat_Monitor.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 Pin15 3 22 GPIO23 Pin16 4 23 GPIO24 Pin18 5 24 SDA1 Pin 3 SCL1 Pin 5 ============ ======== ======== === .. image:: ../python_pi5/img/schematic_over_monitor_mcp3008.png :align: center Experimentelle Schritte ----------------------- **Schritt 1:** Baue die Schaltung auf. .. image:: ../python_pi5/img/july24_3.1.8_overheat_monitor_mcp3008.png **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:** Führe die Programmdatei aus. .. raw:: html .. code-block:: 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. .. note:: * Falls der Fehler ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'`` auftritt, siehe :ref:`i2c_config`, 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. .. warning:: Falls die Fehlermeldung ``RuntimeError: Cannot determine SOC peripheral base address`` erscheint, siehe :ref:`faq_soc` **Code** .. note:: 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. .. raw:: html .. code-block:: python #!/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 -------------- #. 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. .. code-block:: python #!/usr/bin/env python3 import LCD1602 from gpiozero import LED, Buzzer, Button import spidev import time import math #. Initialisiert die Hardwarekomponenten: * ``Button(22)`` für die Joystick-Taste * ``Buzzer(23)`` und ``LED(24)`` als Ausgabesignale für hohe Temperatur .. code-block:: python Joy_BtnPin = Button(22) # GPIO22, Pin15 buzzPin = Buzzer(23) # GPIO23, Pin16 ledPin = LED(24) # GPIO24, Pin18 #. Setzt den Standard-Grenzwert für die obere Temperatur und initialisiert SPI sowie LCD1602. .. code-block:: python upperTem = 40 spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000 LCD1602.init(0x27, 1) #. ``read_adc(channel)`` liest den analogen Wert (0–1023) vom MCP3008-Kanal. .. 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 #. ``get_joystick_value()`` wertet die Joystick-Position (Kanäle 1 und 2) aus und gibt je nach Richtung Anpassungswerte zurück. .. code-block:: python 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 #. ``upper_tem_setting()`` passt den oberen Temperaturgrenzwert an und zeigt ihn auf dem LCD an. .. code-block:: python 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) #. ``temperature()`` berechnet die Temperatur in °C anhand der Steinhart–Hart-Approximation. .. code-block:: python 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) #. ``monitoring_temp()`` überwacht die Temperatur, vergleicht sie mit dem Grenzwert, zeigt beide Werte an und schaltet Summer/LED ein, wenn der Grenzwert überschritten wird. .. code-block:: python 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() #. Die Hauptschleife schaltet mit der Joystick-Taste zwischen Einstell- und Überwachungsmodus um. .. code-block:: python 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() #. Bei Programmende werden LCD geleert und SPI-Verbindung geschlossen. .. code-block:: python except KeyboardInterrupt: LCD1602.clear() spi.close()