基于ESP8266实现温湿度采集及控制【arduino】(SmartConfig+MQTT+DHT11+OLED【模拟I2C】)

一、硬件设备以及连接

1、设备名称

NodeMcu x 1
DHT11 x 1
OLED(0.91) x 1
继电器 x 1
杜邦线若干
面包板 x 1

2、传感器连接

硬件连接图.png

二、软件部分代码以及库的引用

1、库函数引用

ESP8266【WiFi开发板】
文件-首选项-修改附加开发板管理器网址

开发板管理器.png

http://arduino.esp8266.com/stable/package_esp8266com_index.json

工具-管理库

库文件.png

SimpleDHT【DHT11】
PubSubClient【MQTT】
ArduinoJson【Json】

2、程序流程图

流程图.png

3、代码部分

  • DHT11模块使用了SimpleDHT这个库,使用这个库可以加快开发速度。不需要编写协议时序,使用库之后代码也非常简单。
#include 
int DHT_01_pin = D4;   //D4引脚
int read_temp = 0;
int read_hum = 0;
SimpleDHT11 dht11_01(DHT_01_pin);
byte temperature_01 = 0, humidity_01 = 0;

if (dht11_01.read(&temperature_01, &humidity_01, NULL) == SimpleDHTErrSuccess)  
{
      read_temp = (int)temperature_01; 
      read_hum = (int)humidity_01;
}

  • OLED(0.91)模块此模块我使用了软件模拟了I2C的时序,此方法比较困难不适合初学者学习
    • 字模代码
