Erschließung des HX711 Treibers für Linux-IIO

Bekommst Du pylibiio · PyPI folgendermaßen installiert?

apt install python3-libiio

Erste Tests

>>> import iio
>>> iio.version

Ja

pi@raspberrypi:~/linux/tools/iio $ sudo apt install python3-libiio
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
Die folgenden zusätzlichen Pakete werden installiert:
  libiio0 libserialport0
Die folgenden NEUEN Pakete werden installiert:
  libiio0 libserialport0 python3-libiio
0 aktualisiert, 3 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
Es müssen 87,2 kB an Archiven heruntergeladen werden.
Nach dieser Operation werden 251 kB Plattenplatz zusätzlich benutzt.
Möchten Sie fortfahren? [J/n] j
Holen:1 http://ftp.halifax.rwth-aachen.de/raspbian/raspbian buster/main armhf libserialport0 armhf 0.1.1-3 [42,3 kB]
Holen:2 http://mirror.de.leaseweb.net/raspbian/raspbian buster/main armhf libiio0 armhf 0.16-1 [35,4 kB]
Holen:3 http://ftp.halifax.rwth-aachen.de/raspbian/raspbian buster/main armhf python3-libiio all 0.16-1 [9.480 B]
Es wurden 87,2 kB in 1 s geholt (111 kB/s).
Vormals nicht ausgewähltes Paket libserialport0:armhf wird gewählt.
(Lese Datenbank ... 222438 Dateien und Verzeichnisse sind derzeit installiert.)
Vorbereitung zum Entpacken von .../libserialport0_0.1.1-3_armhf.deb ...
Entpacken von libserialport0:armhf (0.1.1-3) ...
Vormals nicht ausgewähltes Paket libiio0:armhf wird gewählt.
Vorbereitung zum Entpacken von .../libiio0_0.16-1_armhf.deb ...
Entpacken von libiio0:armhf (0.16-1) ...
Vormals nicht ausgewähltes Paket python3-libiio wird gewählt.
Vorbereitung zum Entpacken von .../python3-libiio_0.16-1_all.deb ...
Entpacken von python3-libiio (0.16-1) ...
libserialport0:armhf (0.1.1-3) wird eingerichtet ...
libiio0:armhf (0.16-1) wird eingerichtet ...
python3-libiio (0.16-1) wird eingerichtet ...
Trigger für libc-bin (2.28-10+rpi1) werden verarbeitet ...
pi@raspberrypi:~/linux/tools/iio $
pi@raspberrypi:~/linux/tools/iio $ python3
Python 3.7.3 (default, Jan 22 2021, 20:04:44)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import iio
>>> iio.version
(0, 16, 'v0.16')
>>>

Wunderbar. Dann lass doch mal jenes Beispiel laufen:

1 Like

BINGO!!!

local: - hx711 - timestamp
local: - hx711 - voltage0
local: - hx711 - voltage1
local: - 1-002a - voltage0
local: - 1-002a - voltage1
local: - bme280 - humidityrelative
local: - bme280 - pressure
local: - bme280 - temp
2 Likes

Bei libiio kommen u.U. ein paar Werkzeuge gleich automatisch mit:

Danke. Das ist ja eine hervorragende Grundlage für einen entsprechenden Treiberadapter. Vielleicht kannst Du das Codebeispiel noch erweitern, dass als dritte Spalte der entsprechende Sensorwert ausgegeben wird?

Hinweis: dir(variable_name) ist Dein Freund, z.B. print(dir(dev)) oder print(dir(chan)). Im Zweifel ist der Meßwert einfach direkt chan.value ;]

Ganz so einfach ist es wohl leider nicht.

>>> for ctxname in iio.scan_contexts():
...     ctx = iio.Context(ctxname)
...     for dev in ctx.devices:
...         if dev.channels:
...             for chan in dev.channels:
...                 print("{} - {} - {} - {}".format(ctxname, dev.name, chan._id, chan.value))
... else:
...             print("{} - {}".format(ctxname, dev.name))
...
Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
AttributeError: 'Channel' object has no attribute 'value'

Das lesen der Channels scheint über einen buffer zu gehen der momentan aber noch nicht aktiviert ist. Also chan.read(buf).
https://analogdevicesinc.github.io/libiio/master/python/channel.html
nur chan.read() geht leider nicht.
TypeError: read() missing 1 required positional argument: 'buf'

Stimmt. Das Beispielprogramm libiio/bindings/python/examples/iio_readdev.py at main · analogdevicesinc/libiio · GitHub liefert eine Blaupause.

Stimmt, genau dort schaue ich auch gerade. Bekomme ich aber gerade leider nicht hin, da auf die schnelle was draus zu zaubern.
iiolib schaut aber auf alle fälle ein vernünftiger und sauberer Weg zu sein IIO-Devices einfach und schnell zur Verfügung zu stellen.

Muss jetzt erstmal in die Falle morgen geht es wieder sehr früh raus.

