制作了一个 温湿度 空气质量检测仪-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 3620|回复: 2

[分享] 制作了一个 温湿度 空气质量检测仪

[复制链接]
发表于 2019-12-5 17:30 | 显示全部楼层 |阅读模式
本帖最后由 flashtttt 于 2019-12-5 17:52 编辑

本作品完全开源 禁止用于商业用途作品具有温湿度 空气质量可视化功能 通过下方的RGB灯带显示。 IMG_20190922_210751.jpg

IMG_20190922_210425.jpg

IMG_20190922_210404.jpg


主控选用esp-8266  用到的模块有 温湿度传感器-dht11  人体红外感应模块HC-sr505   空气质量传感器ZP01模块
电路板使用立创eda绘制 具体可查看https://oshwhub.com/flashtttt/wu-lian-wang-kong-qi-wen-shi-du-jian-ce-yi
代码:

[pre]/*DHT_DATA IO2
* WS2812 IO15
* 人体感应 IO14
* 空气 A-IO13 B-IO12
*/
/*blinker*/
//Download latest Blinker library here:
//https://github.com/blinker-iot/blinker-library/archive/master.zip
#define BLINKER_WIFI
#define BLINKER_ESP_SMARTCONFIG
#include <Blinker.h>
uint32_t read_time = 0;
char auth[] = "";  //blinker KEY
/************************/


/*WS2812 FastLED库*/
//http://fastled.io
#define FASTLED_ESP8266_RAW_PIN_ORDER
#include"FastLED.h"
#define NUM_LEDS 8        //led数目
#define DATA_PIN 15       //led数据引脚
#define LED_TYPE WS2812   
#define COLOR GRB
int get_bright = 200; //led亮度
int now_bright = 200;
CRGB leds[NUM_LEDS];
int display_ws2812_mod = 1;   //display_ws2812_mod 模式选择 1-显示空气质量 2-显示温度 3-显示湿度  默认1
int color_display = 85;

/***********************/

/*OLED U8G2库*/
//(https://github.com/olikraus/u8g2/)
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

//width:71,height:64
const unsigned char LClogo[] U8X8_PROGMEM=  //开机logo数据 如需修改 直接修改内容即可 不要改变变量名 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xfc,0x07,0xfc,0xff,0xff,0x03,0x00,0x00,0x00,0x3f,0x00,0x80,0xff,0xff,0x0f,0x00,0x00,0x80,0x07,0x00,0x00,0xfe,0xff,0x1f,0x00,0x00,0xc0,0x00,0x00,0x00,0xf8,0xff,0x3f,0x00,0x00,0x60,0x00,0x00,0x00,0xe0,0xff,0x3f,0x00,0x00,0x10,0x00,0x00,0x00,0xc0,0xff,0x7f,0x00,0x00,0x08,0x00,0x00,0x00,0x80,0xff,0xff,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x3f,0x00,0x18,0x00,0x03,0xe0,0x00,0xfc,0x81,0x63,0x00,0x3f,0xe0,0x0f,0x70,0x00,0xff,0xc1,0xc0,0x80,0x7f,0xf0,0x1f,0x70,0x80,0xc7,0x23,0x80,0xc1,0x71,0x38,0x1c,0x70,0xc0,0x83,0x33,0x3e,0xe1,0x20,0x1c,0x1c,0x38,0xc0,0x81,0x11,0x1b,0xe1,0x01,0x0e,0x08,0x38,0xe0,0x00,0x90,0x11,0xe1,0x07,0x0e,0x00,0x18,0xe0,0x00,0x90,0x19,0xc1,0x0f,0x07,0x00,0x1c,0x70,0x00,0x90,0x99,0x81,0x1f,0x07,0x00,0x1c,0x70,0xc0,0x90,0xdf,0x00,0x1e,0x07,0x0e,0x0e,0x70,0xe0,0x10,0x73,0x00,0x1c,0x07,0x06,0x0e,0xf0,0x70,0x30,0x40,0x10,0x0e,0x87,0x03,0xfe,0xf1,0x3f,0x60,0x60,0xf8,0x0f,0xff,0x01,0xff,0xe1,0x0f,0xc0,0x3f,0xf8,0x03,0xfe,0x00,0xff,0xc1,0x07,0x00,0x0f,0xf0,0x01,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x10,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0x7f,0x00,0x20,0x00,0x00,0x00,0x00,0xe0,0xff,0x3f,0x00,0x60,0x00,0x00,0x00,0x00,0xf0,0xff,0x3f,0x00,0xc0,0x00,0x00,0x00,0x00,0xf8,0xff,0x1f,0x00,0x80,0x01,0x00,0x00,0x00,0xfe,0xff,0x0f,0x00,0x80,0x03,0x00,0x00,0x80,0xff,0xff,0x07,0x00,0x00,0x0f,0x00,0x00,0xe0,0xff,0xff,0x03,0x00,0x00,0x3e,0x00,0x00,0xf8,0xff,0xff,0x01,0x00,0x00,0xfc,0x01,0x00,0xff,0xff,0xff,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/*立创LOGO*/
//width:16,height:16
const unsigned char wifi[] U8X8_PROGMEM= {0x00,0x00,0x00,0x00,0xe0,0x07,0xf8,0x1f,0x0e,0x70,0xc7,0xe3,0xf1,0x8f,0x18,0x18,0xcc,0x33,0xe0,0x07,0x20,0x04,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00};
//width:16,height:16
const unsigned char no_wifi[] U8X8_PROGMEM= {0x00,0x00,0x02,0x20,0xe4,0x17,0xf8,0x1f,0x1e,0x74,0xe7,0xe3,0xf1,0x8f,0x98,0x18,0xcc,0x33,0xe0,0x07,0x30,0x04,0x88,0x09,0x84,0x11,0x82,0x21,0x00,0x00,0x00,0x00};
/*****************************/

