赞
踩
受今年的疫情影响,才闲下来有点空搞点小东西玩玩,有些年头没有去接触硬件了,这次重新做点小东西,给自己回忆回忆,同时也能体现一下动手的乐趣。
这个小的空气检测仪使用的材料分为4部分也就是主控、传感器还有显示器件,以及部分元器件:
主控的选择是基于本项目所需要的性能,BME280是通过I2C协议传输数据的,GP2Y1014AU传感器是模拟量,需要使用单片机的AD(模数转换器)来采集数据。屏幕是单片机通过SPI协议进行驱动的,其实也可以使用4/8口的并口来通信,不过在I/O口不是很充足的情况下,SPI也是很好的选择。
LCD12864 | 引脚 |
---|---|
VDD | VCC(5V) |
VSS | GND |
BLK | GND |
BLA | VCC(5V) |
PSB | GND |
RS | D8 |
R/W | D9 |
E | D3 |
如图就是SPI的接法,比较推荐,比较节约I/O资源。图中D/I是RS,CS1是PSB。
值得一提的是PSB是用来做串/并模式选择的,我们采用的SPI串行通信,所以这里PSB接低电平(GND),RS是串行片选信号。
传感器端口 | 引脚 |
---|---|
VCC | 3.3V / 5V(看具体的模块说明) |
GND | gnd |
SCL | A5 |
SDA | A4 |
https://blog.csdn.net/acktomas/article/details/88350817
这位作者的讲解比较详细,我就不作赘述。简单的说一下接线吧。
传感器端口 | 引脚 |
---|---|
V-LED | VCC(5V) |
LED-GND | GND |
LED | D13 |
S-GND | GND |
V0 | A0 |
VCC | VCC(5V) |
https://blog.csdn.net/acktomas/article/details/88350817
使用LCD12864RSPI的库,用来驱动。
#include <LCD12864RSPI.h>
void setup()
{
LCDA.Initialise(); // 屏幕初始化
}
void LcdDisplay()
{
LCDA.CLEAR();
LCDA.DisplayString(0,0,show1,AR_SIZE(show1)); //0行0列开始显示
LCDA.DisplayString(0,3,AirQulity,strlen(AirQulity)); //0行3列开始显示
}
简单一些的话,可以考虑使用Adafruit_BME280的库,这个库相当好用。但是,因为和中断有冲突,所以方法不可以直接写在中断定时器里,程序会直接跑飞。
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
void setup()
{
bme.begin();
}
void get_BME_Value()
{
int tempratureValue = (int)(bme.readTemperature()*100);
int humidityValue = (int)(bme.readHumidity()*100);
int pressureValue = (int)(bme.readPressure()/100.0F);
//TODO 写对这些数据的格式化
}
这个需要使用Arduino NANO的AD(模数转换器)来采集数据,采集到数据后通过公式(公式需要进行一定的校准)。大体是基于官方的一张图。
V0产生有效电压的前提是,在第一个脉冲信号0.28ms后,待电平稳定后进行采集。
/**********************************************/ // SHARP 1014 空气传感器(0.8) //入口函数 无 //出口函 无 /***********************************************/ void get_AirQulity() { digitalWrite(ledPower, LOW); delayMicroseconds(delayTime); dustVal = analogRead(dustPin); delayMicroseconds(delayTime2); digitalWrite(ledPower, HIGH); delayMicroseconds(offTime); if (dustVal > 36.455) { result = (int)((float(dustVal / 1024) * 737.7) - 16.4); //个人总结 } memset(AirQulity, 0, sizeof(AirQulity)); sprintf(AirQulity,"%d",result); strcat(AirQulity," ug/m3"); strcat(AirQulity,'\0'); }
在设计这个小系统的时候,我秉持在主循环尽可能少放方法,多使用定时器去驱动事件的运行,一方面是将方法都放在主循环中无法保证实时性,主要原因是有些方法使用**Delay()**做延时,浪费性能且阻塞进程。
Arduino Nano和Arduino UNO一致,使用MsTimer2库来开启TIME2的中端定时器。
#include <MsTimer2.h>
void setup()
{
MsTimer2::set(1000, LcdDisplay); // 1000ms 触发 LcdDisplay()
MsTimer2::start(); //定时2
}
void loop()
{
get_BME_Value();
delay(100);
}
一个简单的小产品,希望可以带更多的人,学习嵌入式,了解软硬件间的联系。设计或许还有一些不合理的,有些做法和说明不对的地方,请留言指正。代码整理后,上传CSDN。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。