1

I have been working with Raspberry pi 4 to acquire analog signals. I get AD/DA High Precision Board by Waveshare (ADS1256 A/D) to convert analog input and I downloaded python source code from Waveshare to read samples from ADC. The board communicates with Raspberry through SPI. I tried to make a test: I acquired the equivalent in samples of 10s of signal and measured time elapsed reading those samples. I used time.time(). I repeated the test setting different sampling frequencies but I found out that increasing sampling rates resulted in increasing error and delay: at 100 Hz I got 10.34s instead of 10s, at 1000Hz I got 13.20s instead of 10s, at 15kHz I got 57.74s instead of 10s. SPI max speed has been set to 2MHz. Why there's such a delay? Here's the code:

import time
import timeit
import ADS1256
import RPi.GPIO as GPIO

try:
    ADC = ADS1256.ADS1256()
    ADC.ADS1256_init()
    fs = 5 #here I set the value of sampling frequency which has been previously changed in module ADS1256.py
    value = 0

    start = time.time()
    for i in range(10*fs): #cycle of 10s that only reads
        value=ADC.ADS1256_GetAll() * 5.0 / 0x7fffff
    end = time.time()
    print('time',end-start)

except:
    GPIO.cleanup()
    print("\r\nProgram end     ")
    exit()
6
  • Nothing to do with the Pi. – joan Dec 28 '20 at 20:41
  • You should contact Waveshare. It sounds like a problem with their software. – Elliot Alderson Dec 28 '20 at 20:42
  • 3
    @ElliotAlderson Its more likely that the questioner doesn't understand what time.time() does and that software actions take more than zero time. – joan Dec 28 '20 at 20:44
  • I would suggest to try ADS1256 one shot conversion and lower SPI to 50kHz to narrow down troubleshooting zone. – tlfong01 Dec 29 '20 at 1:35
  • @joan, is It wrong using time.time() to measure elapsed time? I write a for cycle, in each iteration there should be a reading, the cycle ends when the number of iterations are reached ( ex. fs*10). Before cycle I set start=time.time(), after cycle I set end=time.time(). Then (end-start) – Tagalog Dec 29 '20 at 8:09
1

This is not a definitive answer because you have not provided the exact code or referenced your hardware. But looking at the data, I see an obvious relation between the timing errors and the respective sample rate.

You need to take into account that the execution of code takes some time (especially in python as it is stupid slow). Let's have a look at the data you provided:

Measuring 1000 times (100Hz for 10s) gives you an error of 340ms, so the average error per measurement is 0.34ms. Assuming that this error is systematic, we can expand this to 10000 measurements (1kHz for 10s). This leads to an expected timing error of around 3.4 seconds, measuring those 10000 samples will take 13.4 seconds, respectively. Finally doing the same math for 15kHz: duration=150000×0.34ms+10s=61s.

Though this does not exactly match your observation, I think it's pretty close and you might ask yourself, how precise the value of time.time() actually is (it's not supposed to handle microseconds).

Things you could try:

  • switch to a faster language, like C/C++ (though this can only reduce, but not solve the problem)
  • ask waveshare for support, the software they provided might be poor or not supposed to work in kHz range
  • account for the expectable delays by reducing the time-to-wait (this is a dirty solution)
  • the hardware might (but I don't know, you didn't tell us the exact hardware) be able to buffer a reasonable amount of samples which you can read out in a burst. In this way, the hardware would also do all the timing and this would be the cleanest solution in my oppinion.

Just FYI: SPI is very fast and communication is handled by hardware. It's very unlikely that changing bus speed makes any difference when there are timing problems like yours. It's the software reading the internal registers that takes CPU time, not the actual data transmission.

6
  • 1
    This is the link for source code: waveshare.com/wiki/File:High-Precision-AD-DA-Board-Code.7z, I used the version written for Raspberry Pi + python 3. In the code they wrote I don't see any way to put data into a buffer. Do you mean that Raspberry pi has a buffer? – Tagalog Jan 2 at 9:52
  • 1
    No, my idea is that the module might have a buffer. Can you give me a link to the actual module or its datasheet? – Sim Son Jan 2 at 11:14
  • at this page you can read some settings of the board waveshare.com/wiki/High-Precision_AD/DA_Board. At the following link you can download ADS1256 datasheet (waveshare.com/wiki/File:ADS1256.pdf) – Tagalog Jan 3 at 14:12
  • I see, it's just a board with ad/da converters, so there is no buffer on that board. That means you have to change the code implementation, so that the time required by time.time() doesn't affect the measurement frequency. The fact that you get delay even for low frequencies and that this delay increases more or less linearily with frequency is an indicator that the code is not implemented well. I took a quick look at how the waveshare library reads the sensor and it looks okay. you may want to share your code – Sim Son Jan 3 at 21:16
  • I've just edited my question with the code – Tagalog Jan 4 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.