不干正事儿系列文章2:AD/DA转换PCF8591模块和树莓派4

不干正事儿系列文章2:PCF8591芯片和树莓派4

有兴趣可以先看前序文章:
不干正事儿系列文章1:Sonic Pi简单应用

1. PCF8591模块

1.1 简单介绍

大家要是在一些贩卖Arduino或者树莓派的淘宝店里搜索一下我想应该很容易找到集成了光电,热电功能的PCF8591 AD/DA转换芯片的模块。PCF8591本身是一块数模转换芯片,根据手册我们可以知道它的输入电压Vcc应该接在2.5-6V之间,通过I2C总线进行输入输出。所集成的光电和热电模块可以让我们获得光电或者热电信号。
它的模拟量输出的范围是和Vcc与GND之间的电压一致的(说是这么说)。数字量输出是一个8位的信号也就是0-255。

1.2 接线方法

这边先提供一张树莓派4的引脚图。注意的是,先前版本的树莓派的引脚和树莓派4有所不同,应该接到对应的引脚上。
树莓派4引脚图
我们这边需要注意的引脚是5v Power, Grund, SDA, SCL。
一般来说我们购买的模块上都会印有引脚名。我们把5v接在Vcc上,Grund接在GND上,把SDA和SCL和芯片上相应的SDA和SCL连接在一起。这边的SCL是I2C当中的控制线,SDA是数据线。具体的原理我在这里就不多说了(因为我也不知道)。

1.3 测试

完成接线之后:
我们首先安装一些必要的包:

sudo apt-get install i2c-tools python-smbus

然后在开始菜单中选择Preferences,然后点击其中的Raspberry Pi Configuration。进入interfaces。
在这里插入图片描述
把这边的I2C开启一下(这里据说最好重启一下,但是我没有重启也ok了)。
然后我们打开一个终端,在其中输入:

i2cdetect -y 1

我们可以获得如下输出:
在这里插入图片描述
由此我们可以知道设备的控制地址为0x48。
过了这一步之后在硬件接线层面就没有任何问题了。我们继续开始软件编程。

2. 利用Python对芯片进行控制

2.1 AD转换

在这边我们需要用到的模块是smbus。
PCF8591可以用于AD转换的接口有ain1, ain2, ain3和ain4。它们的地址分别为0x41, 0x42, 0x43, 0x44。我们来看一下具体操作的代码:

import smbus

bus = smbus.SMBus(1)
address = 0x48
ains = [0x41, 0x42, 0x43, 0x44]

values = [0]*4
while True:
    for i, ain in enumerate(ains):
        bus.write_byte(address, ain)
        values[i] = bus.read_byte(address)
    print(values)

这边address就是我们每次要写入数据的地址了。ains代表着四个模拟量输入接口。我们通过for循环不断地访问四个端口,然后反馈给树莓派模拟量对应的数字量的值。
for循环中的bus.write_byte(address, ain)相当于告诉了树莓派访问哪个接口。bus.read_byte(address)则读出之前写入的哪个ain地址的数值。

2.2 DA转换

如果我们要让aout输出模拟量其实也很简单:

import smbus
import math
import time

bus = smbus.SMBus(1)
address = 0x48
aout = 0x40

while True:
    num = math.sin(time.time())*100+100
    num = int(num)
    bus.write_byte_data(address, aout, num)

这边的num需要是一个0-255之间的整型变量。我这边让它输出了一个正弦信号。

2.3 光电和热电模块的使用

其实设备除了光电和热电,还有一个电压输出的功能。地址分别为0x45, 0x46, 0x47。但是谁是谁大家可以去试一下。这里因为不是重点,就先不多说了。大家可以用之前提到的AD转换的方法来试着访问一下0x45, 0x46, 0x47这三个地址试一下。

3. NE5532P运放的应用

照理说我们讲完了第一章和第二章文章也就结束了,为什么还需要提一下运放呢?
大家可以试一下把aout的输出和ain的输入直接接在一起看一下输出。大家会发现,你期望的输出的aout和ain接收到的输入是相符合的。这是由于芯片的模拟输出量的功率并不是特别的高,因此它的输入段子会对于该信号有很大的影响。因此我们需要利用一个运放芯片将输出信号的电压跟随并且功率放大一下。
回忆一下我们所学过的电工学知识,我们知道电压跟随器应该这样接线:
在这里插入图片描述
然后我们参考一下芯片供应商提供的引脚图:
在这里插入图片描述
值得一提的是,这里接线的时候千万不能简单地将vcc+和5v接在一起,将vcc-和GND接在一起。因为这个样子的话,信号的输出端输出的电压并不是0-5v,而是在大约1-4.5v之间。为了避免这个问题,我们需要将vcc接在5v,然后寻找另外一个电源,将之和树莓派的5v和gnd之间串联,让我们的运放芯片介于5v和-5v之间

4. 简单应用

这边写了一个产生正弦信号并且对于输入信号可视化的一个程序:

import smbus
import time
import math
from matplotlib import pyplot as plot
import threading
from scipy.fftpack import fft, ifft


class Scope():
	def __init__(self):
		self.X = [0]
		self.Y1 = [0]
		self.Y2 = [0]
		self.nums = [0]*4
		self.get_address()
		self.bus = smbus.SMBus(1)
		self.tr = 0.01
	
	def get_address(self, address = 0x48, A0=0x41, \
	A1=0x42, A2=0x43, A3=0x44):
		self.Ads = [A0, A1, A2, A3]
		self.address = 0x48
		
	def read(self):

		values = [0,0,0,0]

		for i, ad in enumerate(self.Ads):
			self.bus.write_byte(self.address, ad)
			self.nums[i] = self.bus.read_byte(self.address)
		# print(values)

	def plt(self):
		plot.clf()
		
		plot.subplot(121)
		plot.ylim(0, 260)
		plot.plot(self.X, self.Y1, "r")
		
		plot.subplot(122)
		plot.ylim(0, 260)
		plot.plot(self.X, self.Y2, "b")
		plot.pause(0.0001)

	def myap(self):
		if self.X[-1]-self.X[0]>self.tr*10:
			self.Y1.pop(0)
			self.Y1.append(self.nums[0])
			self.Y2.pop(0)
			self.Y2.append(self.nums[1])
			self.X.pop(0)
			self.X.append(time.time())
		else:
			self.X.append(time.time())
			self.Y1.append(self.nums[0])
			self.Y2.append(self.nums[1])
			

	def write_aout(self, num):
		self.bus.write_byte_data(self.address, 0x40, int(num))
		return 0

	def update(self):
		self.read()
		self.myap()
		
		num = math.sin(time.time())
		num = num*100+100
		new.write_aout(num)
	
	def thread1(self):
		while True:
			new.update()
			time.sleep(self.tr/1000)
	
	def thread2(self):
		while True:
			self.plt()

new = Scope()

t1 = threading.Thread(target = new.thread1)
t2 = threading.Thread(target = new.thread2)

t1.start()
t2.start()
t1.join()
t2.join()

这边要用的话我们把输出的模拟量通过电压跟随器和输入端子相连就好了。这边plot的话只有ain1和ain2。
刚刚写完这个程序之后,我并没有使用多线程threading。然后就发现采集的数据非常的不连贯。这是由于matplotlib画图是真的很慢很慢!为了解决这个问题,我决定开下面一个坑:MQTT数据传输及pyqtgraph的数据可视化。

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值