博文有点长,因为是两个大项目(四个小项目)放一起了,不过都很适合新手小白(有源程序的情况),也可以再接 OLED 屏,就是前几篇博客的操作

一、esp8266 读取 DHT11 数据并通过微信小程序发送数据

  1. 前言
  • 我们之前有做过这个项目,后来传到了云端 Dweet.io ,以图表的方式复现出来了。传送门:利用 esp8266 搭建简单物联网项目
  • 今天我们把数据与微信小程序连接起来,之前我在做阿里云的时候,捣腾过公众号,其实都差不多道理。
  1. 原理(发布订阅模式)
  • 读取 DHT11 数据
  • 新建主题,然后esp8266往这个主题发送消息
  • 小程序通过http API接口获取数据

    发布订阅模式:

订阅(订阅):订阅给定的一个主题/频道的信息。

发布(发布)将信息发送到指定的主题/频道。

只有订阅该主题的设备才可以收到发往该主题的消息。

  1. 读取 DHT11 数据
  • 接线

    | esp8266 | DHT11 |

    | ---- | ---- |

    | 3V | VCC |

    | GND | GND |

    | D4 | Data |

    • 这里用的D4口,上篇博客的 D1口 被我的 OLED 屏占用了
  • 测试功能
    • 安装库 : SimpleDHT
#include <SimpleDHT.h>
int pinDHT11 = D4;
SimpleDHT11 dht11(pinDHT11); //郑某人的测试代码
void setup() {
Serial.begin(115200);
} void loop() {
// start working...
Serial.println("=================================");
Serial.println("Sample DHT11..."); // read without samples.
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
return;
} Serial.print("Sample OK: ");
Serial.print((int)temperature); Serial.print(" *C, ");
Serial.print((int)humidity); Serial.println(" H"); // DHT11 sampling rate is 1HZ.
delay(1500);
}
  • 正常结果

  1. 数据发送至云端(感谢Arduino社区bemfa大佬提供的源代码和方法)
