Wie im letzten Blogeintrag beschrieben konnte die Funktionalität des Beschleunigungssensors/Gyroskops bestätigt werden, indem erste Daten erfolgreich ausgelesen wurden. Um die ausgelesenen Sensordaten jetzt in die geplante Infrastruktur zu einzugliedern und die Anforderungen an das Projekt einzuhalten, muss die getestete Funktionalität in das bestehende Projekt integriert werden.

Hierzu wurde zunächst die Dockerfile angepasst, um alle Abhängigkeiten zu installieren.

FROM balenalib/%%BALENA_MACHINE_NAME%%-debian-python:latest-run

# Workaround, damit RPi.GPIO während der Installation kompiliert werden kann
#RUN apt-get -y update; apt-get -y upgrade; apt-get -y install build-essential

RUN apt-get update; apt-get -y install i2c-tools

WORKDIR /usr/src/app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app.conf .
COPY ./src .

CMD modprobe i2c-dev && python app.py

Docker installiert jetzt sowohl i2c, das zum Ansteuern des Sensors benutzt wird, als auch das smbus2 Paket über requirements.txt.
Der Code zum Auslesen der Sensordaten wurde soweit angepasst, dass er in die bestehende Infrastruktur passt und die gelesenen Daten an redis weiterleitet, anstatt sie auszugeben.

def _perform_mesaurement(self):
        self._logger.info("Starte neue Messung")

        # Beispiel: Wir messen Beschleunigung und Rotation des Sensors.
        # Register
        power_mgmt_1 = 0x6B
        power_mgmt_2 = 0x6C

        def read_byte(reg):
            return bus.read_byte_data(address, reg)

        def read_word(reg):
            h = bus.read_byte_data(address, reg)
            l = bus.read_byte_data(address, reg + 1)
            value = (h << 8) + l
            return value

        def read_word_2c(reg):
            val = read_word(reg)
            if val >= 0x8000:
                return -((65535 - val) + 1)
            else:
                return val

        def dist(a, b):
            return math.sqrt((a * a) + (b * b))

        def get_y_rotation(x, y, z):
            radians = math.atan2(x, dist(y, z))
            return -math.degrees(radians)

        def get_x_rotation(x, y, z):
            radians = math.atan2(y, dist(x, z))
            return math.degrees(radians)

        bus = SMBus(1)  # bus = smbus.SMBus(0) fuer Revision 1
        address = 0x68  # via i2cdetect

        # Aktivieren, um das Modul ansprechen zu koennen
        bus.write_byte_data(address, power_mgmt_1, 0)

        # Beschleunigungs- und Rotationsmessungen auslesen
        gyroskop_xout = read_word_2c(0x43)
        gyroskop_yout = read_word_2c(0x45)
        gyroskop_zout = read_word_2c(0x47)

        beschleunigung_xout = read_word_2c(0x3B)
        beschleunigung_yout = read_word_2c(0x3D)
        beschleunigung_zout = read_word_2c(0x3F)

        beschleunigung_xout_skaliert = beschleunigung_xout / 16384.0
        beschleunigung_yout_skaliert = beschleunigung_yout / 16384.0
        beschleunigung_zout_skaliert = beschleunigung_zout / 16384.0

        # Werte in Dictionary speichern
        reading = {
            "X_acceleration": beschleunigung_xout_skaliert,
            "Y_acceleration": beschleunigung_yout_skaliert,
            "Z_acceleration": beschleunigung_zout_skaliert,
            "X_rotation": gyroskop_xout,
            "Y_rotation": gyroskop_yout,
            "Z_rotation": gyroskop_zout,
        }

        return reading

An dieser Stelle wäre zu erwarten, dass der Raspberry PI die Sensordaten ausliest und an Redis weiterleitet, allerdings funktioniert dies nicht ganz. In unseren Tests entsteht ein Problem beim Auslesen der Daten, dessen Ursache noch nicht gefunden bzw. repariert werden konnte. Der Code läuft soweit fehlerfrei, allerdings wird bei jedem Messwert immer nur 0.0 ausgelesen. Dies legt nahe, dass entweder der Sensor kaputt ist, oder ein Problem bei der Kommunikation zwischen Raspi und Sensor besteht. Der Sensor kann als Fehlerquelle bereits ausgeschlossen werden, da dieser in vorherigen Tests funktionierte.

Nach mehreren Stunden vergeblicher Fehlersuche und Ärger über mangelnde BalenaOS Dokumentation kann ich den Fehlerbereich einschränken. Zwischen der Raspberry Lite und Balena OS variante unterscheiden sich die Outputs beim Command i2cdetect -y 1

