TS-7100-Z ADC
The TS-7100-Z supports five 12-bit ADC inputs using the i.MX6UL CPU's integrated ADC. Four of these inputs can sample 0-12VDC or 0-20mA. The fifth can sample 0-50VDC.
The pin assignments and names for accessing each ADC input are:
CN32 pin[1] | Pin label | Schematic name | CPU signal | 6UL GPIO | gpio-line-name | ADC | IIO name | Range |
---|---|---|---|---|---|---|---|---|
27 | 4 | AN_0 [2]
|
6UL_AN_0
|
GPIO1_IO04
|
AN_CH0
|
ADC1_IN4
|
voltage4 | 0-50 V |
25 | 5 | AN_1_STC
|
6UL_AN_1
|
GPIO1_IO05
|
AN_CH1
|
ADC1_IN5
|
voltage5 | 0-12 V |
23 | 8 | AN_2_STC
|
6UL_AN_2
|
GPIO1_IO08
|
AN_CH2
|
ADC1_IN8
|
voltage8 | 0-12 V |
21 | 9 | AN_3_STC
|
6UL_AN_3
|
GPIO1_IO09
|
AN_CH3
|
ADC1_IN9
|
voltage9 | 0-12 V |
19 | 0 | AN_4_STC
|
6UL_AN_4
|
GPIO1_IO00
|
AN_CH4
|
ADC1_IN0
|
voltage0 | 0-12 V |
- ↑ See the TS-7100 IO Terminal Block section for a pinout illustration of the header, which is labeled CN32 on the schematic and silkscreen.
- ↑ The 0-50V
AN_0
(Analog pin labeled 4) signal has an alternate function of being a high-side switch, as discussed in the GPIO section.
To switch an ADC to 0-20mA current-loop receiver mode, the appropriate enable must be set high. These are EN_CL_1
through EN_CL_4
, and are controlled by GPIO commands as shown below.
Pin label | Schematic Name | IIO Name | 0-12 V Select | 0-20 mA Loop Select | read-back[1] |
---|---|---|---|---|---|
5 | AN_1_STC
|
voltage5 | gpioset $(gpiofind EN_CL_1)=0
|
gpioset $(gpiofind EN_CL_1)=1
|
gpioget $(gpiofind EN_ADC1_12V)
|
8 | AN_2_STC
|
voltage8 | gpioset $(gpiofind EN_CL_2)=0
|
gpioset $(gpiofind EN_CL_2)=1
|
gpioget $(gpiofind EN_ADC2_12V)
|
9 | AN_3_STC
|
voltage9 | gpioset $(gpiofind EN_CL_3)=0
|
gpioset $(gpiofind EN_CL_3)=1
|
gpioget $(gpiofind EN_ADC3_12V)
|
0 | AN_4_STC
|
voltage0 | gpioset $(gpiofind EN_CL_4)=0
|
gpioset $(gpiofind EN_CL_4)=1
|
gpioget $(gpiofind EN_ADC4_12V)
|
- ↑ The read-back sense is inverted from the write values, so reading 1 indicates that voltage is being sampled, and 0 indicates that current is being sampled.
Note: | Only the four 0-12 V ADC inputs — corresponding with the pins labeled 5, 8, 9, and 0 in the above tables — can be used as current-loop receivers. |
IIO Access to ADCs
The preferred way to access these ADCs is through the Linux Industrial I/O Subsystem (IIO), which provides sample rates up to 6ksps across all inputs. The simplest API it offers for slow speed acquisition is via sysfs (/sys):
cat /sys/bus/iio/devices/iio:device0/in_voltage{4,5,8,9,0}_raw
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, uint32_t max_mv)
{
/* scale a 0-4095 raw reading to 0-max_mv mV */
uint32_t val = raw * max_mv / 4095;
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, "voltage4", false);
chn[1] = iio_device_find_channel(dev, "voltage5", false);
chn[2] = iio_device_find_channel(dev, "voltage8", false);
chn[3] = iio_device_find_channel(dev, "voltage9", false);
chn[4] = iio_device_find_channel(dev, "voltage0", 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, (i == 0) ? 50000 : 13325));
}
return 0;
}
The Python bindings currently achieve about 2ksps with similar code.
#!/usr/bin/env python
import iio
ctx = iio.Context('local:')
dev = ctx.find_device('2198000.adc')
scan_channels = ["voltage4", "voltage5", "voltage8", "voltage9", "voltage0"]
for chan_name in scan_channels:
chan_n = int(chan_name[len("voltage"):])
chn = dev.find_channel(chan_name)
raw = int(chn.attrs['raw'].value)
# Scale 0-4095 raw value to 0-12 V or 0-50 V for ADC 4.
voltage_range = 50. if chan_n == 4 else 12.
scaled = raw * voltage_range / 4095
print('ADC1_IN{}={:.3f}'.format(chan_n, scaled))