ESP8266作为一款功能强大的的物联网模块,已经被应用到了很多实用的物联网项目中。作为一个菜鸟,本人也捣鼓这个东西很长时间了,在捣鼓这个东西的同时我也总结了一些使用经验。在此借助CSDN平台出几个教程,将这些经验分享给大家,同时也做为个人的实践经验总结。
ESP8266的主要开发方式有三种:官方SDK(深圳乐鑫的官方库+深圳安信可的类eclipse开发环境),lua语言以及arduino的ESP8266库。楼主经常使用第一种和第三种(对lua不太熟悉),对于新手而言官方的SDK开发还是比较晦涩难懂的,教程也不是很多(B站技新课堂基于官方SDK的ESP8266视频教程比较不错,有兴趣的可以去了解),因此本esp8266初级入门实用教程还是使用arduino进行开发,需要大家配置好arduino中ESP8266的开发环境并对arduino的ESP8266库有一定的了解。(大家可以去搜单片机菜鸟博哥的教程,私以为是我看过的基于arduino的最好的ESP8266文本教程)。
第一个实践教程当然是从大家喜闻乐见的读取网络实时天气开始,这个搞明白的话,大家基本上也就会对物联网有一个感性的认识了。实现该项目的主要步骤如下:
(一)注册心知天气账户,申请天气数据AP免费版并记下访问私钥。
打开心知天气官网后进行注册和登录。
申请天气数据API免费版
记下访问私钥
完成上述三个步骤我们就拥有了读取心知天气实时天气状况的权限,注意:免费版的访问数据是有限制的,访问频次每分钟只有20次,但对于我们而言已经够用了。
(二)了解HTTP协议,获取URL并确定最终访问格式。
HTTP协议(超文本传输协议)是互联网上应用最为广泛的一种应用层网络协议,用作客户端和服务器之间的请求 - 响应协议,具体可参考此篇博文https://blog.csdn.net/weixin_34259559/article/details/87951549
HTTP协议中客户端的数据请求和上传主要依靠GET请求和POST请求进行。此次教程中我们只需要向服务器进行数据的请求,所以只讲GET请求及其请求格式。
HTTP协议中数据的请求格式包含请求行(request line)、请求头部(header)、空行和请求数据四个部分,下图给出了请求报文的一般格式:
HTTP协议使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息。我们想读取心知天气的数据资源也必须知道它的URL,心知天气的文档中给我们提供了它的URL格式,如下图:
知道了HTTP报文的格式和心知天气的URL我们就可知得到最终的访问格式,如下:
URL是; /v3/weather/now.json?key=“你的私钥”&location=beijing&language=zh-Hans&unit=c HTTP/1.1\r\n
//根据HTTP报文格式,在URL协议后面缀上协议版本HTTP/1.1
请求头部:
主机名:Host: api.seniverse.com\r\n
接收的语言:Accept-Language: zh-cn\r\n
连接的模式-- 断开服务器连接:Connection: close\r\n
(三)程序编写,实现ESP8266访问心知天气并读取当前实时天气。
由于心知天气返回的是JSON字符串,需要进行数据解析,自写解析函数的话比较麻烦,这里我们使用前辈们已经为我们造好的轮子,JSON库。程序中的JSON数据解析我已经附上了B站的教程地址。
#include
#include //使用JSON-v5版的库
const char* AP_SSID = "644"; // XXXXXX -- 使用时请修改为当前你的 wifi ssid
const char* AP_PSK = "@644.1234"; // XXXXXX -- 使用时请修改为当前你的 wifi 密码
WiFiClient client; //创建一个网络对象
/* 请求的Json数据格式如下:
* {
* "results": [
* {
* "location": {
* "id": "WX4FBXXFKE4F",
* "name": "北京",
* "country": "CN",
* "path": "北京,北京,中国",
* "timezone": "Asia/Shanghai",
* "timezone_offset": "+08:00"
* },
* "now": {
* "text": "多云",
* "code": "4",
* "temperature": "23"
* },
* "last_update": "2019-10-13T09:51:00+08:00"
* }
* ]
*}
*/
void wifi_start_connect() //连接WIFI
{
WiFi.mode(WIFI_STA); //设置esp8266 工作模式
Serial.println("Connecting to "); //写几句提示
Serial.println(AP_SSID);
WiFi.begin(AP_SSID, AP_PSK); //连接wifi
WiFi.setAutoConnect(true);
while (WiFi.status()!= WL_CONNECTED) //这个函数是wifi连接状态,返回wifi链接状态
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected IP is");
Serial.println(WiFi.localIP());
}
void parseUserData(String content) // Json数据解析并串口打印.可参考https://www.bilibili.com/video/av65322772
{
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 210;
DynamicJsonBuffer jsonBuffer(capacity);
JsonObject& root = jsonBuffer.parseObject(content);
JsonObject& results_0 = root["results"][0];
JsonObject& results_0_location = results_0["location"];
const char* results_0_location_id = results_0_location["id"];
const char* results_0_location_name = results_0_location["name"];
const char* results_0_location_country = results_0_location["country"];
const char* results_0_location_path = results_0_location["path"];
const char* results_0_location_timezone = results_0_location["timezone"];
const char* results_0_location_timezone_offset = results_0_location["timezone_offset"];
JsonObject& results_0_now = results_0["now"];
const char* results_0_now_text = results_0_now["text"];
const char* results_0_now_code = results_0_now["code"];
const char* results_0_now_temperature = results_0_now["temperature"];
const char* results_0_last_update = results_0["last_update"];
Serial.println(results_0_location_name); //通过串口打印出需要的信息
Serial.println(results_0_now_text);
Serial.println(results_0_now_code);
Serial.println(results_0_now_temperature);
Serial.println(results_0_last_update);
Serial.print("\r\n");
}
void setup()
{
Serial.begin(115200);
wifi_start_connect();
client.setTimeout(5000);//设置服务器连接超时时间
}
void loop()
{
if(client.connect("api.seniverse.com", 80)==1) //连接服务器并判断是否连接成功,若成功就发送GET 请求数据下发
{ //换成你自己在心知天气申请的私钥//改成你所在城市的拼音
client.print("GET /v3/weather/now.json?key=“你的私钥”&location=zhengzhou&language=zh-Hans&unit=c HTTP/1.1\r\n"); //心知天气的URL格式
client.print("Host:api.seniverse.com\r\n");
client.print("Accept-Language:zh-cn\r\n");
client.print("Connection:close\r\n\r\n"); //向心知天气的服务器发送请求。
String status_code = client.readStringUntil('\r'); //读取GET数据,服务器返回的状态码,若成功则返回状态码200
Serial.println(status_code);
if(client.find("\r\n\r\n")==1) //跳过返回的数据头,直接读取后面的JSON数据,
{
String json_from_server=client.readStringUntil('\n'); //读取返回的JSON数据
Serial.println(json_from_server);
parseUserData(json_from_server); //将读取的JSON数据,传送到JSON解析函数中进行显示。
}
}
else
{
Serial.println("connection failed this time");
delay(5000); //请求失败等5秒
}
client.stop(); //关闭HTTP客户端,采用HTTP短链接,数据请求完毕后要客户端要主动断开https://blog.csdn.net/huangjin0507/article/details/52396580
delay(5000);
}
(四)实际演示;
我们可以清楚的看到ESP8266成功的读取到了当前天气数据,并通过串口打印了出来。
(五)总结
本次教程只是做了一个走马观花式的粗略演示(有错误也请各位指出,相互交流),无论是其中的HTTP协议还是JSON解析都可以再引出一大波知识点,这些都需要各位自己去搜索资料学习。 接下来我会更新一些ESP8266使用HTTP和MQTT协议与ONENET交互的教程(楼主作为懒癌晚期患者,就随缘吧)。