Reading analog inputs fast in beaglebone black

3,308 views
Skip to first unread message

Rafael Vega

unread,
May 24, 2014, 4:23:32 AM5/24/14
to beagl...@googlegroups.com

I need to read all 7 analog pins in the BBB every 5 milliseconds. I'm doing so with the following C code:

void main(){
    char value_str[7];
    long int value_int = 0;

    FILE* f0 = fopen("/sys/bus/iio/devices/iio:device0/in_voltage0_raw", "r");

    while(1){
            fread(&value_str, 6, 6, f0);
            value_int = strtol(value_str,NULL,0);
            printf("0 %li\n", value_int);
            fflush(stdout);

            usleep(5000);
            rewind(f0);
    }

Hoever, the cpu usage goes up really high (20%). Is there any way to read the analog inputs differently so that it doesn't use as much CPU? Someone suggested "DMA" but I'm completely lost on that regard...

Any help will be appreciated.

Christian Keck

unread,
May 24, 2014, 6:16:51 AM5/24/14
to beagl...@googlegroups.com
> I need to read all 7 analog pins in the BBB every 5 milliseconds. I'm
> doing so with the following C code:

...

> while(1){
> fread(&value_str, 6, 6, f0);
> value_int = strtol(value_str,NULL,0);
> printf("0 %li\n", value_int);
> fflush(stdout);
>
> usleep(5000);
> rewind(f0);
> }

> Hoever, the cpu usage goes up really high (20%). Is there any way to
> read the analog inputs differently so that it doesn't use as much CPU?

I would replace "printf("0 %li\n", value_int); fflush(stdout);" by
saving the converted values into an array, and print the values only
when the measurement ist finished.

> Someone suggested "DMA" but I'm completely lost on that regard...

That would be for specialists

Christian

Rafael Vega

unread,
May 24, 2014, 10:23:53 AM5/24/14
to beagl...@googlegroups.com
I would replace "printf("0 %li\n", value_int); fflush(stdout);" by
saving the converted values into an array, and print the values only
when the measurement ist finished.

What do you mean when the measurement is finished? I need to read the inputs every 5 milliseconds forever. Is there a "ready" flag or a time to wait after reading the file?

Thanks.

ZubairLK

unread,
May 24, 2014, 1:20:21 PM5/24/14
to beagl...@googlegroups.com
Christian is correct. Don't use printf. It introduces a significant overhead.
remove printf, copy into a variable. Then check and see if you can meet timing. *fingers crossed*

Your email mentioned you wanted to acquire all 7 analog inputs for real time audio every 5ms.
Depending on your level of processing of the audio, you might face difficulty with that. Who knows, might just work.

Is there any correlation regarding timing between the channels? Can you acquire a sample from channel 1, sleep 500ms, acquire from channel 2, sleep 500ms acquire from channel 3,
Or do all samples have to be acquired simultaneously?

ZubairLK

John Syn

unread,
May 24, 2014, 11:24:52 PM5/24/14
to beagl...@googlegroups.com

From: Rafael Vega <email...@gmail.com>
Reply-To: <beagl...@googlegroups.com>
Date: Saturday, May 24, 2014 at 1:23 AM
To: <beagl...@googlegroups.com>
Subject: [beagleboard] Reading analog inputs fast in beaglebone black
You should try the IIO driver which you will find under /driver/IIO/adc/ti_am335x_adc.c. Samples are stored in a buffer which you can read with a user space app. 

Search github for IIO and you will find several user space examples on how to use IIO.

Regards,
John

Any help will be appreciated.

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

John Syn

unread,
May 25, 2014, 12:14:58 AM5/25/14
to beagl...@googlegroups.com
From: Rafael Vega <email...@gmail.com>
Reply-To: <beagl...@googlegroups.com>
Date: Saturday, May 24, 2014 at 1:23 AM
To: <beagl...@googlegroups.com>
Subject: [beagleboard] Reading analog inputs fast in beaglebone black

Here is some additional info on IIO that might be helpful:


Regards,
John

Any help will be appreciated.

--

robert.berger

unread,
May 25, 2014, 2:54:04 PM5/25/14
to beagl...@googlegroups.com
Hi,

Please correct me if I'm wrong, but this is my understanding with a 3.14.x or newer kernel:

Since it looks like you want continuous sampling you might want to use the hardware buffer in iio.
Normally you would use something like the generic_buffer.c [1] as a sample application, but the events were removed from the ti iio driver, so you need to hack the generic test a bit. Here [2] you can find a patch [3] based on which you can create your own patch against 3.14.x

Like this you should be able to let the driver A/D sample and form user space you should be able to read things whenever your process runs.
I don't know your exact problem, but a real-time solution might be needed if you want to get every A/D sample of 7 channels every 5 ms.

Please let me know how things go.

Regards,

Robert

[1] https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/staging/iio/Documentation/generic_buffer.c?id=refs/tags/v3.14.4


TJF

unread,
May 26, 2014, 5:50:50 AM5/26/14
to beagl...@googlegroups.com
Check out libpruio. It makes a PRUSS fetching ADC data.

Using default ADC settings you get 10 ksamples per channel, so ~1.4 ksamples for 7 channels (0.7 ms). Additionally you can customize the ADC settings (open- and sample delay, as well as averaging) to optimize for your purposes.

Rafael Vega

unread,
May 28, 2014, 2:48:56 PM5/28/14
to beagl...@googlegroups.com
Thanks everyone for your replies! I will spend friday and saturday experimenting and will report back here with my findings and probably more questions :)