/*
关于UID:在巴法云注册登陆,即可看到自己UID,推送微信消息,需要手机绑定微信,bemfa.com在控制台进行绑定即可。
QQ交流群:824273231
巴法云官网:bemfa.com
时间:2020/04/25
官方文档见官网:http://www.cloud.bemfa.com/docs/#/
*/
//DHT11数据上传+LED远程控制 //不限于DHT11,可以接其他传感器,也可以接多个传感器,这里只是例程
//DHT11数据上传主题temp //根据自己在控制台命的名字可自己随意修改
//LED灯控制主题light002 //根据自己命的名字可自己随意修改
/*
程序讲解:ESP8266 有两个角色,一个是temp(传感器数据)主题消息的发布者,esp8266往这个主题推送消息,手机app订阅temp主题,就可以收到传感器数据了。
esp8266联网后,订阅light002,手机往这个主题推送消息,esp8266就能收到手机的控制的指令了。
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <SimpleDHT.h> //巴法云服务器地址默认即可
#define TCP_SERVER_ADDR "bemfa.com"
//服务器端口//TCP创客云端口8344//TCP设备云端口8340
#define TCP_SERVER_PORT "8344" ///****************需要修改的地方*****************/// //WIFI名称,区分大小写,不要写错
#define DEFAULT_STASSID "Geohot"
//WIFI密码
#define DEFAULT_STAPSW "zheng123+"
//用户私钥,可在控制台获取,修改为自己的UID
String UID = "4222ebc83f26eac038c8e48bfc208031";
//主题名字,可在控制台新建
String TOPIC = "temp"; //用于传输温湿度的主题
//DHT11引脚值
int pinDHT11 = D4; //连接dht11的引脚
//单片机LED引脚值
const int LED_Pin = D2; //假设连接led的引脚
//主题名字,可在控制台新建
String TOPIC2 = "light002"; //用于led控制的主题 ///*********************************************///
//led 控制函数
void turnOnLed();
void turnOffLed();
//led状态状态
String my_led_status = "off"; //设置上传速率2s(1s<=upDataTime<=60s)
//下面的2代表上传间隔是2秒
#define upDataTime 2*1000 // for DHT11,
// VCC: 5V or 3V
// GND: GND
// DATA: 2 SimpleDHT11 dht11(pinDHT11); //最大字节数
#define MAX_PACKETSIZE 512 //tcp客户端相关初始化,默认即可
WiFiClient TCPclient;
String TcpClient_Buff = "";
unsigned int TcpClient_BuffIndex = 0;
unsigned long TcpClient_preTick = 0;
unsigned long preHeartTick = 0;//心跳
unsigned long preTCPStartTick = 0;//连接
bool preTCPConnected = false; //相关函数初始化
//连接WIFI
void doWiFiTick();
void startSTA(); //TCP初始化连接
void doTCPClientTick();
void startTCPClient();
void sendtoTCPServer(String p); /*
*发送数据到TCP服务器
*/
void sendtoTCPServer(String p){ if (!TCPclient.connected())
{
Serial.println("Client is not readly");
return;
}
TCPclient.print(p);
Serial.println("[Send to TCPServer]:String");
Serial.println(p);
} /*
*初始化和服务器建立连接
*/
void startTCPClient(){
if(TCPclient.connect(TCP_SERVER_ADDR, atoi(TCP_SERVER_PORT))){
Serial.print("\nConnected to server:");
Serial.printf("%s:%d\r\n",TCP_SERVER_ADDR,atoi(TCP_SERVER_PORT));
String tcpTemp="";
tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC2+"\r\n"; sendtoTCPServer(tcpTemp);
preTCPConnected = true;
preHeartTick = millis();
TCPclient.setNoDelay(true);
}
else{
Serial.print("Failed connected to server:");
Serial.println(TCP_SERVER_ADDR);
TCPclient.stop();
preTCPConnected = false;
}
preTCPStartTick = millis();
} /*
*检查数据,发送数据
*/
void doTCPClientTick(){
//检查是否断开,断开后重连
if(WiFi.status() != WL_CONNECTED) return; if (!TCPclient.connected()) {//断开重连 if(preTCPConnected == true){ preTCPConnected = false;
preTCPStartTick = millis();
Serial.println();
Serial.println("TCP Client disconnected.");
TCPclient.stop();
}
else if(millis() - preTCPStartTick > 1*1000)//重新连接
startTCPClient();
}
else
{
if (TCPclient.available()) {//收数据
char c =TCPclient.read();
TcpClient_Buff +=c;
TcpClient_BuffIndex++;
TcpClient_preTick = millis(); if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1){
TcpClient_BuffIndex = MAX_PACKETSIZE-2;
TcpClient_preTick = TcpClient_preTick - 200;
}
preHeartTick = millis();
}
if(millis() - preHeartTick >= upDataTime){//上传数据
preHeartTick = millis(); /*****************获取DHT11 温湿度*****************/
// read without samples.
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
return;
} /*********************数据上传*******************/
/*
数据用#号包裹,以便app分割出来数据,&msg=#23#80#on#\r\n,即#温度#湿度#按钮状态#,app端会根据#号分割字符串进行取值,以便显示
如果上传的数据不止温湿度,可在#号后面继续添加&msg=#23#80#data1#data2#data3#data4#\r\n,app字符串分割的时候,要根据上传的数据进行分割
*/
String upstr = "";
upstr = "cmd=2&uid="+UID+"&topic="+TOPIC+"&msg=#"+temperature+"#"+humidity+"#"+my_led_status+"#\r\n";
sendtoTCPServer(upstr);
upstr = "";
}
}
if((TcpClient_Buff.length() >= 1) && (millis() - TcpClient_preTick>=200))
{//data ready
TCPclient.flush();
Serial.println("Buff");
Serial.println(TcpClient_Buff);
//////字符串匹配,检测发了的字符串TcpClient_Buff里面是否包含&msg=on,如果有,则打开开关
if((TcpClient_Buff.indexOf("&msg=on") > 0)) {
turnOnLed();
//////字符串匹配,检测发了的字符串TcpClient_Buff里面是否包含&msg=off,如果有,则关闭开关
}else if((TcpClient_Buff.indexOf("&msg=off") > 0)) {
turnOffLed();
}
TcpClient_Buff="";//清空字符串,以便下次接收
TcpClient_BuffIndex = 0;
}
} //打开灯泡
void turnOnLed(){
Serial.println("Turn ON");
digitalWrite(LED_Pin,LOW);
my_led_status = "on";
}
//关闭灯泡
void turnOffLed(){
Serial.println("Turn OFF");
digitalWrite(LED_Pin,HIGH);
my_led_status = "off";
} void startSTA(){
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(DEFAULT_STASSID, DEFAULT_STAPSW);
} /**************************************************************************
WIFI
***************************************************************************/
/*
WiFiTick
检查是否需要初始化WiFi
检查WiFi是否连接上,若连接成功启动TCP Client
控制指示灯
*/
void doWiFiTick(){
static bool startSTAFlag = false;
static bool taskStarted = false;
static uint32_t lastWiFiCheckTick = 0; if (!startSTAFlag) {
startSTAFlag = true;
startSTA();
Serial.printf("Heap size:%d\r\n", ESP.getFreeHeap());
} //未连接1s重连
if ( WiFi.status() != WL_CONNECTED ) {
if (millis() - lastWiFiCheckTick > 1000) {
lastWiFiCheckTick = millis();
}
}
//连接成功建立
else {
if (taskStarted == false) {
taskStarted = true;
Serial.print("\r\nGet IP Address: ");
Serial.println(WiFi.localIP());
startTCPClient();
}
}
} // 初始化,相当于main 函数
void setup() {
Serial.begin(115200); //初始化引脚为输出
pinMode(LED_Pin,OUTPUT);
} //循环
void loop() {
doWiFiTick();
doTCPClientTick();
}

