Page 1 of 1

SPI speed and ADC sampling rate

Posted: Fri May 03, 2019 9:15 am
by rmunny
Hello,
I have been working on a project where I'm collecting data from the AD8232 ECG sensor in my raspberry pi 3. As it is an analog sensor I am using MCP3008 as an ADC converter. My problem is I am not getting proper ECG signal shape. I understand the ECG signal is noisy and I need to filter it for further analysis. But the raw ECG signal is not like an ECG signal at all. I was wondering to generate a 200Hz ECG signal what should my SPI speed? I'm using spidev. I checked with SPI speed from 2000hz to 20MHz but got the similar distorted signal. In my code, I set the sampling frequency 200Hz. Can anyone help me with possible issues and fixes?

Thanks,
Row

Re: SPI speed and ADC sampling rate

Posted: Fri May 03, 2019 1:17 pm
by mikronauts
You need to post your code so we can see what you are doing. Use code tags so the indentation is not lost.

Most likely causes:

- you are not sampling at precise intervals
- you are not reading the voltage correctly
(sensor output range vs adc input range)
- your voltage reference is not stable
rmunny wrote:
Fri May 03, 2019 9:15 am
Hello,
I have been working on a project where I'm collecting data from the AD8232 ECG sensor in my raspberry pi 3. As it is an analog sensor I am using MCP3008 as an ADC converter. My problem is I am not getting proper ECG signal shape. I understand the ECG signal is noisy and I need to filter it for further analysis. But the raw ECG signal is not like an ECG signal at all. I was wondering to generate a 200Hz ECG signal what should my SPI speed? I'm using spidev. I checked with SPI speed from 2000hz to 20MHz but got the similar distorted signal. In my code, I set the sampling frequency 200Hz. Can anyone help me with possible issues and fixes?

Thanks,
Row

Re: SPI speed and ADC sampling rate

Posted: Sun May 05, 2019 12:39 am
by rmunny
Thanks a lot for your response. Here is my data acquisition code portion:

Code: Select all

from spidev import SpiDev  
from time import sleep

#Create SPI
spi = 0

def init_spi():
    spi = SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1300000 #1350000
    return spi

def read_adc(adc_num, num_samples=500, sample_freq=500):   #I am actually setting 200Hz sampling rate
    spi= init_spi()
    data = []
    t = 1.0/sample_freq
    # read SPI data from the MCP3008
    if adc_num > 7 or adc_num < 0:
        return -1
    while (num_samples):
        r = spi.xfer2([1, 8 + adc_num << 4, 0])
        data.append(((r[1] & 3) << 8) + r[2])
        sleep(t)
        num_samples = num_samples - 1
    return data
Following is part of my main code (In the main I have other codes like filtering, plotting and storing the data in files here I am only adding related code with data acquisition):

Code: Select all

sample_freq = 200
num_samples = 2000
if __name__ == "__main__":
    while ( count < how_many_times):  
        raw_data = read_adc(adc_num=0, num_samples=num_samples, sample_freq=sample_freq)
        save_data(raw_data, "raw_data.txt") 
Please let me know what you think.

Re: SPI speed and ADC sampling rate

Posted: Sun May 05, 2019 4:15 pm
by mikronauts
You are most welcome.

Python is an interpreted language, with garbage collection, and not well suited to regular, precisely timed sampling.

Writing your app in C would make the timing more predictable.

You can improve your python code somewhat by:

- use an integer array (not list) for storing the samples, see
https://docs.python.org/3/library/array.html

- figure out how long the sampling code takes in microseconds, and subtracting from your timing delay, or use a timed intertupt instead
rmunny wrote:
Sun May 05, 2019 12:39 am
Thanks a lot for your response. Here is my data acquisition code portion:

Code: Select all

from spidev import SpiDev  
from time import sleep

#Create SPI
spi = 0

def init_spi():
    spi = SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1300000 #1350000
    return spi

def read_adc(adc_num, num_samples=500, sample_freq=500):   #I am actually setting 200Hz sampling rate
    spi= init_spi()
    data = []
    t = 1.0/sample_freq
    # read SPI data from the MCP3008
    if adc_num > 7 or adc_num < 0:
        return -1
    while (num_samples):
        r = spi.xfer2([1, 8 + adc_num << 4, 0])
        data.append(((r[1] & 3) << 8) + r[2])
        sleep(t)
        num_samples = num_samples - 1
    return data
Following is part of my main code (In the main I have other codes like filtering, plotting and storing the data in files here I am only adding related code with data acquisition):

Code: Select all

sample_freq = 200
num_samples = 2000
if __name__ == "__main__":
    while ( count < how_many_times):  
        raw_data = read_adc(adc_num=0, num_samples=num_samples, sample_freq=sample_freq)
        save_data(raw_data, "raw_data.txt") 
Please let me know what you think.