Better Analog Inputs - modmaker/BeBoPr GitHub Wiki
The AM335X processor on the BeagleBone has eight analog inputs, of which 7 are available on the P9 expansion connector.
Regrettably, since the original BeagleBone, the analog inputs seem very prone to noise and other unpredictable behaviour. This might still be a driver issue, but nothing has improved for over a year time. In fact, it's gotten worse with the BBB. That's the reason this page was written.
It looks like the inputs can be used either for touchpanel or as analog inputs for the thermistors, but not for both at the same time. Using the ADC for analog inputs requires heavy software filtering of the results, as sometimes reading completely fails, and at other times the result of a neighbour channel is returned. Also, some of the inputs have a square wave signal superimposed that's probably meant for a touchscreen. That signal is even present when the converter is used in adc-only mode!
Luckily, some gut-feeling during the design of the BeBoPr provides a way out. On the bottom of the board there's a tiny footprint for a quad channel I2C ADC. The four ADC inputs are available as via's (the row of 4 holes right above the footprint). Three short pieces of wire will connect the inputs to the analog thermistors signals.
Warning: The pin pitch of the ADC is 0.5 mm, only do this if you're used to mount this kind of fine-pich components! Accidentaly shorting the I2C signals will prevent the BeagleBone from detecting capes properly.
The device marked U9 is the empty footprint for the 12-bit, 4-channel, I2C ADC. The device is spec'd at 12-bits, but only 11 are available when used single-ended.
Update 20130718 - See at the end of this page for instructions how to use the ADS1115 converter.
Update 20130717 - The ADS1115 will not work with the Linux driver that comes as part of the 3.8.13 kernel. Changes to that driver are necessary for proper timing and to get the extra resolution into the result. A patch for using the ADS1115 with the ads1015 driver will follow soon, after some more extensive testing.
Either an ADS1015 (11-bits) or ADS1115 (15-bits) will do. The latter is twice as expensive as the first and much slower. The ADS1015 still gives a resolution of less than 1 Kelvin per bit from 25'C up to 300'C (less than 0.25 Kelvin between 65'C and 225'C). The noise seems to be less than 1 bit, compare that with the AM335X's analog inputs!
On the top side of the board, solder three thin (wire-wrap 0.25mm / AWG30 will do) wires as shown on the photo. This connects the thermistor signals to the ADS1015 ADC.
The proper driver is not enabled by default in the usual kernels. So either a compatible ads1015 kernel module has to be found, or the kernel must be compiled with the adc driver built-in.
For a new kernel, edit the configuration file and change the line
# CONFIG_SENSORS_ADS1015 is not set
into
CONFIG_SENSORS_ADS1015=y
and rebuild the kernel.
Once done, a Device Tree Overlay fragment as shown below will enable the ADC converter and provide a sysfs interface.
The fragment given here configures the programmable gain amplifier (PGA) for an input range of 0-2048 mV. The thermistor signals vary between 0 and 1.60 Volt. With the PGA, the precision can be improved at higher temperatures by selecting a smaller range, if the need should arise.
/* ----------- ADS1015 ------------ */
// reserve resources for exclusive use - not needed
// set pinmux - not needed
// attach driver
fragment@61 {
target = <&i2c2>;
__overlay__ {
// needed to avoid gripping by DTC
#address-cells = <1>;
#size-cells = <0>;
status = "okay"; // probably already set
ads1015: ads1015@48 {
compatible = "ti,ads1015";
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x48>;
channel@1 {
reg = <4>;
ti,gain = <2>;
ti,datarate = <2>;
};
channel@2 {
reg = <5>;
ti,gain = <2>;
ti,datarate = <2>;
};
channel@3 {
reg = <6>;
ti,gain = <2>;
ti,datarate = <2>;
};
};
};
};
The Linux kernel Documentation section contains information on the gain and conversion rate settings for the ADS1015.
After booting the kernel and loading an overlay including the above fragment, the ADC results can be found in the sysfs tree as shown by the simple script below:
for i in 4 5 6 ; do
printf "Channel #%s: %4s mV\n" $i `cat /sys/bus/i2c/drivers/ads1015/1-0048/in${i}_input`
done
This will produce something like the following output:
Channel 4 reads 1605 mV Channel 5 reads 1606 mV Channel 6 reads 1577 mV
The last reading (1577 mV) is from a channel that has a thermistor attached. The other channels read the open input / full-scale value.
Here is a patch for the ADS1015 driver to include support the ADS1115. Documentation is included. As extra feature, a high resolution option can be turned on in the device-tree overlay. To do this, add a line to the ads1015 overlay fragment shown above. At the ads1015 top level, just before the child channel nodes, add:
hi_res = <1>;
This will add 3 decimals to the millivolts that are shown via sysfs. Effectively giving microvolt resolution. As can be seen in the example output below. The last (channel 0) reading is a differential reading and was used to test the driver.
Channel 4 reads 0.250 mV
Channel 5 reads 1598.187 mV
Channel 6 reads 1579.625 mV
Channel 0 reads -1024.000 mV
And on the LCD (Wondering if it's a resistive or a reflective touchscreen!)