一块儿玩转树莓派(7)——树莓派模数/数模转换实践

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

若是你跟随本系列博客阅读到此,那么我相信,你已经可以使用树莓派的GPIO接口作许多有趣的事情了。可是不知你是否有发现,GPIO功能接口不管是输入仍是输出,都只有高电平或低电平这两种选项,抽象到数学中,即只有0和1两种数值选项,这种离散数值的信号咱们将其称为数字信号。更多时候,咱们须要使用的元件并不是只有开和关两种状态,这时候就须要用数值连续的信号来表达,这种连续的信号咱们称之为模拟信号。本篇博客,咱们将初步涉猎在树莓派上如何处理模拟信号。python

1、树莓派模数转换模块基础

其实,直接使用GPIO的功能引脚并不是彻底不能处理模拟信号,咱们知道不管须要多少种状态信号,经过GPIO的电平高低来处理都是没法实现的,可是你必定还记得PWM脉冲宽度调制技术,这其实就是一种将数字信号转换成模拟信号的方式,例如在前面的RGB实验中,咱们曾使用PWM技术来控制3种发光二极管的发光明暗程度,若是将二极管的全亮定义为值1,全暗定义为值0,则在明暗之间能够经过设置不一样的占空比来实现,例如须要亮度值为0.5时,只须要设置占空比为50%便可。经过PWM技术,虽然咱们每一个精确的时刻输出的依然是数字信号(0或1),但最终做用到元件上的信号是模拟的,这就完成了最简单的数模转换。编程

一样的道理,对于某些外接元件来讲,其输出的信号也多是模拟的,例如温度、光亮传感器,若是直接经过GPIO来获取这些元件的信号是模拟的,解析会很是困难,这时咱们就须要一个数模转换模块来帮助咱们将其转换为数字信号。markdown

一、关于模数转换

数模转换器,又称D/A转换器,简称DAC。用来把数字量转换成模拟量的器件,关于数模转换器的电路和工做原理,不在本篇博客的核心讨论范围内,若是你有兴趣能够查阅数字电路和模拟电路的相关书籍。对其对应,模数转换器,又称为A/D转换器,简称ADC。用来把模拟信号转换为数字信号。树莓派自己没有集成模数转换模块,咱们须要外接一个转换单元,在本实验中,咱们采用基于PCF8591芯片的模数转换模块。ide

二、PCF8591芯片

PCF8591是一个单片集成,单独供电,低功耗的8位数A/D转换器,其芯片自己以下图所示:测试

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

能够看到其左右各有8个引脚,引脚功能图以下:编码

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

如上图所示,其AIN0到AIN3都是模拟输入引脚,其用来输入外接元件的模拟信号,它还有1个模拟输入引脚AOUT,用来输出模拟信号。.net

A0,A1,A2这3个引脚用来进行硬件地址编程,在嵌入式编程中,每一个可编程的引脚咱们将其理解为一个二进制位,3个引脚能够表达0-7这8个数字(000,001,010,011,100,101,110,111),所以在同一个I2C总线上,实际能够同时链接8个PCF8591芯片进行工做(I2C总线咱们后面会介绍)。code

VSS是接地引脚,VDD是工做电压引脚,AGND是模拟信号接地引脚,VREF是基准电源引脚。blog

OSC引脚为外部时钟输入端或内部时钟输出端,EXT若是接地,表示使用内部时钟,不然表示使用外部时钟。接口

SCL和SDA是I2C总线接口引脚,咱们使用这两个引脚来进行数据传输,后面会介绍。

下面是PCF8591工做的电路原理图:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

舒适提示,在阅读本篇博客时,难度可能要比本系列的前几篇博客大,你可能会感受云里雾里,不要着急,后面咱们会经过实验来帮助你理解模数转换以及I2总线的工做方式,掌握了这些,你的树莓派开发本领将进一步提高。

三、PCF8591实验模块

上一小节咱们介绍了PCF8591芯片的引脚用法,实际在本实验中,咱们并不会直接使用这个芯片,而是使用基于PCF8591芯片的一个工做模块,以下图所示:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

如上图所示,此模块功能很是丰富,咱们逐一介绍。

左边一列引脚做用分别为:

  • AOUT :内部芯片的DA 输出接口
  • AIN0 :内部芯片的模拟输入接口 0
  • AIN1 :内部芯片的模拟输入接口 1
  • AIN2 :内部芯片的模拟输入接口 2
  • AIN3 :内部芯片的模拟输入接口 3

右边一列引脚的做用为:

  • SCL :I2C 通讯接口
  • SDA :I2C 通讯接口
  • GND :模块地
  • VCC :电源接口 外接 3.3v-5v

