简体   繁体   English

尝试通过SPI(MCP3304,MCP3204或MCP3008)在RPi 2 b +上读取带有Cython的ADC吗?

[英]Trying to read an ADC with Cython on an RPi 2 b+ via SPI (MCP3304, MCP3204, or MCP3008)?

I'd like to read differential voltage values from an MCP3304 (5v VDD, 3.3v Vref, main channel = 7, diff channel = 6) connected to an RPi 2 b+ as close as possible to the MCP3304's max sample rate of 100ksps. 我想从连接到RPi 2 b +MCP3304 (5v VDD,3.3v Vref,主通道= 7, 差分通道= 6)读取差分电压值,该电压应尽可能接近MCP3304的最大采样率100ksps。 Preferably, I'd get > 1 sample per 100µs (> 10 ksps). 最好每100µs(> 10 ksps)获得1个以上的样本。

A kind user recently suggested I try porting my code to C for some speed gains . 一位友善的用户最近建议我尝试将代码移植到C上以提高速度 I'm VERY new to C, so thought I'd give Cython a shot, but can't seem to figure out how to tap into the C-based speed gains. 我是C语言的新手,所以以为我可以给Cython一个机会,但是似乎无法弄清楚如何利用C语言的速度提升。

My guess is that I need to write a .pyx file that includes a more-raw means of accessing the ADC's bits/bytes via SPI than the python package I'm currently using (the python-wrapped gpiozero package). 我的猜测是,我需要编写一个.pyx文件,该文件包含比我当前正在使用的python包 (python封装的gpiozero包)更广泛的通过SPI访问ADC的位/字节的方法 1) Does this seem correct , and, if so, might someone 2) please help me understand how to manipulate bits/bytes appropriately for the MCP3304 in a way that will produce speed gains from Cython? 1)这看起来是否正确 ,如果可以,是否有人2)请帮助我了解如何以一种能够从Cython产生速度提升的方式为MCP3304适当地操纵位/字节? I've seen C tutorials for the MCP3008, but am having trouble adapting this code to fit the timing laid out in the MCP3304's spec sheet; 我已经看过MCP3008的C教程,但是很难适应此代码以适合MCP3304规格表中列出的时序。 though I might be able to adapt a Cython-specific MCP3008 (or other ADC) tutorial to fit the MCP3304. 尽管我也许可以改编Cython专用的MCP3008(或其他ADC)教程以适合MCP3304。

Here's a little .pyx loop I wrote to test how fast I'm reading voltage values. 这是我编写的一个.pyx循环,用于测试读取电压值的速度。 (Timing how long it takes to read 25,000 samples). (指定读取25,000个样本所需的时间)。 It's ~ 9% faster than running it straight in Python. 比直接在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)

There is probably no need to create an MCP3304 object for each iteration. 可能不需要为每个迭代创建MCP3304对象。 Also conversion from float to string can be delayed. 从float到string的转换也可能会延迟。

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'

If that multiplication by 3.3 is not strictly necessary at that point, it could be done later. 如果那时候乘以3.3乘法不是绝对必要的,则可以稍后进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM