TS-7250-V3 ADC

From embeddedTS Manuals

This board supports 5 channels of 12-bit ADC using an integrated ADC in the i.MX6UL CPU. All channels can sample 0-30VDC, but channels 1-3 can optionally sample 0-20mA as a current loop. To minimize noise, the ADC pins use a dedicated analog ground available on the even pins of the header. See the #ADC Header section for more details.

These ADCs are accessed through the IIO layer in Linux. This provides ADC samples up to 6ksps between all channels. The simplest API for slow speed acquisition is through iio_attr:

iio_attr -c 2198000.adc voltage0
iio_attr -c 2198000.adc voltage1
iio_attr -c 2198000.adc voltage5
iio_attr -c 2198000.adc voltage8
iio_attr -c 2198000.adc voltage9
ADC Header Pin Schematic Name IIO device IIO name Voltage Current loop
1 AN_CH1 2198000.adc voltage0 0-30VDC 0-20mA
3 AN_CH2 2198000.adc voltage1 0-30VDC 0-20mA
5 AN_CH3 2198000.adc voltage5 0-30VDC 0-20mA
7 AN_CH4 2198000.adc voltage8 0-30VDC N/A
8 AN_CH5 2198000.adc voltage9 0-30VDC N/A

The current loops are enabled/disabled with GPIO:

gpioset 20ac000.gpio 7=0 # AN_CH1 voltage
gpioset 20ac000.gpio 8=0 # AN_CH2 voltage
gpioset 20ac000.gpio 9=0 # AN_CH3 voltage

gpioset 20ac000.gpio 7=1 # AN_CH1 current
gpioset 20ac000.gpio 8=1 # AN_CH2 current
gpioset 20ac000.gpio 9=1 # AN_CH3 current

The libiio library provides simple access to the IO. The fastest API is in C which will get about 6ksps.

/* Build with gcc adc-test.c -o adc-test -liio 
 * Gets ~6ksps
 * At the time of writing this does not support the buffer interface */

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <iio.h>

uint32_t scale_mv(uint32_t raw)
{
	/* fractions $((330+22)) 22 2500 4095 */
	uint32_t val = raw * 9;
	val += (raw * 629) / 819;

	return val;
}

int main(int argc, char **argv)
{
	static struct iio_context *ctx;
	static struct iio_device *dev;
	static struct iio_channel *chn[5];
	int i, ret;
	long long sample;

	ctx = iio_create_default_context();
	assert(ctx);
	dev = iio_context_find_device(ctx, "2198000.adc");
	assert(dev);

	chn[0] = iio_device_find_channel(dev, "voltage0", false);
	chn[1] = iio_device_find_channel(dev, "voltage1", false);
	chn[2] = iio_device_find_channel(dev, "voltage5", false);
	chn[3] = iio_device_find_channel(dev, "voltage8", false);
	chn[4] = iio_device_find_channel(dev, "voltage9", false);

	for (i = 0; i < 5; i++) {
		ret = iio_channel_attr_read_longlong(chn[i], "raw", &sample);
		assert(!ret);
		printf("AN_CH%d_mv=%d\n", i, scale_mv((uint32_t)sample));
	}

	return 0;
}

The python bindings currently achieve about 2ksps with similar code.

#!/usr/bin/env python3

import iio

ctx = iio.Context('local:')
dev = ctx.find_device('2198000.adc')

scan_channels = ["voltage0", "voltage1", "voltage5", "voltage8", "voltage9"]
i = int(0)
for chan_name in scan_channels:
	chn = dev.find_channel(chan_name)
	raw = int(chn.attrs['raw'].value)

	# Scale 0-4095 to 0-2500(mV)
	scaled = raw * (2.5/4095)

	# Scale voltage divider on the pin
	r1 = 330
	r2 = 22
	v = scaled / (r2 / (r1 + r2))

	i += 1
	print('AN_CH{}_V={:.3f}'.format(i, v))