.. 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.13_py_mcp3008:
4.1.13 Überhitzungsmonitor (MCP3008)
====================================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Abhängig von deiner Kit-Version überprüfe bitte, ob du **ADC0834** oder **MCP3008** hast, und fahre mit dem entsprechenden Abschnitt fort.
Einführung
----------
Vielleicht möchtest du ein Überhitzungsüberwachungsgerät entwickeln, das in verschiedenen Situationen einsetzbar ist, z. B. in der 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 zu erstellen, dessen Schwellenwert einstellbar ist.
Benötigte Komponenten
---------------------
Für dieses Projekt benötigen wir folgende Komponenten.
.. image:: ../img/list2_Overheat_Monitor.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 sie auch separat ü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_led`
- |link_led_buy|
* - :ref:`cpn_joystick`
- \-
* - :ref:`cpn_mcp3008`
- \-
* - :ref:`cpn_transistor`
- |link_transistor_buy|
* - :ref:`cpn_i2c_lcd`
- |link_i2clcd1602_buy|
* - :ref:`cpn_thermistor`
- |link_thermistor_buy|
* - :ref:`cpn_buzzer`
- \-
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
GPIO23 Pin 16 4 23
GPIO24 Pin 18 5 24
SDA1 Pin 3
SCL1 Pin 5
============ ======== ======== ===
.. image:: ../img/schematic_over_monitor_mcp3008.png
:align: center
Experimentelle Schritte
-----------------------
**Schritt 1:** Baue die Schaltung auf.
.. image:: ../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). Wenn du diese Schritte bereits abgeschlossen hast, kannst du diesen Schritt überspringen.
**Schritt 3:** Wechsle in den Code-Ordner.
.. raw:: html
.. code-block::
cd ~/raphael-kit/python
**Schritt 4:** Führe die ausführbare Datei aus.
.. raw:: html
.. code-block::
sudo python3 4.1.13-2_OverheatMonitor.py
Während der Code läuft, werden die aktuelle Temperatur und die Hochtemperaturschwelle **40 °C** auf dem **I2C LCD1602** angezeigt.
Wenn die aktuelle Temperatur die Schwelle überschreitet, werden Summer und LED aktiviert, um dich zu warnen.
Mit dem **Joystick** kannst du die Hochtemperaturschwelle anpassen.
Bewege den Joystick entlang der X- und Y-Achse, um die aktuelle Hochtemperaturschwelle zu erhöhen oder zu senken.
Durch Drücken des Joysticks wird die Schwelle auf den Anfangswert zurückgesetzt.
.. note::
* Wenn der Fehler ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'`` auftritt, aktiviere das I2C gemäß :ref:`i2c_config`.
* Wenn der Fehler ``ModuleNotFoundError: No module named 'smbus2'`` auftritt, führe ``sudo apt install python3-smbus2`` aus.
* Wenn der Fehler ``OSError: [Errno 121] Remote I/O error`` auftritt, ist das Modul falsch verdrahtet oder defekt.
* Wenn Code und Verdrahtung korrekt sind, das LCD aber nichts anzeigt, drehe das Potentiometer auf der Rückseite, um den Kontrast zu erhöhen.
.. warning::
Wenn die Fehlermeldung ``RuntimeError: Cannot determine SOC peripheral base address`` angezeigt wird, siehe :ref:`faq_soc`.
**Code**
--------
.. note::
Du kannst den untenstehenden Code **Bearbeiten/Zurücksetzen/Kopieren/Ausführen/Stoppen**.
Gehe vorher in das Quellcodeverzeichnis wie ``raphael-kit/python``.
Nach Änderungen kannst du den Code direkt ausführen, um den Effekt zu sehen.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
import math
import LCD1602
# GPIO pin definitions
JOY_BTN_PIN = 22 # Button pin
BUZZER_PIN = 23 # Buzzer pin
LED_PIN = 24 # LED pin
# Initialize GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(JOY_BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUZZER_PIN, GPIO.OUT)
GPIO.setup(LED_PIN, GPIO.OUT)
# Set initial upper temperature threshold
upperTem = 40
# Initialize SPI for MCP3008
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000 # 1 MHz
# Initialize LCD1602
LCD1602.init(0x27, 1)
def read_adc(channel):
"""
Read analog value from 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():
"""
Reads the joystick values and returns a change value based on the joystick's position.
"""
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():
"""
Adjusts and displays the upper temperature threshold on the LCD.
"""
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():
"""
Reads the current temperature from the sensor and returns it in Celsius.
"""
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0
if Vr == 0:
return 0
Rt = 10000.0 * (3.3 - Vr) / Vr
tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
Cel = tempK - 273.15
return round(Cel, 2)
def monitoring_temp():
"""
Monitors and displays the current temperature and upper temperature threshold.
Activates buzzer and LED if the temperature exceeds the upper limit.
"""
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:
GPIO.output(BUZZER_PIN, GPIO.HIGH)
GPIO.output(LED_PIN, GPIO.HIGH)
else:
GPIO.output(BUZZER_PIN, GPIO.LOW)
GPIO.output(LED_PIN, GPIO.LOW)
# Main loop
try:
lastState = GPIO.input(JOY_BTN_PIN)
stage = 0
while True:
currentState = GPIO.input(JOY_BTN_PIN)
if currentState == GPIO.HIGH and lastState == GPIO.LOW:
stage = (stage + 1) % 2
time.sleep(0.1)
LCD1602.clear()
lastState = currentState
if stage == 1:
upper_tem_setting()
else:
monitoring_temp()
except KeyboardInterrupt:
pass
finally:
LCD1602.clear()
GPIO.cleanup()
spi.close()
Code-Erklärung
--------------
1. **Bibliotheken importieren**
Lädt Bibliotheken für GPIO, SPI, LCD-Display, Zeitverzögerungen und mathematische Berechnungen.
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
import math
import LCD1602
2. **GPIO- und Geräte-Setup**
Definiert GPIO-Pins für Joystick-Taste, Summer und LED und konfiguriert die GPIO-Modi.
.. code-block:: python
JOY_BTN_PIN = 22 # Button pin
BUZZER_PIN = 23 # Buzzer pin
LED_PIN = 24 # LED pin
GPIO.setmode(GPIO.BCM)
GPIO.setup(JOY_BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUZZER_PIN, GPIO.OUT)
GPIO.setup(LED_PIN, GPIO.OUT)
3. **SPI- und LCD-Initialisierung**
Startet die SPI-Schnittstelle für MCP3008 und initialisiert das LCD1602 mit der I2C-Adresse 0x27.
.. code-block:: python
upperTem = 40
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
LCD1602.init(0x27, 1)
4. **ADC-Werte lesen**
Liest analoge Daten über den MCP3008-ADC ü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
5. **Joystick-Bewegungserkennung**
Erkennt X/Y-Achsenwerte und gibt Änderungen zur Anpassung des Schwellenwerts 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
6. **Einstellen des Temperaturschwellenwerts**
Zeigt „Upper Adjust“ auf dem LCD an und passt den Schwellenwert mit Joystick-Eingaben 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)
7. **Temperaturberechnung**
Wandelt den analogen Sensorausgang in Spannung, Widerstand und schließlich Temperatur (°C) um.
.. code-block:: python
def temperature():
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0
if Vr == 0:
return 0
Rt = 10000.0 * (3.3 - Vr) / Vr
tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
Cel = tempK - 273.15
return round(Cel, 2)
8. **Temperaturüberwachung**
Zeigt kontinuierlich Temperatur und Schwelle an und aktiviert Summer und LED, wenn die Temperatur ü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:
GPIO.output(BUZZER_PIN, GPIO.HIGH)
GPIO.output(LED_PIN, GPIO.HIGH)
else:
GPIO.output(BUZZER_PIN, GPIO.LOW)
GPIO.output(LED_PIN, GPIO.LOW)
9. **Hauptprogramm-Logik**
Wechselt zwischen Temperaturüberwachung und Schwellwert-Einstellmodus bei Joystick-Tastendruck.
.. code-block:: python
try:
lastState = GPIO.input(JOY_BTN_PIN)
stage = 0
while True:
currentState = GPIO.input(JOY_BTN_PIN)
if currentState == GPIO.HIGH and lastState == GPIO.LOW:
stage = (stage + 1) % 2
time.sleep(0.1)
LCD1602.clear()
lastState = currentState
if stage == 1:
upper_tem_setting()
else:
monitoring_temp()
10. **Aufräumen beim Beenden**
Stellt sicher, dass GPIO und SPI korrekt beendet werden, wenn ``Ctrl+C`` gedrückt wird.
.. code-block:: python
except KeyboardInterrupt:
pass
finally:
LCD1602.clear()
GPIO.cleanup()
spi.close()