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