我们在前面已经成功的把温湿度显示到了本地OLED屏幕上,下面我们就结合之前的项目以及教程esp8266模块的使用来完成我们这次远程的数据显示功能。
1、首先我们把开发板连接上ESP8266模块,把数据通过wifi传输到电脑端,我们先在电脑端使用网络调试工具开启客户端来接收我们的数据进行测试下。
我们参照之前esp8266模块使用篇的教程把硬件搭建好,再编写如下代码:
/**
* 文件: 室内温湿度监控系统.ino by 零知实验室([url]www.lingzhilab.com[/url])
* -- 零知开源,让电子制作变得更简单! --
* 时间: 2018/07/04 11:01
* 说明: 使用零知开发板获取室内温湿度数据经过wifi上传到APP显示
**/
#include "HTU3X.h" //加入SHT3X的库
#include "oled_demo.h"//OLED的库
#include "esp8266.h"//esp8266 库
#include <HardwareSerial.h>
//esp8266 在这里作为TCP服务器,配置如下供客户端连接
#define ssid "ESP8266-TCP服务器"
#define password "12345678"
#define serverPort 8081 // 开启的端口号
//定义连接OLED模块的各个引脚
#define OLED_DC 3
#define OLED_RST 2
#define OLED_SCL 4
#define OLED_SDA 5
//OLED需要显示的内容
unsigned char oled_str_head[] =
{
0x00,0x00,0x80,0x80,0x80,0x80,0xC0,0xFC,0xF8,0xC0,0x80,0x80,0x80,0x80,0x00,0x00,
0x00,0x00,0x00,0x41,0x39,0x1F,0x1F,0x0F,0x0F,0x1F,0x1F,0x71,0x01,0x00,0x00,0x00,/*"★"*/
0x00,0x00,0x80,0x80,0x80,0x80,0x60,0x1C,0x38,0x40,0x80,0x80,0x80,0x80,0x00,0x00,
0x00,0x00,0x00,0x41,0x3E,0x22,0x10,0x08,0x08,0x10,0x2E,0x72,0x01,0x00,0x00,0x00,/*"☆"*/
0x00,0x00,0xC0,0x30,0x90,0xF0,0x54,0xFC,0x92,0x7A,0x08,0x08,0x28,0x10,0x00,0x00,
0x00,0x00,0x10,0x08,0x04,0x1A,0x09,0x36,0x6A,0x19,0x02,0x04,0x08,0x08,0x00,0x00,/*"零",0*/
0x00,0x00,0x00,0x00,0x3C,0xA0,0x50,0x30,0x00,0x80,0x00,0x80,0x80,0x40,0x80,0x00,
0x00,0x00,0x04,0x22,0x13,0x0E,0x09,0x09,0x01,0x03,0x0D,0x08,0x08,0x07,0x00,0x00,/*"知",1*/
0x00,0x00,0x00,0x00,0x80,0xE8,0x48,0x28,0x18,0x1C,0xE4,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x03,0x22,0x1E,0x01,0x01,0x01,0x01,0x7F,0x01,0x01,0x00,0x00,0x00,/*"开",2*/
0x00,0x00,0x40,0x84,0x18,0x08,0xC0,0xB8,0x48,0x34,0xC4,0xA4,0xE0,0x00,0x00,0x00,
0x00,0x00,0x1F,0x7E,0x1A,0x06,0x31,0x13,0x25,0x43,0x3F,0x0B,0x10,0x30,0x00,0x00,/*"源",3*/
0x00,0x00,0x80,0x80,0x80,0x80,0x60,0x1C,0x38,0x40,0x80,0x80,0x80,0x80,0x00,0x00,
0x00,0x00,0x00,0x41,0x3E,0x22,0x10,0x08,0x08,0x10,0x2E,0x72,0x01,0x00,0x00,0x00,/*"☆"*/
0x00,0x00,0x80,0x80,0x80,0x80,0xC0,0xFC,0xF8,0xC0,0x80,0x80,0x80,0x80,0x00,0x00,
0x00,0x00,0x00,0x41,0x39,0x1F,0x1F,0x0F,0x0F,0x1F,0x1F,0x71,0x01,0x00,0x00,0x00,/*"★"*/
};
uint8_t oled_str_webaddr[] = "www.lingzhilab.com";
unsigned char oled_str_hutemp[] =
{
0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"温",0*/
0x10,0x60,0x02,0x8C,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
0x04,0x04,0x7E,0x01,0x44,0x48,0x50,0x7F,0x40,0x40,0x7F,0x50,0x48,0x44,0x40,0x00,/*"湿",1*/
0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度",2*/
0x06,0x09,0x09,0xE6,0xF8,0x0C,0x04,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,
0x00,0x00,0x00,0x07,0x1F,0x30,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,0x00,/*"℃",0*/
};
//SHT3X实例化
HTU3X myHumidity;
//存放获取的温湿度数据
float sht3x_humd, sht3x_temp;
//oled实例化
OLED_DEMO myoled(OLED_SDA, OLED_SCL, OLED_DC, OLED_RST);
//esp8266 实例化
Esp8266 wifi;
#define serialDebug Serial
#define serialEsp Serial1
//获取sht3x的数据
void SHT3X_get_sample(float *humd, float *temp);
//在OLED显示温湿度数据
void oled_show_sample(float humd, float temp);
void setup() {
//打开串口,方便在串口中显示
Serial.begin(9600);
Serial.println("program start!");
//开启SHT3X
myHumidity.begin();
//打开OLED
myoled.begin();
//显示标题"零知开源"
for(int i=0; i<8; i++){
myoled.print_p16x16(i, 0, oled_str_head);//显示在第0行的第0-8列,这里一共可以显示4行
}
//显示网址[url]www.lingzhilab.com[/url]
myoled.print_p6x8(16,7,oled_str_webaddr);
//开启ESP8266 wifi
serialEsp.begin(115200);//esp8266的波特率
wifi.begin(&serialEsp, &serialDebug);
//配置ESP8266为AP, 并作为TCP服务器
if (wifi.enableAP(ssid, password)) {
wifi.debugPrintln("AP成功开启!");
}
if (wifi.setMultiConnect()) {
wifi.debugPrintln("开启多连接模式成功!");
}
if (wifi.openTCPServer(serverPort, 180)) {
wifi.debugPrintln("开启TCP服务器成功!");
}
wifi.debugPrintln("服务器IP:" + wifi.getIP() + " 端口:" + String(serverPort));
}
void loop() {
//获取温湿度
SHT3X_get_sample(&sht3x_humd, &sht3x_temp);
//数据显示到OLED
oled_show_sample(sht3x_humd, sht3x_temp);
//先获取wifi状态,如果客户端连接以后,就啊温湿度数据传输到tcp客户端
int state = wifi.getState();
switch (state) {
case WIFI_NEW_MESSAGE: //从客户端接收到了新的信息,打印
wifi.debugPrintln(String(wifi.getWorkingID()) + ":" + wifi.getMessage()); // debug
wifi.sendMessage(wifi.getWorkingID(), wifi.getMessage()); // 把接收到的信息发送回给客户端
wifi.setState(WIFI_IDLE);
break;
case WIFI_CLOSED : // 如果客户端断开连接
wifi.debugPrintln(String(wifi.getFailConnectID()) + ":连接关闭!");
wifi.setState(WIFI_IDLE);
break;
case WIFI_IDLE :
{
//发送温湿度数据
wifi.sendMessage(wifi.getWorkingID(), String(sht3x_temp));
wifi.sendMessage(wifi.getWorkingID(), String(sht3x_humd));
int state = wifi.checkMessage();
wifi.setState(state);
break;
}
case WIFI_CLIENT_ON ://客户端连接成功
wifi.sendMessage(wifi.getWorkingID(), "from ESP8266: Hello, [url]www.lingzhilab.com[/url]");
wifi.setState(WIFI_IDLE);
break;
}
//delay(500);
}
void SHT3X_get_sample(float *humd, float *temp)
{
myHumidity.readTempAndHumi(temp, humd);
//在串口中显示
Serial.print(" 温度:");
Serial.print(*temp, 1);
Serial.print(" °C");
Serial.print(" 湿度:");
Serial.print(*humd, 1);
Serial.print("%");
Serial.println();
}
//我们的温湿度都是1位小数,并且都是 xx.x 的格式
//这个函数把一个1位的小数转换成字符串数组,便于显示,其中最高位放在第一个下标中
//例如:32.1 存放到数组中为:{'3','2','1'};
void float_to_int_array(float f, unsigned char *arr)
{
unsigned int intdata = f*10;//转换为整数
//分别取出每一位
unsigned char d0 = intdata%10;
unsigned char d1 = (intdata%100)/10;
unsigned char d2 = intdata/100;
//转换为数字的ASCII码
arr[0] = d2 + '0';
arr[1] = d1 + '0';
arr[2] = d0 + '0';
}
void oled_show_sample(float humd, float temp)
{
//湿度信息显示,这里主要是位置需要调整
unsigned char arr_str_hum[3];
unsigned char arr_str_tem[3];
float_to_int_array(humd, arr_str_hum);
unsigned char str1[2] = {arr_str_hum[0], '\0'};
unsigned char str2[2] = {arr_str_hum[1], '\0'};
unsigned char str3[2] = {arr_str_hum[2], '\0'};
unsigned char str4[2] = ".";
unsigned char str5[2] = ":";
unsigned char str6[2] = "%";
myoled.print_p8x16(50, 4, str5);
myoled.print_p8x16(60, 4, str1);
myoled.print_p8x16(70, 4, str2);
myoled.print_p8x16(78, 4, str4);
myoled.print_p8x16(86, 4, str3);
myoled.print_p8x16(100, 4, str6);
myoled.print_p16x16(1, 2, oled_str_hutemp, 1);
myoled.print_p16x16(2, 2, oled_str_hutemp, 2);
//温度信息
float_to_int_array(temp, arr_str_tem);
unsigned char str7[2] = {arr_str_tem[0], '\0'};
unsigned char str8[2] = {arr_str_tem[1], '\0'};
unsigned char str9[2] = {arr_str_tem[2], '\0'};
myoled.print_p8x16(50, 2, str5);
myoled.print_p8x16(60, 2, str7);
myoled.print_p8x16(70, 2, str8);
myoled.print_p8x16(78, 2, str4);
myoled.print_p8x16(86, 2, str9);
myoled.print_p16x16(1, 1, oled_str_hutemp, 0);
myoled.print_p16x16(2, 1, oled_str_hutemp, 2);
myoled.print_p16x16(6, 1, oled_str_hutemp, 3);
}
上面的代码在原来的项目基础上更改了引脚(因为串口1使用的0,1号引脚),然后添加了ESP8266的部分代码,我们把代码编译后上传到开发中,然后在电脑上使用网络调试助手开启tcp客户端连接到我们的服务器,就可以看到我们的温湿度数据了:
可以看到我们的温湿度数据已经正常传输到电脑端了,下一步我们使用自己的上位机把数据显示出来。
2、我们一般在电脑端都需要建立自己的上位机,然后根据自己的需求进行开发,这里我们使用的QT来建立我们的上位机,程序很简单,只是建立了一个TCP客户端,然后接收ESP8266传输来的数据,最后在界面上进行显示。本部分不过多的进行解释,直接提供源代码,懂qt的人员可以直接在我们的源码的基础上进行修改,而选择qt是因为QT的强大移植性能,而且使用范围很广。手机端和电脑端一样的步骤就不过多解释,使用的代码完全一样只是编译到安卓平台下了。下面可以看到电脑端和手机端的最终的效果,源代码在附件中可以下载到。
完整工程:
室内温湿度监控系统-v2.zip(点击下载)