Wollen wir den versuchen die IIO Schnittstelle versuchen so weit es geht zu erschließen, oder nur einzelne Treiber wie HX711, BME280 und Nau7802.
Das erschließen sollte mit den von uns gestern gemachten Erfahrungen mit IIOLIB denke ich problemlos möglich sein. Man muss dann nur wenn ein HX711 und NAU7802 erkannt wurde noch die zusätzlichen Berechnungen für die Gewichtsermittlung anhängen.

Die aktuelle Raspberry OS light Kernel müsste jetzt und ab Werk das hier alles können.

  • HX711 (hinzugefügt)
  • NAU7802 (hinzugefügt)
  • ADS1015
  • MCP3x01/02/04/08
  • MCP3421/2/3/4/5/6/7/8

Chemical Sensors

  • BME280
  • BME680
  • CCS811
  • SGPxx Gas Sensors
  • SPS30 particulate matter sensor
  • SGP30

Humidity sensors

  • DHT11
  • TI HDC100x
  • HTD21
  • MPU6050 (I2C)

Light sensors

  • APDS9960 gesture/RGB/ALS/proximity
  • BH1750 ambient light sensor
  • TSL4531 -"-
  • VEML6070 UV A

Pressure Sensors

  • BMP85/BMP180/BMP280

Temperature sensors

  • Maxim thermocouple sensor
  • MAX31856

Aber sehr viel mehr liegen als fertiges Modul im Kernel-Source bereit und müssen nur hinzugefügt werden. Leider habe ich dort keinen IIO ADS1232 Treiber gefunden, dann hätte ich Ihn auch noch hinzugefügt. (Habe davon auch noch einen zum testen und Spielen liegen.)

Mein Vorschlag wäre es den IIO Devices einen eigene Library bzw. Bus-Treiber in Terkin zu spendieren.

1 Like

Ich würde sagen: Wenns geht, dann in der Basis IIO-generisch.

Ja, genau.

Kriegst Du mit diesem Programm - 1:1 verwendet - Werte ausgelesen? Falls ja, kannst Du mir vielleicht die entsprechenden Aufrufparameter für die Abfrage verschiedener bei Dir angeschlossener Devices zur Verfügung stellen? Es geht vermutlich um folgende Parameter:

  • --uri zur Adressierung des IIO Kontexts, sowie

  • device und channel zur Adressierung des Geräts und des Datenkanals. Beide sind positionale Parameter, device ist obligatorisch. Der channel Parameter lässt sich ggf. auch mehrfach angeben.

    iio_readdev [-n <hostname>] [-t <trigger>] [-T <timeout-ms>] [-b <buffer-size>] [-s <samples>] <iio_device> [<channel> ...]

Bei iio_readdev [Analog Devices Wiki] und https://analogdevicesinc.github.io/libiio/v0.20/man1/iio_readdev.1.html finden sich auch Beispiele zur Benutzung.

Im einfachsten Fall klappt es vielleicht schon mit jenen Befehlen?

iio_readdev hx711
iio_readdev hx711 voltage0
iio_readdev bme280 temp
iio_readdev bme280 temp humidityrelative pressure

Mit diesen Informationen kann ich uns gerne einen IIO-Adapter für Terkin zusammenbauen.

bin momentan mit iio_readdev.py noch nicht wirklich weit gekommen. Über iio_attr.py kommen aber ein paar Werte rein. Der HX711 scheint aber noch einen Bock zu haben.
am Nau7802 muß ich aber wieder die Waage hängen (ist momentan am HX711)

pi@raspberrypi:~/iio $ iio_attr -s -c
IIO context has 3 devices:
        iio:device0: hx711, found 3 channels
        iio:device1: 1-002a, found 2 channels
        iio:device2: bme280, found 3 channels

