问题
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