В текущей статье рассказывается, как использовать микроконтроллеры ESP8266 и STM32 в сочетании с OLED-дисплеем для создания интеллектуального устройства, которое может отображать прогнозы погоды в режиме реального времени. API погоды Xinzhi будет использоваться для получения данных о погоде, а протокол MQTT будет использоваться для передачи данных на контроллер STM32 и, наконец, для отображения на OLED-дисплее.
Xinzhi Weather — профессиональный поставщик услуг метеорологических данных, специализирующийся на предоставлении высококачественных, индивидуальных услуг метеорологических данных пользователям по всему миру. Его основные продукты включают API погоды, API качества воздуха, API предупреждения о стихийных бедствиях и т. д. Пользователи могут получать точные данные о погоде в режиме реального времени через API-интерфейс определения погоды, чтобы обеспечить поддержку различных сценариев применения, таких как умный дом, путешествия, электронная коммерция и т. д. Данные Xinzhi Weather охватывают более 200 стран и регионов по всему миру, ежедневно обрабатывая более 1 миллиарда запросов API, и являются одним из ведущих поставщиков услуг метеорологических данных в отрасли. https://www.seniverse.com/
ESP8266 — это модуль Wi-Fi, который обладает мощными возможностями сетевого подключения и легко подключается к Интернету. Модуль ESP8266 будет использоваться для получения данных о погоде и отправки их на контроллер STM32. В частности, мы будем использовать модуль ATK-ESP8266, который представляет собой небольшую плату, объединяющую чип ESP8266.
STM32 — мощный 32-битный микроконтроллер с множеством интерфейсов и функций. Будет использоваться контроллер STM32F103C8T6, очень популярная модель, легко доступная и по разумной цене.
OLED — очень популярная технология отображения, обладающая преимуществами высокой контрастности, низкого энергопотребления и быстрого отклика. Будет использоваться 0,96-дюймовый OLED-дисплей с разрешением 128x64 пикселей.
{
"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 — это облегченный анализатор JSON на языке C, его полное имя — «cJSON», написанное Дэйвом Гэмблом. Он прост и удобен в использовании и может быть встроен в приложения C. Он поддерживает не только анализ строк JSON, но также создание и работу объектов JSON. CJSON не зависит от каких-либо других библиотек или компонентов. Чтобы использовать его, вам нужно только ввести его заголовочный файл.
Использование CJSON относительно просто и требует следующих шагов:
1. Включите файл заголовка cJSON в свое приложение: #include "cJSON.h"。
2. Вызовите функцию cJSON_Parsefunction, чтобы преобразовать JSONнит в CJSONобъект.
3. Используйте функцию API, предоставляемую cJSON, для управления объектом CJSON, включая чтение, изменение, удаление, добавление и т. д.
4. в конце программы,Не забудьте освободить пространство памяти cJSONобъекта.,Избегайте утечек памяти.
Скорость анализа CJSON относительно высока, а затраты памяти относительно невелики, поэтому он очень подходит для использования во встроенных системах с ограниченными ресурсами.
Анализировать приведенные выше данные JSON с использованием CJSON очень просто, просто выполните следующие действия:
#include <cJSON.h>
char* json_data = "{\"results\":[{\"location\":{\"id\":\"WTEMH46Z5N09\",\"name\":\"Хэфэй\",\"country\":\"CN \",\"path\":\"Хэфэй,Хэфэй,Аньхой,Китай\",\"часовой пояс\":\"A Сиа/Шанхай\",\"timezone_offset\":\"+08:00\"},\"сейчас\":{\"текст\":\"Инь\",\"код\":\"9 \",\"температура\":\"12\",\"по ощущениям\":\"18\" , «давление»: «1000», «влажность»: «89», «видимость»: «12,0», «wind_direction»: «Юго-запад»,\ "wind_direction_grade\":\"245\",\"w ind_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* 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_Delete(root);
Наконец, нам нужно освободить созданный ранее объект cJSON, чтобы освободить место в памяти.
Полный пример кода выглядит следующим образом:
#include <cJSON.h>
#include <stdio.h>
int main() {
char* json_data = "{\"results\":[{\"location\":{\"id\":\"WTEMH46Z5N09\",\"name\":\"Хэфэй\",\"country\":\"CN \",\"path\":\"Хэфэй,Хэфэй,Аньхой,Китай\",\"часовой пояс\":\"A Сиа/Шанхай\",\"timezone_offset\":\"+08:00\"},\"сейчас\":{\"текст\":\"Инь\",\"код\":\"9 \",\"температура\":\"12\",\"по ощущениям\":\"18\" , «давление»: «1000», «влажность»: «89», «видимость»: «12,0», «wind_direction»: «Юго-запад»,\ "wind_direction_grade\":\"245\",\"w ind_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: %s\n", city);
printf("Temperature: %d\n", temperature);
printf("Weather: %s\n", text);
cJSON_Delete(root);
return 0;
}
В этом примере кода,использовалcJSON_Parse()
、cJSON_GetObjectItem()
、cJSON_Delete()
ждатьфункцияанализироватьи处理JSONданные。
Ниже приведен код ESP8266 для доступа к запросу интерфейса HTTP:
#include <SoftwareSerial.h>
// Определить объект последовательного порта 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() {
// Отправьте HTTP-запрос на ESP8266.
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.1\r\n" +
"Host: api.seniverse.com\r\n" +
"User-Agent: STM32/1.0\r\n" +
"Connection: close\r\n\r\n";
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()
функциясередина,Отправьте HTTP-запрос на ESP8266.,Включает заголовки и тело запроса. После отправки,Подождите, пока ESP8266 вернет ответ HTTP, и распечатайте его. наконец,Закрыть TCP-соединение并ждать待一秒钟,Затем повторите вышеуказанные шаги.