真的强,我还需要再修炼修炼ovo

  • 运行结果



    其中#号进行封装,28温度,61湿度,OFF表示LED灯的开启状态
  1. 微信小程序开发

    前往微信小程序平台
  • 设置 - 拿到APPID : wx71055a3e823092d9
  • 开发 - 开发设置 - 添加 requests 合法域名:https://api.bemfa.com
  • 下载 demo 示例程序并解压
  • 下载微信开发者工具,导入刚才的文件

  • 导入后,会显示出数据,然后上传就行了

  • 回到微信小程序平台,管理 - 版本管理 - 开发版本 - 提交审核,预计1-2天通过
  1. 那么这个项目就结束了,在此还是感谢Arduino社区bemfa大神

二、心知天气[参考taichi-maker]

  1. 注册
  1. 申请 API 服务
  • 控制台 - 申请免费版
  • 产品管理 - 获取 API 密钥 并复制
  1. 获取并解析心知天气数据
  • Ⅰ.获取实时温度和天气
#include <ArduinoJson.h>
#include <ESP8266WiFi.h> const char* ssid = "Geohot"; // 连接WiFi名 const char* password = "zheng123+"; // 连接WiFi密码 const char* host = "api.seniverse.com"; // 将要连接的服务器地址
const int httpPort = 80; // 将要连接的服务器端口 // 心知天气HTTP请求所需信息
String reqUserKey = "SnMQITaPAa0oGsIrQ"; // 私钥,填上自己的
String reqLocation = "Hangzhou"; // 城市
String reqUnit = "c"; // 摄氏/华氏 void setup(){
Serial.begin(9600);
Serial.println(""); // 连接WiFi
connectWiFi();
} void loop(){
// 建立心知天气API当前天气请求资源地址
String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
+ "&location=" + reqLocation +
"&language=en&unit=" +reqUnit; // 向心知天气服务器服务器请求信息并对信息进行解析
httpRequest(reqRes);
delay(3000);
} // 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes){
WiFiClient client; // 建立http请求信息
String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n";
Serial.println("");
Serial.print("Connecting to "); Serial.print(host); // 尝试连接服务器
if (client.connect(host, 80)){
Serial.println(" Success!"); // 向服务器发送http请求信息
client.print(httpRequest);
Serial.println("Sending request: ");
Serial.println(httpRequest); // 获取并显示服务器响应状态行
String status_response = client.readStringUntil('\n');
Serial.print("status_response: ");
Serial.println(status_response); // 使用find跳过HTTP响应头
if (client.find("\r\n\r\n")) {
Serial.println("Found Header End. Start Parsing.");
} // 利用ArduinoJson库解析心知天气响应信息
parseInfo(client);
} else {
Serial.println(" connection failed!");
}
//断开客户端与服务器连接工作
client.stop();
} // 连接WiFi
void connectWiFi(){
WiFi.begin(ssid, password); // 启动网络连接
Serial.print("Connecting to "); // 串口监视器输出网络连接信息
Serial.print(ssid); Serial.println(" ..."); // 告知用户NodeMCU正在尝试WiFi连接 int i = 0; // 这一段程序语句用于检查WiFi是否连接成功
while (WiFi.status() != WL_CONNECTED) { // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。
delay(1000); // 如果WiFi连接成功则返回值为WL_CONNECTED
Serial.print(i++); Serial.print(' '); // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
} // 同时NodeMCU将通过串口监视器输出连接时长读秒。
// 这个读秒是通过变量i每隔一秒自加1来实现的。
Serial.println(""); // WiFi连接成功后
Serial.println("Connection established!"); // NodeMCU将通过串口监视器输出"连接成功"信息。
Serial.print("IP address: "); // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
Serial.println(WiFi.localIP()); // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。
} // 利用ArduinoJson库解析心知天气响应信息
void parseInfo(WiFiClient client){
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
DynamicJsonDocument doc(capacity); deserializeJson(doc, client); JsonObject results_0 = doc["results"][0]; JsonObject results_0_now = results_0["now"];
const char* results_0_now_text = results_0_now["text"]; // "Sunny"
const char* results_0_now_code = results_0_now["code"]; // "0"
const char* results_0_now_temperature = results_0_now["temperature"]; // "32" const char* results_0_last_update = results_0["last_update"]; // "2020-09-27T16:20:00+08:00" // 通过串口监视器显示以上信息
String results_0_now_text_str = results_0_now["text"].as<String>();
int results_0_now_code_int = results_0_now["code"].as<int>();
int results_0_now_temperature_int = results_0_now["temperature"].as<int>(); String results_0_last_update_str = results_0["last_update"].as<String>(); Serial.println(F("======Weahter Now======="));
Serial.print(F("Weather Now: "));
Serial.print(results_0_now_text_str);
Serial.print(F(" "));
Serial.println(results_0_now_code_int);
Serial.print(F("Temperature: "));
Serial.println(results_0_now_temperature_int);
Serial.print(F("Last Update: "));
Serial.println(results_0_last_update_str);
Serial.println(F("========================"));
}
  • 9600 比特率串口


  • Ⅱ.获取天气预报信息(温度,天气,降水概率,风力,风向,湿度)

