Reading the ADCs with C Code

Hey Everyone,

I’m using the Beaglebone ADC on AIN0 (P9-39) to monitor a high voltage. I’ve used a divider (1/100) to put it within the 1.8V range of the ADC.I am using the cape overlay BB-ADC suggested by Derrick Molloy in Exploring BB. I’ve measured the voltage at the pin while using “cat /sys/devices/ocp.3/helper.12” and it agrees with my multimeter measurement at the pin. It seems the helper gives a direct mV value. They agree. Awesome!

I’m trying to use this same technique with my C code, but for some reason I’m getting weird values from my read function. I think it has something to do with reading two bytes from the 12 bit ADC converter. I’m thinking I’m getting some junk on the end or the beginning, but masking and getting rid of the first or last 4 bits does not get the number I received from the cat’ing the helper device.

Am I reading this wrong with my code? Does anyone have any ideas to get the correct 12 bits?

Thanks! I think I gave enough information below.

Test Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include “DDC2.h”

int main ( int argc, const char *argv[] )
{
float voltage;
voltage = atof ( argv[1] );
set_high_voltage ( voltage );
read_raw_high_voltage ( );
return 0;
}

Read Function:

/***********************************************************************

  • Function- read_high_voltage
  • Description- Reads the ADC on AIN0 and returns the measured value of the
  • high voltage.
    ************************************************************************/
    int read_raw_high_voltage(void)
    {

uint16_t fd;
uint16_t value;

uint16_t value1;
uint16_t value2;

//Open “analog0=/sys/devices/ocp.3/helper.12/AIN0”
if ( ( fd = open ( analog0, O_RDONLY) ) < 0 )
{
perror (“SPI: Can’t open device.”);
return -1;
}
read ( fd, &value, 2);
value1=value & 0x0FFF;
value2=value>>4;
printf (“All Bits=%d\n”, value);
printf (“Bits 0-12=%d\n”, value1);

printf (“Bits 4-16=%d\n”, value1);

return(0);
}

From Command line:

./test 60

Output:

Voltage Given=60.0
All Bits= 14389
Bit 0-12=2101
Bit 4-16=899

Measured Voltage from Multimeter= 600mV (measured after 1/100 voltage divider)

Cat from the helper device = 587

/sys/devices/ocp.3/helper.12/AIN0 returns the string '587'. In you C
code you are reading first two characters, '5' and '8', whose ASCII
codes are 0x38 and 0x35. You are collating them as an integer, whose
value indeed turns out to be 14389 (printf %x 14389 returns 3835).

You could use formatted reading (fscanf()), if you don't care for
speed; or google the way to get binary data from the ADC

Hey Everyone,

I'm using the Beaglebone ADC on AIN0 (P9-39) to monitor a high voltage.
I've used a divider (1/100) to put it within the 1.8V range of the ADC.I am
using the cape overlay BB-ADC suggested by Derrick Molloy in Exploring BB.
I've measured the voltage at the pin while using "cat
/sys/devices/ocp.3/helper.12" and it agrees with my multimeter measurement
at the pin. It seems the helper gives a direct mV value. They agree.
Awesome!

I'm trying to use this same technique with my C code, but for some reason
I'm getting weird values from my read function. I think it has something to
do with reading two bytes from the 12 bit ADC converter. I'm thinking I'm
getting some junk on the end or the beginning, but masking and getting rid
of the first or last 4 bits does not get the number I received from the
cat'ing the helper device.

Am I reading this wrong with my code? Does anyone have any ideas to get
the correct 12 bits?

Several generic things may be bothering this:

1) you have interrupts enabled and you're getting a task switch during
the read. Solution: Make the read atomic.

2) the register order can be wrong. Some processors require a
specific order to read 8 bit registers. If this processor has that
same problem and you're not reading the entire register at one gulp,
then that can be a problem. This should be compensated for in the
compiler, though, so interrupts enabled could be more of a problem.

Harvey

Hi Brendan!