const unsigned char F6x8[][6] =
{
  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// sp
  {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00},// !
  {0x00, 0x00, 0x07, 0x00, 0x07, 0x00},// "
  {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14},// #
  {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12},// $
  {0x00, 0x62, 0x64, 0x08, 0x13, 0x23},// %
  {0x00, 0x36, 0x49, 0x55, 0x22, 0x50},// &
  {0x00, 0x00, 0x05, 0x03, 0x00, 0x00},// '
  {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00},// (
  {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00},// )
  {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14},// *
  {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08},// +
  {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00},// ,
  {0x00, 0x08, 0x08, 0x08, 0x08, 0x08},// -
  {0x00, 0x00, 0x60, 0x60, 0x00, 0x00},// .
  {0x00, 0x20, 0x10, 0x08, 0x04, 0x02},// /
  {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
  {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00},// 1
  {0x00, 0x42, 0x61, 0x51, 0x49, 0x46},// 2
  {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31},// 3
  {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10},// 4
  {0x00, 0x27, 0x45, 0x45, 0x45, 0x39},// 5
  {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30},// 6
  {0x00, 0x01, 0x71, 0x09, 0x05, 0x03},// 7
  {0x00, 0x36, 0x49, 0x49, 0x49, 0x36},// 8
  {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E},// 9
  {0x00, 0x00, 0x36, 0x36, 0x00, 0x00},// :
  {0x00, 0x00, 0x56, 0x36, 0x00, 0x00},// ;
  {0x00, 0x08, 0x14, 0x22, 0x41, 0x00},// <
  {0x00, 0x14, 0x14, 0x14, 0x14, 0x14},// =
  {0x00, 0x00, 0x41, 0x22, 0x14, 0x08},// >
  {0x00, 0x02, 0x01, 0x51, 0x09, 0x06},// ?
  {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E},// @
  {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C},// A
  {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36},// B
  {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22},// C
  {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C},// D
  {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41},// E
  {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01},// F
  {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A},// G
  {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F},// H
  {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00},// I
  {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01},// J
  {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41},// K
  {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40},// L
  {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F},// M
  {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F},// N
  {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E},// O
  {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06},// P
  {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E},// Q
  {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46},// R
  {0x00, 0x46, 0x49, 0x49, 0x49, 0x31},// S
  {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01},// T
  {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F},// U
  {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F},// V
  {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F},// W
  {0x00, 0x63, 0x14, 0x08, 0x14, 0x63},// X
  {0x00, 0x07, 0x08, 0x70, 0x08, 0x07},// Y
  {0x00, 0x61, 0x51, 0x49, 0x45, 0x43},// Z
  {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00},// [
  {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55},// 55
  {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00},// ]
  {0x00, 0x04, 0x02, 0x01, 0x02, 0x04},// ^
  {0x00, 0x40, 0x40, 0x40, 0x40, 0x40},// _
  {0x00, 0x00, 0x01, 0x02, 0x04, 0x00},// '
  {0x00, 0x20, 0x54, 0x54, 0x54, 0x78},// a
  {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38},// b
  {0x00, 0x38, 0x44, 0x44, 0x44, 0x20},// c
  {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F},// d
  {0x00, 0x38, 0x54, 0x54, 0x54, 0x18},// e
  {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02},// f
  {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C},// g
  {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78},// h
  {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00},// i
  {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00},// j
  {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00},// k
  {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00},// l
  {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78},// m
  {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78},// n
  {0x00, 0x38, 0x44, 0x44, 0x44, 0x38},// o
  {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18},// p
  {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC},// q
  {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08},// r
  {0x00, 0x48, 0x54, 0x54, 0x54, 0x20},// s
  {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20},// t
  {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C},// u
  {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C},// v
  {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C},// w
  {0x00, 0x44, 0x28, 0x10, 0x28, 0x44},// x
  {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C},// y
  {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44},// z
  {0x14, 0x14, 0x14, 0x14, 0x14, 0x14},// horiz lines
};

const unsigned char F8X16[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
  0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 1
  0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //" 2
  0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, //# 3
  0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$ 4
  0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //% 5
  0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //& 6
  0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //' 7
  0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //( 8
  0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //) 9
  0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //* 10
  0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+ 11
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //, 12
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //- 13
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //. 14
  0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 15
  0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, //0 16
  0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //1 17
  0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, //2 18
  0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //3 19
  0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, //4 20
  0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, //5 21
  0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //6 22
  0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, //7 23
  0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, //8 24
  0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, //9 25
  0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 26
  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //; 27
  0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //< 28
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //= 29
  0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //> 30
  0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //? 31
  0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@ 32
  0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, //A 33
  0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //B 34
  0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, //C 35
  0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //D 36
  0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, //E 37
  0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, //F 38
  0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, //G 39
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, //H 40
  0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //I 41
  0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, //J 42
  0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, //K 43
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, //L 44
  0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, //M 45
  0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, //N 46
  0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //O 47
  0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, //P 48
  0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, //Q 49
  0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, //R 50
  0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, //S 51
  0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //T 52
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //U 53
  0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, //V 54
  0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, //W 55
  0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, //X 56
  0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //Y 57
  0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, //Z 58
  0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[ 59
  0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\ 60
  0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //] 61
  0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^ 62
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_ 63
  0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //` 64
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, //a 65
  0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //b 66
  0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, //c 67
  0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, //d 68
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, //e 69
  0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //f 70
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, //g 71
  0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //h 72
  0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //i 73
  0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, //j 74
  0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, //k 75
  0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //l 76
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, //m 77
  0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //n 78
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //o 79
  0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, //p 80
  0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, //q 81
  0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, //r 82
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, //s 83
  0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, //t 84
  0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, //u 85
  0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, //v 86
  0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, //w 87
  0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, //x 88
  0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, //y 89
  0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, //z 90
  0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{ 91
  0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //| 92
  0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //} 93
  0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
};
    • I2C端口模拟
//I2C管脚的定义
#define SDA D1
#define SCL D2

//输出电平的宏定义
#define I2C_SCL_L digitalWrite(SCL,LOW)//SCL
#define I2C_SCL_H digitalWrite(SCL,HIGH)
#define I2C_SDA_L digitalWrite(SDA,LOW)//SDA
#define I2C_SDA_H digitalWrite(SDA,HIGH)

//管脚模式的宏定义
#define SCL_OUT  pinMode(SCL, OUTPUT) //SCL
#define SDA_OUT  pinMode(SDA, OUTPUT) //SDA

//初始化
void I2C_Init()
{
  SDA_OUT;
  SCL_OUT;
  I2C_SDA_H;
  I2C_SCL_H;
}

//I2C开始
void I2C_Start()
{
  I2C_SCL_H;
  I2C_SDA_H;
  I2C_SDA_L;
  I2C_SCL_L;
}

//I2C结束
void I2C_Stop()
{
  I2C_SCL_L;
  I2C_SDA_L;

  I2C_SCL_H;
  I2C_SDA_H;
}

//检查应答信号
void I2C_Wait_Ack()
{
  I2C_SCL_H;
  I2C_SCL_L;
}
    • I2C数据发送
//I2C写入一个字节
void Write_I2C_Byte(unsigned char IIC_Byte)
{
  unsigned char i;
  unsigned char m, da;
  da = IIC_Byte;
  I2C_SCL_L;
  for (i = 0; i < 8; i++)
  {
    m = da;
    m = m & 0x80;

    if (m == 0x80)
      I2C_SDA_H;
    else
      I2C_SDA_L;

    da = da << 1;
    I2C_SCL_H;
    I2C_SCL_L;
  }
}

void Write_I2C_Command(unsigned char IIC_Command)
{
  I2C_Start();
  Write_I2C_Byte(0x78);            //Slave address,SA0=0
  I2C_Wait_Ack();
  Write_I2C_Byte(0x00);     //write command
  I2C_Wait_Ack();
  Write_I2C_Byte(IIC_Command);
  I2C_Wait_Ack();
  I2C_Stop();
}

  // IIC Write Data
void Write_I2C_Data(unsigned char IIC_Data)
{
  I2C_Start();
  Write_I2C_Byte(0x78);     //D/C#=0; R/W#=0
  I2C_Wait_Ack();
  Write_I2C_Byte(0x40);     //write data
  I2C_Wait_Ack();
  Write_I2C_Byte(IIC_Data);
  I2C_Wait_Ack();
  I2C_Stop();
}

void OLED_WR_Byte(unsigned char dat, unsigned char cmd)
{
  if (cmd)
  {
    Write_I2C_Data(dat);
  }
  else
  {
    Write_I2C_Command(dat);
  }
}
    • OLED操作函数
//坐标设置
void OLED_Set_Pos(u8 x, u8 y)
{
  OLED_WR_Byte(0xb0 + y, OLED_CMD);
  OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);
  OLED_WR_Byte((x & 0x0f), OLED_CMD);
}

//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
  u8 i, n;
  for (i = 0; i < 8; i++)
  {
    OLED_WR_Byte (0xb0 + i, OLED_CMD); //设置页地址(0~7)
    OLED_WR_Byte (0x00, OLED_CMD);     //设置显示位置—列低地址
    OLED_WR_Byte (0x10, OLED_CMD);     //设置显示位置—列高地址
    for (n = 0; n < 128; n++)OLED_WR_Byte(0, OLED_DATA);
  } //更新显示
}

// 局部刷新 x:0~127 y:0 ~ 3
// 部分刷新 例如 需要刷新OLED 最后一行OLED_Clear_Local(0,3);
void OLED_Clear_Local(u8 x , u8 y)
{
  u8 i, n;
  for (i = y; i < 4; i++)
  {
    OLED_WR_Byte (0xb0 + i, OLED_CMD); //设置页地址(0~7)
    OLED_WR_Byte (0x00, OLED_CMD);     //设置显示位置—列低地址
    OLED_WR_Byte (0x10, OLED_CMD);     //设置显示位置—列高地址
    OLED_Set_Pos(x, i);
    for (n = x; n < 128; n++)OLED_WR_Byte(0, OLED_DATA);
  } //更新显示
}
//显示单个字符
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size)
{
  unsigned char c = 0, i = 0;
  c = chr - ' '; //得到偏移后的值
  if (x > Max_Column - 1) {
    x = 0;
    y = y + 2;
  }
  if (Char_Size == 16)
  {
    OLED_Set_Pos(x, y);
    for (i = 0; i < 8; i++)
    {
      OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);
    }
    OLED_Set_Pos(x, y + 1);
    for (i = 0; i < 8; i++) {
      OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);
    }
  }
  else
  {
    OLED_Set_Pos(x, y);
    for (i = 0; i < 6; i++)
      OLED_WR_Byte(F6x8[c][i], OLED_DATA);
  }
}
//-----------------------------------
//|x→[0,127]            |
//|     OLED显示坐标      |
//|y      范围           |
//|↓                       |
//|[0,3]                  |
//-----------------------------------
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_t Char_Size)
{
  unsigned char j = 0;
  while (chr[j] != '\0')
  {
    OLED_ShowChar(x, y, chr[j], Char_Size);
    x += 8;
    if (x > 120)
    {
      x = 0; y += 2;
    }
    j++;
  }
}
uint32_t oled_pow(uint8_t m, uint8_t n)
{
  uint32_t result = 1;
  while (n--)result *= m;
  return result;
}
//显示数字 
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size2)
{
  uint8_t t, temp;
  uint8_t enshow = 0;
  for (t = 0; t < len; t++)
  {
    temp = (num / oled_pow(10, len - t - 1)) % 10;
    if (enshow == 0 && t < (len - 1))
    {
      if (temp == 0)
      {
        OLED_ShowChar(x + (size2 / 2)*t, y, ' ', size2);
        continue;
      } else
        enshow = 1;
    }
    OLED_ShowChar(x + (size2 / 2)*t, y, temp + '0', size2);
  }
}