#include <ArduinoJson.h>
#include <ESP8266WiFi.h> const char* ssid = "Geohot"; // 连接WiFi名 const char* password = "zheng123+"; // 连接WiFi密码 const char* host = "api.seniverse.com"; // 将要连接的服务器地址
const int httpPort = 80; // 将要连接的服务器端口 // 心知天气HTTP请求所需信息
String reqUserKey = "SnMQITaPAa0oGsIrQ"; // 私钥
String reqLocation = "Hangzhou"; // 城市
String reqUnit = "c"; // 摄氏/华氏 void setup(){
Serial.begin(9600);
Serial.println(""); // 连接WiFi
connectWiFi();
} void loop(){
// 建立心知天气API当前天气请求资源地址
String reqRes = "/v3/weather/daily.json?key=" + reqUserKey +
+ "&location=" + reqLocation + "&language=en&unit=" +
reqUnit + "&start=0&days=3"; // 向心知天气服务器服务器请求信息并对信息进行解析
httpRequest(reqRes); delay(3000);
} // 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes){
WiFiClient client; // 建立http请求信息
String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n";
Serial.println("");
Serial.print("Connecting to "); Serial.print(host); // 尝试连接服务器
if (client.connect(host, 80)){
Serial.println(" Success!"); // 向服务器发送http请求信息
client.print(httpRequest);
Serial.println("Sending request: ");
Serial.println(httpRequest); // 获取并显示服务器响应状态行
String status_response = client.readStringUntil('\n');
Serial.print("status_response: ");
Serial.println(status_response); // 使用find跳过HTTP响应头
if (client.find("\r\n\r\n")) {
Serial.println("Found Header End. Start Parsing.");
} // 利用ArduinoJson库解析心知天气响应信息
parseInfo(client);
}
else {
Serial.println(" connection failed!");
}
//断开客户端与服务器连接工作
client.stop();
} // 连接WiFi
void connectWiFi(){
WiFi.begin(ssid, password); // 启动网络连接
Serial.print("Connecting to "); // 串口监视器输出网络连接信息
Serial.print(ssid); Serial.println(" ..."); // 告知用户NodeMCU正在尝试WiFi连接 int i = 0; // 这一段程序语句用于检查WiFi是否连接成功
while (WiFi.status() != WL_CONNECTED) { // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。
delay(1000); // 如果WiFi连接成功则返回值为WL_CONNECTED
Serial.print(i++); Serial.print(' '); // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
} // 同时NodeMCU将通过串口监视器输出连接时长读秒。
// 这个读秒是通过变量i每隔一秒自加1来实现的。
Serial.println(""); // WiFi连接成功后
Serial.println("Connection established!"); // NodeMCU将通过串口监视器输出"连接成功"信息。
Serial.print("IP address: "); // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
Serial.println(WiFi.localIP()); // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。
} // 利用ArduinoJson库解析心知天气响应信息
void parseInfo(WiFiClient client){
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 3*JSON_OBJECT_SIZE(14) + 860; DynamicJsonDocument doc(capacity); deserializeJson(doc, client); JsonObject results_0 = doc["results"][0]; JsonArray results_0_daily = results_0["daily"]; JsonObject results_0_daily_0 = results_0_daily[0];
const char* results_0_daily_0_date = results_0_daily_0["date"];
const char* results_0_daily_0_text_day = results_0_daily_0["text_day"];
const char* results_0_daily_0_code_day = results_0_daily_0["code_day"];
const char* results_0_daily_0_text_night = results_0_daily_0["text_night"];
const char* results_0_daily_0_code_night = results_0_daily_0["code_night"];
const char* results_0_daily_0_high = results_0_daily_0["high"];
const char* results_0_daily_0_low = results_0_daily_0["low"];
const char* results_0_daily_0_rainfall = results_0_daily_0["rainfall"];
const char* results_0_daily_0_precip = results_0_daily_0["precip"];
const char* results_0_daily_0_wind_direction = results_0_daily_0["wind_direction"];
const char* results_0_daily_0_wind_direction_degree = results_0_daily_0["wind_direction_degree"];
const char* results_0_daily_0_wind_speed = results_0_daily_0["wind_speed"];
const char* results_0_daily_0_wind_scale = results_0_daily_0["wind_scale"];
const char* results_0_daily_0_humidity = results_0_daily_0["humidity"]; JsonObject results_0_daily_1 = results_0_daily[1];
const char* results_0_daily_1_date = results_0_daily_1["date"];
const char* results_0_daily_1_text_day = results_0_daily_1["text_day"];
const char* results_0_daily_1_code_day = results_0_daily_1["code_day"];
const char* results_0_daily_1_text_night = results_0_daily_1["text_night"];
const char* results_0_daily_1_code_night = results_0_daily_1["code_night"];
const char* results_0_daily_1_high = results_0_daily_1["high"];
const char* results_0_daily_1_low = results_0_daily_1["low"];
const char* results_0_daily_1_rainfall = results_0_daily_1["rainfall"];
const char* results_0_daily_1_precip = results_0_daily_1["precip"];
const char* results_0_daily_1_wind_direction = results_0_daily_1["wind_direction"];
const char* results_0_daily_1_wind_direction_degree = results_0_daily_1["wind_direction_degree"];
const char* results_0_daily_1_wind_speed = results_0_daily_1["wind_speed"];
const char* results_0_daily_1_wind_scale = results_0_daily_1["wind_scale"];
const char* results_0_daily_1_humidity = results_0_daily_1["humidity"]; JsonObject results_0_daily_2 = results_0_daily[2];
const char* results_0_daily_2_date = results_0_daily_2["date"];
const char* results_0_daily_2_text_day = results_0_daily_2["text_day"];
const char* results_0_daily_2_code_day = results_0_daily_2["code_day"];
const char* results_0_daily_2_text_night = results_0_daily_2["text_night"];
const char* results_0_daily_2_code_night = results_0_daily_2["code_night"];
const char* results_0_daily_2_high = results_0_daily_2["high"];
const char* results_0_daily_2_low = results_0_daily_2["low"];
const char* results_0_daily_2_rainfall = results_0_daily_2["rainfall"];
const char* results_0_daily_2_precip = results_0_daily_2["precip"];
const char* results_0_daily_2_wind_direction = results_0_daily_2["wind_direction"];
const char* results_0_daily_2_wind_direction_degree = results_0_daily_2["wind_direction_degree"];
const char* results_0_daily_2_wind_speed = results_0_daily_2["wind_speed"];
const char* results_0_daily_2_wind_scale = results_0_daily_2["wind_scale"];
const char* results_0_daily_2_humidity = results_0_daily_2["humidity"]; const char* results_0_last_update = results_0["last_update"]; // 从以上信息中摘选几个通过串口监视器显示
String results_0_daily_0_date_str = results_0_daily_0["date"].as<String>();
String results_0_daily_0_text_day_str = results_0_daily_0["text_day"].as<String>();
int results_0_daily_0_code_day_int = results_0_daily_0["code_day"].as<int>();
String results_0_daily_0_text_night_str = results_0_daily_0["text_night"].as<String>();
int results_0_daily_0_code_night_int = results_0_daily_0["code_night"].as<int>();
int results_0_daily_0_high_int = results_0_daily_0["high"].as<int>();
int results_0_daily_0_low_int = results_0_daily_0["low"].as<int>();
String results_0_last_update_str = results_0["last_update"].as<String>(); Serial.println(F("======Today Weahter ======="));
Serial.print(F("DATE: "));
Serial.println(results_0_daily_0_date_str);
Serial.print(F("Day Weather: "));
Serial.print(results_0_daily_0_text_day_str);
Serial.print(F(" "));
Serial.println(results_0_daily_0_code_day_int);
Serial.print(F("Night Weather: "));
Serial.print(results_0_daily_0_text_night_str);
Serial.print(F(" "));
Serial.println(results_0_daily_0_code_night_int);
Serial.print(F("High: "));
Serial.println(results_0_daily_0_high_int);
Serial.print(F("LOW: "));
Serial.println(results_0_daily_0_low_int);
Serial.print(F("Last Update: "));
Serial.println(results_0_last_update_str);
Serial.println(F("=============================="));
}
  • 如图

  • Ⅲ.获取实时生活指数(穿衣,紫外线强度,洗车,旅游,感冒,运动)

