试图通过SPI(MCP3304,MCP3204或MCP3008)在RPi 2 b +上读取带有Cython的ADC?
问题描述:
我想读取连接到RPi 2 b+的MCP3304(5V VDD,3.3V Vref,主通道= 7,差分通道= 6)的差分电压值,尽可能接近MCP3304的最大采样率100ksps。优选地,每100μs(> 10ksps)我会得到> 1个样本。试图通过SPI(MCP3304,MCP3204或MCP3008)在RPi 2 b +上读取带有Cython的ADC?
一种用户recently suggested I try porting my code to C for some speed gains。我对C非常陌生,所以我认为我会给Cython一枪,但似乎无法弄清楚如何利用基于C的速度增益。
我的猜测是,我需要写一个.pyx文件,其中包括通过SPI访问ADC的比特/字节比我目前使用 Python包的更原始的手段(蟒包裹gpiozero包)。 1)这看起来是否正确,如果是的话,可能会有人2)请帮助我理解如何以适当的方式处理MCP3304的位/字节,从而产生从Cython获得的速度增益?我已经看过MCP3008的C教程,但无法适应此代码以适应MCP3304规格表中列出的时序;尽管我可能可以修改Cython特定的MCP3008(或其他ADC)教程以适应MCP3304。
这是我写的一个小小的.pyx循环,用于测试我读取电压值的速度。 (定时读取25,000个样本需要多长时间)。它比在Python中直接运行速度快9%。
# Load packages
import time
from gpiozero import MCP3304
# create a class to ping PD every ms for 1 minute
def pd_ping():
cdef char *FILENAME = "testfile.txt"
cdef double v
# cdef int adc_channel_pd = 7
cdef size_t i
# send message to user re: expected timing
print "Runing for ", 25000 , "iterations. Fingers crossed!"
print time.clock()
s = []
for i in range(25000):
v = MCP3304(channel = 7, diff = True).value * 3.3
# concatenate
s.append(str(v))
print "donezo" , time.clock()
# write to file
out = '\n'.join(s)
f = open(FILENAME, "w")
f.write(out)
答
大概没有必要为每个迭代的MCP3304对象。从浮点到字符串的转换可能会延迟。
s = []
mcp = MCP3304(channel = 7, diff = True)
for i in range(25000):
v = mcp.value * 3.3
s.append(v)
out = '\n'.join('{:.2f}'.format(v) for v in s) + '\n'
如果乘以3.3
并非绝对必要在这一点上,它可以稍后再进行。
不可思议!这个改进的性能稍微超过了10倍(从大约33秒到2秒),谢谢! – drewbles
注意:如果对于后代很重要,我也将乘法除去3.3,并将{:.2f}增加到{:.17f}以获得尽可能多的信息。谢谢! – drewbles
后续,任何想法如何我可以声明(通过“cdef”)列表“s”?我想知道如果这可能会获得我更多的速度改善 – drewbles