// 此函数仅供0.91寸使用
void OLED_Init(void)   
{
  I2C_Init(); //初始化I2C 管脚输出高电平
  delay(200);
  OLED_WR_Byte(0xAE, OLED_CMD); //关闭显示

  OLED_WR_Byte(0x40, OLED_CMD); //---set low column address
  OLED_WR_Byte(0xB0, OLED_CMD); //---set high column address

  OLED_WR_Byte(0xC8, OLED_CMD); //-not offset

  OLED_WR_Byte(0x81, OLED_CMD); //设置对比度
  OLED_WR_Byte(0xff, OLED_CMD);

  OLED_WR_Byte(0xa1, OLED_CMD); //段重定向设置

  OLED_WR_Byte(0xa6, OLED_CMD); //

  OLED_WR_Byte(0xa8, OLED_CMD); //设置驱动路数
  OLED_WR_Byte(0x1f, OLED_CMD);

  OLED_WR_Byte(0xd3, OLED_CMD);
  OLED_WR_Byte(0x00, OLED_CMD);

  OLED_WR_Byte(0xd5, OLED_CMD);
  OLED_WR_Byte(0xf0, OLED_CMD);

  OLED_WR_Byte(0xd9, OLED_CMD);
  OLED_WR_Byte(0x22, OLED_CMD);

  OLED_WR_Byte(0xda, OLED_CMD);
  OLED_WR_Byte(0x02, OLED_CMD);

  OLED_WR_Byte(0xdb, OLED_CMD);
  OLED_WR_Byte(0x49, OLED_CMD);

  OLED_WR_Byte(0x8d, OLED_CMD);
  OLED_WR_Byte(0x14, OLED_CMD);

  OLED_WR_Byte(0xaf, OLED_CMD);
  OLED_Clear();
}
  • 继电器控制
    • 继电器初始化
  int relay = D6;
  pinMode(relay, OUTPUT);
  delay(200);
  digitalWrite(relay, LOW);
    • 继电器控制 此方法和mqtt_callback函数以及Json配合使用
      如果上位机通过MQTT协议向ESP8266发送数据,这些数据会经过mqtt_callback函数进行接收,使用ArduinoJson进行Json解析。
  String relayState = "OFF";

  if (strcmp("ON", relayState.c_str()) == 0)
  {
    digitalWrite(relay, HIGH);
    reflashFlag = 1; //OLED 刷新标志
    Serial.println(Relay_01_State);
  }
  if (strcmp("OFF", relayState.c_str()) == 0)
  {
    digitalWrite(relay, LOW);
    reflashFlag = 1; //OLED 刷新标志
    Serial.println(Relay_01_State);
  }
  • SmartConfig
    智能硬件处于混杂模式下,监听网络中的所有报文,手机 APP 将 SSID 和密码编码到 UDP 报文中,通过广播包或组播报发送,智能硬件接收到 UDP 报文后解码,得到正确的 SSID 和密码,然后主动连接指定 SSID 的路由完成连接。