#include <ArduinoJson.h>
#include <ESP8266WiFi.h> const char* ssid = "Geohot"; // 连接WiFi名(此处使用taichi-maker为示例)
// 请将您需要连接的WiFi名填入引号中
const char* password = "zheng123+"; // 连接WiFi密码(此处使用12345678为示例)
// 请将您需要连接的WiFi密码填入引号中 const char* host = "api.seniverse.com"; // 将要连接的服务器地址
const int httpPort = 80; // 将要连接的服务器端口 // 心知天气HTTP请求所需信息
String reqUserKey = "SnMQITaPAa0oGsIrQ"; // 私钥
String reqLocation = "Hangzhou"; // 城市
String reqUnit = "c"; // 摄氏/华氏 void setup(){
Serial.begin(9600);
Serial.println(""); // 连接WiFi
connectWiFi();
} void loop(){
// 建立心知天气API当前天气请求资源地址
String reqRes = "/v3/life/suggestion.json?key=" + reqUserKey +
+ "&location=" + reqLocation +
"&language=en"; // 向心知天气服务器服务器请求信息并对信息进行解析
httpRequest(reqRes);
delay(3000);
} // 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes){
WiFiClient client; // 建立http请求信息
String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n";
Serial.println("");
Serial.print("Connecting to "); Serial.print(host); // 尝试连接服务器
if (client.connect(host, 80)){
Serial.println(" Success!"); // 向服务器发送http请求信息
client.print(httpRequest);
Serial.println("Sending request: ");
Serial.println(httpRequest); // 获取并显示服务器响应状态行
String status_response = client.readStringUntil('\n');
Serial.print("status_response: ");
Serial.println(status_response); // 使用find跳过HTTP响应头
if (client.find("\r\n\r\n")) {
Serial.println("Found Header End. Start Parsing.");
} // 利用ArduinoJson库解析心知天气响应信息
parseInfo(client);
}
else {
Serial.println(" connection failed!");
}
//断开客户端与服务器连接工作
client.stop();
} // 连接WiFi
void connectWiFi(){
WiFi.begin(ssid, password); // 启动网络连接
Serial.print("Connecting to "); // 串口监视器输出网络连接信息
Serial.print(ssid); Serial.println(" ..."); // 告知用户NodeMCU正在尝试WiFi连接 int i = 0; // 这一段程序语句用于检查WiFi是否连接成功
while (WiFi.status() != WL_CONNECTED) { // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。
delay(1000); // 如果WiFi连接成功则返回值为WL_CONNECTED
Serial.print(i++); Serial.print(' '); // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
} // 同时NodeMCU将通过串口监视器输出连接时长读秒。
// 这个读秒是通过变量i每隔一秒自加1来实现的。
Serial.println(""); // WiFi连接成功后
Serial.println("Connection established!"); // NodeMCU将通过串口监视器输出"连接成功"信息。
Serial.print("IP address: "); // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
Serial.println(WiFi.localIP()); // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。
} // 利用ArduinoJson库解析心知天气响应信息
void parseInfo(WiFiClient client){
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 6*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 2*JSON_OBJECT_SIZE(6) + 400;
DynamicJsonDocument doc(capacity); deserializeJson(doc, client); JsonObject results_0 = doc["results"][0]; JsonObject results_0_suggestion = results_0["suggestion"]; const char* results_0_suggestion_car_washing_brief = results_0_suggestion["car_washing"]["brief"];
const char* results_0_suggestion_car_washing_details = results_0_suggestion["car_washing"]["details"]; const char* results_0_suggestion_dressing_brief = results_0_suggestion["dressing"]["brief"];
const char* results_0_suggestion_dressing_details = results_0_suggestion["dressing"]["details"]; const char* results_0_suggestion_flu_brief = results_0_suggestion["flu"]["brief"];
const char* results_0_suggestion_flu_details = results_0_suggestion["flu"]["details"]; const char* results_0_suggestion_sport_brief = results_0_suggestion["sport"]["brief"];
const char* results_0_suggestion_sport_details = results_0_suggestion["sport"]["details"]; const char* results_0_suggestion_travel_brief = results_0_suggestion["travel"]["brief"];
const char* results_0_suggestion_travel_details = results_0_suggestion["travel"]["details"]; const char* results_0_suggestion_uv_brief = results_0_suggestion["uv"]["brief"];
const char* results_0_suggestion_uv_details = results_0_suggestion["uv"]["details"]; const char* results_0_last_update = results_0["last_update"]; // 通过串口监视器显示以上信息
String results_0_suggestion_car_washing_brief_str = results_0_suggestion["car_washing"]["brief"]; String results_0_suggestion_dressing_brief_str = results_0_suggestion["dressing"]["brief"]; String results_0_suggestion_flu_brief_str = results_0_suggestion["flu"]["brief"]; String results_0_suggestion_sport_brief_str = results_0_suggestion["sport"]["brief"]; String results_0_suggestion_travel_brief_str = results_0_suggestion["travel"]["brief"]; String results_0_suggestion_uv_brief_str = results_0_suggestion["uv"]["brief"]; const char* results_0_last_update_str = results_0["last_update"]; Serial.println(F("======Life Info======="));
Serial.print(F("Car Washing: "));
Serial.println(results_0_suggestion_car_washing_brief_str);
Serial.print(F("Dressing: "));
Serial.println(results_0_suggestion_dressing_brief_str);
Serial.print(F("Flu: "));
Serial.println(results_0_suggestion_flu_brief_str);
Serial.print(F("Sport: "));
Serial.println(results_0_suggestion_sport_brief_str);
Serial.print(F("Travel: "));
Serial.println(results_0_suggestion_travel_brief_str);
Serial.print(F("UV: "));
Serial.println(results_0_suggestion_uv_brief_str);
Serial.print(F("Last Update: "));
Serial.println(results_0_last_update_str);
Serial.println(F("======================"));
}
  • 如图

