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
    Commented Dec 28, 2020 at 20:41
  • You should contact Waveshare. It sounds like a problem with their software. Commented Dec 28, 2020 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
    Commented Dec 28, 2020 at 20:44
  • I would suggest to try ADS1256 one shot conversion and lower SPI to 50kHz to narrow down troubleshooting zone.
    – tlfong01
    Commented Dec 29, 2020 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
    Commented Dec 29, 2020 at 8:09

1 Answer 1

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
    Commented Jan 2, 2021 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
    Commented Jan 2, 2021 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
    Commented Jan 3, 2021 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
    Commented Jan 3, 2021 at 21:16
  • I've just edited my question with the code
    – Tagalog
    Commented Jan 4, 2021 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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