#include 
bool wifiConnectState = false;
void WIFISmartConfig() {  //wifi配置
  int testConnectCount = 0;
  Serial.println("\nAuto for connection ...");
  while (WiFi.status() != WL_CONNECTED) {
    if (!wifiConnectState) {
      LEDStartInfo(500);
      testConnectCount++;
      if (testConnectCount >= 10 ) {
        wifiConnectState = true;
        Serial.println("Linked Faied ! Jump to SmartConfig...");
      }
      Serial.println("Linking ...");
    } else {
      WiFi.mode(WIFI_STA); //设置WIFI模块为STA模式
      Serial.println("Waiting for connection ...");
      WiFi.beginSmartConfig();
      while (true) {
        Serial.print(".");
        LEDStartInfo(500);
        if (WiFi.smartConfigDone()) {
          Serial.println("\nSmartConfig Successed !");
          for (int i = 0; i < 20; i++) {
            LEDStartInfo(200);
          }
          break;
        }
      }
    }
  }
  Serial.printf("\nSSID: %s", WiFi.SSID().c_str());//输出账号
  Serial.printf("\nPassword: %s", WiFi.psk().c_str());//输出密码
  Serial.printf("\nIP address: "); Serial.print(WiFi.localIP()); //输出IP地址
  ipinfo = "IP:" + ip2Str(WiFi.localIP());
}
SmartConfig.png
  • 此图为乐鑫ESPTouch软件 选择组播进行数据包的发送
    APP下载地址:https://www.espressif.com/zh-hans/support/download/apps?keys=&field_type_tid%5B%5D=14
app.png
  • ArduinoJson6函数及方法
    注:ArduinoJson5版本和ArduinoJson6版本部分方法不一致,具体需要查询文档。
    ArduinoJson6 文档:https://blog.csdn.net/weixin_30546933/article/details/96227470
    • Json拼接
#include 
String JSONmessageBuffer = "";  // 储存Json数据
StaticJsonDocument<200> json; //创建实例

JsonObject json_root = json.to();  // 创建Json根节点
json_root["roomLocation"] = "LivingRoom";
JsonObject device_name = json_root.createNestedObject("DeviceName");
JsonObject DHT11_01_values = device_name.createNestedObject("DHT11_01");
DHT11_01_values["Temperature:"] = read_temp;
DHT11_01_values["Humidity:"] = read_hum;

JsonObject Relay_01_state = device_name.createNestedObject("Relay_01");
Relay_01_state["State"] = relayState;

serializeJson(json, JSONmessageBuffer); // 将Json转化为String

//拼接之后
{
    "roomLocation":"LivingRoom",
    "DeviceName":{
        "DHT11_01":{
            "Temperature:":24,
            "Humidity:":34
        },
        "Relay_01":{
            "State":"OFF"
        }
    }
}

    • Json解析
// 接收的Json数据
{
  "Relay_01_State": "ON"
}
#include 
StaticJsonDocument<200> docParser;
char receiveDataChar[length];
deserializeJson(docParser, receiveDataChar);  //将char* 转化为Json数据
const char* Relay_01_State = docParser["Relay_01_State"];  

Relay_01_State 的内容为 ON

RecMsg.png

  • MQTT函数及方法
  1. boolean connect (clientID, [username, password], [willTopic, willQoS, willRetain, willMessage], [cleanSession])
    client_Id 是当前设备的唯一标识,并且不能重复
    username 是服务器的用户名【可不写】
    password 是服务器的密码【可不写】
mqttClient.connect(client_Id, "admin", "public");
  1. boolean publish (topic, payload, [length], [retained])
    topic 是一主题,如果其他设备订阅此主题,就可以接收到消息。
    payload 需要发送的消息负载 【接收char数组】
mqttClient.publish(topic, JSONmessageBuffer.c_str());  

3.boolean subscribe (topic, [qos])
topic 需要订阅的主题 【可以是自己的主题也可以是其他主题】

mqttClient.subscribe(subTopic);

4.boolean loop () 应该在循环中用它,以允许客户端处理传入的消息并维持其与服务器的连接。

void loop() 
{
  mqttClient.loop();  // 循环
}
  1. PubSubClient* setCallback(callback) 设置消息回调函数。
    callback function* 指向消息回调函数的指针,当消息到达此客户端创建的预订时调用。
void mqtt_callback(char* topic, byte* payload, unsigned int length)
{
  // 需要实现的方法
}
  1. MQTT实现
#include 
#include 
const char* mqtt_ServerIP = "192.168.1.195";  // MQTT服务器IP
const char* topic = "mqtt_NodeMucu";
const char* client_Id = "mqtt_client_NodeMcu_Device_01"; // 设备名称
const char* subTopic = "NodeMcu_Rec_Msg";
const int mqtt_ServerPort = 1883; //端口

WiFiClient espClient;
PubSubClient mqttClient(espClient);

