先直接看成品效果吧
用的是Arduino nano,直接焊线焊上,然后3M双面胶粘。
话说这个塑料盒实在难处理,费死劲了,以后有机会搞个3D打印机去。
代码如下,有注释,基本能看明白,有不明白的,直接问 - /**
- * PM2.5&温湿度显示
- * 激光PM2.5传感器:攀藤 G5 PMS5005
- * 温湿度传感器:DHT22
- * Arduino Nano
- * SSD1306
- *
- * @Author: Coeus <r.anerg at gmail.com>
- */
- #include <DHT.h>
- #include <U8glib.h>
- #include <SoftwareSerial.h>
- #define DHTPIN 3 //DHT SIG口接PIN3
- #define DHTTYPE DHT22 //定义DHT型号
- SoftwareSerial mySerial(9, 10);
- U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);
- DHT dht(DHTPIN, DHTTYPE);
- struct PARAMS {
- float T;//显示温度
- float H;//显示湿度
- long P;//显示PM2.5
- long _P;//读取PM2.5
- } _params;
- //G5 相关变量
- static unsigned char ucRxBuffer[250];
- static unsigned char ucRxCnt = 0;
- //循环计数器
- unsigned char loopCnt = 0;
- void setup() {
- Serial.begin(9600);
- //软串口读取G5
- mySerial.begin(9600);
- delay(500);
- //设置屏幕字体和背景颜色
- u8g.setColorIndex(255);
- u8g.setHiColorByRGB(255, 255, 255);
- delay(800);
- }
- void showTemperature(void) {
- int x = 30, y = 10;//温度显示位置
- //画LOGO
- u8g.drawRFrame(x, y, 16, 16, 1);
- u8g.drawFrame(x + 5, y + 3, 3, 6);
- u8g.drawDisc(x + 6, y + 10, 2);
- u8g.setFont(u8g_font_04b_03b);
- u8g.setPrintPos(x + 10, y + 8);
- u8g.print("C");
- //设置双倍大小字体显示
- u8g.setScale2x2();
- u8g.setPrintPos(x / 2 + 11, y / 2 + 7);
- u8g.setFont(u8g_font_orgv01);
- u8g.print(_params.T);
- u8g.undoScale();
- }
- void showPM25(void) {
- int x = 30, y = 28;//PM2.5显示位置
- //画LOGO
- u8g.drawRFrame(x, y, 16, 16, 1);
- u8g.setFont(u8g_font_orgv01);
- u8g.setPrintPos(x + 3, y + 10);
- u8g.print("pm");
- //设置双倍大小字体显示
- u8g.setScale2x2();
- u8g.setPrintPos(x / 2 + 11, y / 2 + 7);
- u8g.setFont(u8g_font_orgv01);
- u8g.print(_params.P);
- u8g.undoScale();
- }
- void showRH() {
- int x = 30, y = 46;//湿度显示位置
- //画LOGO
- u8g.drawRFrame(x, y, 16, 16, 1);
- u8g.drawFrame(x + 5, y + 3, 3, 6);
- u8g.drawDisc(x + 6, y + 10, 2);
- u8g.setFont(u8g_font_04b_03b);
- u8g.setPrintPos(x + 10, y + 8);
- u8g.print("H");
- //设置双倍大小字体显示
- u8g.setScale2x2();
- u8g.setPrintPos(x / 2 + 11, y / 2 + 7);
- u8g.setFont(u8g_font_orgv01);
- u8g.print(_params.H);
- u8g.undoScale();
- }
- //画界面
- void draw(void) {
- showTemperature();
- showPM25();
- showRH();
- }
- //获取温湿度
- void getDHT22() {
- _params.H = dht.readHumidity();
- _params.T = dht.readTemperature();
- }
- //获取PM2.5的值
- void getPM25(unsigned char ucData) {
- ucRxBuffer[ucRxCnt++] = ucData;
- if (ucRxBuffer[0] != 0x42 && ucRxBuffer[1] != 0x4D) {
- ucRxCnt = 0;
- }
- if (ucRxCnt > 31) {
- _params._P = (float)ucRxBuffer[6] * 256 + (float)ucRxBuffer[7]; //美国标准
- // _params._P = (float)ucRxBuffer[12] * 256 + (float)ucRxBuffer[13]; //中国标准
- ucRxCnt = 0;
- }
- }
- //中位值平均滤波,处理PM2.5的值
- #define FILTER_N 5
- int Filter() {
- int i;
- int filter_sum = 0;
- int filter_max, filter_min;
- int filter_buf[FILTER_N];
- for (i = 0; i < FILTER_N; i++) {
- filter_buf[i] = _params._P;
- delay(1);
- }
- filter_max = filter_buf[0];
- filter_min = filter_buf[0];
- filter_sum = filter_buf[0];
- for (i = FILTER_N - 1; i > 0; i--) {
- if (filter_buf[i] > filter_max)
- filter_max = filter_buf[i];
- else if (filter_buf[i] < filter_min)
- filter_min = filter_buf[i];
- filter_sum = filter_sum + filter_buf[i];
- filter_buf[i] = filter_buf[i - 1];
- }
- i = FILTER_N - 2;
- filter_sum = filter_sum - filter_max - filter_min + i / 2; // +i/2 的目的是为了四舍五入
- filter_sum = filter_sum / i;
- return filter_sum;
- }
- void loop() {
- while (mySerial.available()) {
- getPM25(mySerial.read());
- }
- _params.P = Filter();
- //DHT22更新数据速度很慢,所以不要读的那么快
- if (loopCnt % 40 == 0) {
- getDHT22();
- }
- if (++loopCnt > 99) {
- loopCnt = 0;
- }
- u8g.firstPage();
- do {
- draw();
- } while ( u8g.nextPage());
- }
复制代码 |