.. note:: Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauchen Sie tiefer in Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten ein. **Warum beitreten?** - **Expertenunterstützung**: Lösen Sie nach dem Kauf auftretende Probleme und technische Herausforderungen mit Hilfe unserer Community und unseres Teams. - **Lernen & Teilen**: Tauschen Sie Tipps und Tutorials aus, um Ihre Fähigkeiten zu verbessern. - **Exklusive Vorschauen**: Erhalten Sie frühzeitigen Zugriff auf neue Produktankündigungen und exklusive Einblicke. - **Sonderrabatte**: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte. - **Festliche Aktionen und Verlosungen**: Nehmen Sie an Verlosungen und Feiertagsaktionen teil. 👉 Bereit, mit uns zu forschen und zu kreieren? Klicken Sie auf [|link_sf_facebook|] und treten Sie noch heute bei! .. _4.1.11_py_pi5_mcp3008: 4.1.8 Batterieanzeige (MCP3008) ================================= .. note:: .. image:: ../img/mcp3008_and_adc0834.jpg :width: 25% :align: left Abhängig von Ihrer Kit-Version identifizieren Sie bitte, ob Sie **ADC0834** oder **MCP3008** haben, und fahren Sie mit dem entsprechenden Abschnitt fort. Einführung -------------- In diesem Projekt erstellen wir ein Batterieanzeigegerät, das den Batteriestand visuell auf der LED-Bargraph-Anzeige darstellen kann. .. warning:: Verwenden Sie keine Batteriekomponenten, die 3,3 V überschreiten, um eine Überlastung zu vermeiden, die den Chip oder den Raspberry Pi beschädigen könnte. Benötigte Komponenten ---------------------- In diesem Projekt benötigen wir die folgenden Komponenten: .. image:: ../python_pi5/img/list2_Battery_Indicator.png :align: center Es ist auf jeden Fall bequem, ein komplettes Kit zu kaufen, hier ist der Link: .. list-table:: :widths: 20 20 20 :header-rows: 1 * - Name - ELEMENTE IN DIESEM KIT - LINK * - Raphael Kit - 337 - |link_Raphael_kit| Sie können diese 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_bar_graph` - \- * - :ref:`cpn_mcp3008` - \- 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 GPIO25 Pin 22 6 25 GPIO12 Pin 32 26 12 GPIO16 Pin 36 27 16 GPIO20 Pin 38 28 20 GPIO21 Pin 40 29 21 GPIO5 Pin 29 21 5 GPIO6 Pin 31 22 6 GPIO13 Pin 33 23 13 GPIO19 Pin 35 24 19 GPIO26 Pin 37 25 26 ============ ======== ======== === .. image:: ../python_pi5/img/schematic_battery_indicator_mcp3008.png :align: center :width: 800 Experimentelle Verfahren ------------------------- **Schritt 1:** Bauen Sie die Schaltung auf. .. image:: ../python_pi5/img/july24_3.1.5_battery_indicator_mcp3008.png :width: 800 **Schritt 2:** Richten Sie die SPI-Schnittstelle ein und installieren Sie die ``spidev``-Bibliothek (siehe :ref:`spi_configuration` für detaillierte Anweisungen). Wenn Sie diese Schritte bereits abgeschlossen haben, können Sie diesen Schritt überspringen. **Schritt 3:** Wechseln Sie in den Ordner mit dem Code. .. raw:: html .. code-block:: cd ~/raphael-kit/python-pi5 **Schritt 4:** Führen Sie die ausführbare Datei aus. .. raw:: html .. code-block:: sudo python3 4.1.11-2_Battery_indicator_zero.py Nach dem Start des Programms schließen Sie das 3. Pin des MCP3008 und GND separat an die beiden Pole einer Batterie an. Sie können sehen, dass die entsprechenden LEDs auf dem LED-Bargraph aufleuchten, um den Ladezustand anzuzeigen (Messbereich: 0-5 V). .. warning:: Wenn die Fehlermeldung ``RuntimeError: Cannot determine SOC peripheral base address`` erscheint, lesen Sie bitte :ref:`faq_soc` Code ------ .. note:: Sie können den untenstehenden Code **Ändern/Zurücksetzen/Kopieren/Ausführen/Stoppen**. Vorher müssen Sie jedoch zum Quellcodepfad wie ``raphael-kit/python-pi5`` wechseln. Nach dem Ändern des Codes können Sie ihn direkt ausführen, um das Ergebnis 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 # Initialize joystick button, buzzer, and LED Joy_BtnPin = Button(22) # GPIO22, Pin15 buzzPin = Buzzer(23) # GPIO23, Pin16 ledPin = LED(24) # GPIO24, Pin18 # Set initial upper temperature threshold upperTem = 40 # Initialize SPI for MCP3008 (Bus 0, CE0 -> GPIO8 / Pin24) spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000 # 1 MHz # Initialize LCD (I2C address 0x27, backlight on) LCD1602.init(0x27, 1) def read_adc(channel): """ Read analog value from MCP3008 """ 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 # Voltage across the fixed resistor if Vr == 0: return 0 # Prevent division by zero Rt = 10000.0 * (3.3 - Vr) / 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) 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: buzzPin.on() ledPin.on() else: buzzPin.off() ledPin.off() # Main execution loop 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 ---------------- Dieses Python-Programm läuft auf einem Raspberry Pi. Es verwendet einen MCP3008 Analog-Digital-Wandler, um Temperaturdaten von einem analogen Sensor zu lesen. Ein Joystick wird verwendet, um den Temperaturschwellenwert anzupassen, und ein LCD1602-Display zeigt die aktuelle Temperatur und den Schwellenwert an. Ein Summer und eine LED werden ausgelöst, wenn die Temperatur den Schwellenwert überschreitet. 1. **Import der benötigten Bibliotheken** .. code-block:: python #!/usr/bin/env python3 import RPi.GPIO as GPIO import spidev import time import math import LCD1602 * ``RPi.GPIO`` is used for controlling GPIO pins. * ``spidev`` communicates with MCP3008 using SPI. * ``math`` is needed for temperature conversion calculations. * ``LCD1602`` controls the LCD display. Nutzt ``RPi.GPIO`` für GPIO-Steuerung, ``spidev`` für die Kommunikation mit dem MCP3008, ``math`` für Berechnungen und ``LCD1602`` für die LCD-Anzeige. 2. **GPIO-Setup** .. code-block:: python JOY_BTN_PIN = 22 BUZZER_PIN = 23 LED_PIN = 24 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) Initialisiert Pins für Joystick-Taste, Summer und LED mit Pull-up-Widerständen. 3. **SPI- und LCD-Initialisierung** .. code-block:: python upperTem = 40 # Default temperature threshold spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000 # 1 MHz LCD1602.init(0x27, 1) Stellt SPI-Kommunikation mit MCP3008 und LCD1602 über I²C bereit. 4. **ADC-Kanal 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 zum Auslesen von analogen Werten vom MCP3008 (0–7) und Rückgabe eines 10-Bit-Wertes (0–1023). 5. **Joystick-Eingaben** .. 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 Liest X- und Y-Richtung des Joysticks und gibt Änderungen des Schwellenwerts aus. 6. **Schwellenwert anpassen** .. 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) Ermöglicht das Anpassen des Temperaturschwellenwertes über den Joystick und zeigt den Wert auf dem LCD an. 7. **Temperaturberechnung** .. 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) Wandelt die Spannung in Widerstand um und berechnet die Temperatur mithilfe der Steinhart-Hart-Gleichung. 8. **Überwachungsmodus** .. 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) Zeigt aktuelle Temperatur und Schwellenwert an und aktiviert Summer und LED bei Überschreitung des Grenzwerts. 9. **Hauptschleife** .. 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() Schaltet zwischen Schwellenwertanpassung und Temperaturüberwachung um (über Joystick-Taste). 10. **Aufräumen beim Beenden** .. code-block:: python except KeyboardInterrupt: pass finally: LCD1602.clear() GPIO.cleanup() spi.close() Stellt sicher, dass GPIOs zurückgesetzt, das LCD gelöscht und SPI sauber geschlossen wird, wenn das Programm beendet wird (z. B. mit Strg+C).