querdenker engineering
Schnittstellen und Services

Analoge Eingänge

Analoge Messwerte über die Linux-IIO-Schnittstelle aus C und Python lesen.

Analoge Eingänge werden als Single-Ended-Eingänge über das Linux Industrial-I/O-Subsystem (IIO) abgebildet. Der Messbereich beträgt 0–10 V und kann auf 0–20 mA umgeschaltet werden. Der Device Tree beschreibt den ADC und seine Kanäle; im Userspace werden die vom IIO-Treiber bereitgestellten Kanäle gelesen.

Voraussetzungen

  • Der ADC-Treiber ist aktiviert und im Device Tree konfiguriert.
  • Ein IIO-Gerät /dev/iio:deviceX und die zugehörigen Kanalattribute sind vorhanden.
  • Kanal und Einheit sind bekannt.
  • IIO-Treiber und Kernel-Version sind freigegeben: [KERNEL-UND-IIO-VERSION].
for device in /sys/bus/iio/devices/iio:device*; do
    printf '%s: ' "$device"
    cat "$device/name"
done

Die Kanalwerte und ihre Parameter stehen unter /sys/bus/iio/devices/iio:deviceX/. Für hohe Abtastraten oder Ereignisse wird die gepufferte Schnittstelle /dev/iio:deviceX verwendet.

Aufbereiteten Messwert verwenden

Prüfe zuerst, ob der IIO-Treiber für den Kanal ein bereits aufbereitetes *_input-Attribut bereitstellt. Dieser Wert ist dem direkten Umgang mit Rohwerten vorzuziehen.

from pathlib import Path


device = Path("/sys/bus/iio/devices/iio:device0")
channel = "voltage0"  # [IIO-KANAL]
input_file = device / f"in_{channel}_input"

if input_file.exists():
    value = float(input_file.read_text().strip())
    print(f"Messwert: {value}")
/* Bevorzugt: das vom Treiber bereitgestellte *_input-Attribut lesen. */
/* Beispielpfad: /sys/bus/iio/devices/iio:device0/in_voltage0_input */

Welche Einheit und Skalierung ein *_input-Attribut verwendet, steht in der Kanalbeschreibung des jeweiligen Treibers.

Rohwert als Fallback umrechnen

Wenn kein *_input-Attribut existiert, können raw, scale und gegebenenfalls offset verwendet werden. Die konkrete Formel ist der Dokumentation des IIO-Treibers zu entnehmen. Häufig gilt:

Messwert = (raw + offset) * scale
#include <stdio.h>

int read_iio_value(const char *device_path, const char *channel, double *value)
{
    char path[256];
    int raw;
    double scale;
    double offset = 0.0;
    FILE *file;

    (void)snprintf(path, sizeof(path), "%s/in_%s_raw", device_path, channel);
    file = fopen(path, "r");
    if (!file || fscanf(file, "%d", &raw) != 1) {
        if (file) {
            (void)fclose(file);
        }
        return -1;
    }
    (void)fclose(file);

    (void)snprintf(path, sizeof(path), "%s/in_%s_scale", device_path, channel);
    file = fopen(path, "r");
    if (!file || fscanf(file, "%lf", &scale) != 1) {
        if (file) {
            (void)fclose(file);
        }
        return -1;
    }
    (void)fclose(file);

    (void)snprintf(path, sizeof(path), "%s/in_%s_offset", device_path, channel);
    file = fopen(path, "r");
    if (file) {
        (void)fscanf(file, "%lf", &offset);
        (void)fclose(file);
    }

    *value = ((double)raw + offset) * scale;
    return 0;
}

/* Beispiel: read_iio_value("/sys/bus/iio/devices/iio:device0", "voltage0", &value); */

Kanalbeschreibung und Sicherheit

Die Kanalnummer, Skalierung, Einheit und Abtastrate sind systemspezifisch. Prüfe vor dem Anschluss, ob der Eingang für 0–10 V oder 0–20 mA konfiguriert ist. Ein falscher Anschluss oder eine nicht zur Signalquelle passende Betriebsart kann den ADC oder die angeschlossene Hardware beschädigen.

[PLATZHALTER: IIO-Gerät, Kanalnamen, Einheiten, Skalierung, Offset-Definition und gepufferte Beispielkonfiguration]