/*DHT*/
// REQUIRES the following Arduino libraries:
// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor
#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float humi_read, temp_read;
/*********************************/
#define A 13
#define B 12
#define PEP 14    //人体检测模块引脚

/*blinker 组件对象*/        //在app中修改对应组件的key 或者修改括号里的值 对应你的app组件
BlinkerNumber temt("wd");
BlinkerNumber hu("sd");
BlinkerText airq("tex-spo");
BlinkerButton Button1("bth-air");
BlinkerButton Button2("bth-wd");
BlinkerButton Button3("bth-sd");
BlinkerSlider LEDleve("led-leve");

/*声明函数*/
void sys_init();        //系统初始化
void read_DHTdata();    //DHT数据读取
void display_boot();    //开机画面显示
void heartbeat();       //心跳函数
int read_airq();        //空气质量读取   返回值 优-1  良-2 中-3 差-4
void updata();          //app数据上传
void peomode_status();  //人体模块检测 切换oled显示
void display_OLDE_ON(); //oled 显示函数
void display_ws2812_airq(); //ws2812显示空气传感器
void display_ws2812_wd();
void display_ws2812_sd();
void Button1_callback();
void Button2_callback();
void Button3_callback();
void LEDleve_callback();
void LEDleve_set();

void setup()
{
    Serial.begin(9600);
    //delay(1000);
    sys_init();
    blinker_attach_init();
    display_boot();
}

void loop()
{
    peomode_status();
    Blinker.run();
    if (read_time == 0 || (millis() - read_time) >= 5000)
    {
        read_time = millis();
        read_DHTdata();
    }
}

void sys_init()     //系统初始化
{
  LEDS.addLeds<LED_TYPE,DATA_PIN,COLOR>(leds,NUM_LEDS);
  FastLED.setBrightness(now_bright);      //LED亮度设置
  u8g2.begin();
  u8g2.enableUTF8Print();                 //打开UTF8编码 否则不支持中文输出
  u8g2.setDisplayRotation(U8G2_R2);       //屏幕翻转180°
  dht.begin();
  BLINKER_DEBUG.stream(Serial);
  Blinker.begin(auth);
  pinMode(A,0);
  pinMode(B,0);
  pinMode(PEP,0);
}

void blinker_attach_init()
{
  Blinker.attachHeartbeat(heartbeat); //注册心跳函数
  Button1.attach(Button1_callback);
  Button2.attach(Button2_callback);
  Button3.attach(Button3_callback);
  LEDleve.attach(LEDleve_callback);
  LEDleve.print(now_bright);
  display_ws2812_mod = 1;
  Button1.print("on");
  Button1.color("#00FFFF");
  Button2.print("off");
  Button2.color("#FFFFFF");
  Button3.print("off");
  Button3.color("#FFFFFF");
}

void read_DHTdata()   //DHT数据读取     temt_read-温度变量  humi_read-湿度变量
{
  humi_read = dht.readHumidity();
  temp_read = dht.readTemperature();        
}

int read_airq()      //空气质量读取   优-1  良-2 中-3 差-4
{
  if(digitalRead(A)==0||digitalRead(B)==0)
    {
      return 1;  
    }
  else if(digitalRead(A)==0||digitalRead(B)==1)
    {
      return 2;  
    }
  else if(digitalRead(A)==1||digitalRead(B)==0)
    {
      return 3;  
    }
    else if(digitalRead(A)==1||digitalRead(B)==1)
    {
      return 4;  
    }
}

