The ADC Pi and ADC Differential Pi from AB Electronics UK use the MCP3424 analogue to digital converter from Microchip. The MCP3424 has programmable bit rates from 12 bits to 18 bits, and the number of samples that can be taken each second depends on the bit rate you have chosen. According to the datasheet for the MCP3424, the data rates are as follows.
Samples Per Second | Bit Rate |
---|---|
240 | 12 bit |
60 | 14 bit |
15 | 16 bit |
3.75 | 18 bit |
After getting several enquiries about the actual data rate available on the Raspberry Pi, we decided to do some experiments and show you the results. We decided to test the ADC Pi on a Raspberry Pi 3 using the Python 2 programming language. We provide our own Python library for the ADC Pi, which we used for the experiment.
First, we wrote a simple program to initialise the ADC Pi and take 1000 samples. The current time was recorded before and after the 1000 samples were taken; from that, the total elapsed time and the number of samples per second were calculated. We also recorded the voltage for each sample and calculated the average voltage at the end. The program we used is shown below.
#!/usr/bin/env python from ADCPi import ADCPi import time adc = ADCPi(0x68, 0x69, 12) adc.set_conversion_mode(1) samples = 1000 value = [] start_time = time.time() for x in range(0, samples): value.append(adc.read_voltage(1)) elapsed_time = time.time() - start_time samplerate = samples / elapsed_time averagevalue = float(sum(value))/max(len(value), 1) print("%d samples in %.3f seconds" % (samples, elapsed_time)) print("%.3f samples per second" % samplerate) print("%.6fV average" % averagevalue)
The MCP3424 supports two modes of operation: one-shot sampling and continuous sampling. During one-shot sampling, the ADC wakes up from a sleep state, takes a sample, sends the result to the Raspberry Pi and then goes back to sleep. During continuous sampling mode, the ADC takes samples continuously and returns the last sample when requested. One-time sampling uses less energy than continuous sampling mode but at the cost of a slower sample rate as it takes time to wake up and sleep between samples.
First, we tested the ADC Pi by reading 1000 samples from a single channel in continuous sampling mode.
Bit Rate | Samples Per Second |
---|---|
12 |
252.104 |
14 |
63.736 |
16 |
15.974 |
18 |
3.996 |
The results above show that the actual sample rate from the ADC Pi is slightly higher than the manufacturer's specifications.
Next, we tested the ADC Pi by reading 1000 samples from a single channel in a one-shot sampling mode. This was changed with the set_conversion_mode() function:
adc.set_conversion_mode(0)
Bit Rate | Samples Per Second |
---|---|
12 |
163.472 |
14 |
57.055 |
16 |
15.546 |
18 |
3.963 |
As the results above show, there are significant delays when using one-shot mode on the 12 and 14-bit rates, with only short delays on the 16 and 18-bit modes. The one-shot mode may be helpful if you only need to take single samples at well-spaced intervals, but if performance is more critical than power usage, then it may be better to use continuous conversion mode.
When reading from several channels on the same MCP3424 ADC, it takes a short time for the ADC to change the channel, which can impact the sample rate. To test this, we modified the Python program to read from two channels, as shown below and then repeated the same tests above.
#!/usr/bin/env python from ADCPi import ADCPi import time adc = ADCPi(0x68, 0x69, 18) adc.set_conversion_mode(1) samples = 100 value = [] start_time = time.time() for x in range(0, samples): value.append(adc.read_voltage(1)) value.append(adc.read_voltage(2)) elapsed_time = time.time() - start_time samplerate = (samples * 2) / elapsed_time averagevalue = float(sum(value))/max(len(value), 1) print("%d samples in %.3f seconds" % (samples, elapsed_time)) print("%.3f samples per second" % samplerate) print("%.6fV average" % averagevalue)
Reading 1000 samples from two channels in continuous sampling mode.
Bit Rate | Samples Per Second |
---|---|
12 |
173.759 |
14 |
58.2 |
16 |
15.627 |
18 |
3.969 |
Reading two channels in continuous conversion mode is slightly faster than reading from one channel in one-shot mode. This is probably because the time it takes to change channels is similar to the time it takes to wake and sleep in one-shot mode.
Reading 1000 samples from two channels in one-shot sampling mode.
Bit Rate | Samples Per Second |
---|---|
12 |
163.209 |
14 |
57.023 |
16 |
15.546 |
18 |
3.961 |
In one-shot mode, the sample rate for two channels is only fractionally slower than for one. This shows that if you use one-shot mode, there will be less performance penalty when reading from 2 or more channels.
Improving Performance When Reading Multiple Channels
The ADC Pi and ADC Differential Pi contain two MCP3424 ADC chips you can read from. As the MCP3424 only adds an additional delay when switching channels, it is possible to read a single channel from each chip without causing any additional delay.
We will read from channels 1 and 5 on an ADC Pi to demonstrate this. This will read from the first channel on chip U2 and the first channel from chip U3 in continuous conversion mode. The Python code was modified to read from channels 1 and 5, as shown below, and the total time to read 1000 samples from both channels was recorded for each bit rate.
#!/usr/bin/env python from ADCPi import ADCPi import time adc = ADCPi(0x68, 0x69, 18) adc.set_conversion_mode(1) samples = 100 value = [] start_time = time.time() for x in range(0, samples): value.append(adc.read_voltage(1)) value.append(adc.read_voltage(5)) elapsed_time = time.time() - start_time samplerate = (samples * 2) / elapsed_time averagevalue = float(sum(value))/max(len(value), 1) print("%d samples in %.3f seconds" % (samples, elapsed_time)) print("%.3f samples per second" % samplerate) print("%.6fV average" % averagevalue)
Bit Rate | Samples Per Second |
---|---|
12 |
504.217 |
14 |
127.429 |
16 |
31.943 |
18 |
7.991 |
As you can see, the time to read 1000 samples from two channels in independent chips is far faster than reading two from a single chip. If your application requires more than one input, spreading your inputs across the two MCP3424 chips may be beneficial to increase the sample rate.
These tests were performed on a Raspberry Pi 3 running Raspian Jessie using Python 2. Python is an interpreted language that is slower than a compiled language such as C. When reading from an ADC Pi, this performance difference will be less noticeable as the main limiting factor is the time needed to wait for each sample.
If your application does other processing between each ADC read, you may see slower sample rates than we have listed above. Suppose you need to get the most performance out of your application. In that case, we have a C library for the ADC Pi and ADC Differential Pi that should boost your application speed. Still, it will not make any noticeable difference to the sample rate from the ADC as the internal circuitry in the MCP3424 chip limits that.