ADC Pi: Simultaneous measurements?
The ADC Pi is an Analogue to Digital converter for the Raspberry Pi
17/01/2020
Posted by:
aa3025
is it possible to make continious simultaneous measurements on 8 channels?
I just started playing with boards today (got 2 x ADC Pi) and in the demo examples, channels are sampled in "serial" fasion, e.g. do N samples on one channel, then do N samplas on another chanel (continiously or one off) etc. It is in a loop. So there is a time delay between sampling one channel and then another.
Can I say "do N samples continiously on channels [1-8]" (at least within one board), so that each recorded sample on each channel is acquired approximately at the "same" time instant?
I found it great that I can sample one channel in a loop in one terminal and can sample another channel independently in another terminal etc. So, if there is no way to do them "simulteneously" in continious mode, may be it is possible to use openmpi/mpirun to launch "simultaneously" (kind of) acquisitions on each channel as a separate mpi thread?
Regards
Alex
17/01/2020
Posted by:
andrew
Unfortunately, it is not possible to read from the ADC channels simultaneously as the ADCs only support reading from a single channel at a time.
We have an article in our knowledge base which goes into detail about the sample rates of the ADCs used on our ADC Pi and ADC Differential Pi and how to maximise the performance. Hopefully, this will be useful in helping you to get the maximum ADC sample rate for your project.
17/01/2020
Posted by:
aa3025
but you are saying "ADCs only support reading from a single channel at a time"
but then how can I read in two different channels of the same ADC seemingly'independently' from two different processes (each doing inf. loop of 1-off readings on the same ADC from different channels). So it is possible to access another channel while different channel being read already by another process.... perhaps not If two processes accessing different channels in continuous mode though? need to try that....
Alex
17/01/2020
Posted by:
aa3025
21/01/2020
Posted by:
aa3025
If I sample with the same single script 2 ADC Pi boards, I get half of that, around 12 Hz per 16 channels (here I mean 1 sample is when each of 16 channels takes one reading, so 16 readings=1 sample, so "true" speed would be 16*12Hz, which does not help for "multichannel measurements")
Now if I launch 2 python scripts (roughly "simultaneously") instead, one per single ADC Pi board (each sampling 8 channels in cont. mode), they will run on separate CPU-cores (I can see that in "top") and I get effectively 21 Hz sampling rate with 16 channels (2 boards):
pi@adc-raspi3:~/ABElectronics_Python_Libraries/ADCPi/demos $ ./continious_1.py & ./continious_2.py
[4] 3904
100 samples in 4.720 seconds on 8 channels of board 2
21.185 samples per second
100 samples in 4.720 seconds on 8 channels of board 1
21.186 samples per second
[3] Done ./continious_1.py
Both finish practically identically by time. I used here my old RPi 2, need to try the same with Pi 4 soon... My hope is to use 1 CPU per ADC PI board, so if I can get 8 x 4 CPU = 32 channels per one RPi, that may suffice for my purpose...
Alex
21/01/2020
Posted by:
andrew
It is interesting that you have managed to increase the sample rate across the ADC chips by using multiple scripts. One problem you may run into is if two scripts try to access the I2C port simultaneously they may crash as only one process can hold the bus open at a time.
It may be possible to modify the ADC Pi python library to make it read from several ADC chips simultaneously. At the moment when it reads a sample, it sends a request to the ADC to start sampling and then sits in a while loop waiting until the sample is ready. I will look into whether there is a way to change the library so that it can check several ADC chips at the same time without blocking the I2C bus.
21/01/2020
Posted by:
aa3025
Thanks
Alex
22/01/2020
Posted by:
andrew
I have spent the day trying to improve the performance when sampling from the ADC Pi and I have managed to make some performance gains by using threading in Python.
I first updated the demo_speedtest.py file to read from all 8 channels and record the overall sample rate to give me a baseline to work from. The results were:
Bit Rate: 12 - 214.82 samples per second
Bit Rate: 14 - 64.29 samples per second
Bit Rate: 16 - 16.32 samples per second
Bit Rate: 18 - 4.10 samples per second
Next, I created a new file demo_speedtestthreaded.py which splits the ADC reads from each chip into a separate thread. This allowed the program to read from both chips at the same time. The results were almost a doubling in performance.
Bit Rate: 12 - 434.87 samples per second
Bit Rate: 14 - 123.65 samples per second
Bit Rate: 16 - 31.94 samples per second
Bit Rate: 18 - 8.05 samples per second
I made a couple of changes to the main ADCPi.py library to improve its threading performance, so you may want to update it to the latest version.
I also changed the speed of the I2C bus to be 1MHz which is the maximum speed supported by the ADC chip. If you have not done this on your Raspberry Pi you can find out how to do it in our I2C tutorial.
In theory, if you use two ADC Pi boards and create a new thread for each chip that should give you a performance improvement but the gains will probably not be as big as you are still limited by the speed of the I2C bus. I tried creating a separate thread for each channel but that just caused timeout errors where it tried to switch channels before getting the results from the first one so you will be limited to one thread per ADC chip.
These tests were all done on a Raspberry Pi 3+ so you may see some small improvements using a Raspberry Pi 4. The other way to improve the sample rate would be to use a compiled language like C or C++ instead of Python.
Hopefully, the new threaded demo will help you improve the performance of your program.
22/01/2020
Posted by:
aa3025
That updated ADCPi library supposed to work also with ADC Pi differential? (I've got recently 4 differential boards )
Thanks a lot
Alex
22/01/2020
Posted by:
andrew
23/01/2020
Posted by:
andrew
I have updated the ADC Differential Pi library with the changes I made to the ADC Pi library so it should now work better in threaded applications.
23/01/2020
Posted by:
aa3025
Regards,
Alex
30/01/2020
Posted by:
aa3025
After setting i2c bus speed to 1Mhz as you suggested and with updated ver of your code (demo-speedtestthreaded.py) I have 222.54 Sps @12bit. So can't see actually your 434 Hz. Hence for all 8 channels that would be about 28 Hz.
Now I got 32 Channels across 4 ADCDifferentialPi boards.
What I did next is created py script (without threads in python) for each ADC -- 8 scripts in total, each for certain 4 channels corresponding to each ADC. When run them simultaneously I get about 42 Hz per each ADC and since they seemingly start and stop almost at the same time, that should do 42 x 32ch = 1344 Sps ?
i used pi4 this time. Can see about 40 % cpu load for your demo_threaded (8 channels only)
and about 6-7% per process (so again about 48-56% cpu in total) for my multiprocess approach (8 proc x 4 chan).
pi@adc-raspi4:~/ADC/ABElectronics_Python_Libraries/ADCDifferentialPi/demos $ clear; ./continious_1A.py & ./continious_1B.py & ./continious_2A.py & ./continious_2B.py & ./continious_3A.py & ./continious_3B.py & ./continious_4A.py & ./continious_4B.py &
[1] 1237
[2] 1238
[3] 1239
[4] 1240
[5] 1241
[6] 1242
[7] 1243
[8] 1244
pi@adc-raspi4:~/ADC/ABElectronics_Python_Libraries/ADCDifferentialPi/demos $ 200 samples in 4.175 seconds on 4 channels of board 2.2
47.902 samples per second
200 samples in 4.561 seconds on 4 channels of board 3.2
43.852 samples per second
200 samples in 4.638 seconds on 4 channels of board 3.1
43.124 samples per second
200 samples in 4.648 seconds on 4 channels of board 1.1
43.026 samples per second
200 samples in 4.653 seconds on 4 channels of board 4.1
42.983 samples per second
200 samples in 4.694 seconds on 4 channels of board 2.1
42.604 samples per second
200 samples in 4.696 seconds on 4 channels of board 1.2
42.591 samples per second
200 samples in 4.716 seconds on 4 channels of board 4.2
42.410 samples per second
[1] Done ./continious_1A.py
[2] Done ./continious_1B.py
[3] Done ./continious_2A.py
[4] Done ./continious_2B.py
[5] Done ./continious_3A.py
[6] Done ./continious_3B.py
[7]- Done ./continious_4A.py
[8]+ Done ./continious_4B.py
pi@adc-raspi4:~/ADC/ABElectronics_Python_Libraries/ADCDifferentialPi/demos $
... I think its time for me to switch to C and MPI... (1 MPI process per ADC I guess)
Alex
30/01/2020
Posted by:
andrew
I just tested the demo-speedtestthreaded.py script again and on the Pi 3+ I got 434.67 SPS at 12-bit and on the Pi 4, I got 463.83 SPS so I am not sure why you are getting a slower sample rate.
The reason why the scripts start and stop almost at the same time is probably due to the a.join() and b.join() lines which make the loop wait until both threads have completed before starting the next loop. I had to add that in as otherwise, it would start another loop before the first one completed causing it to try and read from several channels on the same chip simultaneously causing the program to crash.
Switching to C should drop the CPU load on your Raspberry Pi. Python being an interpreted language is not very efficient compared to compiled languages like C and the sort of things you are trying to do is very IO-intensive. With C you can talk to the hardware at a lower level so you are not reliant on several layers of software libraries.
31/01/2020
Posted by:
aa3025
31/01/2020
Posted by:
aa3025
OK, I now modified your demo_speedtestthreaded.py to have 8 queues (4 ADCDiff. boards).
I've got 71% of CPU @ 50C deg usage during the test (I did not use cpu fan, just a small sink), results are
Testing 100 samples---- This may take some time
Bit Rate: 12
1144.51 samples per seconds
35.77 Hz Acquisition rate per channel
---------------------------------------------
Bit Rate: 14
414.25 samples per seconds
12.95 Hz Acquisition rate per channel
---------------------------------------------
Bit Rate: 16
117.89 samples per seconds
3.68 Hz Acquisition rate per channel
---------------------------------------------
Bit Rate: 18
29.93 samples per seconds
0.94 Hz Acquisition rate per channel
On 1 ADCDiff.board Ive got about 420 sps (52.5 Hz per channel). Then On 4 boards it drops down to 35 Hz/channel @12 bit.
It is a bit slower than it was with my multi-process approach (35 Hz vs 42Hz @12 bit), but still decent and should give me more sync between separate channels. Wonderful!
Thanks again,
Alex
Note: documents in Portable Document Format (PDF) require Adobe Acrobat Reader 5.0 or higher to view.
Download Adobe Acrobat Reader or other PDF reading software for your computer or mobile device.