Sensor Array ansprechen mit I2C - Unterschiede zu Mega2560 und Seeed RP2040

#7737267
Lesenswert?

Hallo zusammen.

ich bin ein absoluter Anfänger in der Welt des Raspberry Pis und bin auf ein Problem gestoßen und suche daher nach eurem Rat und Wissen.

In meinem Projekt habe ich eine Platine entworfen, auf der insgesamt 16 Magnetsensoren (MMC5633NJL) in einem Sensor Array zusammengefasst sind. Die Sensoren werden über I2C angesprochen, da aber jeder Sensor die gleiche I2C Adresse hat, müssen diese mit einem I2C Multiplexer (TCA9548) zwischengeschaltet werden. Dieser ist ein 1- 8 Kanal Multiplexer und hat pro Kanal 2 Anschlüsse für jeweils SDA und SCL.

Dazu habe ich jeweils PullUp Widerstände (2,7 kOhm oder 10 kOhm) zwischen Sensor und Multiplexer Kanal gesetzt. Da der Raspberry Pi 5 bereits integrierte PullUp Widerstände hat, habe ich keine zusätzlichen zwischen Multiplexer und Microcontroller platziert (beim RP2040 habe ich 10kOhm Widerstände auf einem Breadboard dazwischen platziert).

Letztendlich sind also die 2 Multiplexer mit den Adressen 0x70 und 0x71 direkt mit dem Raspberry Pi 5 verbunden, während die Sensoren mit den Multiplexern verbunden sind, um Adressenkonflikte zu vermeiden.

Mittlerweile habe ich es geschafft, die Sensoren über I2C mit dem Seeed RP2040 bzw. auch dem Arduino Mega 2560 zu erkennen und zu initialisieren. Diese geben auch Messwerte aus.

Der Code für den RP2040 sieht folgendermaßen aus:

1
import time
2
import board
3
import busio
4
from adafruit_mmc56x3 import MMC5603
5
from adafruit_bus_device.i2c_device import I2CDevice
6

7
'# Adressen der Multiplexer
8
TCAADDR1 = 0x70
9
TCAADDR2 = 0x71
10
'# Initialisiere I2C
11
i2c = busio.I2C(board.SCL, board.SDA)
12
'# Funktion zur Auswahl des Kanals am Multiplexer
13
def tcaselect(mux_address, channel):
14

15
if channel > 7:
16
return
17

18
with I2CDevice(i2c, mux_address) as mux:
19
mux.write(bytes([1 << channel]))
20
'# Überprüfen, ob die Multiplexer ansprechbar sind
21
print("Überprüfe Multiplexer...")
22
try:
23
with I2CDevice(i2c, TCAADDR1) as mux:
24
print("Multiplexer 1 (0x70) gefunden.")
25
except:
26
print("Multiplexer 1 (0x70) nicht gefunden.")
27
try:
28
with I2CDevice(i2c, TCAADDR2) as mux:
29
print("Multiplexer 2 (0x71) gefunden.")
30
except:
31
print("Multiplexer 2 (0x71) nicht gefunden.")
32
'# Initialisiere jeden Sensor an den entsprechenden Kanälen der Multiplexer
33
sensors = []
34
sensor_found = []
35
for i in range(16):
36
mux_address = TCAADDR1 if i < 8 else TCAADDR2
37
channel = i % 8
38
tcaselect(mux_address, channel)
39
print(f"Initialisiere Sensor auf MUX {1 if i < 8 else 2}, channel {channel}")
40

41
try:
42
sensor = MMC5603(i2c)
43
sensors.append(sensor)
44
sensor_found.append(True)
45
print(f"Sensor gefunden auf MUX {1 if i < 8 else 2}, channel {channel}")
46

47
except ValueError:
48
sensors.append(None)
49
sensor_found.append(False)
50
print(f"Keinen Sensor gefunden auf MUX {1 if i < 8 else 2}, channel {channel}")
51

52
'# Zeige Details für jeden gefundenen Sensor
53
for i in range(16):
54
if sensor_found[i]:
55
print(f"Sensor {i + 1}:")
56
print(sensors[i])
57
while True:
58
for i in range(16):
59
mux_address = TCAADDR1 if i < 8 else TCAADDR2
60
channel = i % 8
61
tcaselect(mux_address, channel)
62
print(f"Abfrage Sensor auf MUX {1 if i < 8 else 2}, channel {channel}")
63

64
if sensor_found[i]:
65
sensor = sensors[i]
66

67
mag_x, mag_y, mag_z = sensor.magnetic
68
temp_c = sensor.temperature
69

70
print(f"Sensor {i + 1}: X={mag_x} uT, Y={mag_y} uT, Z={mag_z} uT, Temp: {temp_c} *C")
71

72
else:
73
print(f"Sensor {i + 1}: X=0 uT, Y=0 uT, Z=0 uT, Temp: 0 *C")
74

75
print("****************************")
76
time.sleep(10)

Kurzfassung des Codes:

Zuerst prüft es, ob die Multiplexer erkannt werden und initialisiert diese. Danach prüft es pro Kanal, ob ein Sensor erkannt wird und initialisiert diese. Im letzten Schritt holt er sich die Messwerte der Sensoren durch Eventabfragen.

Nun zu meinem Problem:

Der Arduino Mega 2560 erkennt und initialisiert alle I2C Teilnehmer (den Code kann ich bei Bedarf gerne hochladen). Der Seeed Rp2040 läuft mit CircuitPython und erkennt auch alle I2C Teilnehmer. Beide holen sich auch Messwerte ab. Nur der Raspberry Pi 5, der genau den gleichen Code wie der RP2040 verwendet, erkennt nur die Multiplexer, aber nicht die Sensoren. Das Board hat sich nicht geändert und wurde auf allen 3 Mikrocontrollern verwendet.

Ich möchte den Raspberry Pi 5 verwenden, da ich mit ihm das Sensorarray initialisieren, messen, visualisieren und in einem gemeinsamen, kompakten Programm auswerten möchte.

Habt ihr Ideen, weshalb der Pi im Vergleich zum RP2040 nicht die Sensoren erkennt?

Vielen Dank im Voraus und beste Grüße

Datley

[Mod: Code in code-Tags eingefasst]

#7737293
Lesenswert?

Ich hab jetzt nicht dein Programm angeschaut, da mir das Scrollen zu doof ist. Bitte halte dich doch an die Forenregeln: Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang!

Und die Sprache der Elektronik ist ein anständiger! Schaltplan. Da gilt das gleiche: Bitte so zeichnen, damit man ohne scrollen etwas sieht!

#7738343
Lesenswert?

Genau, das hatte ich schon probiert. Leider wurde selbst beim Einstellen eines Channels vom MUX kein Sensor erkannt.

Ich habe mir jetzt auch noch einen Logic Analyzer bestellt, weil ich die Vermutung ebenfalls hatte.

Aber gibt es nicht bei I2C nur zwei verschiedene Taktfrequenzen (100kHz und 400kHz)? Beides hatte ich eingestellt beim Pi, aber ohne Erfolg.

Viele Grüße

Dat

(Firma: Gast) #7738362
Lesenswert?

Dat L. schrieb:

Aber gibt es nicht bei I2C nur zwei verschiedene Taktfrequenzen (100kHz und 400kHz)?

Nicht wirklich!

Am Rande: Alle deine genannten µC kommen mit Clockstretching klar. Dein RPI5 nicht unbedingt. Ihm hat eine recht eng bemessenen Timeout zwischen Byte und Clockstretching zwischen Bit mag ihm gar nicht. Ist das die Ursache deiner Probleme? KA!

Moderator (Firma: Titel) Persönliche Seite #7738377
Lesenswert?

Dat L. schrieb:

Aber gibt es nicht bei I2C nur zwei verschiedene Taktfrequenzen (100kHz und 400kHz)?

Das sind die maximal erreichbaren Frequenzen, wenn keines der I2C Devices den Takt verzögert.

Ich habe mir jetzt auch noch einen Logic Analyzer bestellt

Der zeichnet leider nur ein sehr binäres Bild seiner Signale. Und das muss nicht genau das Bild sein, das die Busteilnehmer sehen. Denn die haben garantiert andere Schaltschwellen als der LA. Deshalb sollte der erste Blick auf die Signale mit einem Oszilloskop erfolgen. Dann sieht man, ob das hübsche Rechtecksignale mit brauchbaren und stetigen Flanken sind. Wenn das der Fall ist, dann reicht für die weitere Analyse ein LA.

#7738403
Lesenswert?

Helmut -. schrieb:

Mir kommen R2B und R2D auf der 3V3-Seite etwas groß vor. Würde da auch 2k7 verwenden. Außerdem solltest du mal am RasPi auch Pullups verwenden. Vielleicht sind die doch nicht vorhanden?

Tatsächlich habe ich zwei Leiterplatten gebaut, einen mit 2k7 Pullups Widerständen und einmal mit 10k zwischen Sensor und MUX.

Ich hatte vorsichtshalber auch die beiden Leiterplatten mit Pullups über einem Breadboard zum RasPi5/ RP2040/ Arduino verbunden. Da waren ebenfalls die gleichen Ergebnisse. Dabei habe ich ebenfalls die Höhe/Größe der Pullups variiert.

RP2040 und Arduino konnten die Sensoren erfassen und deren Werte wiedergeben. Der RasPi5 konnte allerdings nur die Multiplexer erfassen. Das Skript mit der Channelabfragung habe ich auch abgespielt, jedoch ohne großen Erfolg.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren