NodeMCU实现温湿度等数据在thingspeak查看-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2078|回复: 0

NodeMCU实现温湿度等数据在thingspeak查看

[复制链接]
发表于 2021-2-15 14:33 | 显示全部楼层 |阅读模式
关于ThingSpeak的特点和优点请查看有关网站,这里不啰嗦。
硬件:WEMOS-D1-mini R2 (ESP8266), 或者NodeMCU-V1.0, DHT11 or DHT22, 光照BH1750, OLED0.96, 无源蜂鸣器,LED灯,面包板,导线
测试了几个DHT11,数据不准也不稳。

Fritzing 模拟接线如图:
D1_mini_DHT22.jpg
OLED显示如图:
OLED_green.jpg
ThingSpeak 显示如图:
Things_DHT_01.jpg

Things_DHT_02.jpg
代码如下:

#include <ESP8266WiFi.h>      //支持WiFi基本功能的头文件
#include <WiFiClient.h>         //WiFiClient库用于ESP8266的TCP协议物联网通讯
#include <Wire.h>      //OLED和BH1750用到I2C总线
#include <BH1750.h>  //光照传感器
#include <Adafruit_GFX.h>         //Core graphics library,图形驱动
#include <Adafruit_SSD1306.h>  //Hardware-specific library,OLED硬件驱动
#include "DHT.h"

#define OLED_RESET  4    // Reset pin # (or -1 if sharing Arduino reset pin) -1会反复重启
Adafruit_SSD1306 display(128,32,&Wire,OLED_RESET);  //实例化显示对象并传参

#define DHTPIN2 D3 //GPIO0=D3,GPIO2=D4
#define DHTTYPE2 DHT22

DHT dht2(DHTPIN2,DHTTYPE2);
BH1750 lightMeter;

WiFiClient espClient;   //实例化WiFi客户端

// replace with your channel’s thingspeak API key and your SSID and password
// Write API Key.在thingspeak.com 注册开通频道channel后会得到一个秘钥
String apiKey = "你的秘钥";  
const char* ssid = "你家的热点";
const char* password = "你家的密码";
const char* server = "api.thingspeak.com";

int frequency500 = 500;  //无源蜂鸣器频率
int frequency900 = 900;
int pinLamp = D1;
int pinHeater = D6; //GPIO12=D6;
int pinAlarm = D7;  //GPIO13=D7
int pinBuzzer = D8; //GPIO15=D8 管脚D8连接到无源蜂鸣器模块的正极,或者接有源蜂鸣器的信号脚

void setup(){
  pinMode(pinHeater,OUTPUT);  //使能继电器控制加热膜GPIO12=D6
  pinMode(pinBuzzer, OUTPUT); //蜂鸣报警
  pinMode(pinLamp,OUTPUT);    //照明设备
  pinMode(pinAlarm,OUTPUT);   //灯光报警  

  Serial.begin(9600);
  Serial.println("  GreenHouse Monitor System...");
  Serial.printf("Chip ID of ESP = %08X\n", ESP.getChipId());

  Wire.begin(2,14);  //=(D4,D5),GPIO2=SDA,GPIO14=SCL)

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);                                         // Don't proceed, loop forever
    }
    else
    Serial.println(F("OLED-SSD1306 allocation succeed!"));

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(1000); // Pause for 1 seconds
  display.clearDisplay();// Clear the buffer

  dht2.begin();
  lightMeter.begin();  //begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire);

  Serial.println(F("BH1750 light sensor test begin..."));
    if (lightMeter.begin()) {
    Serial.println(F("BH1750 light sensor initialised 光照传感器初始化完成!"));
    }
    else {
    Serial.println(F("Error initialising BH1750"));
    }
  setup_wifi();  
}

void setup_wifi(){
   delay(10);
   Serial.printf("\n Connecting to your SSID --> %s\n",ssid);
   WiFi.mode(WIFI_AP_STA);
   WiFi.begin(ssid, password);  //建立wifi链接

   while (WiFi.status() != WL_CONNECTED) {
   delay(500);
   Serial.print(".");
   }
   randomSeed(micros());
   Serial.println("");  //回车换行
   Serial.println("Great! WiFi connected!");
   IPAddress ip=WiFi.localIP();  //返回值为当前无线终端分配的IP地址,数据类型为IPAdress型
   Serial.print("The IP address of your WiFi module: ");
   Serial.println(ip);  
   Serial.println("WiFi status:");
   WiFi.printDiag(Serial);
   Serial.println();
}

void loop() {
  uint16_t lux = lightMeter.readLightLevel();
  float h2=dht2.readHumidity();
  float t2=dht2.readTemperature();  // Computes temperature values in Celsius
  float f2=dht2.readTemperature(true);
  if (isnan(h2)||isnan(t2)||isnan(f2)){  //isnan(x),Returns whether x is a NaN (Not-A-Number) value.

    Serial.println("Failed to read from DHT sensor");
    return;
  }

  float hic = dht2.computeHeatIndex(t2, h2, false);  //体感温度

  controla(t2,lux);       //控制逻辑
  displaychar(h2,t2,lux); //OLED显示
  thingSpeak(h2,t2,lux);  //远程网页显示
}

