I2C Adresse nicht gefunden

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo zusammen

    Ich lese einen Distanz Sensor VL53L1X über den I2C Bus aus.
    Initialisiert wird dieser mit der Adresse 0X29, diese wird auch mit dem dem Befehl "i2cdetect -y 1" angezeigt.
    Initialisiert wird die Schnittstelle mit "tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_adress=0X29 "

    Das auslesen des Sensors funktioniert bestens, aber leider nur beim ersten Mal.
    Rufe ich das Programm ein weiteres mal auf, kommt die Meldung, dass die Adresse nicht gefunden wird.
    Starte ich nun den Befehl "i2cdetect -y 1" wird auch keine Adresse mehr angezeigt.

    Die lese Funktionen habe ich in einem separaten Modul ausgelagert.
    Das Hauptprogramm Programm importiert dieses Modul.

    Muss ich die Schnittstelle im Hauptprogramm auch noch initialisieren oder
    nur im Hauptprogramm initialisieren oder mache ich generell etwas falsch?

    Gruss
    Thomas


  • Hier der Code

    Modul


    Testprogramm

  • Post by hyle (October 21, 2024 at 9:58 AM).

    This post was deleted by the author themselves (October 21, 2024 at 9:59 AM).
  • Hellstern Das Programm hinterlässt den Sensor also in einem Zustand in dem er nicht mehr auf dem I²C-Bus antwortet.

    Ich würde das als erstes mal in ein Modul zusammenfassen. Die Trennung macht hier nicht wirklich Sinn.

    Da sind zu viele Kommentare drin, die dem Leser keinen Mehrwert bringen. # Benötigte importe — wenn etwas importiert wird, dann wird das auch benötigt, sonst würde man es ja nicht importieren. Man sollte auch nichts kommentieren was man in der Dokumentation von Sprache oder Bibliothek nachlesen kann. Faustregel: Nicht kommentieren was der Code macht, denn das steht da ja bereits als Code, sondern warum er das so macht, sofern das nicht offensichtlich ist.

    Oft kann man Kommentare auch einsparen wenn man sinnvolle Namen wählt. Beispielsweise statt dem nichtssagenden number besser xshut_pin, dann muss man nicht Kommentieren, dass es sich dabei im die Pin-Nummer des XSHUT-Pins handelt. Oder auch überhaupt Namen statt magischer Werte, also statt 1 besser VL53L1xDistanceMode.SHORT, dann muss man nicht raten oder nachlesen wofür die 1 wohl stehen mag.

    Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die main() heisst. Funktionen und Methoden bekommen alles was sie ausser Konstanten benötigen, als Argument(e) übergeben.

    Statt Warnungen zu ignorieren/abzuschalten, sollte man deren Ursache beheben. In der Regel fehlt dann ein Aufruf von GPIO.cleanup() der garantiert vor dem Programmende ausgeführt wird. Zum Beispiel weil er in einem finally:-Zweig steht.

    Das Aufsetzen der GPIO-Pins sollte nur einmal passieren und nicht jedes mal wenn man etwas auf dem Pin ausgeben will. Und auch open() und close() beim VL53L1X-Objekt sollte nur einmal passieren, am Programmanfang und am Programmende. Auch hier gerne wieder mit Massnahmen um das schliessen sicherzustellen, egal wie das Programm beendet wird. Also beispielsweise mit der with-Anweisung und contextlib.closing().

    Programmieren durch kopieren, einfügen, und leicht ändern ist selten eine gute Idee. Man vergisst entweder dabei schon Änderungen oder man bekommt später Probleme die Kopien beim Entwickeln immer gleichartig anzupassen. Jetzt ist das schon passiert, das in beiden Kopien „Distanz hinten:“ ausgegeben wird, auch bei der Messung vorne. Für solch redundanten Code gibt es Schleifen und/oder Funktionen, wo man die Unterschiede aus dem Code heraus zieht.

    Das die selbe Entfernung immer zweimal hintereinander ausgegeben wird, macht keinen Sinn und statt format() würde man eher eine f-Zeichenkette schreiben. Hier fällt dann noch ein Nachteil von kopiertem Code auf: man muss diese Änderungen in jeder Kopie machen, statt nur einmal.

    Die get_distance()-Funktion ist eigentlich überflüssig, denn distance als 0 zu definieren wenn man diesen Wert nirgends benötigt, und den Messwert vor dem return an einen Namen zu binden, ist sinnlos, so dass am Ende nur eine Zeile mit einem Methodenaufruf übrig bleibt, die man auch direkt an der Aufrufstelle schreiben kann.

    Python
    def get_distance(sensors):
        distance = 0
        distance = sensors.get_distance()
        return distance
    
    # =>
    
    def get_distance(sensors):
        return sensors.get_distance()

    Zwischenstand (ungetestet):

    Stupid question of the day: If someone with multiple personalities threatens to kill himself, is it considered a hostage situation?

  • Hallo hyle und blackjack

    Vielen Dank für Eure Unterstützung.
    Dank Euren Kommentaren habe ich als Anfänger wieder viel gelernt.
    Eure Tips haben nicht ganz geholfen, aber führte mich auf die richtige Spur.
    Sogar der Original Download vom Buch konnte nur einmal gestartet werden.
    Nachdem ich die Herstellerseiten durchforstet habe bin ich der Lösung näher gekommen.

    Falls es Euch interessiert, hier der funktionierende Code:

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!