How to obtain the highest sample rate possible in Raspbery Pi using a ADC?

亡梦爱人 提交于 2019-12-24 01:13:55

问题


I am working in a project using Raspberry Pi 3 B where I get data from a IR sensor(Sharp GP2Y0A21YK0F) through a ADC MPC3008 and display it in real-time using PyQtgraph library.

The datasheet of the ADC says that at 5.0V, the sampling rate is 200khz. However I am only getting about 30 samples per second.

Is it possible to achieve 200khz using Raspberry pi?

If yes, what should I study or implement in order to obtain it?

If not, what should I do to obtain the highest sample rate possible and how can I find out what is the highest sample rate?

Here is my code:

# -*- coding: utf-8 -*-

import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008
from collections import deque
import serial
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np

SPI_PORT   = 0
SPI_DEVICE = 0
mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))

win = pg.GraphicsWindow()
win.setWindowTitle('pyqtgraph example: Scrolling Plots')

nsamples=600 #tamanho das matrizes para os dados
tx_aq = 0 #velocidade da aquisição
intervalo_sp = 0.5 #intervalo para secao de poincare

# 1) Simplest approach -- update data in the array such that plot appears to scroll
#    In these examples, the array size is fixed.
p1 = win.addPlot()
p1.setRange(yRange=[0,35])

p2 = win.addPlot()
p2.setRange(yRange=[-100,100])

p3 = win.addPlot()
p3.setRange(yRange=[-100,100])
p3.setRange(xRange=[-0,35])

#p3.plot(np.random.normal(size=100), pen=(200,200,200), symbolBrush=(255,0,0), symbolPen='w')
'''
p3.setDownsampling(mode='peak')
p3.setClipToView(True)
p3.setRange(xRange=[-100, 0])
p3.setLimits(xMax=0)
'''

data1= np.zeros((nsamples,2),float) #ARMAZENAR POSICAO
vec_0=deque()
vec_1=deque()
vec_2=deque()
ptr1 = 0

data2= np.zeros((nsamples,2),float) #ARMAZENAR VELOCIDADE
diff=np.zeros((2,2),float)
diff_v=deque()

data3= np.zeros((nsamples,2),float)
data3_sp=np.zeros((1,2),float)

ptr3=0

curve1 = p1.plot(data1)
curve2 = p2.plot(data2)
curve3 = p3.plot(data3)

#Coeficientes da calibração do IR
c1=-7.246
c2=44.17
c3=-95.88
c4=85.28

tlast=time.clock()
tlast_sp=time.clock()
#print tlast

def getdata():
    global vec_0, vec_1, vec_2, tlast
    timenow=time.clock()

    if timenow-tlast>=tx_aq:
        #name=input("HUGO")

        tlast=timenow

        t0=float(time.clock())
        str_0 =mcp.read_adc(0)
        t1=float(time.clock()) 
        str_1 =mcp.read_adc(0)
        t2=float(time.clock())
        str_2 =mcp.read_adc(0)

        d0x=(float(str_0))*(3.3/1023)
        d0= c1*d0x**3+c2*d0x**2+c3*d0x+c4
        vec_0=(t0, d0)

        d1x=(float(str_1))*(3.3/1023)
        d1= c1*d1x**3+c2*d1x**2+c3*d1x+c4
        vec_1=(t1, d1)

        d2x=(float(str_2))*(3.3/1023)
        d2= c1*d2x**3+c2*d2x**2+c3*d2x+c4
        vec_2=(t2, d2)

        functions()

def diferenciar():
    global data2


    diff=(data1[-1,1]-data1[-3,1])/(data1[-1,0]-data1[-3,0])

    data2[:-1] = data2[1:]
    data2[-1,1] = diff
    data2[-1,0] = data1[-2,0]


def organizar():
    global data1, data3

    data1[:-1] = data1[1:]
    vec_x1=np.array(vec_1)
    data1[-1]=vec_x1

def EF(): #ESPACO DE FASE
    global data3, ptr3

    data3[:-1] = data3[1:]
    data3[-1,0]=data1[-1,1]
    data3[-1,1]=data2[-1,1]

def SP():
    global timenow_sp, tlast_sp

    timenow_sp=time.clock()

    if timenow_sp-tlast_sp>=intervalo_sp:

        tlast_sp=timenow_sp

        data3_sp[0,0]=data3[-2,0]
        data3_sp[0,1]=data3[-2,1]
        p3.plot(data3_sp, pen=None, symbol='o', symbolPen=None, symbolSize=4, symbolBrush=('r'))
        #print data3_sp

def plotar():
    global ptr1
    curve1.setData(data1)    
    ptr1 += 1
    curve2.setData(data2)
    #curve2.setPos(ptr1, 0)

    #p3.plot(data3)

def functions():

    diferenciar()
    organizar()
    EF()
    SP()
    plotar()

def update1():
    global data1, curve1, ptr1

    getdata()


# update all plots
def update():
    update1()

timer = pg.QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)



## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

I am trying to find a way to solve it, but I have failed so far.

Would you guys help me with that or at least point me out where I can find information about this?


回答1:


This kind of Sampling rate is not achievable with a general-purpose computer like Raspberry Pi, especially with MCP3008. The reason being the MCP series of ADC's tops out at ~2.7Mhz SPI clock at 5V.

In order to read at 200KHz rate, you would need a dedicated board.

However, you can try PCM1803A which could evidently achieve sampling rate of up to 96 kHz,

96kHz sampling is easily achived with an I2S ADC. I have 96kHz,24bit stereo input working using a simple I2S codec on a breakout board. Higher sampling rates may be possible but the codec I'm using (PCM1803A) maxes out at 96kHz.

This is also discussed here, as follows,

You are not going to get to 150ksps on a Pi with just SPI ADC(s). Not even with one channel. I think the best I heard of was 50ksps, and there would be a certain amount of jitter on the frequency of sampling.

2 channels * 150ksps = 300ksps

with overhead, assuming about 32 bit per sample, you are looking at 9.6mbps of raw data

NO WAY with just a Pi and ADC.

You need an external microcontroller / adc sending the data to the Pi over USB or Ethernet

and here,

The basic problems are:

  • the Raspberry Pi is NOT designed for high speed data collection
  • the MCP series of ADC's tops out at ~2.7Mhz SPI clock at 5V
  • SPI latency with the RPi

The SPI interface on the Pi is simply not capable of accurately reading 100,000 samples from an ADC at precise intervals.



来源:https://stackoverflow.com/questions/40499890/how-to-obtain-the-highest-sample-rate-possible-in-raspbery-pi-using-a-adc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!