The Analog to Digital Converter (ADC) on the BeagleBone is both a Touch Screen Controller (TSC) and a general purpose ADC. Depending on how many of the lines are reserved for the TSC (4, 5, or 8), the remaining lines can be used for reading analog values. One of the lines is connected to the power Management Integrated Circuit (PMIC, TPS65217) of the white Bone, in order to sense the power used by the board. This does not appear to be the case for the new BeagleBone Black.

The basics
To read the analog inputs on your BeagleBone Black, first enable the driver:

echo cape-bone-iio > /sys/devices/bone_capemgr.*/slots

The analog inputs should now be activated and exported to the filesystem. To read their values, just cat the files:

cat /sys/devices/ocp.2/helper.11/AIN1

This will read the analog value of AIN1 (The pin is P9_40). What you see is a voltage between 0 and 1.8V, but in millivolts (0 to 1799). If you tie the pin high by shorting the pin to the analog VDD (P9_32), you will see a 1799. If you tie the pin low to (P9_34, Analog ground), you will see a 0. There is a bug in the driver, so the value you read is actually the previous value you read. For now, just read the value twice. More on that later.

Bug in the ADC driver

Note: This was tested on kernel 3.8.6, the one that came with the early BeagleBone Black.

The driver for the ADC was riddled with errors early on. This manifested itself as getting weird values from the ADC when reading from one or several pins in rapid succession:

Clearly, a negative value is not right. The reason why this occurs is that there is no test to make sure the ADC is finished with sampling the pin. Furthermore, when one pin is read, the reading of this pin triggers the ADC to sample a new value (for all the pins) for the next reading. For further reading, consult the Linux mainline source: ti_am335x_adc.c. This will probably be fixed in later veriosn of the kernel, but if you need a solution now, have a look at these adc-patches and see if you can’t figure it out : )

Troubleshooting
If your analog inputs do not show up at the above spot, make sure the helper module is loaded:

lsmod

This shows a list of loaded kernel modules, make sure “bone_iio_helper” shows up in the list.
If the helper modules is loaded, but the fiels are not in the right place, try searching for them:

find /sys -name *AIN*

This should show you a list of the analog input files. If not, go to forum and rant. Make sure you include the kernel version you are using:

26 thoughts on “Reading analog (ADC) values on BeagleBone black”

What’s the method behind the /sys/devices madness?
I just got a BeagleBone Black and would like to update the PyBBIO library ( https://github.com/alexanderhiam/PyBBIO/issues/18 ) but I’m not clear on all the magic filesystem locations.
Would you happen to know of documentation other than the source code?

Shea, I agree with you that the FS locations created by device tree seem random. The worst part is that the location of some of the devices change depending on the loading order. If you add a cape, this changes the order for when the device is added to the device tree and thus the unique number appended. I think the OCP (On Chip Peripherals to the uninvited) is pretty static [citation needed]. For the Replicape, this means that adding an LCD cape on top changes the locations of the PWM devices. I bet Koen Kooi and Jason Kridner knows about this, the latter has recently written a book on the topic, so there should be something in there about it.
BTW, by using helper drivers, I have more or less abandoned the PyBBIO. Don’t get me wrong, it’s a great library, but with the broken compatibility I’ve found that it’s easier to just use (or make) helper drivers. I’m using SPI, I2C, PWM, analog and the PRU on Replicape, so if you need any these you can have look at the source code for that. Written in Python: Replicape software

Brock, are you having trouble with the PRU on BBB? It should work out of the box, unless you are experiencing a bug that (gulp) I introduced.. Have a look at this thread: BBB PRU bug.

I have a couple of BBBs on my desk, but I am very busy making a new revision of Replicape that is more compatible with the BBB. In the final stage now. Once I have sent it in, I will start blogging about the quirks of BBB. FML (o_0)

hi there, i have 2 BBW (different kernel version) using LM35DZ temperature sensor.
I have problem with the value of the AIN.
in the same condition BBW with kernel 23.2.34
~# cat /sys/devices/platform/omap/tsc/ain1
494

Did you see the in_voltage*_raw devices in the /sys/devices/ocp.2/44e0d000.tscadc/tiadc/iio\:device0/ directory?
(replace the number suffixes where appropriate ) For the BeBoPr, to be backwards compatible, I was scaling the voltage back to raw adc values by using a vsense_scale setting of 228, but now it looks like the in_voltage*_raw devices provide the same results.
– Bas

First of all, your post on Reading Beaglebone Black analogues helped me a lot – thank you.
I am very new to Linux and have a related question and perhaps you can answer it.
I followed the steps to enable the analog driver “echo cape-bone-iio > /sys/devices/bone_capemgr.*/slots”, it works fine and I can read reference input voltage fairly accurate. The problem however is that when I cycle the power to the B3 this analog driver enabling is lost and I must manually enable the driver again. Is there a process I can follow to automatically enable the analog drivers every time I power/reboot the B3?

Thanks for your qucick response. YEs, in this way, we can keep aalog driver persistent. But I can not read analog data using command “cat /sys/devices/ocp.*/helper.*/AIN1″. It is giving me an error indicating ” can’t open ‘/sys/devices/ocp.3/helper.11/AIN0′: No such file or directory”

Before adding “capemgr.enable_partno=cape-bone-iio” in uEnv.txt file, there was no directory named “helper*” in /sys/devices/ocp*. “helper*” directory was getting generated once I enable the driver manually using “echo cape-bone-iio > /sys/devices/bone_capemgr.*/slots” command. But as per your suggestion, I have added “capemgr.enable_partno=cape-bone-iio” in uEnv.txt file and now “helper*” directory is visible but there is no directories named AIN* to read analog data. Also I have tried to grep “iio” word in dmesg but there is no such word in dmesg. Any thoughts?

Yes, this is described above. I have submitted a patch for it, but it has not yet been pulled into the 3.8 kernel. For now, just read it twice and discard the first value, or you could try one of my custom kernels located at distros.replicape.com, but you really have to know what you are doing if you want to get a new kernel! Once downloaded and extracted on your bone, a “make kernel” will install a new kernel. Look at the make files for more info..