为树莓派开发板增加模拟信号接口

大家可能已经在树莓派开发板上发现了一个问题,树莓派没有模拟信号的输入引脚,这意味着树莓派不能直接处理模拟输入信号,为了解决这个问题,本文将讨论如何通过使用 MCP3008 A/D信号转换器实现树莓派模拟信号输入的问题。

MCP3008

MCP3008是一个10位8通道的ADC(模拟数字转换器),它使用SPI总线协议,价格便宜,也不需要使用额外的组件,不含电源和接地引脚 只占用4个树莓派的引脚,
就可以提供8个模拟信号输入。 MCP3008输出最大值(2的10次方)= 1023,所以输出的范围是0-1023,0表示0V,1023表示3.3V 。

MCP3008 引脚定义
MCP3008 引脚定义

MCP3008 ADC共有16个引脚,其中左侧8个引脚用于接收模拟信号输入,分别是CH0-CH7(引脚序号:1-8)。D.Groud是芯片的数字地,CS/SHDN是芯片选择引脚,Din和Dout是数据输入和输出脚,CLOCK是时钟,A.Ground是模拟地,Vref是模拟基准电压脚,Vdd/Vcc是供电引脚。

打开树莓派的SPI接口

打开树莓派的命令终端并输入以下命令:sudo raspi-config,

树莓派命令终端
树莓派命令终端

会弹出如下窗口

树莓派接口设置
树莓派接口设置

然后启用SPI。

树莓派启用SPI接口
树莓派启用SPI接口

安装NumPy

关于NumPy将稍后进行讨论。首先要安装它,在终端中输入以下命令 :

sudo apt-get install python-numpy

通过电位器控制LED的亮度

首先,我们将尝试使用电位器的模拟输出值来控制LED的亮度。电路连接如下。

树莓派通过电位器控制LED的亮度
树莓派通过电位器控制LED的亮度

我们先将树莓派和MCP3008按下表的对应关系完成连接。

MCP3008Raspberry Pi
VDD3.3V
VREF3.3V
AGNDGND
CLKGPIO11
DOUTGPIO9
DINGPIO10
CSGPIO8
DGNDGND

然后,将10k电位计的中心引脚连接到MCP3008的CH0上,将电位计的另外两端连接到3.3V和GND上。最后将LED的正极引脚(LED的长脚)连接到树莓派的GPIO 20,再将220欧电阻从LED的负极引脚连接到树莓派的GND。

通过电位器控制LED的亮度的代码

# Importing modules
import spidev # To communicate with SPI devices
from numpy import interp	# To scale values
from time import sleep	# To add delay
import RPi.GPIO as GPIO	# To use GPIO pins

# Start SPI connection
spi = spidev.SpiDev() # Created an object
spi.open(0,0)	

# Initializing LED pin as OUTPUT pin
led_pin = 20
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin, GPIO.OUT)

# Creating a PWM channel at 100Hz frequency
pwm = GPIO.PWM(led_pin, 100)
pwm.start(0) 

# Read MCP3008 data
def analogInput(channel):
  spi.max_speed_hz = 1350000
  adc = spi.xfer2([1,(8+channel)<<4,0])
  data = ((adc[1]&3) << 8) + adc[2]
  return data

while True:
	output = analogInput(0) # Reading from CH0
	output = interp(output, [0, 1023], [0, 100])
	print(output)
  	pwm.ChangeDutyCycle(output)
  	sleep(0.1)

其中,interp(output,[0,1023],[0,100])函数用于将值从0-1023转换到0-100。我们上面提到过MCP3008 ADC的输出范围是0-1023,这里需要对应0-100的占空比,因此需要对这些值进行了转换。

树莓派从TMP36读取实时温度

解决了树莓派模拟信号输入的问题,现在,我们将使用树莓派从TMP36的测量值中读取并计算温度值。电路图如下所示:

树莓派从TMP36读取实时温度

树莓派从TMP36读取实时温度

实现代码

# Importing modules
import spidev # To communicate with SPI devices
from time import sleep  # To add delay

# Start SPI connection
spi = spidev.SpiDev() # Created an object
spi.open(0,0) 

# Read MCP3008 data
def analogInput(channel):
  spi.max_speed_hz = 1350000
  adc = spi.xfer2([1,(8+channel)<<4,0])
  data = ((adc[1]&3) << 8) + adc[2]
  return data

# Below function will convert data to voltage
def Volts(data):
  volts = (data * 3.3) / float(1023)
  volts = round(volts, 2) # Round off to 2 decimal places
  return volts
 
# Below function will convert data to temperature.
def Temp(data):
  temp = ((data * 330)/float(1023))-50
  temp = round(temp)
  return temp

while True:
  temp_output = analogInput(0) # Reading from CH0
  temp_volts = ConvertVolts(temp_output)
  temp       = ConvertTemp(temp_output)
 
  print("Temp : {} ({}V) {} deg C".format(temp_level,temp_volts,temp))
  sleep(5)

以上通过将MCP3008连接至树莓派,实现了树莓派连接模拟信号传感器的问题,并通过电位器和TMP36两个模拟元件做了相应的测试,要完成测试,请拷贝上面的代码另存为.py文件,并在树莓派命令行输入:Python XXXX.py 来运行。

标签: