Home / Tutorials / BeagleBone Tutorial / Beaglebone Black ADC: Reading Analog Voltages

# Beaglebone Black ADC: Reading Analog Voltages

One of the most important things your microcontroller can do is read analog voltages. It is important particularly in interfacing with sensors where most throw varying voltage levels that represent varying physical quantities (temperature, pressure, etc.). Microcontrollers, including the Beaglebone Black, have analog to digital converters to do this. Here I will show you how to use the Beaglebone Black ADC module.

If this is your first time reading my site, you must know that:

My BBB runs on Ubuntu 16.04 LTS with kernel 4.4.9-ti-r25. There is a slight difference on this distro and with others. The differences will be included in this tutorial

#### Some ADC Math

The BBB has a 12-bit ADC module with a 1.8 V reference. The AM335x, which is the BBB's CPU, uses successive approximation and can take 200,000 samples per second. The digital value can be calculated using the formula:

$D = \frac{Vin * (2^n - 1)}{Vref}$

This means the Beaglebone Black can read voltage levels from 43.96 uV to 1.8 V. If your sensor goes above 1.8, then you need additional circuits to scale down the voltage.

#### The Device Tree

The Beaglebone Black ADC function is not enabled by default. You need this device tree to enable it:

As you can see above, the pins P9.39, P9.40, P9.37, P9.38, P9.33, P9.36, P9.35 are your analog input pins. Compile the above .dts file to a .dtbo binary object:

The compiled .dtbo object must then be moved to /lib/firmware:

Both the .dts and .dtbo files are already in the /lib/firmware in the latest debian and angstrom distro

The next step is to load the device tree fragment into the cape manager using:

For debian and ubuntu, the slots location is:

You can check if it's loaded by doing:

I don't have any other device tree overlay loaded so it's the only thing you can see.

Shameless plug but you have to grab this board. It's very much like the Beaglebone Black only smaller:

If the above steps are successful then the /sys/bus/iio/devices folder will now have been created.

The five analog channels (AIN0 to AIN5) are represented by the in_voltagex_raw files you see above. To read the input on a particular channel, just do:

I didn't connect anything so mine reads 3914 (which I believe is due to noise voltages).

#### Beaglebone Black ADC Continuous Reading

So far we are reading analog voltages in one-shot mode. Most applications need continuous reading of input values. For continuous mode, we need a buffer to capture the input values while the BBB is doing something else. The buffer can be enabled by doing:

The first line tells which analog channel to scan. Just change the x in in_voltagex_en if you need a different analog channel. The second line specifies the length of the buffer and the last line enables the buffer.

The kernel source has a sample application located at drivers/staging/iio/Documentation/ named generic_buffer.c. If you're like me who's lazy to download the kernel source, here's the generic_buffer.c file.

Open the nano file editor

And copy-paste the code above.

However, this code uses hardware trigger to fire up continuous ADC. You need the patch file to disable the hardware trigger.

Again, open the nano editor

and copy-paste the above code.

Run the patch command using

You'll also need the iio_utils.c file and the iio_utils.h file and must be saved to the same directory as the generic_buffer.c file. Compile all the files using:

Now we have an executable command to print the analog values! To use the file, just type:

Where 5 is the buffer length and 3 is the number of iterations. The above command will print 5 readings three times:

If you need to go back to one-shot mode then just do:

That's all to it. Next I'm planning to use the analog readings and put them into a web page hosted by the BBB. Come back to this site for updates!

## Controlling a Servo Motor with BoneScript

Using the Beaglebone Black's PWM Bonescript also includes an analogWrite function which utilizes the 8 …

### 2 comments

1. ABDUL RAHEEM ANSARI

nice to read...

2. The math is wrong in the 'Some ADC Math'. 1.8V / 4096 = 439.5uV not 43.96uV.

This site uses Akismet to reduce spam. Learn how your comment data is processed.