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

flashtttt 发表于 2019-12-5 17:30

制作了一个 温湿度 空气质量检测仪

本帖最后由 flashtttt 于 2019-12-5 17:52 编辑

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






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

/*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;
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();
}

app组件创建:
作品外壳是3d打印 这里附上3d模型文件
楼主的3d建模很烂 所以 大家将就用一下0.0
作品前面的olde是1.3寸的oled 不要用0.96寸 不然还得修改程序,外壳也安装不上
作品顶用半透明的材料去打建议模块的连接使用xh2.54间距连接器和排线连接 不要使用杜邦线 容易接触不良 也不方便。同时注意正负极 一旦接反就GG了。
具体的安装过程就不放了 或者日后有时间再做一期帖子,有问题的话大家下方留言。


shark526 发表于 2020-1-10 16:37

好大的个头

17608381887 发表于 2020-10-31 09:44

OLED U8G2库怎么添加进去一直是无效库,求救
页: [1]
查看完整版本: 制作了一个 温湿度 空气质量检测仪