Output Raspberry Lite OS:

pi@raspberrypi ~ $ sudo i2cdetect -y 1
 0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Output Balena OS:

root@f2bb9fb94eb9:/usr/src/app# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 
70: 70 71 72 73 74 75 76 77

Auch die Outputs beim Befehl i2cget -y 1 0x68 0x75 unterscheidet sich.

Output Raspberry Lite OS:

pi@raspberry:~$ sudo i2cget -y 1 0x68 0x75
0x68

Output Balena OS:

root@f2bb9fb94eb9:/usr/src/app# sudo i2cget -y 1 0x68 0x75
0x00

Der erste Unterschied ist, dass in Balena OS Geräte erkannt werden, die gar nicht vorhanden sind. Dies macht mich bereits stutzig. Auch beim 2. Command wird ein anderer Output als erwartet ausgegeben, nämlich 0x00 statt 0x68. An dieser Stelle bin ich ehrlich gesagt etwas überfordert und hoffe, dass @dennis uns etwas aushelfen kann.

Der Umstieg von Raspbian Lite auf Balena OS und die damit verbundenen Schwierigkeiten
Markiert in:         

10 Kommentare zu „Der Umstieg von Raspbian Lite auf Balena OS und die damit verbundenen Schwierigkeiten

    • 15. Juni 2021 um 18:37 Uhr
      Permalink

      Wenn ich modprobe i2c-dev weglasse funktioniert es auch nicht. Bei meinem Test wurden zwar auch 0.0 Werte geschrieben, allerdings konnte ich anschließend nicht mehr auf das Sensor Modul zugreifen

      • 15. Juni 2021 um 19:00 Uhr
        Permalink

        Ich korrigiere mich, der Zugriff ist trotzdem noch möglich, am Ergebnis ändert sich allerdings trotzdem nichts.

  • 11. Juni 2021 um 14:48 Uhr
    Permalink

    Wie sieht denn der Eintrag in der docker-compose.yml aus? Ist dort „privileged: true“ gesetzt? Und wie sieht denn das /dev-Verzeichnis auf dem Pi aus (einmal im Host OS und einmal im Container)? Gibt es dort Dateien wie /dev/i2c-0, /dev/i2c-1 und so weiter?

    • 15. Juni 2021 um 18:38 Uhr
      Permalink

      Privileged:true ist gesetzt und in den /dev Verzeichnissen befindet sich jeweils /i2c-1, ansonsten allerdings nichts aus der i2c Familie.

  • 16. Juni 2021 um 23:04 Uhr
    Permalink

    Zwei Möglichkeiten sehe ich noch um verlinkten Forumspost, die Sie ausprobieren könnten:

    1. Docker-Container auf balenalib/rpi-raspbian aufbauen (FROM balenalib/rpi-raspbian). Dann müssten Sie halt nur python3 noch in den Container hinein installieren.

    2. Devicetree Overlays auf folgenden Wert ändern: „i2c-gpio,i2c_gpio_delay_us=14,i2c_gpio_sda=2,i2c_gpio_scl=3“ (in der Balena Cloud unter „Device Configuration“ –> „Define DT overlays“.

    Bei 2 bin ich mir nicht sicher, ob es sich auch auf ein Device im Entwicklungsmodus auswirkt. Sollte aber eigentlich. Was ist ein Device Tree? Ein Device Tree ist eine Beschreibung der vorhandenen Hardware für den Linux Kernel.

    • 17. Juni 2021 um 20:20 Uhr
      Permalink

      Erstmal Danke für die Hilfe, die Sie wiederholt anbieten. Ich habe beide von Ihnen angesprochenen Optionen getestet und kam in diesem Fall zu keinem anderen Ergebnis. Die Umstellung auf rpi-raspbian war etwas knifflig, hat am Ende dann aber auch nichts verändert. Ich hatte vorher auch schon einmal testweise das Ubuntu Image mit dem gleichen Ergebnis getestet.

      In DT-Overlays habe ich mich jetzt auch eingelesen und einiges probiert. Wenn ich das von Ihnen genannte Beispiel Teste verändert sich auch nichts am Ergebnis, allerdings wurde im Beispiel dieser Webseite, wenn ich das richtig verstehe, auch diese Zeile herausgelöscht, um die Lösung zu erzielen. Beide Varianten haben leider allerdings nichts gebracht. Ich habe mir um auf dieser Spur zu bleiben mehrere Websiten angesehen und unter anderem diese hier gefunden:
      https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/overlays/README
      Auf dieser Website wird unter anderem ein Overlay für den MPU6050 angeboten, die Konfiguration dieses Overlays wollte mir allerdings nicht gelingen und hat wiederholt für Fehler gesorgt.

      Bei genauerer Betrachtung des i2cdetect -y 1 Commands, bei dem alles angezeigt wird, bin ich wiederholt auf diese Website gestoßen: https://www.raspberrypi.org/forums/viewtopic.php?t=93222
      Dort hat jemand das gleiche Problem, auch wenn er den Sensor entfernt. Ich habe den Sensor jetzt auch komplett vom Raspi entfernt und habe nach wie vor das gleiche Verhalten. Dementsprechend gehe ich davon aus, dass das Problem schon irgendwo vorher im Prozess liegt. Da ich die Hardware dank vorheriger Tests bereits ausschließen kann, muss das Problem an der Software liegen. Dafür wird auf dieser Seite nur ein Hinweis geliefert, wobei ich nicht sicher bin wie ich diesem nachgehen könnte. Haben Sie vlt noch Ideen? Ansonsten wollte ich Ihnen nur bescheid geben, dass ich ihren Hinweisen intensiv nachgehe.

      Ich habe mittlerweile das Gefühl, dass ich eine kleine Vorlesung füllen könnte, mit der Menge an Fehlersuche die ich betrieben habe. Vlt sollte ich auch noch einen Blogpost schreiben *thinking*

      • 17. Juni 2021 um 23:30 Uhr
        Permalink

        Ein Blogbeitrag sollte mindestens dabei rausspringen. 🙂

        Folgender Satz aus Ihrem Raspi-Formslink lässt mich aufhorchen: „I had the same issue. In my case there was a program running at boot that was setting the SDA pin as GPIO-Output.“

        Versuchen Sie mal, nur einen Dummy-Container auf dem Pi zu deployen mit einem kleinen Python-Programm, das die Pins als INPUT konfiguriert, sonst aber nichts macht. Dann loggen Sie sich mit SSH in den Container ein und führen nochmal i2cdetect aus. Wichtig ist, dass außer diesem Dummy-Container nichts sonst auf dem Pi laufen sollte.

        Das mal als weiterer Versuch, um herauszufinden, ob hier vielleicht einfach zwei Softwarekomponenten „gegeneinander“ arbeiten.

        • 18. Juni 2021 um 19:28 Uhr
          Permalink

          Der Tag ist gerettet. Tatsächlich funktioniert der Code jetzt, wenn man ihn von der restlichen Umgebung isoliert. Ich habe hierzu ein neues Balena Projekt erstellt und das Sensor Modul kopiert. Natürlich mussten noch Anpassungen getroffen werden, aber nachdem diese vollzogen waren liefert der Code jetzt endlich Messwerte.
          [Logs] [2021-6-18 19:22:03] [main] {‚X_acceleration‘: 0.948974609375, ‚Y_acceleration‘: -0.087646484375, ‚Z_acceleration‘: 0.85107421875, ‚X_rotation‘: -1056, ‚Y_rotation‘: -49, ‚Z_rotation‘: 25}
          [Logs] [2021-6-18 19:22:05] [main] {‚X_acceleration‘: 1.14599609375, ‚Y_acceleration‘: 0.209228515625, ‚Z_acceleration‘: -0.491943359375, ‚X_rotation‘: -5523, ‚Y_rotation‘: -52, ‚Z_rotation‘: -403}
          […]

          Jetzt gilt es noch herauszufinden welches Modul, bzw. welche Codestelle interferiert.

  • 18. Juni 2021 um 17:59 Uhr
    Permalink

    Noch eine weitere Idee: I²C ist doch auch eine serielle Kommunikation. Welche Pins verwenden Sie denn hierfür? Nicht dass Sie dasselbe Problem haben, das ich heute im Blogbeitrag „Serielle Schnittstelle im Balena Local Mode nutzen“ beschrieben habe.

    Die Kurzversion: Die Dev-Version von Balena OS belegt die seriellen Ports mit einer Login-Konsole. Diese kann, wenn man sich via SSH mit dem Host-OS verbindet, über folgenden Befehl gestoppt werden:

    systemctl stop serial-getty@serial0

    Allerdings muss man das nach jedem Neustart des Pi wiederholen.

Schreibe einen Kommentar