|
关于ThingSpeak的特点和优点请查看有关网站,这里不啰嗦。
硬件:WEMOS-D1-mini R2 (ESP8266), 或者NodeMCU-V1.0, DHT11 or DHT22, 光照BH1750, OLED0.96, 无源蜂鸣器,LED灯,面包板,导线
测试了几个DHT11,数据不准也不稳。
Fritzing 模拟接线如图:
OLED显示如图:
ThingSpeak 显示如图:
代码如下:
#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);
}
|
|