void connection_mqtt_server() {
  while (!mqttClient.connected()) {
    Serial.println("\nAttempting MQTT connection...");
    if (mqttClient.connect(client_Id, "admin", "public")) { // 连接成功
      Serial.println("MQTT Server Connceted ! ");
      mqttClient.subscribe(subTopic);  // 订阅主题
    } else { // 连接失败
      Serial.println("failed, rc=");
      Serial.print(mqttClient.state());
    }
  }
}

void setup() {
  //此时WIFI以及成功连接
  mqttClient.setServer(mqtt_ServerIP, mqtt_ServerPort);
  mqttClient.setCallback(mqtt_callback);
  connection_mqtt_server();
}
void loop(){
  mqttClient.loop();
}
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
  //Callback回调函数
}

三、完整代码

#include 
#include 
#include 
#include 

/************************* OLED SET *********************************/
//I2C管脚的定义
#define SDA D1
#define SCL D2

//输出电平的宏定义
#define I2C_SCL_L digitalWrite(SCL,LOW)//SCL
#define I2C_SCL_H digitalWrite(SCL,HIGH)

#define I2C_SDA_L digitalWrite(SDA,LOW)//SDA
#define I2C_SDA_H digitalWrite(SDA,HIGH)

//管脚模式的宏定义
#define SCL_OUT  pinMode(SCL, OUTPUT) //SCL
#define SDA_OUT  pinMode(SDA, OUTPUT) //SDA

#define Max_Column  128
#define Max_Row   32
#define OLED_CMD  0  //写命令
#define OLED_DATA 1 //写数据