void display_boot()  //开机画面显示
{
  u8g2.clearBuffer();           // 清空显示设备内部缓冲区
  u8g2.drawXBMP( 30 , 0 , 71 , 64 , LClogo );     //50,50为图片尺寸,根据你的图片尺寸修改
  u8g2.sendBuffer();         // 显示缓冲区内容
  for(int i = 0; i<255;i++)
    {
      fill_rainbow(leds, NUM_LEDS, i, 35);
      FastLED.show();
      Blinker.delay(20);
    }
    for(int i = 0; i<255;i++)
    {
      fill_rainbow(leds, NUM_LEDS, i, 35);
      FastLED.show();
      Blinker.delay(20);
    }
}

void heartbeat()  //心跳函数
{   
  read_DHTdata();
  updata();
}

void updata()     //app数据上传
{
  read_DHTdata();
  temt.print(temp_read);
  hu.print(humi_read);
  switch(read_airq())
  {
    case 1:
      airq.print("空气清洁");  
      break;

    case 2:
      airq.print("轻度污染");
      break;
      
    case 3:
      airq.print("中度污染");
      break;
      
    case 4:
      airq.print("重度污染");
      break;
  }     
}

void display_OLDE_ON()
{
    u8g2.clearBuffer();                             // 清空显示设备内部缓冲区
    u8g2.setFont(u8g2_font_wqy12_t_gb2312a);
    u8g2.setCursor(0, 15);
    u8g2.print(humi_read);
    u8g2.setCursor(30, 15);
    u8g2.print("%");
    u8g2.setCursor(50, 15);
    u8g2.print(temp_read);
    u8g2.setCursor(80, 15);
    u8g2.print("℃");
    u8g2.drawLine(108 ,0 , 108 , 18);
    u8g2.drawLine(109 , 18 , 128 ,18);
    if(Blinker.connected())
      {
          u8g2.drawXBMP( 110 , 0 , 16 , 16 , wifi);
      }
    else
    {
          u8g2.drawXBMP( 110 , 0 , 16 , 16 , no_wifi);
    }
    switch(read_airq())
    {
      case 1:
        u8g2.setCursor(0, 30);
        u8g2.print("空气质量:优");
        break;

      case 2:
        u8g2.setCursor(0, 30);
        u8g2.print("空气质量:良");
        break;
      
      case 3:
        u8g2.setCursor(0, 30);
        u8g2.print("空气质量:中");
        break;
      
      case 4:
        u8g2.setCursor(0, 30);
        u8g2.print("空气质量:差");
        break;
    }
    u8g2.setCursor(0, 45);
    u8g2.print("LED_MOD:");
    u8g2.setCursor(55, 45);
    switch(display_ws2812_mod)
    {
      case 1:
        u8g2.print("空气");
        break;

      case 2:
        u8g2.print("温度");
        break;

      case 3:
        u8g2.print("湿度");
        break;
    }
    u8g2.sendBuffer();                       // 显示缓冲区内容
   
}

void peomode_status()     //人体感应判断函数    display_ws2812_mod 模式选择 1-显示空气质量 2-显示温度 3-显示湿度
{
  if(digitalRead(PEP))      
    {
      display_OLDE_ON();
      switch(display_ws2812_mod)
      {
        case 1:
          display_ws2812_airq();
          break;

        case 2:
          display_ws2812_wd();
          break;

        case 3:
          display_ws2812_sd();
          break;
      }      
    }
  else
    {
      u8g2.clear();   //oled清屏关闭
      switch(display_ws2812_mod)
      {
        case 1:
          display_ws2812_airq();
          break;

        case 2:
          display_ws2812_wd();
          break;

        case 3:
          display_ws2812_sd();
          break;
      }      
    }  
}

void display_ws2812_airq()      //ws2812显示空气质量
{
  int x = 0;
  switch(read_airq())
    {
      case 1:
        x = 85;
        break;

      case 2:
        x = 127;
        break;
      
      case 3:
        x = 170;
        break;
      
      case 4:
        x = 213;
        break;
    }
  if(color_display == x)
  {
    fill_rainbow(leds, NUM_LEDS, color_display, 0);
    FastLED.show();
  }
  else if(color_display <x)
  {
    for(;color_display<x;color_display++)
    {
      fill_rainbow(leds, NUM_LEDS, color_display, 0);
      FastLED.show();
      Blinker.delay(5);
    }
  }
  else if(color_display > x)
  {
    for(;color_display>x;color_display--)
    {
      fill_rainbow(leds, NUM_LEDS, color_display, 0);
      FastLED.show();
      Blinker.delay(5);   
    }  
  }   
}