Rafael Vega

unread,
Jun 12, 2014, 4:25:49 PM6/12/14
to beagl...@googlegroups.com
I ended up using libpruio, the installation instrucions are kind of scattered but it works really well. Thanks!

TJF

unread,
Jun 13, 2014, 2:25:15 AM6/13/14
to beagl...@googlegroups.com
Thanks for feedback. Feel free to mail your suggested improvements for the installation instructions.

srik...@gmail.com

unread,
Jun 18, 2014, 1:06:30 PM6/18/14
to beagl...@googlegroups.com
Rafael,

Can you please post detailed instructions on installing libruio.

Thanks
Srikant

Rafael Vega

unread,
Jun 18, 2014, 4:02:07 PM6/18/14
to beagl...@googlegroups.com
I can take the time to do so tomorrow. Stay tuned :)


--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to a topic in the Google Groups "BeagleBoard" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/beagleboard/9NYdGWOT_Mg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to beagleboard...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

Rafael Vega

unread,
Jun 21, 2014, 6:39:56 PM6/21/14
to beagl...@googlegroups.com, srik...@gmail.com
Here's what I did:


1. Install FreeBasic compiler in BBB



1.2. Uncompress and copy files

   cd bbb_fbc-0.0.2
   cp usr/local/bin/fbc /usr/local/bin/
   cp -R usr/local/lib/freebasic /usr/local/lib/
   
2. Install pruss driver kit for freebasic and BBB.


2.2. Copy files

   cd FB_prussdrv-0.0
   cp bin/libprussdrv.* /usr/local/lib
   ldconfig
   mkdir /usr/local/include/freebasic/BBB
   cp include/* /usr/local/include/freebasic/BBB
   cp bin/pasm/usr/local/bin
   cp bin/PRUSSDRV-00A0.dtbo /lib/firmware

2.3. Install am335x-pru-package 

   apt-get install am335x-pru-package  

2.4. Activate the PRUSS by enabling the tree overlay. This must be done everytime, after each boot or before running your programs. 

   echo PRUSSDRV> /sys/devices/bone_capemgr.9/slots

3. Install libpruio


3.2. Copy files

   cd libpruio-0.0.2
   cd src/c_wrapper/
   cp libpruio.so /usr/local/lib
   cp libpruio.a /usr/local/lib
   ldconfig
   cd ../pruio/
   cp pruio.bi /usr/local/include/freebasic/BBB
   cp pruio.hp /usr/local/include/freebasic/BBB
   cp pruio_pins.bi /usr/local/include/freebasic/BBB

4. Here's a simple example C program that uses the library

   #include <stdio.h>
   #include <unistd.h>
   #include "pruio_c_wrapper.h"
   #include "pruio_pins.h"

   int main(int argc, const char *argv[]) { 
      PruIo *io = pruio_new(0, 0x98, 0, 1);
      if (io->Errr) {
         printf("Initialisation failed (%s)\n", io->Errr);
         return 1;
      }

      if(pruio_config(io, 0, 0x1FE, 0, 4, 0)){
         printf("Config failed (%s)\n", io->Errr); 
         return 1;
      }

      int a = 0;
      int i;
      while(1){
         printf("\r%12o  %12o  %12o  %12o  %4X %4X %4X %4X %4X %4X %4X %4X\n", io->Gpio[0].Stat, io->Gpio[1].Stat, io->Gpio[2].Stat, io->Gpio[3].Stat, io->Value[1], io->Value[2], io->Value[3], io->Value[4], io->Value[5], io->Value[6], io->Value[7], io->Value[8]);
         fflush(STDIN_FILENO);
         usleep(1000);
       }


      pruio_destroy(io);

           return 0;
   }

5. To compile it, here's a makefile:

   all: bbb-io.c Makefile
        gcc -Wall -o bbb-io bbb-io.c /usr/local/lib/freebasic/fbrt0.o -lpruio -L"/usr/local/lib/freebasic/" -lfb -lpthread -lprussdrv -ltermcap -lsupc++ -Wno-unused-variable





TJF

unread,
Jun 22, 2014, 2:07:26 PM6/22/14
to beagl...@googlegroups.com, srik...@gmail.com
Hello Rafael,

thanks for your complete installation instructions. I plan to include them in the next version of the documentation, if you don't mind (at least I like to add a link to your post here).


BTW: In your C code example the destructor pruio_destroy() wont be called in case of an error. This means that the devices wont be restored to their original states.

Rafael Vega

unread,
Jun 24, 2014, 10:17:16 AM6/24/14
to beagl...@googlegroups.com, srik...@gmail.com


thanks for your complete installation instructions. I plan to include them in the next version of the documentation, if you don't mind (at least I like to add a link to your post here).

Of course I don't mind, go ahead and include it :)

family...@googlemail.com

unread,
Jun 25, 2014, 8:36:30 AM6/25/14
to beagl...@googlegroups.com, srik...@gmail.com
Hi, a maybee stupid question regarding this "howto":

What kernel version is needed for this to work?
How to build kernel for pruss support?
Or is the dtbo file doing all the magic?

Reagrds,
Ben

Rafael Vega

unread,
Jun 25, 2014, 9:09:28 AM6/25/14
to beagl...@googlegroups.com, srik...@gmail.com
I'm using a Debian Stable image downloaded from http://beagleboard.org/latest-images


--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to a topic in the Google Groups "BeagleBoard" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/beagleboard/9NYdGWOT_Mg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

TJF

unread,
Jun 25, 2014, 12:08:31 PM6/25/14
to beagl...@googlegroups.com, srik...@gmail.com
Hi Ben!


Am Mittwoch, 25. Juni 2014 14:36:30 UTC+2 schrieb family...@googlemail.com:
Or is the dtbo file doing all the magic?
 
The dtbo file is pretty simple. It only powers on the PRUSS. Here's the dts file to compile:

/* Minimal device tree overlay to activate PRUSS

Licence: GPLv3
(C) 2014 by Thomas{ DoT ]Freiherr[ aT ]gmx[ dOt }net

compile with
   dtc -O dtb -o PRUSSDRV-00A0.dtbo -b 0 -@ PRUSSDRV.dts
*/

/dts-v1/;

/ {
    compatible
= "ti,beaglebone", "ti,beaglebone-black";
    part
-number = "PRUSSDRV";
    version
= "00A0";

    fragment@0
{
        target
= <&pruss>;

        __overlay__
{
            status
= "okay";
       
};
   
};
};

All that 'magic' comes with the libpruio binary.



Am Mittwoch, 25. Juni 2014 14:36:30 UTC+2 schrieb family...@googlemail.com:
What kernel version is needed for this to work?
How to build kernel for pruss support?

libpruio contains
  • ARM software as user interface (can get compiled on every kernel version)
  • PRU software to control the hardware (for ARM33xx CPU family)
So can use any kernel version. (I build the binary on 3.8.13-bone37.)

family...@googlemail.com

unread,
Jun 26, 2014, 9:44:13 AM6/26/14
to beagl...@googlegroups.com, srik...@gmail.com
Cool, Thanks for the info.
When I have some more time i will try it out.
Regards, Ben

BBBx

unread,
Jul 7, 2014, 2:09:19 AM7/7/14
to beagl...@googlegroups.com, srik...@gmail.com
trying to compile the test I get the message: /usr/bin/ld: cannot find -ltermcap
can you tell me how can I solve this issue?

walter harms

unread,
Jul 7, 2014, 5:15:55 AM7/7/14
to beagl...@googlegroups.com


Am 07.07.2014 08:09, schrieb BBBx:
> trying to compile the test I get the message: /usr/bin/ld: cannot find
> -ltermcap
> can you tell me how can I solve this issue?
>


install libtermcap, it is handel part of
* libtinfo-dev
or
* libncurses-dev
http://packages.ubuntu.com/search?searchon=contents&keywords=libtermcap&mode=filename&suite=precise&arch=any

BBBx

unread,
Jul 7, 2014, 7:55:08 AM7/7/14
to beagl...@googlegroups.com, wha...@bfs.de
Thank you. It works.

else...@gmail.com

unread,
Jul 21, 2014, 9:12:12 PM7/21/14
to beagl...@googlegroups.com, srik...@gmail.com
Having trouble compiling because I don't have libsupc++, how do I get that on the beagle?

else...@gmail.com

unread,
Jul 21, 2014, 11:37:20 PM7/21/14
to beagl...@googlegroups.com
Trying to get the libpru stuff to work but it won't compile because I don't have libsupc++. How do I get that on beaglebone using the angstrom distro?

TJF

unread,
Jul 30, 2014, 11:40:40 AM7/30/14
to beagl...@googlegroups.com, else...@gmail.com
Do you mean libpruio?

Which OS are you using? AFAIK, libsupc++ isn't available on Angström (but on Debian/Ubuntu).

mahmou...@hotmail.com

unread,
Sep 16, 2014, 2:50:47 PM9/16/14
to beagl...@googlegroups.com, srik...@gmail.com
Hello sir, I was following your steps but I got an error in the last step. I created a file in "bbb_fbc-0.0.2/FB_prussdrv-0.0/libpruio-0.0.2/libpruio/src/c_wrapper" and named it "bbb-io.c" and pasted the code you wrote. I then created another file named it "Makefile" and pasted "all: bbb-io.c Makefile
        gcc -Wall -o bbb-io bbb-io.c /usr/local/lib/freebasic/fbrt0.o -lpruio -L"/usr/local/lib/freebasic/" -lfb -lpthread -lprussdrv -ltermcap -lsupc++ -Wno-unused-variable" in it. after running "make" command, I got the following:

/usr/bin/ld: cannot find -lncurses
collect2: ld returned 1 exit status
make: *** [all] Error 1

Any ideas how to solve it? I'm running "Linux beaglebone 3.8.13-bone50 #1 SMP Tue May 13 13:24:52 UTC 2014 armv7l GNU/Linux" on my beaglebone black.
I am setting the libpruio library to read from the all the 7 analog pins with a sampling rate of 40KHz at least for each pin. You're help os appreciated. Thanks.

TJF

unread,
Sep 17, 2014, 11:23:02 AM9/17/14
to beagl...@googlegroups.com, srik...@gmail.com, mahmou...@hotmail.com


Hello!


Am Dienstag, 16. September 2014 20:50:47 UTC+2 schrieb mahmou...@hotmail.com:
I got the following:

/usr/bin/ld: cannot find -lncurses
collect2: ld returned 1 exit status
make: *** [all] Error 1
Install libncurses
sudo apt-get install libncurses5-dev

I am setting the libpruio library to read from the all the 7 analog pins with a sampling rate of 40KHz at least for each pin. You're help os appreciated. Thanks.
The maximum sampling rate is 160 kHz for one step and about 22 kHz for 7 steps (TSC_ADC_SS hardware limitations for software triggered ADC start).

Reply all
Reply to author
Forward
0 new messages