String ipinfo;
int read_temp = 0;
int read_hum = 0;
String relayState = "OFF";
const unsigned char F6x8[][6] =
{
  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// sp
  {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00},// !
  {0x00, 0x00, 0x07, 0x00, 0x07, 0x00},// "
  {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14},// #
  {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12},// $
  {0x00, 0x62, 0x64, 0x08, 0x13, 0x23},// %
  {0x00, 0x36, 0x49, 0x55, 0x22, 0x50},// &
  {0x00, 0x00, 0x05, 0x03, 0x00, 0x00},// '
  {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00},// (
  {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00},// )
  {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14},// *
  {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08},// +
  {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00},// ,
  {0x00, 0x08, 0x08, 0x08, 0x08, 0x08},// -
  {0x00, 0x00, 0x60, 0x60, 0x00, 0x00},// .
  {0x00, 0x20, 0x10, 0x08, 0x04, 0x02},// /
  {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
  {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00},// 1
  {0x00, 0x42, 0x61, 0x51, 0x49, 0x46},// 2
  {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31},// 3
  {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10},// 4
  {0x00, 0x27, 0x45, 0x45, 0x45, 0x39},// 5
  {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30},// 6
  {0x00, 0x01, 0x71, 0x09, 0x05, 0x03},// 7
  {0x00, 0x36, 0x49, 0x49, 0x49, 0x36},// 8
  {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E},// 9
  {0x00, 0x00, 0x36, 0x36, 0x00, 0x00},// :
  {0x00, 0x00, 0x56, 0x36, 0x00, 0x00},// ;
  {0x00, 0x08, 0x14, 0x22, 0x41, 0x00},// <
  {0x00, 0x14, 0x14, 0x14, 0x14, 0x14},// =
  {0x00, 0x00, 0x41, 0x22, 0x14, 0x08},// >
  {0x00, 0x02, 0x01, 0x51, 0x09, 0x06},// ?
  {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E},// @
  {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C},// A
  {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36},// B
  {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22},// C
  {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C},// D
  {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41},// E
  {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01},// F
  {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A},// G
  {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F},// H
  {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00},// I
  {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01},// J
  {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41},// K
  {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40},// L
  {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F},// M
  {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F},// N
  {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E},// O
  {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06},// P
  {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E},// Q
  {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46},// R
  {0x00, 0x46, 0x49, 0x49, 0x49, 0x31},// S
  {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01},// T
  {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F},// U
  {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F},// V
  {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F},// W
  {0x00, 0x63, 0x14, 0x08, 0x14, 0x63},// X
  {0x00, 0x07, 0x08, 0x70, 0x08, 0x07},// Y
  {0x00, 0x61, 0x51, 0x49, 0x45, 0x43},// Z
  {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00},// [
  {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55},// 55
  {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00},// ]
  {0x00, 0x04, 0x02, 0x01, 0x02, 0x04},// ^
  {0x00, 0x40, 0x40, 0x40, 0x40, 0x40},// _
  {0x00, 0x00, 0x01, 0x02, 0x04, 0x00},// '
  {0x00, 0x20, 0x54, 0x54, 0x54, 0x78},// a
  {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38},// b
  {0x00, 0x38, 0x44, 0x44, 0x44, 0x20},// c
  {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F},// d
  {0x00, 0x38, 0x54, 0x54, 0x54, 0x18},// e
  {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02},// f
  {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C},// g
  {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78},// h
  {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00},// i
  {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00},// j
  {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00},// k
  {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00},// l
  {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78},// m
  {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78},// n
  {0x00, 0x38, 0x44, 0x44, 0x44, 0x38},// o
  {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18},// p
  {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC},// q
  {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08},// r
  {0x00, 0x48, 0x54, 0x54, 0x54, 0x20},// s
  {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20},// t
  {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C},// u
  {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C},// v
  {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C},// w
  {0x00, 0x44, 0x28, 0x10, 0x28, 0x44},// x
  {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C},// y
  {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44},// z
  {0x14, 0x14, 0x14, 0x14, 0x14, 0x14},// horiz lines
};

const unsigned char F8X16[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
  0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 1
  0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //" 2
  0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, //# 3
  0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$ 4
  0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //% 5
  0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //& 6
  0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //' 7
  0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //( 8
  0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //) 9
  0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //* 10
  0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+ 11
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //, 12
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //- 13
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //. 14
  0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 15
  0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, //0 16
  0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //1 17
  0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, //2 18
  0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //3 19
  0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, //4 20
  0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, //5 21
  0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //6 22
  0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, //7 23
  0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, //8 24
  0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, //9 25
  0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 26
  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //; 27
  0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //< 28
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //= 29
  0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //> 30
  0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //? 31
  0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@ 32
  0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, //A 33
  0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, //B 34
  0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, //C 35
  0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //D 36
  0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, //E 37
  0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, //F 38
  0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, //G 39
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, //H 40
  0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //I 41
  0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, //J 42
  0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, //K 43
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, //L 44
  0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, //M 45
  0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, //N 46
  0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, //O 47
  0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, //P 48
  0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, //Q 49
  0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, //R 50
  0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, //S 51
  0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //T 52
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //U 53
  0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, //V 54
  0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, //W 55
  0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, //X 56
  0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, //Y 57
  0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, //Z 58
  0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[ 59
  0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\ 60
  0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //] 61
  0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^ 62
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_ 63
  0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //` 64
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, //a 65
  0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, //b 66
  0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, //c 67
  0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, //d 68
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, //e 69
  0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //f 70
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, //g 71
  0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //h 72
  0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //i 73
  0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, //j 74
  0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, //k 75
  0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, //l 76
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, //m 77
  0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, //n 78
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, //o 79
  0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, //p 80
  0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, //q 81
  0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, //r 82
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, //s 83
  0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, //t 84
  0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, //u 85
  0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, //v 86
  0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, //w 87
  0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, //x 88
  0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, //y 89
  0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, //z 90
  0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{ 91
  0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //| 92
  0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //} 93
  0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
};

void oled_display_info();
void connection_mqtt_server();
void LEDStartInfo(int delay_ms);
String ip2Str(IPAddress ip);
//I2C初始化
void I2C_Init()
{
  SDA_OUT;
  SCL_OUT;
  I2C_SDA_H;
  I2C_SCL_H;
}

//I2C开始
void I2C_Start()
{
  I2C_SCL_H;
  I2C_SDA_H;
  I2C_SDA_L;
  I2C_SCL_L;
}

//I2C结束
void I2C_Stop()
{
  I2C_SCL_L;
  I2C_SDA_L;

  I2C_SCL_H;
  I2C_SDA_H;
}
//检查应答信号
void I2C_Wait_Ack()
{
  I2C_SCL_H;
  I2C_SCL_L;
}

//I2C写入一个字节
void Write_I2C_Byte(unsigned char IIC_Byte)
{
  unsigned char i;
  unsigned char m, da;
  da = IIC_Byte;
  I2C_SCL_L;
  for (i = 0; i < 8; i++)
  {
    m = da;
    m = m & 0x80;

    if (m == 0x80)
      I2C_SDA_H;
    else
      I2C_SDA_L;

    da = da << 1;
    I2C_SCL_H;
    I2C_SCL_L;
  }
}
void Write_I2C_Command(unsigned char IIC_Command)
{
  I2C_Start();
  Write_I2C_Byte(0x78);            //Slave address,SA0=0
  I2C_Wait_Ack();
  Write_I2C_Byte(0x00);     //write command
  I2C_Wait_Ack();
  Write_I2C_Byte(IIC_Command);
  I2C_Wait_Ack();
  I2C_Stop();
}

  // IIC Write Data
void Write_I2C_Data(unsigned char IIC_Data)
{
  I2C_Start();
  Write_I2C_Byte(0x78);     //D/C#=0; R/W#=0
  I2C_Wait_Ack();
  Write_I2C_Byte(0x40);     //write data
  I2C_Wait_Ack();
  Write_I2C_Byte(IIC_Data);
  I2C_Wait_Ack();
  I2C_Stop();
}
void OLED_WR_Byte(unsigned char dat, unsigned char cmd)
{
  if (cmd)
  {
    Write_I2C_Data(dat);
  }
  else
  {
    Write_I2C_Command(dat);
  }
}
//坐标设置
void OLED_Set_Pos(u8 x, u8 y)
{
  OLED_WR_Byte(0xb0 + y, OLED_CMD);
  OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);
  OLED_WR_Byte((x & 0x0f), OLED_CMD);
}

//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
  u8 i, n;
  for (i = 0; i < 8; i++)
  {
    OLED_WR_Byte (0xb0 + i, OLED_CMD); //设置页地址(0~7)
    OLED_WR_Byte (0x00, OLED_CMD);     //设置显示位置—列低地址
    OLED_WR_Byte (0x10, OLED_CMD);     //设置显示位置—列高地址
    for (n = 0; n < 128; n++)OLED_WR_Byte(0, OLED_DATA);
  } //更新显示
}

// 局部刷新 x:0~127 y:0 ~ 3
// 部分刷新 例如 需要刷新OLED 最后一行OLED_Clear_Local(0,3);
void OLED_Clear_Local(u8 x , u8 y)
{
  u8 i, n;
  for (i = y; i < 4; i++)
  {
    OLED_WR_Byte (0xb0 + i, OLED_CMD); //设置页地址(0~7)
    OLED_WR_Byte (0x00, OLED_CMD);     //设置显示位置—列低地址
    OLED_WR_Byte (0x10, OLED_CMD);     //设置显示位置—列高地址
    OLED_Set_Pos(x, i);
    for (n = x; n < 128; n++)OLED_WR_Byte(0, OLED_DATA);
  } //更新显示
}
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size)
{
  unsigned char c = 0, i = 0;
  c = chr - ' '; //得到偏移后的值
  if (x > Max_Column - 1) {
    x = 0;
    y = y + 2;
  }
  if (Char_Size == 16)
  {
    OLED_Set_Pos(x, y);
    for (i = 0; i < 8; i++)
    {
      OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);
    }
    OLED_Set_Pos(x, y + 1);
    for (i = 0; i < 8; i++) {
      OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);
    }
  }
  else
  {
    OLED_Set_Pos(x, y);
    for (i = 0; i < 6; i++)
      OLED_WR_Byte(F6x8[c][i], OLED_DATA);
  }
}
//-----------------------------------
//|x→[0,127]            |
//|     OLED显示坐标      |
//|y      范围           |
//|↓                    |
//|[0,3]                |
//-----------------------------------
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_t Char_Size)
{
  unsigned char j = 0;
  while (chr[j] != '\0')
  {
    OLED_ShowChar(x, y, chr[j], Char_Size);
    x += 8;
    if (x > 120)
    {
      x = 0; y += 2;
    }
    j++;
  }
}
uint32_t oled_pow(uint8_t m, uint8_t n)
{
  uint32_t result = 1;
  while (n--)result *= m;
  return result;
}
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size2)
{
  uint8_t t, temp;
  uint8_t enshow = 0;
  for (t = 0; t < len; t++)
  {
    temp = (num / oled_pow(10, len - t - 1)) % 10;
    if (enshow == 0 && t < (len - 1))
    {
      if (temp == 0)
      {
        OLED_ShowChar(x + (size2 / 2)*t, y, ' ', size2);
        continue;
      } else
        enshow = 1;
    }
    OLED_ShowChar(x + (size2 / 2)*t, y, temp + '0', size2);
  }
}

void OLED_Init(void)
{
  I2C_Init(); //初始化I2C 管脚输出高电平
  delay(200);
  OLED_WR_Byte(0xAE, OLED_CMD); //关闭显示

  OLED_WR_Byte(0x40, OLED_CMD); //---set low column address
  OLED_WR_Byte(0xB0, OLED_CMD); //---set high column address

  OLED_WR_Byte(0xC8, OLED_CMD); //-not offset

  OLED_WR_Byte(0x81, OLED_CMD); //设置对比度
  OLED_WR_Byte(0xff, OLED_CMD);

  OLED_WR_Byte(0xa1, OLED_CMD); //段重定向设置

  OLED_WR_Byte(0xa6, OLED_CMD); //

  OLED_WR_Byte(0xa8, OLED_CMD); //设置驱动路数
  OLED_WR_Byte(0x1f, OLED_CMD);

  OLED_WR_Byte(0xd3, OLED_CMD);
  OLED_WR_Byte(0x00, OLED_CMD);

  OLED_WR_Byte(0xd5, OLED_CMD);
  OLED_WR_Byte(0xf0, OLED_CMD);

  OLED_WR_Byte(0xd9, OLED_CMD);
  OLED_WR_Byte(0x22, OLED_CMD);

  OLED_WR_Byte(0xda, OLED_CMD);
  OLED_WR_Byte(0x02, OLED_CMD);

  OLED_WR_Byte(0xdb, OLED_CMD);
  OLED_WR_Byte(0x49, OLED_CMD);

  OLED_WR_Byte(0x8d, OLED_CMD);
  OLED_WR_Byte(0x14, OLED_CMD);

  OLED_WR_Byte(0xaf, OLED_CMD);
  OLED_Clear();
}
/************************* MQTT SET *********************************/

const char* mqtt_ServerIP = "192.168.1.195";
const char* topic = "mqtt_NodeMucu";
const char* client_Id = "mqtt_client_NodeMcu_Device_01";
const char* subTopic = "NodeMcu_Rec_Msg";
const int mqtt_ServerPort = 1883;
int relay = D6;
int DHT_01_pin = D4;


WiFiClient espClient;
PubSubClient mqttClient(espClient);

SimpleDHT11 dht11_01(DHT_01_pin);

StaticJsonDocument<200> json;

