1

我目前正在做一个项目,该项目需要我读取 16 个不同传感器的模拟电压并将它们转换为角度读数。为了实现这一点,我决定使用 MCP3008 ADC 芯片以及 rpi 和 python,因为这是我之前为需要类似过程的其他项目所做的事情。然而,与我之前的项目不同,我必须使用 2 个 MCP3008 芯片,因为它们每个只能读取 8 个通道。我知道根据 spi 通信的工作方式和 MCP3008 芯片的工作方式,这应该是可能的,但我遇到了一些问题,让两个芯片同时工作。作为序言,我正在使用 adafruits mcp3xxx 库来处理这些芯片。我尝试的第一件事是使用不同的芯片选择将两个芯片放在同一 spi 总线上。

import busio
import digitalio
import board
import time
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn
# this function is used to calculate angle of displacement
def Angle(Vmin,Vmax,R,Vt):
    return ((Vt-Vmin)/(Vmax-Vmin))*R
# create the spi bus
spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)

#create the chip select(s)
cs0 = digitalio.DigitalInOut(board.CE0)
cs1 = digitalio.DigitalInOut(board.CE1)



#create the mcp object(s)
mcp0 = MCP.MCP3008(spi,cs0)
mcp1 = MCP.MCP3008(spi,cs1)


#create the analog channels
chan0_0 = AnalogIn(mcp0, MCP.P0)
chan1_0 = AnalogIn(mcp1, MCP.P0)


R_elbow = 180;
from CalibratedVoltages import*


while True:
#     A_elbow = Angle(VminElbow,VmaxElbow,R_elbow,chan0_0.voltage)
#     time.sleep(1)
#     A_knee = Angle(VminKnee, VmaxKnee, R_knee,chan1_0.voltage)
#     print('elbow angle:', A_elbow,'degrees')
     print('0',chan0_0.voltage)
     print('1',chan1_0.voltage)
     time.sleep(2)
     print('update')

但是,使用此设置,由于某种原因,在 mcp1 对象上获取的任何读数都依赖于在 mcp0 对象上获取的读数。例如,如果您要在 mcp1 的通道 0 上读取读数,而不是从 0 到 3.3 伏,因为它应该从 0 到在 mcp0 对象的通道 0 上读取的任何值。这对于 mcp1 对象上的所有通道都是相同的。

无法弄清楚为什么会发生这种情况,我决定尝试简单地将每个 MCP3008 芯片放在单独的 spi 总线上,以防止由于共享总线造成的干扰,我认为这是导致错误的原因。我做了一个 dtoverlay 来启用 spi1 总线,然后将我的代码更改为更像这样的东西。

import busio
import digitalio
import board
import time
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn
# this function is used to calculate angle of displacement
def Angle(Vmin,Vmax,R,Vt):
    return ((Vt-Vmin)/(Vmax-Vmin))*R
# create the spi bus
spi0 = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
spi1 = busio.SPI(clock=21, MISO=19, MOSI=20)

#create the chip select(s)
cs0 = digitalio.DigitalInOut(board.D5)
cs1 = digitalio.DigitalInOut(board.D9)



#create the mcp object(s)
mcp0 = MCP.MCP3008(spi0,cs0)
mcp1 = MCP.MCP3008(spi1,cs1)


#create the analog channels
chan1_0 = AnalogIn(mcp1, MCP.P0)
chan0_0 = AnalogIn(mcp0, MCP.P0)
#chan0_1 = AnalogIn(mcp0, MCP.P1)
#chan0_2 = AnalogIn(mcp0, MCP.P2)
#chan0_3 = AnalogIn(mcp0, MCP.P3)
#chan0_4 = AnalogIn(mcp0, MCP.P4)
#chan0_5 = AnalogIn(mcp0, MCP.P5)
#chan0_6 = AnalogIn(mcp0, MCP.P6)


R_elbow = 180;
from CalibratedVoltages import*


while True:
#     A_elbow = Angle(VminElbow,VmaxElbow,R_elbow,chan0_0.voltage)
#     time.sleep(1)
#     A_knee = Angle(VminKnee, VmaxKnee, R_knee,chan1_0.voltage)
#     print('elbow angle:', A_elbow,'degrees')
     print('0',chan0_0.voltage)
     print('1',chan1_0.voltage)
#     print('2',chan0_2.voltage)
#     print('3',chan0_3.voltage)
#     print('4',chan0_4.voltage)
#     print('5',chan0_5.voltage)
#     print('6',chan0_6.voltage)
     time.sleep(2)
     print('update')

使用此设置,只有 spi1 总线上的 MCP 芯片工作,而另一个芯片在所有通道上返回 0.0,无论附加什么电压。即使您将代码改回仅使用 spi0 总线,spi0 总线上的芯片仍会继续返回所有 0.0 读数,直到并且除非我重新启动 rpi 并运行代码以仅使用 spi0 总线读数而无需运行任何行为 spi1 总线设置任何东西。在这一点上,我相当迷茫,只能假设它与我正在使用的一个库有关,我选择了 MCP3008 芯片,因为我知道 adafruit 有一个易于使用的库,我想避免必须专门为项目的这一部分付出很多努力。如果有人遇到过同样的问题并且知道如何解决它,或者只是猜测一下,将不胜感激。对所描述的任何一个问题的解决方案都可以让我完成这个项目。

4

0 回答 0