三、结尾

  • 我现在暂时停留在能用会看源代码阶段,C语言也会一些,但上手项目比较少

    后面···上课表 = = 可能博客会选择周更,或者三天一更,尽量保持质量,把学到的都能分享出来

对之前IoT项目的完善的更多相关文章

  1. 【物联网】 9个顶级开发IoT项目的开源物联网平台(转)

    物联网(IoT)是帮助人工智能(AI)以更好的方式控制和理解事物的未来技术. 我们收集了一些最有名的物联网平台,帮助您以受控方式开发物联网项目. 物联网平台是帮助设置和管理互联网连接设备的组件套件. ...

  2. 9个顶级开发IoT项目的开源物联网平台

    https://blog.csdn.net/shnbiot/article/details/80432017 物联网(IoT)是帮助人工智能(AI)以更好的方式控制和理解事物的未来技术. 我们收集了一 ...

  3. 干货分享 | 3个开发IoT项目的开源物联网平台

    物联网(IoT)是帮助人工智能(AI)以更好的方式控制和理解事物的未来技术. 艾艺收集了一些最有名的物联网平台,帮助您以受控方式开发物联网项目.物联网平台是帮助设置和管理互联网连接设备的组件套件. 一 ...

  4. IoT生态不完善、与智能电视区别不大,荣耀智慧屏概念大于实际

    编辑 | 于斌 出品 | 于见(mpyujian) 前两天,华为荣耀略显"低调"地在北京召开了一场小型的媒体沟通会.在这场沟通会上,荣耀却颇为"重磅"地推出了坊 ...

  5. Docker应用部署实录(包含完善Docker安装步骤)

    Docker应用部署实录(包含完善Docker安装步骤) 前言 首先说一下这篇文章的来源.我之前接手的一个IOT项目,需要安装多个中控服务器.中控服务器需要安装RabbitMQ,Mysql,多个服务, ...

  6. 【基于WinForm+Access局域网共享数据库的项目总结】之篇一:WinForm开发总体概述与技术实现

    篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...

  7. 【基于WinForm+Access局域网共享数据库的项目总结】之篇二:WinForm开发扇形图统计和Excel数据导出

    篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...

  8. 【基于WinForm+Access局域网共享数据库的项目总结】之篇三:Access远程连接数据库和窗体打包部署

    篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...

  9. 《Windows IoT 应用开发指南》

    物物互联的时代已经到来,智能家居.智慧校园.智慧交通.可穿戴.无人机.全息投影,各种各样的新名词.黑科技层出不穷.当我们为五年前能够通过手机控制家电而欣喜若狂的时候,可曾憧憬过当前使用增强现实设备完成 ...

