一、开发环境配置
系统要求:使用windows操作系统的电脑
所需资源:
- 开发软件arduinoIDE2.0及以上版本均可
- 驱动
- 拓展库 u8g2 DHT sensor libraryPubSubClient
-
本项目中的引脚定义:IIC : SCL— D1,SDA—D2;DHT11 : DATA—D4
二、开发板硬件介绍
最终效果图展示
散件套装中有一块未焊接的主板和几个部件,现在进行分部的介绍。
图中标注了每个部件的名称,分别是主控板ESP8266,它搭载了一颗小型的处理器,具有运算处理的能力,接下来是一块分辨率为128*64的单色oled屏幕,用于显示信息。知道后就是本次实验比较关键的温湿度传感器和液体检测传感器。
下图是将每个模块拆下后的展示:
但是电路板上是没有这些接口的,需要自行焊接。
三、处理开发环境
下载配置arduinoIDE
1. 进入arduino.cc,在software中可以下载最新的2.0版本的IDE。下载后安装即可。
2. 安装本次项目所需要的库。库的名称已经列在上文了,启动IDE后,将库名复制到图示的框内搜索,确认库名以及作者和给出的截图一致就可以安装了。
3. 添加esp8266开发板,点击文件->首选项,将这个链接http://arduino.esp8266.com/stable/package_esp8266com_index.json
添加到其他开发板管理器地址中
之后在开发板管理器中,搜素ESP8266下载安装就完成了!
4. 驱动安装,搜索CH34x驱动安装,或者使用提供的安装包
代码示例:(Arduino代码)
基础版:
#include <U8g2lib.h>
#include <Arduino.h>
#include "DHT.h"
#define DHTPIN D4 //参照BBS项目前期准备的内容
#define DHTTYPE DHT11
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ D1, /* data=*/ D2, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
//这一条是使用u8g2库初始化屏幕实例的语句,是从example里面找到对应合适的屏幕种类后填入了我们对应的板子的引脚号
DHT dht(DHTPIN,DHTTYPE); //初始化DHT11 温湿度传感器
int t1 = 0; //用于储存温度值
int t2 = 0; //用于储存湿度值
int errorFlag = 0; //记录是否出错
void setup() {
pinMode(D4, INPUT); //从D4这个接口读取温湿度的数据
dht.begin();
u8g2.begin();
u8g2.enableUTF8Print(); //一些初始化
Serial.begin(115200); //建立串口通讯
}
void loop() {
delay(2000); //可以自己调整一下,看看有什么效果
if (isnan(dht.readTemperature())) {
Serial.println(F("Error !"));
errorFlag = 1;// 如果连接有问题或者传感器有问题就设置错误标记
}
t1 = (int)(dht.readTemperature());
t2 = (int)(dht.readHumidity());
//读取DHT11传感器内的信息
Serial.println(t1);
Serial.println(t2);
//将信息打印在串口通讯
u8g2.firstPage();//刷新页面
do {
u8g2.setFont(u8g2_font_ncenB08_tr);//u8g2_font_ncenB08_tr:先设置显示屏显示什么类型的文字,中文需要设置成另外的参数。
if(!errorFlag){
u8g2.drawStr(16, 13, "Tem:");//128*64,横坐标为128,纵坐标为64,原点在屏幕的左上角。在坐标为(6,13)的地方插入“Tem”。
u8g2.setCursor(49,13);
u8g2.print(t1); //print 之前需要先设置光标
u8g2.setCursor(49,28);
u8g2.print(t2);
u8g2.drawCircle(62,3,1,U8G2_DRAW_ALL);
u8g2.drawStr(63,13,"C");
u8g2.drawStr(16, 28, "Hum:");
u8g2.drawStr(62, 28, "%");
}else{
u8g2.setCursor(20,40);
u8g2.print("Error"); //print 之前需要先设置光标
}//加入DHT11连接错误的判断
u8g2.setCursor(25,60);
u8g2.print("Makers Go!");
} while (u8g2.nextPage());
errorFlag = 0; //标志位重置
}
进阶版:
#include <U8g2lib.h>
#include <Arduino.h>
#include "DHT.h"
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#define DHTPIN D4 //参照BBS项目前期准备的内容
#define DHTTYPE DHT11
// Update these with values suitable for your network.
const char* ssid = "xxxxx";
const char* password = "xxxxxx"; //个人的WIFI和密码
const char* mqtt_server = "scumaker.org"; //MQTT服务器 默认的这个只能在校园网下访问
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ D1, /* data=*/ D2, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
//这一条是使用u8g2库初始化屏幕实例的语句,是从example里面找到对应合适的屏幕种类后填入了我们对应的板子的引脚号
DHT dht(DHTPIN,DHTTYPE); //初始化DHT11 温湿度传感器
int t1 = 0;
int t2 = 0;
int errorFlag = 0;
void setup() {
setup_wifi();
client.setServer(mqtt_server, 1883);
pinMode(D4, INPUT); //从D4这个接口读取温湿度的数据
dht.begin();
u8g2.begin();
u8g2.enableUTF8Print(); //一些初始化
Serial.begin(115200);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
delay(2000); //可以自己调整一下,看看有什么效果
if (isnan(dht.readTemperature())) {
Serial.println(F("Error !"));
errorFlag = 1;// 如果连接有问题或者传感器有问题就设置错误标记
}
t1 = (int)(dht.readTemperature());
t2 = (int)(dht.readHumidity());
//读取DHT11传感器内的信息
snprintf (msg, MSG_BUFFER_SIZE, "Temp: %d Humid: %d", t1,t2);
client.publish("%$%$%", msg);
Serial.println(t1);
Serial.println(t2);
//
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB08_tr);//u8g2_font_ncenB08_tr:先设置显示屏显示什么类型的文字,中文需要设置成另外的参数。
if(!errorFlag){
u8g2.drawStr(16, 13, "Tem:");//128*64,横坐标为128,纵坐标为64,原点在屏幕的左上角。在坐标为(6,13)的地方插入“Tem”。
u8g2.setCursor(49,13);
u8g2.print(t1); //print 之前需要先设置光标
u8g2.setCursor(49,28);
u8g2.print(t2);
u8g2.drawCircle(62,3,1,U8G2_DRAW_ALL);
u8g2.drawStr(63,13,"C");
u8g2.drawStr(16, 28, "Hum:");
u8g2.drawStr(62, 28, "%");
}else{
u8g2.setCursor(20,40);
u8g2.print("Error"); //print 之前需要先设置光标
}//加入DHT11连接错误的判断
u8g2.setCursor(25,60);
u8g2.print("Makers Go!");
} while (u8g2.nextPage());
errorFlag = 0; //标志位重置
}
三、网络连接能力
以上代码成功地让程序运行了起来,并且实现了温湿度检测和液体检测。但是现在只能通过数据线把信息传到电脑上,这就导致了使用受限制,如何解决呢,我们给出的办法是利用WIFI和MQTT通讯协议,WIFI相信大家都很熟悉了,就是有一个名称(SSID)和密码就可以连接到指定的WIFI,然后就可以上网等等操作了。但是在上网这个过程中,是有很多协议在背后的,是他们让我们能够上网、聊天的。也就是说这里我们也需要一个协议来让我们的开发板“上网”发送消息,我们的选择就是MQTT协议。
简单来说MQTT通讯协议中有三种角色,一个是发布信息的发送者,一个中间人,一个接收者。发送者把消息送给中间人之后就不管了,之后接收者会去向中间人索要消息。描述到这里,你会发现,如果只是一个发送者的话,这个架构是没问题的,但是当有多个发送者怎么办,中间人如何给接收者正确的消息呢。为了解决这个问题,MQTT还引入了“主题”这个概念,主题就像信箱,发送者把消息给中间人的特定主题,而接收者也只从特定的主题去获取信息,就可以确保大家不会拿错了。当然,在这里,接收者和发送者可以在同一个人身上实现,就做到了消息的收发。
接下来让我们打开示例中的“完整版.ob”,先不急上传,让我们看看有什么变化。
我们看到多了三个绿色的积木块,其中有一些需要我们修改的信息,首先是wifi名称和密码,大家可以选择自己用手机开个热点。还有就是MQTT的发送主题和接收主题一定要设置一个不同的,比如send1234(1234可以改成手机号后四位)。确保你不会收到别人的消息。修改好后,就上传吧!
上传后,我们使用MQTT的客户端,比如MQTTX
MQTTbroker可以使用一些免费的公共服务器进行测试,例如broker.mqttdashboard.org
设置好服务器和主题(主题是mytopic开头的,mytopic/(自己写的内容))后就可以看到消息了,我们设置的是发送是否有水,可以用水靠近传感器看一看是否有反应呢。
四、拓展:水位监测
尝试将水位监测模块利用起来,在oled现实模块上再输出一行信息,显示当前是否有水。