项目介绍:
一直想用树莓派来监测车内环境信息,购买了MQ-3乙醇气体传感器模块,想用来检测车内人员饮酒情况。后来发现树莓派不具备模数转换功能,MQ-3模块使用比较器提供了一个高低电平的输出管脚,可以通过电位器调整阈值,但是无法具体给出酒精气体的浓度信息。
如此强大的树莓派怎么能有短板呢!身为一个单片机爱好者,当然不能忍受这个短板啦!所以给树莓派增加一个模数转换功能,使得树莓派能够感知外部世界的模拟量,更好地感知外部世界。给树莓派添加一个ADC模数转换芯片,使得外部模拟量可以转换为数字量,让机器识别,通过对酒精传感器电阻的变化值的量化,从而更加详细地感知空气中乙醇含量。
硬件介绍:
主控使用树莓派5。
MQ-3酒精传感器:是一个使用的气敏材料感知酒精浓度的传感器。是在清洁空气中电导率较低的二氧化锡(SnO2)。当酒精传感器所处环境中存在酒精蒸汽时,气体传感器的电导率随空气中酒精气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。
ADS1115 是一款 16 位低功耗精密模数转换器(ADC),具有16分辨率。最高可达 860 次/秒(SPS)采样率。支持差分输入和单端输入。ADS1115 具有 4 个单端输入通道或 2 个差分输入通道。使用I2C通讯。
任务选择:
选择任务为 方向二:安全监测,实现在汽车驾驶中发现酒后驾车行为。
设计思路:
设计思路很简单,MQ-3模块通过感知空气中酒精浓度,改变阻值。模块电路中有分压器,当阻值改变时输出电压就有变化。ADS1115将电压值转换为数字值,通过I2C传送给树莓派。树莓派通过获得的数字值,转换为电压的浮点数,计算出空气中酒精的含量。
绘制电路图,打板。然后就遇到了第一个大问题:购买的芯片和绘制的PCB不匹配。绘制的是SOT封装,购买的却是QFN封装。还好购买时出于对自我的怀疑,还购买了ADS1115的模块,可以替换板子上的芯片功能。通过杜邦线接到了树莓派的I2C1(3、5管脚),使用5供电。MQ-3接到ADS1115模块的A3脚。
编程实现:
树莓派上读取ADS1115还是比较简单的。我使用的是python,有对应的包,引入后即可读取。树莓派首先开启I2C总线。
pip3 install adafruit-circuitpython-ads1x15
import time
import board
import busio
import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
# Create the I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
# Create the ADC object using the I2C bus
ads = ADS.ADS1015(i2c)
# Create single-ended input on channel 0 相当于读取ads1115 A0 的信息
chan = AnalogIn(ads, ADS.P3)
# Create differential input between channel 0 and 1
#chan = AnalogIn(ads, ADS.P0, ADS.P1)
print("{:>5}\t{:>5}".format('raw', 'v'))
while True:
print("{:>5}\t{:>5.3f}".format(chan.value, chan.voltage))
time.sleep(0.5)
使用简单的例程,就能读取到ADS1115模块转换出来的电压值了。
这里获得的电压值是MQ-3模块上对5V分压后的电压值,还需要对这个电压值进行转换,换算出空气中酒精的含量。
参考着资料和网上老师们的经验,使用拟合方式计算酒精浓度,单位PPM。公式:
ppm=pow((6.467*10*V)/(5-V),(1.0/0.3962))(变量V为ADC采集到的电压值)
但是通过上边公式计算出来的值的单位是PPM,如何转换为交警同志认可的酒精血液浓度,却没找到相关资料,这里先简单地使用PPM来做喝酒的估算处理,通过实际测量,10000以下仅仅是淡淡的酒精味道,当酒味稍微浓郁一些时,空气中酒精浓度的PPM就超过10000了,程序里先使用10000作为阈值。
#读取其它传感器 二氧化碳传感器,酒精传感器 空气质量传感器
airqualitysensor = DFRobot_AirQualitySensor()
i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1015(i2c)
alcoholval = AnalogIn(ads, ADS.P3) #使用P3管脚
def readDevice():
#读取二氧化碳传感器 单位 PPM
co2dic=read_all()
airinfo['co2']=co2dic['co2']
#读取空气质量信息 单位 指定颗粒物类型的浓度 PM1.0 PM2.5 PM10 浓度(ug/m3)
airinfo['PM25']=airqualitysensor.read_standard()
#酒精浓度 大致为 ppm=pow((6.467*10*V)/(5-V),(1.0/0.3962)) 单位ppm
airinfo['alcohol']=pow((6.467*10*alcoholval.voltage)/(5.0-alcoholval.voltage),(1.0/0.3962))
# print("{:>5}\t{:>5.3f}".format(alcoholval.value, alcoholval.voltage))
效果演示:
对着传感器吹气
打开一包湿纸巾(含酒精),仅仅是较远距离,传感器就能有反应。
湿纸巾靠近,传感器直接爆表。
心得体会:
感谢硬禾学堂和贸泽电子举办的活动,一直对树莓派没有模数转换心有怨念,借此活动机会,完成了树莓派的模数转换功能。贸泽电子货品非常丰富,购买方便,收货也挺快!非常开心参加活动!