随机推荐

  1. Paillier同态加密实现

    一.C++(该方案只实现了加密以及解密) 1.git clone https://github.com/klei0229/paillier.git 2.下载GMP与NTL包: 下载版本以及操作参见ht ...

  2. springboot的常用注解

    1. @SpringBootApplication2. @Repository3. @Service4. @RestController5. @Controller6. @Component7. @R ...

  3. 全国大学生信息安全竞赛初赛writeup

    本文首发于“合天智汇”公众号 作者:Fortheone WEB Babyunserialize 扫目录发现了 www.zip 下载下来发现似曾相识 之前wmctf2020的webweb出了f3的反序列 ...

  4. Pycharm2019.3永久激活

    1. 下载破解补丁,https://pan.baidu.com/s/1mcQM8CLUnweY02ahKEr4PQ ,下载最新上传的压缩包 2. 将压缩包解压,里面有激活文件ACTIVATION_CO ...

  5. Python爬虫实战点触验证码, 模拟登陆bilibili

    爬虫思路如下: 利用自动化爬虫工具 Selenium 模拟点击输入等操作来进行登录 分析页面,获取点触验证码的点触图片,通过将图片发送给超级鹰打码平台识别后获取坐标信息 根据超级鹰返回的数据,模拟坐标 ...

  6. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  7. oeasy教您玩转linux010203显示logo

    我们来回顾一下 上一部分我们都讲了什么?

  8. 总结回顾js arr的常见方法以及相关的使用场景(一)

    Array对象方法 1.arr.concat() 连接两个或更多的数组,并返回结果. 连接数组中的值 连接两个数组 连接三个数组 2.arr.join() 把数组的所有元素放入一个字符串.元素通过指定 ...

  9. java初探(1)之静态页面化——客户端缓存

    利用服务端缓存技术,将页面和对象缓存在redis中,可以减少时间浪费,内存开销.但在每次请求的过程中,仍然会有大量静态资源的请求和返回. 使用静态页面技术,页面不必要使用页面交互技术,比如thymel ...

  10. Agumaster 增加日交易数据列表