Hallo
Betreibe einen PCF8591 mit 4 analogen Eingängen von 0-5V, Dazu verwende ich diese Bibliothek,
Python
import utime
from machine import I2C, Pin
class PCF8591:
# Kanalbezeichner
AIN0 = 0b00000000
AIN1 = 0b00000001
AIN2 = 0b00000010
AIN3 = 0b00000011
# Auto-Inkrement-Modus (wird in diesem Fall nicht verwendet)
AUTOINCREMENT_READ = 0b00000100
# Eingabemodus
SINGLE_ENDED_INPUT = 0b00000000
def __init__(self, i2c, address=0x48):
"""
Initialisiert den PCF8591 ADC mit dem angegebenen I2C-Bus und der Adresse.
:param i2c: I2C-Objekt für die Kommunikation
:param address: Die I2C-Adresse des PCF8591 (Standard ist 0x48)
"""
self._i2c = i2c
self._address = address
def begin(self):
"""Überprüft, ob der PCF8591 über I2C erreichbar ist."""
if self._i2c.scan().count(self._address) == 0:
return False
else:
return True
def analog_read(self, channel):
"""Liest den digitalen Wert eines einzelnen Kanals des PCF8591.
:param channel: Der Kanal, der abgerufen werden soll (0 bis 3)
:return: Der digitale Wert des Kanals (0 bis 255)
"""
# Setzt den Lese-Befehl entsprechend des Kanals
if channel == 0:
operation = self.AIN0
elif channel == 1:
operation = self.AIN1
elif channel == 2:
operation = self.AIN2
elif channel == 3:
operation = self.AIN3
else:
raise ValueError("Ungültiger Kanal. Es können nur Kanäle 0 bis 3 verwendet werden.")
# Sende Lese-Befehl an den PCF8591
self._i2c.writeto(self._address, bytearray([operation]))
# Kleine Verzögerung für Stabilität
utime.sleep_ms(1)
# Lese den Wert vom Kanal
data = self._i2c.readfrom(self._address, 1)
return data[0]
def convert_to_voltage(self, digital_value, vcc=5.0):
"""Konvertiert den digitalen Wert (0 bis 255) in eine Spannung.
:param digital_value: Der digitale Wert (0 bis 255)
:param vcc: Die Referenzspannung (Standard ist 5V)
:return: Die berechnete Spannung
"""
return (digital_value / 255) * vcc
Display More
Und das verwendete Programm dazu:
Python
from machine import I2C, Pin
import utime
# Adresse und I2C-Bus-Initialisierung
I2C_ADDR = 0x48 # Adresse des PCF8591
i2c = I2C(0, scl=Pin(21), sda=Pin(20))
# Funktion zum Lesen eines analogen Wertes
def analog_read(channel):
# Kanal ansteuern (0-3)
cmd = 0x40 | (channel & 0x03)
i2c.writeto(I2C_ADDR, bytes([cmd])) # Befehl senden
utime.sleep_ms(10) # Kleine Verzögerung
data = i2c.readfrom(I2C_ADDR, 1) # Daten lesen
return data[0]
# Umrechnung des digitalen Wertes in Spannung (für Vcc = 5V)
def digital_to_voltage(digitale_zahl, vcc=5.0):
return (digitale_zahl / 255.0) * vcc
# Werte von allen Kanälen lesen
ain0 = analog_read(0) #0
ain1 = analog_read(1) #1
ain2 = analog_read(2) #2
ain3 = analog_read(3) #3
# Spannung anzeigen
print("AIN0 Spannung: {:.2f} V".format(digital_to_voltage(ain0)))
print("AIN1 Spannung: {:.2f} V".format(digital_to_voltage(ain1)))
print("AIN2 Spannung: {:.2f} V".format(digital_to_voltage(ain2)))
print("AIN3 Spannung: {:.2f} V".format(digital_to_voltage(ain3)))
Display More
Das Programm funktioniert ohne jeglichen Fehler, Beim testen ist mir aufgefallen das die Ausgabe der Werte versetzt ist. AIN0 wird als AIN1 angezeigt und so weiter. Habe es mit dem DB verglichen, scheint alles zu stimmen. Habe ich was übersehen?