//声热光控制函数
void controla(float t2,uint16_t lux){

  if (t2 <= 23.5) {
    digitalWrite(pinHeater,HIGH);  //驱动继电器加热
    tone(pinBuzzer, frequency500); //蜂鸣器发声,500毫秒
    delay(1000);
    noTone(pinBuzzer);             //停止发声  
    delay(500);
    digitalWrite(pinAlarm,HIGH);

    }

  else if (t2 >= 26.5||lux>=3000){
    digitalWrite(pinHeater,LOW);
    digitalWrite(pinAlarm,LOW);
    tone(pinBuzzer, frequency900);//蜂鸣器发声,900毫秒
    delay(2000);
    noTone(pinBuzzer);             //停止发声  

    }
}

//屏幕显示函数
void  displaychar(float h2,float t2,uint16_t lux){
  Serial.print("Humidity湿度: ");
  Serial.print(h2,1);  //保留小数点后一位数据
  Serial.print(" %,\t");

  Serial.print("Temperature温度: ");
  Serial.print(t2,1);
  Serial.print(" *C,\t");

  Serial.print("Light照度: ");
  Serial.print(lux);
  Serial.print(" lx");
  if(lux<=300){ Serial.print(",光线不足!");
  }
  Serial.println("");

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(8,0);
  display.println("GREENHOUSE MONITOR");
  display.drawFastHLine(0,7,128,WHITE); //从第1列第8行划线,长度128像素

  display.print("HUMDT:");
  display.setCursor(40,8);
  display.print(h2,1);
  display.println(" %");

  display.print("TEMPT:");
  display.setCursor(40,16);
  display.print(t2,1);
  display.println(" C");

  display.print("LIGHT:");
  display.setCursor(40,24);
  display.print(lux);  
  display.println(" LUX");

  display.display();   
  delay(3000);

  if (lux<=300){
  display.clearDisplay();  
  display.setCursor(8,0);
  display.print(lux);
  display.println(" lux");
  display.drawFastHLine(0,7,128,WHITE);
  display.setTextSize(2);
  display.setCursor(16,10);
  display.print(F("BAD Light"));
  display.display();
  //字幕左右动态显示
  display.startscrollright(0x01,0x03);  //对第2~4行文本作用
  delay(2000);
  display.startscrollleft(0x01,0x03);
  delay(2000);
  display.stopscroll();
   }

  else if(t2<=18.5){
  display.clearDisplay();  
  display.setCursor(8,0);
  display.print(t2);
  display.println("C of today");
  display.drawFastHLine(0,7,128,WHITE);
  display.setTextSize(2);
  display.setCursor(16,10);
  display.print(F("VERY COLD"));
  display.display();

  display.startscrollright(0x01,0x02);
  delay(2000);
  display.startscrollleft(0x01,0x02);
  delay(2000);
  display.stopscroll();
  }
}

//在网页发布温湿度、光照数据
void thingSpeak(float h2,float t2,uint16_t lux){
  if (espClient.connect(server,80)) {  //connect(host,port)函数用于ESP8266开发板通过TCP协议连接网络服务器
  String postStr = apiKey; //秘钥
  postStr +="&field1=";   //字段1
  postStr += String(t2);  //温度
  postStr +="&field2=";
  postStr += String(h2);  //湿度
  postStr +="&field3=";
  postStr += String(lux); //光照
  postStr += "\r\n\r\n\r\n";
  //服务器知道参数用符号&间隔,如果参数值中需要&,则必须对其进行编码
  //编码格式就是浏览器默认的编码格式application/x-www-form-urlencoded(将键值对的参数用&连接起来,
  //如果有空格,将空格转换为+加号;有特殊符号,将特殊符号转换为ASCII HEX值)
  //HTTP POST is used to send data to a server to create/update a resource.
  //For example, publish sensor readings to a server.
  espClient.print("POST /update HTTP/1.1\n");  
  espClient.print("Host: api.thingspeak.com\n");
  espClient.print("Connection: close\n");  //以上三行向服务器发送HTTP请求
  espClient.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");  //传递秘钥,不同的字符串之间可以用+进行连接
  espClient.print("Content-Type: application/x-www-form-urlencoded\n");  //规定表单上传编码格式,把字符串转换成表单
  espClient.print("Content-Length: ");
  espClient.print(postStr.length());  //计算字符串(表单)长度
  espClient.print("\n\n");
  espClient.print(postStr);  //向服务器推送数据

  Serial.print("");
  Serial.println("Sending data to Thingspeak--->>>");
  }
  espClient.stop();  //断开与服务器的链接

  Serial.println("Waiting 20 secs......");
  // thingspeak needs at least a 15 sec delay between updates
  // 20 seconds to be safe  20秒更新一次数据
  delay(20000);
}

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-28 10:45 , Processed in 0.155801 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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