void display_ws2812_wd()
{
  int color_wd;
  color_wd = 127 - (2 * temp_read);
  if(color_display == color_wd)
  {
    fill_rainbow(leds, NUM_LEDS, color_display, 0);
  }
  else if(color_display < color_wd)
  {
    for(;color_display < color_wd ; color_display++)
    {
      fill_rainbow(leds, NUM_LEDS, color_display, 0);
      FastLED.show();
      Blinker.delay(5);
    }
  }
  else if(color_display > color_wd)
  {
    for(;color_display > color_wd ; color_display--)
    {
      fill_rainbow(leds, NUM_LEDS, color_display, 0);
      FastLED.show();
      Blinker.delay(5);   
    }  
  }   
}

void display_ws2812_sd()
{
  int color_sd;
  color_sd = 42 + (1.5 * humi_read);
  if(color_display == color_sd)
  {
    fill_rainbow(leds, NUM_LEDS, color_display, 0);
  }
  else if(color_display < color_sd)
  {
    for(;color_display < color_sd ; color_display++)
    {
      fill_rainbow(leds, NUM_LEDS, color_display, 0);
      FastLED.show();
      Blinker.delay(5);
    }
  }
  else if(color_display > color_sd)
  {
    for(;color_display > color_sd ; color_display--)
    {
      fill_rainbow(leds, NUM_LEDS, color_display, 0);
      FastLED.show();
      Blinker.delay(5);   
    }  
  }   
}

void Button1_callback(const String & state)
{
    display_ws2812_mod = 1;
    Button1.print("on");
    Button1.color("#00FFFF");
    Button2.print("off");
    Button2.color("#FFFFFF");
    Button3.print("off");  
    Button3.color("#FFFFFF");
    BLINKER_LOG("Button1 ", state);  
}

void Button2_callback(const String & state)
{
    display_ws2812_mod = 2;
    Button1.print("off");
    Button1.color("#FFFFFF");
    Button2.print("on");
    Button2.color("#00FFFF");
    Button3.print("off");  
    Button3.color("#FFFFFF");
    BLINKER_LOG("Button2 ", state);
}

void Button3_callback(const String & state)
{
    display_ws2812_mod = 3;
    Button1.print("off");
    Button1.color("#FFFFFF");
    Button2.print("off");
    Button2.color("#FFFFFF");
    Button3.print("on");
    Button3.color("#00FFFF");
    BLINKER_LOG("Button3 ", state);   
}

void LEDleve_set()
{
  if(now_bright == get_bright)
  {
     FastLED.setBrightness(now_bright) ;
  }  
  else if(now_bright < get_bright)
  {
    for(;now_bright < get_bright;now_bright ++)
    {
        FastLED.setBrightness(now_bright) ;
        Blinker.delay(5);
    }
  }
  else if(now_bright > get_bright)
  {
    for(;now_bright > get_bright ; now_bright--)
    {
        FastLED.setBrightness(now_bright) ;
        Blinker.delay(5);
    }
  }
}

void LEDleve_callback(int32_t value)
{
    get_bright = value;
    LEDleve.print(get_bright);
    LEDleve_set();
}[/pre]

app组件创建:
Screenshot_2019-10-22-14-42-01-130_iot.clz.me.png Screenshot_2019-12-05-17-25-08-643_iot.clz.me.jpg Screenshot_2019-12-05-17-25-13-076_iot.clz.me.jpg Screenshot_2019-12-05-17-25-18-436_iot.clz.me.jpg Screenshot_2019-12-05-17-25-22-867_iot.clz.me.jpg Screenshot_2019-12-05-17-25-27-070_iot.clz.me.jpg Screenshot_2019-12-05-17-25-32-712_iot.clz.me.jpg Screenshot_2019-12-05-17-25-37-018_iot.clz.me.jpg 作品外壳是3d打印 这里附上3d模型文件
楼主的3d建模很烂 所以 大家将就用一下0.0
作品前面的olde是1.3寸的oled 不要用0.96寸 不然还得修改程序,外壳也安装不上
作品顶用半透明的材料去打建议模块的连接使用xh2.54间距连接器和排线连接 不要使用杜邦线 容易接触不良 也不方便。同时注意正负极 一旦接反就GG了。
具体的安装过程就不放了 或者日后有时间再做一期帖子,有问题的话大家下方留言。
3d模型.rar (13.91 KB, 下载次数: 16)

IMG_20190922_210722.jpg
IMG_20190922_191237.jpg
发表于 2020-1-10 16:37 | 显示全部楼层
好大的个头
发表于 2020-10-31 09:44 | 显示全部楼层
OLED U8G2库怎么添加进去一直是无效库,求救
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 13:40 , Processed in 0.110085 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表