使用python(SPI)从ADC(MCP3001)读取数据

时间:2014-06-24 04:38:33

标签: python

我尝试用python从ADC读取一些数据,但不幸的是它不起作用。我希望有人给我一个提示,因为我的脚本只创建混乱数据。但我没有看到这些错误......

我已经更新了下面的脚本,因为我正在读取16位并切断第一个和最后一个3位。我需要数据的10个中间位 - 如果我正确理解数据表...

数据表MCP3001:(第15页)http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf

import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

HIGH = True
LOW  = False

def readAnalogData(SCLKPin, MOSIPin, MISOPin, CSPin):
    GPIO.output(CSPin,   HIGH)    
    GPIO.output(CSPin,   LOW)
    GPIO.output(SCLKPin, LOW)

    adcvalue = 0
    for i in range(16):
        GPIO.output(SCLKPin, HIGH)
        GPIO.output(SCLKPin, LOW)
        adcvalue <<= 1
        if(GPIO.input(MISOPin)):
            adcvalue |= 0x01
    adcvalue >>= 3
    adcvalue &= 0x3ff
    time.sleep(0.5)

    return adcvalue

SCLK        = 11 # Serial-Clock
MOSI        = 10 # Master-Out-Slave-In
MISO        = 9 # Master-In-Slave-Out
CS          = 17 # Chip-Select

GPIO.setup(SCLK, GPIO.OUT)
GPIO.setup(MOSI, GPIO.OUT)
GPIO.setup(MISO, GPIO.IN)
GPIO.setup(CS,   GPIO.OUT)

while True:
    print readAnalogData(SCLK, MOSI, MISO, CS) 

2 个答案:

答案 0 :(得分:0)

通过粗略阅读数据表和您的代码,您似乎试图通过转换为str并使用str切片来丢弃最初3个时钟周期内的数据/ p>

adcvalue = str(adcvalue)
adcvalue = adcvalue[3:12]
adcvalue = int(adcvalue)

如果是这样,这将无效。 adcvalueint并将其转换为str将生成小数(基数为10)字符串。相反,要么在前三个周期内不采样数据,要么使用位掩码将其从整数中剥离(即adcvalue &= 0x1ff

此外,您似乎在负时钟边沿上采样数据,但这是在数据处于瞬态状态时。我怀疑你要么在这里延迟,要么在数据稳定时在+ ve时钟边缘采样。

修改

如上所述,尝试在+ ve时钟边沿采样。数据表第16页的图6-1显示了这一点。它看起来像是以MSB格式抽出9位,然后以LSB格式重复数据(见图6-2),所以我认为你不想保留10位。您可能只需要输出总共12位,然后丢弃前3位。

像(未经测试)的东西:

def readAnalogData(SCLKPin, MOSIPin, MISOPin, CSPin):
    GPIO.output(CSPin,   HIGH)    
    GPIO.output(CSPin,   LOW)

    adcvalue = 0
    for i in range(12):
        GPIO.output(SCLKPin, LOW) # reverse order of hi/lo here
        GPIO.output(SCLKPin, HIGH)
        adcvalue <<= 1
        if(GPIO.input(MISOPin)):
            adcvalue |= 0x01
    adcvalue >>= 3
    # adcvalue &= 0x3ff <- commented out this line as should be no longer necessary

    return adcvalue

答案 1 :(得分:0)

这有效。基本上是先前的答案,但经过了调整和测试。

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

def ReadMCP3001():
    GPIO.setup(11, GPIO.OUT)
    GPIO.setup(7, GPIO.OUT)
    GPIO.setup(9, GPIO.IN)
    GPIO.output(11, False)  # CLK low
    GPIO.output(7, False)   # /CS low
    adcvalue = 0
    for i in range(13):
        GPIO.output(11, True)
        GPIO.output(11, False)
        adcvalue <<= 1
        if(GPIO.input(9)):
            adcvalue |= 0x001
    GPIO.output(7, True)    # /CS high
    adcvalue &= 0x3ff
    return adcvalue