最开始接触到ESP8266主要是在做完树莓派电子价签之后看到的,由ESP8266连接OLED屏幕可以显示图案,比树莓派连接电子价签显示要更灵活一些,从那之后开始正式接触ESP8266,后续又做了WIFI Killer,连接温湿度传感器,以及最近做好的通过小程序远程控制开关灯,期间编写脚本从Micropython到ArduinoIDE也算学习了不少。
在这些学习中主要感谢B站up主
会飞的阿卡林(UID:751219)
Hans叫泽涵(UID:15481541)
爱学习的素丸子(UID:269864982)
下面给几个之前做的链接,方便查找和参考:
0.【好奇心驱动力】e-paper电子价签从零开始折腾记录
1.【好奇心驱动力】ESP8266制作WiFikiller过程
2.【好奇心驱动力】ESP8266刷MicroPython及OLED显示
3.【好奇心驱动力】基于MicroPython的ESP8266连接OLED显示实时天气
4.【好奇心驱动力】ESP8266 PIN与GPIO引脚对应关系
5.【好奇心驱动力】ESP8266制作透明小电视
利用ESP8266连接OLED屏幕显示时间、天气、室内温度
并通过小程序控制开关发光二极管。
至此最开始预计实现的功能全都实现了,贴下代码,第一次学习改写还比较乱,请大佬轻喷,需要修改的地方有WIFI用户名密码、openweatherAPI链接。
#include //安装esp8266arduino开发环境
#include //安装PubSubClient库
#include //json V6版本
#include
#include "aliyun_mqtt.h"
//------------------
#include
#include
//#include
//#include
#include
#include
#include
#include
#include
//U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/4, /* dc=*/5, /* reset=*/3);
//如果是四线IIC的屏幕请替换成下面这行代码
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//---------------修改此处""内的信息---------------------------------------------
const char ssid[] = "XXXXXXXXXXX"; //WiFi名
const char pass[] = "XXXXXXXXXXX"; //WiFi密码
//-----------------------------------------------------------------------------
static const char ntpServerName[] = "ntp1.aliyun.com"; //NTP服务器,阿里云
const int timeZone = 8; //时区,北京时间为+8
const unsigned long HTTP_TIMEOUT = 10000;
WiFiClient client;
HTTPClient http;
WiFiUDP Udp;
unsigned int localPort = 8888; // 用于侦听UDP数据包的本地端口
#define DHT11PIN 14 //dht11连线接口
dht11 DHT11; //定义为DHT11
//函数定义
time_t getNtpTime();
void sendNTPpacket(IPAddress& address);
void oledClockDisplay();
void sendCommand(int command, int value);
void initdisplay();
//变量参数
bool getJson();
String response;
String weather_main;
String location;
String icon;
int wind_speed;
bool parseJson(String json);
boolean isNTPConnected = false;
const unsigned char xing[] U8X8_PROGMEM = {
0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x08, 0x08, 0xF8, 0x0F, 0x80, 0x00, 0x88, 0x00,
0xF8, 0x1F, 0x84, 0x00, 0x82, 0x00, 0xF8, 0x0F, 0x80, 0x00, 0x80, 0x00, 0xFE, 0x3F, 0x00, 0x00
}; /*星*/
const unsigned char liu[] U8X8_PROGMEM = {
0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
0x20, 0x02, 0x20, 0x04, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10, 0x04, 0x20, 0x02, 0x20, 0x00, 0x00
}; /*六*/
//天气图标
const unsigned char A_01d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x80,0x03,0x00,0x00,0x82,0x83,0x00,0x00,0x07,0xc1,0x01,0x00,0x8e,0xe3,0x00,0x00,0xec,0x6f,0x00,0x00,0xf0,0x1e,0x00,0x00,0x38,0x38,0x00,0x00,0x18,0x30,0x00,0xc0,0x1d,0x30,0x03,0xc0,0x0f,0xb0,0x07,0xc0,0x1d,0xb0,0x07,0x00,0x18,0x30,0x00,0x00,0x38,0x38,0x00,0x00,0xf0,0x1f,0x00,0x00,0xec,0x6f,0x00,0x00,0x0e,0xe0,0x00,0x00,0x07,0xc3,0x01,0x00,0x80,0x83,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_01n[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xcf,0x00,0x00,0x00,0xc7,0x00,0x00,0x80,0xc3,0x00,0x00,0xc0,0xc1,0x00,0x00,0xc0,0xc0,0x00,0x00,0xc0,0xc0,0x01,0x00,0xe0,0x80,0x03,0x00,0xe0,0x00,0x07,0x00,0xe0,0x00,0x1e,0x00,0xe0,0x00,0xfc,0x07,0xc0,0x00,0xf0,0x07,0xc0,0x00,0x80,0x03,0xc0,0x01,0x80,0x03,0x80,0x03,0x80,0x01,0x00,0x07,0xc0,0x01,0x00,0x0f,0xf0,0x00,0x00,0x7c,0x7e,0x00,0x00,0xf8,0x1f,0x00,0x00,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_02d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x06,0x06,0x03,0x00,0x0c,0x80,0x03,0x00,0x98,0x9f,0x01,0x00,0xc0,0x3f,0x00,0x00,0x60,0x70,0x00,0x00,0x30,0x60,0x00,0x00,0x30,0xc0,0x00,0xc0,0x1b,0xc0,0x1e,0xc0,0x1b,0xc0,0x1e,0x00,0x10,0xc0,0x00,0x00,0x00,0xe0,0x00,0x00,0x78,0x60,0x00,0x80,0xff,0x38,0x00,0xc0,0x87,0x9d,0x01,0x60,0x02,0x83,0x03,0x60,0x00,0x03,0x03,0x70,0x00,0x07,0x02,0x18,0x00,0x0e,0x00,0x18,0x00,0x0c,0x00,0x18,0x00,0x0c,0x00,0xf0,0xff,0x0f,0x00,0xe0,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_02n[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x1f,0x00,0x00,0x80,0x1b,0x00,0x00,0xc0,0x39,0x00,0x00,0xc0,0x31,0x00,0x00,0xc0,0x70,0x00,0x00,0xc0,0xe0,0x00,0x00,0xc0,0xe0,0x01,0x00,0xc0,0xc0,0x3f,0x00,0xc0,0x00,0x1f,0x00,0x00,0x00,0x1c,0x00,0xe0,0x03,0x1c,0x00,0xf0,0x07,0x0e,0x00,0x3f,0xce,0x07,0x80,0x1f,0xdc,0x03,0xc0,0x09,0x18,0x00,0xc0,0x00,0x18,0x00,0xe0,0x00,0x38,0x00,0xf0,0x00,0x78,0x00,0x38,0x00,0xe0,0x00,0x18,0x00,0xc0,0x00,0x18,0x00,0xc0,0x00,0x30,0x00,0xc0,0x00,0xf0,0xff,0xff,0x00,0xe0,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_03d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x21,0x0c,0x00,0x00,0x03,0x06,0x00,0x00,0xfa,0x02,0x00,0x00,0x8c,0x01,0x00,0x00,0x04,0x03,0x00,0x00,0x04,0x3f,0x00,0x00,0x00,0x1b,0x00,0x80,0x8f,0x01,0x00,0xe0,0x9f,0x01,0x00,0x7e,0x30,0x06,0x00,0x3f,0x60,0x0e,0x80,0x11,0x40,0x0c,0xc0,0x00,0xc0,0x00,0xc0,0x00,0x40,0x00,0xe0,0x00,0xc0,0x01,0x30,0x00,0xe0,0x03,0x18,0x00,0x00,0x06,0x18,0x00,0x00,0x06,0x18,0x00,0x00,0x04,0x18,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0xe0,0xfe,0xbf,0x03,0xc0,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_03n[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x00,0x00,0xf0,0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x98,0x01,0x00,0x00,0x98,0x03,0x00,0x00,0x08,0x0f,0x00,0x00,0x08,0x3e,0x00,0x00,0x04,0x18,0x00,0x80,0x3f,0x1c,0x00,0xc0,0xe1,0x0e,0x00,0x7c,0xc0,0x00,0x00,0x7f,0x80,0x01,0x80,0x23,0x00,0x01,0x80,0x01,0x00,0x03,0x80,0x01,0x00,0x03,0xe0,0x01,0x00,0x03,0x70,0x00,0x80,0x0f,0x30,0x00,0x00,0x1c,0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x30,0x18,0x00,0x00,0x30,0x18,0x00,0x00,0x18,0x70,0x00,0x00,0x1c,0xe0,0xff,0xff,0x0f,0xc0,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_04d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x80,0x3f,0x00,0x00,0xc0,0xe1,0x00,0x00,0xfe,0xc0,0x01,0x00,0x7f,0x80,0x01,0x80,0x23,0x00,0x01,0x80,0x01,0x00,0x03,0x80,0x00,0x00,0x03,0xc0,0x00,0x00,0x03,0xe0,0x00,0x80,0x0f,0x30,0x00,0x00,0x1c,0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x30,0x18,0x00,0x00,0x30,0x18,0x00,0x00,0x30,0x30,0x00,0x00,0x18,0xe0,0xff,0xff,0x0f,0xc0,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_09d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x00,0xc0,0x7f,0x00,0x00,0xe0,0xc0,0x00,0x00,0x7e,0x80,0x01,0x00,0x27,0x80,0x01,0x80,0x01,0x00,0x03,0x80,0x00,0x00,0x03,0xc0,0x00,0x00,0x03,0xe0,0x01,0x00,0x07,0x30,0x00,0x00,0x0f,0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x30,0x18,0x00,0x00,0x30,0x18,0x00,0x00,0x30,0x38,0x00,0x00,0x38,0x70,0x00,0x00,0x1c,0xe0,0x6f,0xe9,0x0f,0x80,0xb7,0xed,0x07,0x00,0xf0,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb6,0x01,0x00,0x00,0xb6,0x01,0x00,0x00,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_10d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x00,0x80,0x7f,0x00,0x00,0xc0,0xe0,0x00,0x00,0x7e,0x80,0x01,0x00,0x3f,0x80,0x01,0x80,0x01,0x00,0x03,0x80,0x01,0x00,0x03,0x80,0x00,0x00,0x03,0xe0,0x01,0x00,0x07,0x70,0x00,0x80,0x1f,0x38,0x00,0x00,0x18,0x18,0x00,0x00,0x30,0x18,0x00,0x00,0x30,0x18,0x00,0x00,0x30,0x38,0x60,0x12,0x38,0x70,0x60,0x1b,0x18,0xe0,0x6f,0xfb,0x0f,0xc0,0xbf,0xed,0x07,0x00,0xb0,0x0d,0x00,0x00,0xd8,0x0f,0x00,0x00,0xd8,0x06,0x00,0x00,0xd8,0x06,0x00,0x00,0x6c,0x03,0x00,0x00,0x6c,0x03,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_11d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x00,0x80,0x7f,0x00,0x00,0xe0,0xe0,0x00,0x00,0x7e,0x80,0x01,0x00,0x37,0x80,0x01,0x80,0x01,0x00,0x03,0x80,0x00,0x00,0x03,0x80,0x00,0x00,0x03,0xe0,0x01,0x00,0x07,0x70,0x00,0x80,0x1f,0x38,0x00,0x00,0x18,0x18,0x00,0x00,0x30,0x18,0x00,0x06,0x30,0x18,0x00,0x06,0x30,0x38,0x00,0x03,0x38,0x70,0x80,0x03,0x1c,0xe0,0x8f,0xe1,0x0f,0xc0,0xcf,0xee,0x07,0x00,0xe0,0x0f,0x00,0x80,0x6d,0x27,0x03,0x80,0x0d,0xb3,0x03,0xc0,0x86,0xb3,0x01,0xc0,0x86,0xd9,0x01,0x40,0xc2,0x98,0x00,0x00,0xc0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_13d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x40,0x05,0x00,0x00,0xd6,0xd7,0x00,0x00,0xbe,0x53,0x00,0x00,0x3c,0x31,0x00,0x00,0xbe,0xf9,0x00,0x00,0x74,0x6d,0x00,0x00,0xe3,0x85,0x01,0x80,0xd6,0xd7,0x03,0xc0,0xff,0xff,0x07,0x00,0x86,0xc7,0x00,0x00,0x63,0x8f,0x01,0x00,0x34,0x1d,0x00,0x00,0x9e,0xf9,0x00,0x00,0x38,0x71,0x00,0x00,0xb6,0xf3,0x00,0x00,0xd2,0xd7,0x00,0x00,0xc0,0x05,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_50d[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x80,0x7f,0x00,0x00,0xc0,0xef,0x00,0x04,0x40,0x80,0x03,0x07,0x00,0x10,0xfe,0x03,0x80,0x7f,0x78,0x00,0xc0,0xe1,0x01,0x04,0x40,0x80,0x87,0x07,0x00,0x0c,0xfe,0x03,0x80,0xff,0x30,0x00,0xc0,0xc1,0x01,0x06,0x40,0x00,0x87,0x07,0x00,0x00,0xfe,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char A_unknown[] U8X8_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x80,0x7f,0x00,0x00,0xc0,0xf1,0x00,0x00,0xfe,0xc0,0x01,0x00,0x7f,0x80,0x01,0x80,0xa3,0x87,0x03,0x80,0xc1,0x0f,0x03,0x80,0xc0,0x0c,0x03,0xe0,0xc1,0x0c,0x07,0x70,0x00,0x86,0x0f,0x30,0x00,0x03,0x1c,0x18,0x00,0x03,0x38,0x18,0x00,0x03,0x30,0x18,0x00,0x03,0x30,0x18,0x00,0x03,0x30,0x30,0x00,0x03,0x18,0xf0,0xff,0xff,0x1f,0xc0,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const int slaveSelect = 5;
const int scanLimit = 7;
int times = 0;
//------------------
//需要安装crypto库
#define LED D7
#define WIFI_SSID "XXXXXXXX"//替换自己的WIFI
#define WIFI_PASSWD "XXXXXXXX"//替换自己的WIFI
#define PRODUCT_KEY "XXXXXXXX" //替换自己的PRODUCT_KEY
#define DEVICE_NAME "ESP8266Side" //替换自己的DEVICE_NAME
#define DEVICE_SECRET "XXXXXXXX"//替换自己的DEVICE_SECRET
#define DEV_VERSION "S-TH-WIFI-v1.0-20190220" //固件版本信息
#define ALINK_BODY_FORMAT "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
#define ALINK_TOPIC_PROP_POSTRSP "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply"
#define ALINK_TOPIC_PROP_SET "/" PRODUCT_KEY "/" DEVICE_NAME "/user/sub"
#define ALINK_METHOD_PROP_POST "thing.event.property.post"
#define ALINK_TOPIC_DEV_INFO "/ota/device/inform/" PRODUCT_KEY "/" DEVICE_NAME ""
#define ALINK_VERSION_FROMA "{\"id\": 123,\"params\": {\"version\": \"%s\"}}"
unsigned long lastMs = 0;
int pos = 90;
WiFiClient espClient;
PubSubClient mqttClient(espClient);
Servo myServo;
void init_wifi(const char *ssid, const char *password) //连接WiFi
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
Serial.println("WiFi does not connect, try again ...");
delay(500);
}
Serial.println("Wifi is connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void mqtt_callback(char *topic, byte *payload, unsigned int length) //mqtt回调函数
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
payload[length] = '\0';
Serial.print("****** ");
Serial.println((char *)payload);
Serial.print("****** ");
// https://arduinojson.org/v5/assistant/ json数据解析网站
Serial.println((char *)payload);
if (strstr(topic, ALINK_TOPIC_PROP_SET))
{
StaticJsonDocument<100> jsonBuffer;
deserializeJson(jsonBuffer,payload);
JsonObject root = jsonBuffer.as<JsonObject>();
auto error = deserializeJson(jsonBuffer,payload);
//JsonObject &root = jsonBuffer.parseObject(payload);
int params_LightSwitch = root["params"]["LightSwitch"];
if(params_LightSwitch==1)
{Serial.println("led off");
digitalWrite(LED, HIGH);
}
else
{Serial.println("led on");
if (!digitalRead(LED)){
digitalWrite(LED, HIGH);
for(pos=90;pos>55;pos--){
myServo.write(pos); // 使用pos变量数值设置伺服电机
delay(15);}
}else{
digitalWrite(LED, LOW);
for(pos=55 ;pos<=90;pos++){
myServo.write(pos); // 使用pos变量数值设置伺服电机
delay(15);
}
}
}
if (error)
{
Serial.println("parseObject() failed");
return;
}
}
}
void mqtt_version_post()
{
char param[512];
char jsonBuf[1024];
//sprintf(param, "{\"MotionAlarmState\":%d}", digitalRead(13));
sprintf(param, "{\"id\": 123,\"params\": {\"version\": \"%s\"}}", DEV_VERSION);
// sprintf(jsonBuf, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
Serial.println(param);
mqttClient.publish(ALINK_TOPIC_DEV_INFO, param);
}
void mqtt_check_connect()
{
while (!mqttClient.connected())//
{
while (connect_aliyun_mqtt(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET))
{
Serial.println("MQTT connect succeed!");
//client.subscribe(ALINK_TOPIC_PROP_POSTRSP);
mqttClient.subscribe(ALINK_TOPIC_PROP_SET);
Serial.println("subscribe done");
mqtt_version_post();
}
}
}
void mqtt_interval_post()
{
char param[512];
char jsonBuf[1024];
//sprintf(param, "{\"MotionAlarmState\":%d}", digitalRead(13));
sprintf(param, "{\"LightSwitch\":%d,\"CurrentTemperature\":%d}", !digitalRead(LED),random(0,55));
sprintf(jsonBuf, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
Serial.println(jsonBuf);
mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
}
void setup()
{
myServo.attach(D8);
pinMode(LED, OUTPUT);
/* initialize serial for debugging */
Serial.begin(115200);
Serial.println("Demo Start");
init_wifi(WIFI_SSID, WIFI_PASSWD);
mqttClient.setCallback(mqtt_callback);
//-----
while (!Serial)
continue;
Serial.println("NTP Clock Weather Display v1.0");
initdisplay();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(0, 14);
u8g2.print("Waiting for WiFi");
u8g2.setCursor(0, 30);
u8g2.print("Connection...");
u8g2.setCursor(0, 47);
u8g2.print("By CC.INC");
u8g2.setCursor(0, 64);
u8g2.print("WeatherClock");
u8g2.sendBuffer();
Serial.print("Connecting WiFi...");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("Starting UDP");
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.localPort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(300); //每300秒同步一次时间
isNTPConnected = true;
//-----
}
//----
time_t prevDisplay = 0; //当时钟已经显示
// the loop function runs over and over again forever
void loop()
{
if (millis() - lastMs >= 50000) //5S
{
lastMs = millis();
mqtt_check_connect();
// mqtt_interval_post();
}
mqttClient.loop();
if (times <10) {
if (timeStatus() != timeNotSet)
{
if (now() != prevDisplay)
{
//时间改变时更新显示
prevDisplay = now();
oledClockDisplay();
}
}
}
if (times == 10) {
if (WiFi.status() == WL_CONNECTED){
if (getJson()){
if (parseJson(response)){
DHT11.read(DHT11PIN);
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_unifont_t_chinese2);
//icon
if (icon == "A_01d"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_01d );
}
else if (icon == "A_01n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_01n );
}
else if (icon == "A_02d"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_02d );
}
else if (icon == "A_02n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_02n );
}
else if (icon == "A_03d"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_03d );
}
else if (icon == "A_03n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_03n );
}
else if (icon == "A_04d" or icon == "A_04n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_04d );
}
else if (icon == "A_09d" or icon == "A_09n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_09d );
}
else if (icon == "A_10d" or icon == "A_10n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_10d );
}
else if (icon == "A_11d" or icon == "A_11n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_11d );
}
else if (icon == "A_13d" or icon == "A_13n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_13d );
}
else if (icon == "A_50d" or icon == "A_50n"){
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_50d );
}
else {
u8g2.drawXBMP( 96 , 32 , 32 , 32 , A_unknown );
}
//Temperature
u8g2.setCursor(0, 45);
u8g2.print("InD_Tem:");
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(64, 45);
u8g2.println((int)DHT11.temperature);
u8g2.println("C");
//Humidity
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(0, 62);
u8g2.print("InD_Hum:");
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(64, 62);
u8g2.println((int)DHT11.humidity);
u8g2.println("%");
//wind
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(0, 28);
u8g2.println("Now_Wind:");
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(71, 28);
u8g2.println(wind_speed);
u8g2.println("m/s");
//location
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(0, 11);
u8g2.println(location);
//weather
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(64, 11);
u8g2.println(weather_main);
u8g2.sendBuffer();
}
}
delay(1000);
}
}
times += 1;
if (times >= 15) {
times = 0;
}
delay(1000);
}
bool getJson()
{
bool r = false;
http.setTimeout(HTTP_TIMEOUT);
http.begin("http://api.openweathermap.org/data/2.5/weather?q=beijing&appid=XXXXXXX");
int httpCode = http.GET();
if (httpCode > 0){
if (httpCode == HTTP_CODE_OK){
response = http.getString();
Serial.println(response);
r = true;
}
}else{
Serial.printf("[HTTP] GET JSON failed, error: %s\n", http.errorToString(httpCode).c_str());
r = false;
}
http.end();
return r;
}
//JSON
bool parseJson(String json){
const size_t capacity = 1024;
DynamicJsonDocument doc(capacity);
deserializeJson(doc,json);
//weather
const char *weather_main_fun = doc["weather"][0]["main"];
//city
const char *location_fun = doc["name"];
//wind_speed
JsonObject wind_c = doc["wind"];
int wind = wind_c["speed"];
//icon
String icon_fun = doc["weather"][0]["icon"];
//parameter
weather_main = weather_main_fun;
location = location_fun;
wind_speed = wind;
icon = "A_"+icon_fun;
//Serial.println(icon);
//true
return true;
}
void initdisplay()
{
u8g2.begin();
u8g2.enableUTF8Print();
}
void oledClockDisplay()
{
int years, months, days, hours, minutes, seconds, weekdays;
years = year();
months = month();
days = day();
hours = hour();
minutes = minute();
seconds = second();
weekdays = weekday();
Serial.printf("%d/%d/%d %d:%d:%d Weekday:%d\n", years, months, days, hours, minutes, seconds, weekdays);
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.setCursor(0, 14);
if (isNTPConnected)
u8g2.print("当前时间 (UTC+8)");
else
u8g2.print("无网络!"); //如果上次对时失败,则会显示无网络
String currentTime = "";
if (hours < 10)
currentTime += 0;
currentTime += hours;
currentTime += ":";
if (minutes < 10)
currentTime += 0;
currentTime += minutes;
currentTime += ":";
if (seconds < 10)
currentTime += 0;
currentTime += seconds;
String currentDay = "";
currentDay += years;
currentDay += "/";
if (months < 10)
currentDay += 0;
currentDay += months;
currentDay += "/";
if (days < 10)
currentDay += 0;
currentDay += days;
u8g2.setFont(u8g2_font_logisoso24_tr);
u8g2.setCursor(0, 44);
u8g2.print(currentTime);
u8g2.setCursor(0, 61);
u8g2.setFont(u8g2_font_unifont_t_chinese2);
u8g2.print(currentDay);
u8g2.drawXBM(80, 48, 16, 16, xing);
u8g2.setCursor(95, 62);
u8g2.print("期");
if (weekdays == 1)
u8g2.print("日");
else if (weekdays == 2)
u8g2.print("一");
else if (weekdays == 3)
u8g2.print("二");
else if (weekdays == 4)
u8g2.print("三");
else if (weekdays == 5)
u8g2.print("四");
else if (weekdays == 6)
u8g2.print("五");
else if (weekdays == 7)
u8g2.drawXBM(111, 49, 16, 16, liu);
u8g2.sendBuffer();
}
/*-------- NTP 代码 ----------*/
const int NTP_PACKET_SIZE = 48; // NTP时间在消息的前48个字节里
byte packetBuffer[NTP_PACKET_SIZE]; // 输入输出包的缓冲区
time_t getNtpTime()
{
IPAddress ntpServerIP; // NTP服务器的地址
while (Udp.parsePacket() > 0); // 丢弃以前接收的任何数据包
Serial.println("Transmit NTP Request");
// 从池中获取随机服务器
WiFi.hostByName(ntpServerName, ntpServerIP);
Serial.print(ntpServerName);
Serial.print(": ");
Serial.println(ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500)
{
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE)
{
Serial.println("Receive NTP Response");
isNTPConnected = true;
Udp.read(packetBuffer, NTP_PACKET_SIZE); // 将数据包读取到缓冲区
unsigned long secsSince1900;
// 将从位置40开始的四个字节转换为长整型,只取前32位整数部分
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
Serial.println(secsSince1900);
Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-("); //无NTP响应
isNTPConnected = false;
return 0; //如果未得到时间则返回0
}
// 向给定地址的时间服务器发送NTP请求
void sendNTPpacket(IPAddress& address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123); //NTP需要使用的UDP端口号为123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}