除此以外,P4,P5,P6三个地方咱们能够经过接短路帽的方式来选择是否接入相关功能。

P4:接上短路帽,表示将热敏电阻接入电路。

P5:接上短路帽,表示将光敏电阻接入电路。

P6:接上短路帽,表示将0-5V的可调节电压接入电路。

若是P4,P5,P6都不接短路帽,可使用外部元件经过4个AIN引脚进行输入。关于这几个功能如何使用,后面咱们会介绍。

此模块的工做示意图以下:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

4.I2C总线基础知识

I2C总线是有Philips公司开发的一种简单、双向的同步串行总线。只须要两根线便可实现链接在总线上的设备间进行通讯。在I2C总线的通信协议中,SDA用来传输数据,SCL是串行的时钟线,传输流程以下图所示:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

只看图你可能会感受很是疑惑,结合树莓派工做起来,其实要理解并不复杂,在I2C协议中,树莓派就是主机,链接的PCF8591就是从机,主机与从机间不管是发送数据仍是接受数据,都是由主机先发起,形象化的流程以下:

1.主机触发开始通讯条件(SDA和SCL电平知足必定条件)。

2.经过地址找到要通讯的从机(即PCF8591的3个地址编程引脚设置的地址)。

3.主机发送工做命令,即指定要从从机读数据仍是写数据,读哪一个通道的数据等(PCF8591有4个输入通道)。

4.收到数据会发送ACK回执。

5.结束这次通信后,主机发送完成指令给从机(SDA和SCL电平知足必定条件)。

5.几个重要的指标概念

1.位数

ADC元件的位数很是重要,它描述了一种可读概念,以PCF8591为例,其实8位的数模转换芯片,也就是说其输出的数字量是0到255之间的数值,一共256种(2的8次方)。

2.基准电压

基准电压用来标准数模转换芯片输出的数值与电压之间关系,例如基准电压为5V,则0到255这256个刻度至关于将5V的电压平均分红了255份,数值没增长1,至关于电压约增长0.019V。

2、实验:测定温度和光亮度

如今,咱们已经准备好了须要使用到的基础知识,能够开始咱们的试验了。PCF8591自带光感与温度传感器,咱们尝试使用这两个传感器来读取环境的温度与亮度。

一、连线

首先,咱们能够先使用3个短路帽将PCF8591模块的P四、P五、P6都进行短接,以下图所示:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

短接后,至关于咱们将PCF8591模块自带的可调节输出电压、光感信号输出和温度信号输出都接入了电路,能够直接经过I2C总线对其数据进行获取。

以后,咱们将PCF8591模块模块的SCL、SDA分别链接树莓派对应功能的引脚,GND进行接地,VCC接5V。关于找到树莓派上这些引脚的位置,能够参考下面博客:

https://my.oschina.net/u/2340880/blog/5123429

笔者这里使用扩展板来接线,会更加直观方便,以下图所示:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

如今,咱们已经完成了接线部分的工做。

二、代码编写

由于须要使用到树莓派的I2C总线功能,在开始编码前,咱们须要将树莓派的I2C功能开启,打开树莓派的配置页面,在其interfaces选项中打开SPI和I2C选项,以下图所示。

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

咱们先将完整的实验代码奉上:

#coding:utf-8

#SMBus (System Management Bus,系统管理总线) 
import smbus   #在程序中导入“smbus”模块
import time

bus = smbus.SMBus(1)         #建立一个smbus实例

# 数据读取的方法
def read(chn): #channel
    if chn == 0:
        #发送一个控制字节到设备 表示要读取AIN0通道的数据
        bus.write_byte(0x48,0x00)   
    if chn == 1:
        #发送一个控制字节到设备 表示要读取AIN1通道的数据
        bus.write_byte(0x48,0x01)
    if chn == 2:
        #发送一个控制字节到设备 表示要读取AIN2通道的数据
        bus.write_byte(0x48,0x02)
    if chn == 3:
        #发送一个控制字节到设备 表示要读取AIN3通道的数据
        bus.write_byte(0x48,0x03)
    bus.read_byte(0x48)         # 空读一次,消费掉无效数据
    return bus.read_byte(0x48)  # 返回某通道输入的模拟值A/D转换后的数字值

if __name__ == "__main__":
    while True:
        print('电位计 AIN3 = ', 0.0196 * read(3))   #电位计模拟信号转化的数字值
        print('光敏电阻 AIN0 = ', 255 - read(0))   #光敏电阻模拟信号转化的数字
        print('热敏电阻 AIN1 = ',255-read(1))      #热敏电阻模拟信号转化的数字值
        time.sleep(2)

