06-Jun-2014
7 channels of the ADC are available on the expansion port of the Beaglebone Black. Accessing them can seem like a daunting task at first but it is quite simple once you get the hang of it.
The kernel that ships with the BBB as of 27 July doesn't support the stuff below. So compile one from the latest sources available at
https://github.com/beagleboard/kernel/tree/3.8.
If you don't know how to compile the latest kernel sources, check the following links for help on how to compile the kernel.
http://beagleboard.org/linux
http://wiki.beyondlogic.org/index.php/BeagleBoneBlack_Building_Kernel#Compiling_the_BeagleBone_Black_Kernel_2
http://eewiki.net/display/linuxonarm/BeagleBone+Black
After booting the BBB, you have to configure the ADC pins and enable the Touchscreen/ADC (TSADC) module in the processor. This is done via the device tree(DT) files.
DT is a standard format since kernel 3.8 that tells the kernel what it needs to do to enable the TSADC module and configure the ADC pins.
Thanks to the great people at BB.org, you only need to do this
echo BB-ADC >
/sys/devices/bone_capemgr.*/slots
Check that it loaded correctly using
dmesg
You can also list the current configured peripherals using
cat
/sys/devices/bone_capemgr.*/slots
Now checking the analogue value at one instant is simple
All you need to do is type the following
cat /sys/bus/iio/iio:deviceX/in_voltageY
_raw
where X is your adc device number and usually 0.
And Y is your analogue channel number.
Some people might be happy with one sample every once in a while in their applications.
However, the ADC is capable of much more. If you need to sample a signal continuously via a C/C++ application from the userspace, you are in luck.
The am335x driver is a standard IIO driver. And the IIO subsystem provides a sample test application to test the driver. Or in our case, to read from the driver.
The test application can be found in your kernel sources in the drivers/staging/iio/Documentation directory titled generic_buffer.c
Or if you want to take the easy route, check the following link for sources.
https://github.com/ZubairLK/adc-iio-continuous-sampling-userspace
There are two parts to continuous sampling.
Configuring the ADC and the buffer.
Triggering the driver to tell it when to start filling in the buffer.
The IIO subsystem supports a trigger mechanism which is separate from the main ADC driver. The ADC driver supports any standard IIO trigger. And IIO provides trigger files which enable triggering via GPIOs or sysfs files.
Here I'll explain the sysfs way of doing things.
To add a sysfs trigger file type the following
echo 1 > /sys/bus/iio/iio_sysfs_trigger/add_trigger
this creates a trigger directory in
/sys/bus/iio/trigger0
Note: If you dont see this directory. You don't have a supported kernel. Compile the one using the latest sources.
Running the following pulses the trigger.
echo 1 >
/sys/bus/iio/trigger0/trigger_now
The trigger alone is useless. We need to connect this trigger to the adc driver.
Compile generic_buffer.c from the above github repo.
Then run the file using the following parameters
./generic_buffer -n TI-am335x-adc -t sysfstrig1 -l 128
The application searches for an IIO driver named 'TI-am335x-adc'.
Connects the trigger named "sysfstrig1" to the driver.
And configures the buffer size for 128 samples.
You might have noticed that you haven't exactly specified which channel you wish to sample. That is enabled separately via sysfs.
All this might seem confusing at first. But the IIO subsystem is designed to be highly configurable and adaptable to accommodate a variety of peripherals such as accelerometers, gyros, adcs etc.
Enabling which channel to sample using the triggered buffer mechanism is as simple as
echo 1 > /sys/bus/iio/iio:deviceX/scan_elements/in_voltageX_en
Where X is the channel number.If you wish to enable another channel. Go ahead. The generic_buffer application will list both channels. Just note that the buffer is common for both channels.
e.g. 128 will result in 64 samples of 2 channels.
generic_buffer.c is just a starting point for your userspace application.
To sum up, you need to run the following to read continuously from the ADC.
echo 1 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger
echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage7_en
echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage5_en
/home/root/main -n TI-am335x-adc -t sysfstrig1 -l 128
And then run this in another terminal to trigger the driver to start sampling
echo 1 >
/sys/bus/iio/trigger0/trigger_now
The generic_buffer application will display the length of samples.
Enjoy hacking with the BBB.
Leave a comment if you have a question or notice a bug somewhere.