Hallo
versuche mit dem I2C Bus von einem Master auf einen Slave zuzugreiffen. Ist ja eigentlich (sollte) kein Problem mit AVR und C. Wie ist das aber bei Python? Wenn ich die beschreibung im Netz richtig verstanden habe, ist die Lib zum I2C nur als Master nutzbar. Habe aber auch das gefunden:
from machine import Pin
import utime
class SoftwareI2CSlave:
def __init__(self, scl_pin, sda_pin, address):
# Initialisieren der Pins für SCL und SDA
self.scl = Pin(scl_pin, Pin.IN, Pin.PULL_UP)
self.sda = Pin(sda_pin, Pin.IN, Pin.PULL_UP)
self.address = address
self.buffer = bytearray() # Buffer für empfangene Daten
self.state = "IDLE" # Zustand des Slaves (IDLE, RECEIVING, etc.)
self.listen()
def listen(self):
print(f"I2C-Slave auf Adresse {hex(self.address)} gestartet...")
while True:
if self.detect_start():
self.handle_transaction()
def detect_start(self):
"""Start-Bedingung detektieren (SDA von HIGH auf LOW, während SCL HIGH bleibt)"""
if not self.sda.value() and self.scl.value():
utime.sleep_us(10) # Kurz warten, um Stabilität zu gewährleisten
if not self.sda.value() and self.scl.value(): # Startbedingung erkannt
print("Start-Bedingung erkannt")
return True
return False
def handle_transaction(self):
"""Verarbeitung einer I2C-Transaktion: Empfang von Daten"""
self.buffer = bytearray()
bit_count = 0 # Zähler für die Bits im Byte
# Leseadressen und Daten bis zum Stop-Bit
while True:
# Warten auf den SCL High-Zustand
while self.scl.value() == 0:
pass # SCL ist Low, warten bis es High wird
# Lese SDA-Wert, wenn SCL High ist (Datenbit)
bit = self.sda.value()
self.buffer.append(bit)
bit_count += 1
utime.sleep_us(10)
# Wenn 8 Bits gesammelt wurden, in ein Byte umwandeln
if bit_count == 8:
byte_data = 0
for i in range(8):
byte_data |= (self.buffer[i] << (7 - i))
print(f"Empfangenes Byte: {hex(byte_data)}")
# Zurücksetzen für das nächste Byte
self.buffer = []
bit_count = 0
# Warten bis SCL Low wird
while self.scl.value() == 1:
pass # SCL ist High, warten bis es Low wird
# Stop-Bedingung: SDA geht von Low auf High, während SCL High bleibt
if self.sda.value() and self.scl.value():
print(f"Ende der Transaktion. Empfangene Daten: {self.buffer}")
break
# Konfiguration für den Slave (RP2040 Zero)
SCL_PIN = 1 # SCL-Pin
SDA_PIN = 0 # SDA-Pin
SLAVE_ADDR = 0x42 # Slave-Adresse
# Starten des I2C-Slaves
slave = SoftwareI2CSlave(scl_pin=SCL_PIN, sda_pin=SDA_PIN, address=SLAVE_ADDR)
Display More
Habe den Zero als Slave genommen und dabei die Adresse 42 und SCL-1 und SDA-0. Geht aus der Pinbelegung des Zero hervor. Die Software ahbe ich als main.py auf dem Zero gespeichert und müsste damit beim einschalten automatisch anlaufen. Wenn ich vom Zero einen Bus Scanner laufen lasse werden mir alle angeschlossenen Slave korrekt angezeigt. Umgekehrt, wenn ich vom Pico einen Scanner laufen lasse wird zwar alle angeschlossenen Slave angezeigt aber der Zero nicht.
Hsat jemand eine Idee waran das liegen könnte?