pi@raspberrypi:~/iio $iio_attr  -c hx711
dev 'hx711', channel 'timestamp' (inputTraceback (most recent call last):
  File "iio_attr.py", line 486, in <module>
    main()
  File "iio_attr.py", line 482, in main
    information.write_information()
  File "iio_attr.py", line 245, in write_information
    self._devices_information()
  File "iio_attr.py", line 266, in _devices_information
    self._device_information(dev)
  File "iio_attr.py", line 288, in _device_information
    self._channel_information(dev, channel)
  File "iio_attr.py", line 321, in _channel_information
    self._scan_channel_information(channel)
  File "iio_attr.py", line 328, in _scan_channel_information
    sign = "s" if channel.data_format.is_signed else "u"
AttributeError: 'Channel' object has no attribute 'data_format'
pi@raspberrypi:~/iio $ iio_attr -c 1-002a
dev '1-002a', channel 'voltage0' (input), found 4 channel-specific attributes
dev '1-002a', channel 'voltage1' (input), found 4 channel-specific attributes
pi@raspberrypi:~/iio $ iio_attr  -c 1-002a
dev '1-002a', channel 'voltage0' (input), found 4 channel-specific attributes
dev '1-002a', channel 'voltage1' (input), found 4 channel-specific attributes
pi@raspberrypi:~/iio $ iio_attr  -c 1-002a voltage0
dev '1-002a', channel 'voltage0' (input), attr 'raw', value '-8388607'
dev '1-002a', channel 'voltage0' (input), attr 'sampling_frequency', value '320'
dev '1-002a', channel 'voltage0' (input), attr 'scale', value '0.000000000'
dev '1-002a', channel 'voltage0' (input), attr 'scale_available', value '0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000'
pi@raspberrypi:~/iio $ iio_attr -c 1-002a voltage1
dev '1-002a', channel 'voltage1' (input), attr 'raw', value '-8388608'
dev '1-002a', channel 'voltage1' (input), attr 'sampling_frequency', value '320'
dev '1-002a', channel 'voltage1' (input), attr 'scale', value '0.000000000'
dev '1-002a', channel 'voltage1' (input), attr 'scale_available', value '0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000'
pi@raspberrypi:~/iio $ iio_attr  -c bme280
dev 'bme280', channel 'humidityrelative' (input), found 2 channel-specific attributes
dev 'bme280', channel 'pressure' (input), found 2 channel-specific attributes
dev 'bme280', channel 'temp' (input), found 2 channel-specific attributes
pi@raspberrypi:~/iio $ iio_attr -c bme280 temp
dev 'bme280', channel 'temp' (input), attr 'input', value '24220'
dev 'bme280', channel 'temp' (input), attr 'oversampling_ratio', value '2'
pi@raspberrypi:~/iio $ iio_attr  -c bme280 pressure
dev 'bme280', channel 'pressure' (input), attr 'input', value '101.631152343'
dev 'bme280', channel 'pressure' (input), attr 'oversampling_ratio', value '16'
pi@raspberrypi:~/iio $ iio_attr  -c bme280 humidityrelative
dev 'bme280', channel 'humidityrelative' (input), attr 'input', value '59619'
dev 'bme280', channel 'humidityrelative' (input), attr 'oversampling_ratio', value '16'
pi@raspberrypi:~/iio $

einzelne Werte lassen sich so abrufen:

pi@raspberrypi:~/iio $ iio_attr  -c bme280 humidityrelative input
dev 'bme280', channel 'humidityrelative' (input), attr 'input', value '59528'
1 Like

Der etwas Komische Name für den Nau7802 kommt übrigens von der /drivers/iio/adc/nau7802.c#L433 im vergleich dazu die Zeile von der drivers/iio/adc/hx711.c#L553.
Soll ich das ändern, oder so lassen?
Theoretisch könnte dann auch gleich versuchen den 3. Channel für die Temperatur im index frei zu schalten. Schaut auf den 1.Blick sehr einfach aus.

Der HX711 funktioniert übrigens trotz der Fehlermeldung genauso auszulesen wie die anderen IIO Devices.
der Fehler liegt wohl irgendwo am Treiber,

pi@raspberrypi:~/iio $ iio_attr -c hx711 voltage0
dev 'hx711', channel 'voltage0' (input), attr 'raw', value '8377619'
dev 'hx711', channel 'voltage0' (input), attr 'scale', value '0.000001536'
dev 'hx711', channel 'voltage0' (input), attr 'scale_available', value '0.000001536 0.000003072 '
pi@raspberrypi:~/iio $ iio_attr -c hx711 voltage0 raw
dev 'hx711', channel 'voltage0' (input), attr 'raw', value '8377754'
pi@raspberrypi:~/iio $ iio_attr -c hx711 voltage0
dev 'hx711', channel 'voltage0' (input), attr 'raw', value '8377754'

Nur wenn nur das Device und nicht der Cannel mit angegeben wird kommt die Fehlermeldung

pi@raspberrypi:~/iio $iio_attr -c hx711
dev 'hx711', channel 'timestamp' (inputTraceback (most recent call last):
  File "iio_attr.py", line 486, in <module>
    main()
  File "iio_attr.py", line 482, in main
    information.write_information()
  File "iio_attr.py", line 245, in write_information
    self._devices_information()
  File "iio_attr.py", line 266, in _devices_information
    self._device_information(dev)
  File "iio_attr.py", line 288, in _device_information
    self._channel_information(dev, channel)
  File "iio_attr.py", line 321, in _channel_information
    self._scan_channel_information(channel)
  File "iio_attr.py", line 328, in _scan_channel_information
    sign = "s" if channel.data_format.is_signed else "u"
AttributeError: 'Channel' object has no attribute 'data_format'

Finde den Fehler irgendwie nicht.
Der Hund müsste aber hier begraben liegen hx711.c#L456 wirft anscheinend nicht das aus, was erwartet wird.
Dieser channel lässt sich übrigens auch nicht auslesen.

2 Likes

Das hat mir irgendwie keine Ruhe gelassen und ich habe mal geschaut, wo das her kommt.

Auch hat es mich interessiert, welche Cannel Typen es überhaupt gibt.

Und auch zu den Variablennahmen und deren Einheiten habe ich noch evtl. was interessantes gefunden.
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-iio

Hi,

damit dieses Thema nicht in Vergessenheit gerät, habe ich gerade bei Terkin » Add support for Linux IIO sensor devices eine entsprechende Notiz angelegt.

Viele Grüße,
Andreas.

1 Like