bool wifiConnectState = false;
long upLoadMsgTime = 0;

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(relay, OUTPUT);
  delay(200);
  digitalWrite(relay, LOW);
  OLED_Init();
  WIFISmartConfig();
  mqttClient.setServer(mqtt_ServerIP, mqtt_ServerPort);
  mqttClient.setCallback(mqtt_callback);
  connection_mqtt_server();
}
byte temperature_01 = 0, humidity_01 = 0;
String JSONmessageBuffer = "";
long reflashTime = 0 ;
int reflashFlag = 0;
void loop() {
  upLoadMsgTime = millis();
  reflashTime = millis();
  mqttClient.loop();

  if ((reflashTime % 6000 == 0) || reflashFlag == 1)  //每6s刷新一次屏幕 立即刷新标志位 
  {
    reflashFlag = 0;
    oled_display_info();
  }

  if (upLoadMsgTime % 5000 == 0)  //5s采集一次数据并上传到服务器
  {
    if (dht11_01.read(&temperature_01, &humidity_01, NULL) == SimpleDHTErrSuccess)
    {
      read_temp = (int)temperature_01;
      read_hum = (int)humidity_01;

      JsonObject json_root = json.to();
      json_root["roomLocation"] = "LivingRoom";
      JsonObject device_name = json_root.createNestedObject("DeviceName");  //创建Obj
      JsonObject DHT11_01_values = device_name.createNestedObject("DHT11_01");
      DHT11_01_values["Temperature:"] = read_temp;
      DHT11_01_values["Humidity:"] = read_hum;

      JsonObject Relay_01_state = device_name.createNestedObject("Relay_01");
      Relay_01_state["State"] = relayState;

      serializeJson(json, JSONmessageBuffer);
      Serial.println(JSONmessageBuffer);
      mqttClient.publish(topic, JSONmessageBuffer.c_str());  // String.c_str() String转化为char[]
      JSONmessageBuffer = "";
    }
  }

}

void WIFISmartConfig() {  //wifi配置
  int testConnectCount = 0;
  Serial.println("\nAuto for connection ...");
  while (WiFi.status() != WL_CONNECTED) {
    if (!wifiConnectState) {
      LEDStartInfo(500);
      testConnectCount++;
      if (testConnectCount >= 10 ) {
        wifiConnectState = true;
        Serial.println("Linked Faied ! Jump to SmartConfig...");
      }
      Serial.println("Linking ...");
    } else {
      WiFi.mode(WIFI_STA); //设置WIFI模块为STA模式
      Serial.println("Waiting for connection ...");
      WiFi.beginSmartConfig();
      while (true) {
        Serial.print(".");
        LEDStartInfo(500);
        if (WiFi.smartConfigDone()) {
          Serial.println("\nSmartConfig Successed !");
          for (int i = 0; i < 20; i++) {
            LEDStartInfo(200);
          }
          break;
        }
      }
    }
  }
  Serial.printf("\nSSID: %s", WiFi.SSID().c_str());//输出账号
  Serial.printf("\nPassword: %s", WiFi.psk().c_str());//输出密码
  Serial.printf("\nIP address: "); Serial.print(WiFi.localIP()); //输出IP地址
  ipinfo = "IP:" + ip2Str(WiFi.localIP());
}

void connection_mqtt_server() {
  while (!mqttClient.connected()) {
    Serial.println("\nAttempting MQTT connection...");
    if (mqttClient.connect(client_Id, "admin", "public")) { // 连接成功
      Serial.println("MQTT Server Connceted ! ");
      mqttClient.subscribe(subTopic);  // 订阅主题
    } else { // 连接失败
      Serial.println("failed, rc=");
      Serial.print(mqttClient.state());
    }
  }
}

StaticJsonDocument<200> docParser;

void mqtt_callback(char* topic, byte* payload, unsigned int length) {
  char receiveDataChar[length];

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] \n");

  for (int i = 0; i < length; i++)
  {
    receiveDataChar[i] = (char)payload[i];
  }

  deserializeJson(docParser, receiveDataChar);

  const char* Relay_01_State = docParser["Relay_01_State"];
  relayState = Relay_01_State;

  if (strcmp("ON", relayState.c_str()) == 0)
  {
    digitalWrite(relay, HIGH);
    reflashFlag = 1;  //OLED 刷新
    Serial.println(Relay_01_State);
  }
  if (strcmp("OFF", relayState.c_str()) == 0)
  {
    digitalWrite(relay, LOW);
    reflashFlag = 1;//OLED 刷新
    Serial.println(Relay_01_State);
  }
}

void LEDStartInfo(int delay_ms) { //LED闪烁函数
  digitalWrite(LED_BUILTIN, 0);
  delay(delay_ms);
  digitalWrite(LED_BUILTIN, 1);
  delay(delay_ms);
}
String ip2Str(IPAddress ip) { //IP地址转字符串
  String s = "";
  for (int i = 0; i < 4; i++) {
    s += i ? "." + String(ip[i]) : String(ip[i]);
  }
  return s;
}

void oled_display_info()
{
  OLED_ShowString(0, 0, (uint8_t *)ipinfo.c_str()  , 8);
  delay(200);
  OLED_ShowString(0, 1, (uint8_t *)"Temp:"  , 8);
  OLED_ShowNum(45, 1, read_temp,  2, 15);
  OLED_ShowString(60, 1, (uint8_t *)"*C"   , 8);
  delay(200);
  OLED_ShowString(0, 2, (uint8_t *)"Hum:"   , 8);
  OLED_ShowNum(35, 2, read_hum,  2, 15);
  OLED_ShowString(50, 2, (uint8_t *)"%"   , 8);
  delay(200);
  OLED_ShowString(0, 3, (uint8_t *)"RelayState:"   , 8);
  delay(200);
  OLED_Clear_Local(90, 3);
  OLED_ShowString(90, 3, (uint8_t *)relayState.c_str()   , 8);
}

四、作品效果

1、关闭继电器

image.png

image.png

image.png

2、打开继电器

image.png
image.png

image.png

你可能感兴趣的:(基于ESP8266实现温湿度采集及控制【arduino】(SmartConfig+MQTT+DHT11+OLED【模拟I2C】))