下面咱们来详细解释下上面的代码,首先smbus是一个Python模块,咱们以前并没使用过,咱们此次实验不使用GPIO,使用smbus来进行I2C总线管理。

在核心逻辑执行前,首先须要进行总线管理器的实例化,使用以下方法:

bus = smbus.SMBus(1)

其中的参数表示要使用的I2C版本。

前面咱们分析过,在I2C总线通讯中,主机先要发送指令告诉从机要作什么,对应代码中就是write_byte方法,这个方法用来向PCF芯片发送一个8位的控制指令,经过查阅芯片手册,很容易找到这个8位的控制指令每一位的意义,以下图所示:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

咱们从左往右来分析上图。

对于上图,咱们在多解释一下,这个8位的控制指令,第1位和第5位都是默认填充位,都用0填充,目前没有任何意义。

第2位表示是否开启AOUT输出口,只有这一位为1,数模转换才会工做,数字信号才会被转换为模拟信号从AOUT引脚输出。(本次实验咱们暂不使用)

第3位和第4位用来编程控制输入模式,这两位能够组成的数值有00,01,10,11共四种,设置为00表示AIN端口与输入通道一一对应。01,10,11这3种模式通道的值都是通过 处理的,上图有明确的标注,好比在11模式下,通道0的值是AIN0和AIN1输入的差分,通道1的值是AIN2和AIN3输入的差分。(本次实验咱们也无需使用这一功能)

第6位的做用是设置是否自动切换通道,当其设置为1时,每次读取数据后,通道都会切换,例如第一次读取通道0的数值,第二次会在读取时,会自动读取通道1的数值。

第7位和第8位用来指定从哪一个通道读取数值,有4个通道可用,分别经过00,01,10,11进行设置。

咱们再来看下write_byte方法:

bus.write_byte(0x48,0x00)

这个方法有两个参数,第2个参数就是咱们上面说的指令参数,其用16进制表示,例如0x03设置为:

第1位 第2位 第3位 第4位 第5位 第6位 第7位 第8位
0(占位) 0(不使用AOUT) 0(一一对应模式) 0(一一对应模式) 0(占位) 0(不启动切换通道) 1(设置要读取的通道) 1(设置要读取的通道)

 write_byte这个方法的第1个参数用来设置I2C总线中要为哪个从机设置指令,PCF的地址设置是7位,查阅手册以下:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

能够看到第4位到第7位都是固定的,前3位是可编程的,还记得PCF的A0到A3引脚吧,就是让主机来分配从机地址使用的。咱们能够知道,PCF从机的地址必定在二进制数01001000(0x48)到01001111(0x4F)之间,要查阅当前链接到树莓派的PCF从机的地址,能够在树莓派终端输入以下指令:

sudo i2cdetect -y 1

效果以下图所示:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

从图中能够看到,树莓派当前只链接了一个I2C从机模块,分配的地址是0x48。

如今,上面的代码对你来讲很是好理解了,须要注意,其中除了0x48表示的是PCF从机的地址外,其余十六进制数都是指令。指令设置完成后,接下来就能够进行数据的通讯,使用以下方法:

bus.read_byte(0x48)

这个方法用来经过I2C总线从PCF读取数据,上面代码中咱们在读取数据时连续调用了两次,这是由于PCF8591接收到读取数据的命令后会同时进行上一次转换数据的传输和本次数据的转换,空读一次能够消费掉不正确的数据。

还有一点须要注意,对于咱们使用的PCF8591模块来讲,其自带的可调节电压会输出到第4个通道,光敏传感器的数据会输出到第1个通道,热敏传感器的数据会输出到第2个通道,在本次实验中,第3个通道不被使用(若是你使用的PCF8591模块和笔者的不太同样,对应通道可能会不一样,能够自行测试)。

3、尽情玩耍

如今,你能够尝试在树莓派上运行写好的程序,经过输出能够看到当前的可调节电压、环境亮度和环境温度的状况。你能够尝试使用螺丝刀对电位计进行调节,能够实时的看到输出电压的改变,能够关灯和开灯来改变环境亮度,你也能够将热敏传感器握在手中,这些均可以明显的从输出信息上看到环境数据的变化。以下图所示:

一块儿玩转树莓派(7)——树莓派模数/数模转换实践

此次,关于树莓派编程,咱们学到了一些新的东西,使用I2C总线和数模转换模块咱们能够作出更多有意思的东西,好比红外控制的自制电视机?好比有有马达驱动的遥控小车?等等...。你能够作好准备,咱们后面会一块儿开发一些更好玩的东西!

专一技术,懂的热爱,愿意分享,作个朋友

QQ:316045346

相关文章
相关标签/搜索