模块:esp-01s
SDK版本:ESP8266_RTOS_SDK-3.0
开发环境:wsl+vscode
功能模块:wifi,tcp_client,http_request
本文使用esp8266来获取网络天气,首先我们需要找一个天气的api,例如和风天气,心知天气。关于怎么获取api就不多说了,问度娘吧。
想要从网络获取天气首先我们得联网,然后解析获取天气的地址端口,然后返回数据解析数据。
我分别把连接wifi,和http请求获取天气的函数分别封装出来,连接wifi就不多说了,这里只贴了通过http请求来获取天气的代码。
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include <netdb.h>
#include <sys/socket.h>
#include "http_request.h"
#include "tcp_client.h"
#include "wifi.h"
#define WEB_SERVER "example.com"//请求服务器地址
#define WEB_PORT 80//请求端口
#define WEB_URL "https://example.com"//请求url
static const char *TAG = "example";
static const char *REQUEST = "GET " WEB_URL " HTTP/1.0\r\n"
"Host: "WEB_SERVER"\r\n"
"User-Agent: esp-idf/1.0 esp32\r\n"
"\r\n";
static void http_get_task(void *pvParameters)
{
const struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
};
struct addrinfo *res;
struct in_addr *addr;
int s, r;
while(1) {
/* Wait for the callback to set the CONNECTED_BIT in the
event group.
*/
if(get_wifi_status()==false) //在此处等待,直到有了wifi
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "Connected to AP");
int err = getaddrinfo(WEB_SERVER, "80", &hints, &res);
if(err != 0 || res == NULL) {
ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res);
vTaskDelay(1000 / portTICK_PERIOD_MS);
continue;
}
/* Code to print the resolved IP.
Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));
s = socket(res->ai_family, res->ai_socktype, 0);
if(s < 0) {
ESP_LOGE(TAG, "... Failed to allocate socket.");
freeaddrinfo(res);
vTaskDelay(1000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "... allocated socket");
if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
ESP_LOGE(TAG, "... socket connect failed errno=%d", errno);
close(s);
freeaddrinfo(res);
vTaskDelay(4000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "... connected");
freeaddrinfo(res);
if (write(s, REQUEST, strlen(REQUEST)) < 0) {
ESP_LOGE(TAG, "... socket send failed");
close(s);
vTaskDelay(4000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "... socket send success");
struct timeval receiving_timeout;
receiving_timeout.tv_sec = 5;
receiving_timeout.tv_usec = 0;
if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &receiving_timeout,
sizeof(receiving_timeout)) < 0) {
ESP_LOGE(TAG, "... failed to set socket receiving timeout");
close(s);
vTaskDelay(4000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "... set socket receiving timeout success");
/* Read HTTP response */
do {
bzero(recv_buf, sizeof(recv_buf));
r = read(s, recv_buf, sizeof(recv_buf)-1);
for(int i = 0; i < r; i++) {
putchar(recv_buf[i]);
}
SendString(recv_buf);
} while(r > 0);
ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d\r\n", r,
errno);
close(s);
}
}
void http_start()
{
xTaskCreate(&http_get_task, "http_get_task", 16384, NULL, 5, NULL);
}
本文链接:
https://www.veryxs.com/index.php/archives/9/
你这也没把数据解析出来吧 只是获取到返回的数据
@1 没有解析,后来我写了没有贴上来,返回的是json字符串,判断如果读取到了就使用cjson解析,下面是解析部分代码