一、實現功能
當前文章介紹如何使用ESP8266和STM32微控制器,搭配OLED顯示屏,制作一個能夠實時顯示天氣預報的智能設備。將使用心知天氣API來獲取天氣數據,并使用MQTT協議將數據傳遞給STM32控制器,最終在OLED顯示屏上顯示。
心知天氣是一家專業的氣象數據服務提供商,致力于為全球用戶提供高質量、定制化的氣象數據服務。其主要產品包括天氣API、空氣質量API、災害預警API等。用戶可以通過心知天氣的API接口,獲取準確、實時的天氣數據,從而為各種應用場景提供支持,例如智能家居、出行、電商等。心知天氣的數據覆蓋全球200多個國家和地區,每日處理超過10億次API請求,是業內領先的氣象數據服務提供商之一。
二、硬件準備
1. ESP8266模塊
ESP8266是一款WiFi模塊,它具有強大的網絡連接功能,可以輕松地連接到互聯網。將使用ESP8266模塊來獲取天氣數據,并將其發送給STM32控制器。具體來說,我們將使用正點原子ATK-ESP8266模塊,這是一款集成ESP8266芯片的小板子。
2. STM32微控制器
STM32是一款強大的32位微控制器,具有多種接口和功能。將使用STM32F103C8T6控制器,這是一款非常流行的型號,易于獲得且價格較為合理。
3. OLED顯示屏
OLED是一種非常流行的顯示技術,具有高對比度、低功耗、快速響應等優點。將使用0.96英寸128x64像素的OLED顯示屏。
三、CJSON解析天氣預報數據
3.1 接口返回的數據
{
"results": [
{
"location": {
"id": "WTEMH46Z5N09",
"name": "合肥",
"country": "CN",
"path": "合肥,合肥,安徽,中國",
"timezone": "Asia/Shanghai",
"timezone_offset": "+08:00"
},
"now": {
"text": "陰",
"code": "9",
"temperature": "12",
"feels_like": "18",
"pressure": "1000",
"humidity": "89",
"visibility": "12.0",
"wind_direction": "西南",
"wind_direction_degree": "245",
"wind_speed": "19.0",
"wind_scale": "3",
"clouds": "85",
"dew_point": ""
},
"last_update": "2023-04-04T14:20:13+08:00"
}
]
}
3.2 CJSON是什么
CJSON是一款輕量級的C語言JSON解析器,其全稱是“cJSON”,由Dave Gamble編寫。它簡單易用,可嵌入到C應用程序中,既支持JSON字符串的解析,也支持JSON對象的創建及操作。CJSON不依賴于任何其他的庫或組件,使用它只需要引入其頭文件即可。
CJSON的使用方式相對來說比較簡單,需要進行以下幾個步驟:
1. 在應用程序中包含cJSON的頭文件:#include "cJSON.h"。
2. 調用cJSON_Parse函數,將JSON字符串轉換為CJSON對象。
3. 使用cJSON提供的API函數對CJSON對象進行操作,包括讀取、修改、刪除、添加等。
4. 在程序結束時,記得釋放cJSON對象的內存空間,避免內存泄漏。
CJSON的解析速度相對較快,占用的內存開銷也比較小,因此非常適用于資源有限的嵌入式系統中使用。
3.3 解析數據
使用CJSON解析上述JSON數據非常簡單,只需要按照以下步驟操作:
- 引入CJSON庫文件
cCopy Code#include
- 解析JSON數據并創建cJSON對象
cCopy Codechar* json_data = "{"results":[{"location":{"id":"WTEMH46Z5N09","name":"合肥","country":"CN","path":"合肥,合肥,安徽,中國","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"陰","code":"9","temperature":"12","feels_like":"18","pressure":"1000","humidity":"89","visibility":"12.0","wind_direction":"西南","wind_direction_degree":"245","wind_speed":"19.0","wind_scale":"3","clouds":"85","dew_point":""},"last_update":"2023-04-04T14:20:13+08:00"}]}";
cJSON* root = cJSON_Parse(json_data);
在這個代碼片段中,我們首先定義了一個字符串類型的變量json_data
,用于存儲上述JSON數據。然后,我們調用cJSON_Parse()
函數來解析JSON數據,并將解析結果保存在root
指針所指向的cJSON對象中。
- 從cJSON對象中提取數據
cCopy CodecJSON* location = cJSON_GetObjectItem(root, "location");
char* city = cJSON_GetObjectItem(location, "name")->valuestring;
cJSON* now = cJSON_GetObjectItem(root, "now");
int temperature = cJSON_GetObjectItem(now, "temperature")->valueint;
char* text = cJSON_GetObjectItem(now, "text")->valuestring;
在這個代碼片段中,我們使用cJSON_GetObjectItem()
函數從root
指針所指向的cJSON對象中提取一個名為location
的JSON對象,并從該JSON對象中獲取名為name
的字符串類型變量。類似地,我們也可以從root
指針所指向的cJSON對象中提取名為now
的JSON對象,并從該JSON對象中獲取名為temperature
和text
的整型和字符串類型變量。
- 釋放cJSON對象
cCopy CodecJSON_Delete(root);
最后,我們需要釋放之前創建的cJSON對象,以釋放內存空間。
完整的代碼示例如下:
cCopy Code#include
#include
?
int main() {
char* json_data = "{"results":[{"location":{"id":"WTEMH46Z5N09","name":"合肥","country":"CN","path":"合肥,合肥,安徽,中國","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"陰","code":"9","temperature":"12","feels_like":"18","pressure":"1000","humidity":"89","visibility":"12.0","wind_direction":"西南","wind_direction_degree":"245","wind_speed":"19.0","wind_scale":"3","clouds":"85","dew_point":""},"last_update":"2023-04-04T14:20:13+08:00"}]}";
cJSON* root = cJSON_Parse(json_data);
?
cJSON* location = cJSON_GetObjectItem(root, "location");
char* city = cJSON_GetObjectItem(location, "name")->valuestring;
cJSON* now = cJSON_GetObjectItem(root, "now");
int temperature = cJSON_GetObjectItem(now, "temperature")->valueint;
char* text = cJSON_GetObjectItem(now, "text")->valuestring;
?
printf("City: %sn", city);
printf("Temperature: %dn", temperature);
printf("Weather: %sn", text);
?
cJSON_Delete(root);
?
return 0;
}
在這個代碼示例中,使用了cJSON_Parse()
、cJSON_GetObjectItem()
、cJSON_Delete()
等函數來解析和處理JSON數據。
3.4 獲取數據
下面是ESP8266訪問HTTP接口請求的代碼:
#include
?
// 定義ESP8266串口對象
SoftwareSerial esp8266(PA10, PA9); // RX, TX
?
void setup() {
Serial.begin(9600);
?
// 初始化ESP8266串口通信波特率為9600
esp8266.begin(9600);
?
// 發送AT指令測試ESP8266是否正常工作
esp8266.println("AT");
delay(500);
if (esp8266.find("OK")) {
Serial.println("ESP8266 is working properly.");
} else {
Serial.println("ESP8266 is not working properly.");
}
}
?
void loop() {
// 向ESP8266發送HTTP請求
esp8266.println("AT+CIPSTART="TCP","api.seniverse.com",80");
if (esp8266.find("OK")) {
Serial.println("TCP connection established.");
} else {
Serial.println("TCP connection failed.");
}
?
String url = "/v3/weather/now.json?key=your_API_KEY&location=your_LOCATION";
String request = "GET " + url + " HTTP/1.1rn" +
"Host: api.seniverse.comrn" +
"User-Agent: STM32/1.0rn" +
"Connection: closernrn";
int length = request.length();
String cmd = "AT+CIPSEND=" + String(length);
esp8266.println(cmd);
if (esp8266.find(">")) {
Serial.println("Sending HTTP request...");
esp8266.print(request);
} else {
Serial.println("Failed to send HTTP request.");
}
?
// 接收HTTP響應
while (esp8266.available()) {
String response = esp8266.readStringUntil('n');
Serial.println(response);
}
?
// 關閉TCP連接
esp8266.println("AT+CIPCLOSE");
delay(1000);
}
在這個示例代碼中,初始化了ESP8266串口對象,并通過發送AT
指令測試ESP8266是否正常工作。然后,在loop()
函數中,向ESP8266發送一個HTTP請求,包括請求頭和請求體。發送完畢后,等待ESP8266返回HTTP響應并將其打印出來。最后,關閉TCP連接并等待一秒鐘,然后重復上述步驟。
-
微控制器
+關注
關注
48文章
7487瀏覽量
151045 -
單片機
+關注
關注
6032文章
44514瀏覽量
632975 -
STM32
+關注
關注
2266文章
10871瀏覽量
354793 -
API
+關注
關注
2文章
1485瀏覽量
61814 -
ESP8266
+關注
關注
50文章
962瀏覽量
44832
發布評論請先 登錄
相關推薦
評論