cancel
Showing results for 
Search instead for 
Did you mean: 

iis2mdc magnetometer not writing timestamp

Ginkgo
Associate II

I am trying to get the raw data (with timestamp included) from a few IIO devices (hardware sensors, such as accelerometer, gyroscope, magnetometer and barometer) mounted on a linux platform and with the ST drivers. I was able to get the data for the accelerometer and for the gyroscope using the libiio library within a C++ code or using sysfs commands (enabling the buffer). However, for the magnetometer and for the barometer it seems (I'm not expert in this field) this procedure doesn't work. In particular, with the magnetometer (device2), I am able to get the data but not the timestamp (that remains 0).

root@dab:/sys/devices/platform/soc@0/soc@0:bus@30800000/30a50000.i2c/i2c-3/3-001e/iio:device2/buffer# hexdump -C /dev/iio:\device2

00000000  85 01 20 00 34 fe 00 00  00 00 00 00 00 00 00 00  |.. .4...........|

00000010  87 01 24 00 31 fe 00 00  00 00 00 00 00 00 00 00  |..$.1...........|

 

I've noticed, from the iio_info commands that there is a trigger set-up for the magnetometer, however it seems to me (I am not expert in this field) it isn't really working (as we're able to get the data but not the timestamp), so the problem might be elsewhere. I thought there might be a problem in the location (some REGs maybe?) where the timestamp is written, but I am not sure, as this is the first time I work with sensors.

Is there anything I could check to see why am I getting this problem and how to solve it?

 

This is the output of the "iio_info" command:

 

Library version: 0.19 (git tag: v0.19)
Compiled with backends: local xml ip usb serial
IIO context created with local backend.
Backend version: 0.19 (git tag: v0.19)
Backend description string: Linux dab 5.4.193-toradex #1 SMP PREEMPT Fri Oct 6 13:55:59 CEST 2023 aarch64
IIO context has 1 attributes:
        local,kernel: 5.4.193-toradex
IIO context has 6 devices:
....

        iio:device2: iis2mdc (buffer capable)                4 channels found:
                        magn_x:  (input, index: 0, format: le:S16/16>>0)
                        3 channel-specific attributes found:
                                attr  0: raw ERROR: Device or resource busy (-16)
                                attr  1: scale value: 0.001500
                                attr  2: scale_available value: 0.001500
                        magn_y:  (input, index: 1, format: le:S16/16>>0)
                        3 channel-specific attributes found:
                                attr  0: raw ERROR: Device or resource busy (-16)
                                attr  1: scale value: 0.001500
                                attr  2: scale_available value: 0.001500
                        magn_z:  (input, index: 2, format: le:S16/16>>0)
                        3 channel-specific attributes found:
                                attr  0: raw ERROR: Device or resource busy (-16)
                                attr  1: scale value: 0.001500
                                attr  2: scale_available value: 0.001500
                        timestamp:  (input, index: 3, format: le:S64/64>>0)
                5 device-specific attributes found:
                                attr  0: consumers ERROR: Input/output error (-5)
                                attr  1: current_timestamp_clock value: realtime

                                attr  2: sampling_frequency value: 10
                                attr  3: sampling_frequency_available value: 10 20 50 100
                                attr  4: suppliers ERROR: Input/output error (-5)
                2 buffer-specific attributes found:
                                attr  0: data_available value: 16
                                attr  1: watermark value: 1
                Current trigger: trigger0(iis2mdc-trigger)
...
                                attr  1: watermark value: 1
        trigger0: iis2mdc-trigger
                0 channels found:
                2 device-specific attributes found:
                                attr  0: consumers ERROR: Input/output error (-5)
                                attr  1: suppliers ERROR: Input/output error (-5)

 

4 REPLIES 4
Federica Bossi
ST Employee

Hi @Ginkgo ,

Are you using the sensor interrupt pin or are you using an external software trigger?

What libiio shell command do you use to read the sensor data?

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Ginkgo
Associate II

Hi @Federica Bossi,

The shell commands I am using are the following ones:

echo 1 > scan_elements/elements/in_magn_x_en (for the three components of the magnetic field)

echo 1 > scan_elements/in_timestamp_en

echo 16 > buffer/length

echo 1 > buffer/enable

And then the hexdump command.

However, I've also written a script in C++ using libiio-dev v. 0.19 (attached).
Through the iio_info command (in my previous message) you can see there is a "iis2mdc-trigger" trigger is already set by default (so not set by me) appearing among the devices. However I do not know if this might have an influence on this problem, and if so, if I should set it up somehow or disable it.
In the attached code I also tried to set this trigger by associating it with the magnetometer through the command iio_device_set_trigger(). I am able to get the data (with or without setting the trigger) but it seems the timestamp is not available.

 

#include <iostream>
#include <iio.h>
#include <sys/time.h>
#include <cstring>
#include <thread>

int main() {
    struct iio_context *ctx;
    struct iio_device  *magn_device, *magn_trigger;
    struct iio_channel  *magn_x, *magn_y, *magn_z, *timestamp_magn;
    struct iio_buffer  *magn_buffer;
    int64_t time_out;

    // Create a local context for interacting with Industrial I/O devices
    ctx = iio_create_local_context();
    if (!ctx) {
        std::cerr << "Error creating IIO context" << std::endl;
        return -1;
    }

    // Find the magnetometer device and trigger device by their names
    magn_device = iio_context_find_device(ctx,"iis2mdc");
    magn_trigger = iio_context_find_device(ctx,"iis2mdc-trigger");

    // Get a reference to the specific device using its description
    if (magn_trigger) {
        // Check if the device is a trigger
        if (iio_device_is_trigger(magn_trigger)) {
            printf("The device is a trigger.\n");
        } else {
            printf("The device is not a trigger.\n");
        }
    } else {
        printf("Device not found.\n");
    }

    if (!magn_device || !magn_trigger) {
        std::cerr << "Devices not found" << std::endl;
        iio_context_destroy(ctx);
        return -1;
    }

    // Set the number of kernel buffers for the magnetometer device
    iio_device_set_kernel_buffers_count(magn_device, 1);

    // Find magnetometer channels and timestamp channel
    magn_x = iio_device_find_channel(magn_device, "magn_x", false);
    magn_y = iio_device_find_channel(magn_device, "magn_y", false);
    magn_z = iio_device_find_channel(magn_device, "magn_z", false);
    timestamp_magn = iio_device_find_channel(magn_device, "timestamp", false);

    if (!magn_x || !magn_y || !magn_z || !timestamp_magn) {
        std::cerr << "Channels not found" << std::endl;
        iio_context_destroy(ctx);
        return -1;
    }

    // Enable magnetometer channels and timestamp channel
    iio_channel_enable(timestamp_magn);
    iio_channel_enable(magn_x);
    iio_channel_enable(magn_y);
    iio_channel_enable(magn_z);

    // Set the trigger for the magnetometer device
    if (iio_device_set_trigger(magn_device, magn_trigger) < 0) {
        std::cerr << "Error setting trigger" << " " << iio_device_set_trigger(magn_device, magn_trigger) << std::endl;
        iio_context_destroy(ctx);
        return -1;
    }

    // Create a buffer for reading magnetometer data
    magn_buffer = iio_device_create_buffer(magn_device, 1, false);

    if (!magn_buffer) {
        std::cerr << "Error creating buffer" << std::endl;
        iio_context_destroy(ctx);
        return -1;
    }

    // Set the timeout for the context
    time_out = iio_context_set_timeout(ctx, 0);
    if (time_out < 0){
        std::cerr << "Error setting timeout" << std::endl;
        iio_context_destroy(ctx);
        return -1;
    }

    // Continuously read data from the buffer
    while (true) {
        // Refill the buffer with data
        ssize_t magn_bytes = iio_buffer_refill(magn_buffer);
        std::cout << "Data filled in the magnetometer buffer: " << magn_bytes << " bytes" << std::endl;

        if (magn_bytes < 0) {
            std::cerr << "Error refilling buffer" << std::endl;
            break;
        }

        // Read magnetometer data from the buffer and print
        for (void *ptr = iio_buffer_first(magn_buffer, magn_x); ptr < iio_buffer_end(magn_buffer); ptr += iio_buffer_step(magn_buffer)) {
            int16_t Magn_x = *(uint16_t*)(ptr);
            std::cout << "Magn_x = " << Magn_x << std::endl;
        }

        for (void *ptr = iio_buffer_first(magn_buffer, magn_y); ptr < iio_buffer_end(magn_buffer); ptr += iio_buffer_step(magn_buffer)) {
            int16_t Magn_y = *(uint16_t*)(ptr);
            std::cout << "Magn_y = " << Magn_y << std::endl;
        }

        for (void *ptr = iio_buffer_first(magn_buffer, magn_z); ptr < iio_buffer_end(magn_buffer); ptr += iio_buffer_step(magn_buffer)) {
            int16_t Magn_z = *(uint16_t*)(ptr);
            std::cout << "Magn_z = " << Magn_z << std::endl;
        }

        for (void *ptr = iio_buffer_first(magn_buffer, timestamp_magn); ptr < iio_buffer_end(magn_buffer); ptr += iio_buffer_step(magn_buffer)) {
            int64_t Timestamp_magn = *(uint64_t*)(ptr);
            std::cout << "Timestamp_magn = " << Timestamp_magn << std::endl;
        }
    }

    // Destroy the buffer and context before exiting
    iio_buffer_destroy(magn_buffer);
    iio_context_destroy(ctx);

    return 0;
}

 

Federica Bossi
ST Employee

Hi @Ginkgo ,

Thanks for your answer. To better understand what could be the issue I need to know if you are using the sensor interrupt pin or an external software trigger.

Let me know :)

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Federica Bossi
ST Employee

Hi @Ginkgo ,

A patch has been made and is currently in the CI test phase, soon it will be public on the github.

I will let you know when it will be released.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.