Post Go back to editing

Inconsistent channel position in a libiio buffer

Category: Software
Product Number: CN0554

Hi Everyone,

While working on an application that continuously acquires data from multiple channels using the AD7124 on a CN0554 board, I noticed that sometimes the order of the channels is mixed up. I thought that was an issue with my code, but then I observed the same behavior when using the iio_readdev example that comes with the libiio distribution. I tried the following test.

  • I applied 1000 mV to channel "voltage0-voltage1", 2000 mV to channel "voltage2-voltage3", 3000 mV to "voltage4-voltage5", and 4000 mV to "channel6-channel7". 
  • Set the sampling rate to 19200 for those channels
  • Run the command:  ./iio_readdev -u ip:localhost ad7124-8 voltage0-voltage1 voltage2-voltage3 voltage4-voltage5 voltage6-voltage7 | ./showout -n 4, where showout is a simple program that gets the binary output dumped by iio_readdev and converts it into readable values (the code of this program is reported below)

At the beginning the output is as expected, e.g.,  

1000.25         1998.33         3006.18   4008.38, 

however after sometime, typically within 30 seconds, the order of the values changes, e.g., 

  1999.74         3007.41         4008.81   1001.40,

i.e. the order of the channels is a circular permutation of the original order. 

The iio_readdev app basically dumps the entire buffer without de-interleaving the data. However, I observed the same behavior even when the code iterates over the samples channel by channel (using the functions iio_buffer_first(),  iio_buffer_step() and iio_buffer_end() ).

Has anybody come across this behavior? It seems that the libiio loses track of the correct slot assigned to a channel. 

Thanks,

Massimo

Here is the code for printing the values dumped by the iio_readdev app.

 

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#define WORD_SIZE 4
#define COUNT2MILLIVOLT 0.000149011
#define scale_res_div 11.3373


int main(int argc, char **argv )
{
int i, flag, c, n = 1, k;
unsigned char buf[4], tmp[4];
unsigned long * p, dc;
double volt;

while ((c = getopt(argc, argv, "n:")) != -1)
{
switch (c)
{
case 'n':
n = atoi(optarg);
break;
case '?':
if (optopt == 'n')
printf("Option -%c requires an argument.\n", optopt);
else
printf("Unknown option -%c", optopt);
return 1;
default:
n = 1;
break;
}
}

flag = 1 ;
k = 0;
while (flag > 0) {
flag = fread(buf, sizeof(char), WORD_SIZE, stdin) ;
if (flag != WORD_SIZE) {
break ;
}
// dc = (long)buf[0] << 24 + (long)buf[1] << 16 + (long)buf[2] << 8 + (long)buf[0];
for(i = 0; i < WORD_SIZE; i++)
{
tmp[i] = buf[WORD_SIZE - 1 - i];
}
dc = *((unsigned long *)tmp);
printf("%9.2f\t", dc * COUNT2MILLIVOLT * scale_res_div);
k++;
if(k == n)
{
k = 0;
printf("\n");
}
}

return 0 ;
}

  •   - are you using the latest Kuiper Linux release - 2021_r2 from https://wiki.analog.com/resources/tools-software/linux-software/adi-kuiper_images/release_notes? If you run:

    uname -r

    you would see 5.10.63xxx, where xxx depends on which Raspberry Pi you are using. (I'm assuming since you've got a CN0554 that you're connecting it directly to a Raspberry Pi?)

      - it looks like there have been some updates in the rpi-5.15,y related to the sequencer - could this be the issue?

    -Mark

  • Hi Mark, thanks for your feedback.

    I am connecting the CN0554 to a raspberry pi 4 (8GB of RAM). The Kuiper release is 5.10.63-v7l+.

    The libiio version is 0.25 - bbbbc42 (as returned by the iio_library_get_version() function).

    Massimo

  • Given  comments I tried the newly release Kuiper version (2022_r2) to see if it was fixing this issue. Unfortunately it didn't. Running the same example given in the previous post, the only difference is in the voltages applied to the 4 analog inputs (in mV: 1000, 1100, 1200, and 1300, respectively), now the same value is reported on all 4 slots of the buffer. Here is a snippet of the output

       999.56          999.56          999.56          999.56
       999.56          999.56         1100.28         1100.28
      1100.28         1100.28         1100.28         1100.28
      1100.28         1202.51         1202.51         1202.51
      1202.51         1202.51         1202.51         1202.51
      1202.51         1202.51         1202.51         1202.51
      1202.51         1202.51         1202.51         1202.51
      1202.51         1202.51         1202.51         1202.51
      1202.51         1100.28         1100.28         1100.28
      1100.28         1100.28         1100.28         1100.28
      1205.21         1205.21         1205.21         1205.21
      1205.21         1205.21         1205.21         1303.91
      1303.91         1303.91         1303.91         1303.91
      1303.91         1303.91         1000.68         1000.68
      1000.68         1000.68         1000.68         1000.68

    Here is a plot of the data contained in one buffer (128 samples). It should have been 4 straight lines...

    Hopefully, somebody will have a look at this issue.

    Thanks,

    Massimo

  • Hi Bowei, apparently there is more information about this issue at the link you provided than in here. I was glad to read on that post that they are actually working on it albeit for a future release. Hopefully they will let me know when a fix is available.

    Massimo

  • I posted this question almost a year ago, and I haven't received any useful feedback yet. All the Kuiper Linux versions released after this posting behave in the same way as I described in the original posting.

    In my view this was an issue that seriously affected the CN0554 as a product, and that leaves me even more (unpleasantly) surprised by this complete lack of support. 

    Massimo

  • Hi  ,

    This issue was related to the ad7124 driver in the older 5.1x linux branches. It was fixed recently with a backport: https://github.com/analogdevicesinc/linux/pull/2571

    From what I can see, there is not yet a release available with this fix included so current options are either to build the 5.15 linux branch or to replace the boot files with the ones in the rpi_latest_boot.tar.gz archive (https://swdownloads.analog.com/...rpi-5.15.y)

  • Hello  ,

    Thanks for answering my question. I used the 2022_r2 Patch 2 release and replaced the boot files and after that the issue I raised in my original post was fixed.

    Thanks!!

  • I'm glad the issue was fixed, however there might still be a problem: the CPU is losing samples (reading of the data register does not occur soon enough so the ADC overwrites with the next sample). The original bug occurred due to losing samples and the fix does not addresses the underlying problem, just drops subsequent samples until we get back to the first selected channel.

    This might be a problem depending on your use case. You could mitigate this by setting channels to a lower sampling rate.

    Dumitru

  • Hi  ,

    From my (as a user) perspective, the CPU losing samples is one thing, but the libiio API returning wrong values is a different one. At least now I can use the CN0554 with multiple channels.

    I do have some comments on your advice of using lower speeds. During my troubleshooting, I used speeds as low as 100 Samp/sec and the issue was still occurring (before the fix, that is). Considering that, when multiple channels are used, the AD7124-8 sampling rate drops dramatically (with 100 Samp/sec setting and 4 channels, the effective rate is about 8 Hz per channel), I would be very surprised if this was just a CPU speed issue.

    Massimo