当前位置: 首页 > 工具软件 > Feed SDK > 使用案例 >

ESP8266使用NONOS_SDK获取心知天气数据(HTTP)

马欣德
2023-12-01

        为了读者容易读懂,该文章里面附的所以代码我都写在了user_main.c里面。

一、配置为Station模式

        首先需要在user_init(void)函数里面加入下面的代码来配置ESP

8266为客户端模式,然后自动去连接路由器。

/********************************************************************************************************************
 *
 * 连配置为客户端station模式,自动去连接 WiFi 路由器	( 注意! 注意! 注意! : 不要使用别的定时器,以免在连接WiFi时被打断,从而造成一直连接不上 WiFi )
 *
************************************************************************************************************/
	user_set_station_config();//设置 Wi-Fi Station 接口的配置
    os_timer_disarm (&os_timer_station);//取消定时器器定时
    os_timer_setfn(&os_timer_station, (ETSTimerFunc *)(time_station), NULL);//设置定时器器回调函数。使用定时器器,必须设置回调函数。
    os_timer_arm (&os_timer_station, 200, true);//使能毫秒级定时器器

上面对应的定时器回调函数,如下所示:

/****************************************************************************
 * 功能: Wi-Fi Station(客户端)		定时器
 * 注意:在user_init中调用,则 ESP8266 Station 接口会在系统初始化完成后,自动连接 AP(WiFi路由器)
**************************************************************************/
static os_timer_t os_timer_station;
//软件定时器回调函数
void time_station(void){
	struct ip_info info;
	static uint16 station_x = 0;
	os_printf("time_station: %d !!!!!!!!!!!!!!!!!\r\n",station_x++);
	if(wifi_station_get_connect_status() == STATION_GOT_IP) {//查询 ESP8266 Wi-Fi Station 接口连接 AP 的状态	(连接成功则关闭定时器)
		os_timer_disarm (&os_timer_station);

		wifi_get_ip_info(STATION_IF, &info);//查询 Wi-Fi Station 接口的 IP 地址
		uint8 ESP8266_IP[4];
		ESP8266_IP[0] = info.ip.addr;		//	最高8位
		ESP8266_IP[1] = info.ip.addr>>8;	//	次高8位
		ESP8266_IP[2] = info.ip.addr>>16;	//	次低8位
		ESP8266_IP[3] = info.ip.addr>>24;	//	低8位
		os_printf("station_IP: %d . %d . %d . %d \r\n",ESP8266_IP[0],ESP8266_IP[1],ESP8266_IP[2],ESP8266_IP[3]);


		dns_test();//获取服务器的IP

		espconn_user.type = ESPCONN_TCP;
		espconn_user.proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));// 开辟内存
		// 此处需要设置目标IP/端口(ESP8266作为Client,需要预先知道Server的IP/端口)
		espconn_user.proto.tcp->local_port = espconn_port() ;	// 设置本地端口
		espconn_user.proto.tcp->remote_port = 80;	// 设置目标端口

		//uint8 remote_ip[4] = {104,108,185,124};		// 目标ip地址
		os_memcpy(espconn_user.proto.tcp->local_ip,ESP8266_IP,4);	// 拷贝内存


		// 注册连接成功回调函数、异常断开回调函数
		espconn_regist_connectcb(&espconn_user, ESP8266_TCP_Connect_Cb_JX);	// 注册TCP连接成功建立的回调函数
		espconn_regist_reconcb(&espconn_user, ESP8266_TCP_Break_Cb_JX);		// 注册TCP连接异常断开的回调函数
		// 连接 TCP server
		espconn_connect(&espconn_user);	// 连接TCP-server

	}
	system_soft_wdt_feed();//这里我们喂下看门狗  ,不让看门狗复位
}

二、获取服务器的IP地址

在连接远端服务器时,需要获取IP才能进行连接,而我们平常只能知道服务器的域名,乐鑫SDK_API参考手册的espconn_gethostbyname()函数则是通过域名获取对应服务器的IP地址;

上面回调函数里面的dns_test()函数则是调用该函数获取服务器IP,代码如下所示:

// 获取到对应域名 IP 地址的回调函数
struct espconn espconn_user;
struct ip_addr_t *esp_server_ip;
LOCAL void ICACHE_FLASH_ATTR
user_esp_platform_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) {
	struct espconn *pespconn = (struct espconn *)arg;
	if (ipaddr != NULL){
		os_printf("user_esp_platform_dns_found %d.%d.%d.%d \r\n",
			*((uint8 *)&ipaddr->addr), *((uint8 *)&ipaddr->addr + 1),
			*((uint8 *)&ipaddr->addr + 2), *((uint8 *)&ipaddr->addr + 3));

		espconn_user.proto.tcp->remote_ip[0] = *((uint8 *)&ipaddr->addr);	// 设置目标IP地址
		espconn_user.proto.tcp->remote_ip[1] = *((uint8 *)&ipaddr->addr + 1);
		espconn_user.proto.tcp->remote_ip[2] = *((uint8 *)&ipaddr->addr + 2);
		espconn_user.proto.tcp->remote_ip[3] = *((uint8 *)&ipaddr->addr + 3);
	}
}
// 获取到对应域名 IP 地址
void dns_test(void) {
	os_printf("999999%d \r\n");
	espconn_gethostbyname(&espconn_user,"api.seniverse.com", &esp_server_ip,
			user_esp_platform_dns_found);
}

三、服务器连接异常回调函数

在上上面的定时器回调函数里面,注册了TCP连接异常断开的回调函数espconn_regist_reconcb(&espconn_user, ESP8266_TCP_Break_Cb_JX); 函数,对应的回调代码函数代码,如下所示:

// TCP连接异常断开时的回调函数【ESP8266作为TCP_Client,连接TCP_Server失败,也会进入此函数】
void ICACHE_FLASH_ATTR
ESP8266_TCP_Break_Cb_JX(void *arg,sint8 err){
	struct espconn * T_arg = arg;		// 缓存网络连接结构体指针
	os_printf("\nESP8266_TCP_Break\n");

	espconn_connect(&espconn_user);	// 重新连接TCP-server
}

四、服务器连接成功回调函数

在上上上面的定时器回调函数里面,注册了TCP连接成功建立的回调函数espconn_regist_connectcb(&espconn_user, ESP8266_TCP_Connect_Cb_JX);  函数,对应的回调代码函数代码,如下所示:


// TCP连接建立成功的回调函数
void ICACHE_FLASH_ATTR
ESP8266_TCP_Connect_Cb_JX(void *arg){

	#define data "GET /v3/weather/daily.json?key=rrpd2zmqkpwlsckt&location=guangzhou&language=en&unit=c&start=0&days=3 HTTP/1.1\r\nContent-Type: text/html;charset=utf-8\r\nAccept: */*\r\nHost: api.seniverse.com\r\nConnection: Keep-Alive\r\n\r\n"
	os_printf("###################### len: %d \r\n",os_strlen(data));
	os_printf(data);

	// 也可以不打招呼,因为TCP本身就是握手建立连接。只要TCP连接建立,TCP_Server就已经知道TCP_Client的信息
	espconn_send((struct espconn *)arg,data,os_strlen(data));	// 打招呼

	espconn_regist_sentcb((struct espconn *)arg, ESP8266_WIFI_Send_Cb_JX);			// 注册网络数据发送成功的回调函数
	espconn_regist_recvcb((struct espconn *)arg, ESP8266_WIFI_Recv_Cb_JX);			// 注册网络数据接收成功的回调函数
	espconn_regist_disconcb((struct espconn *)arg,ESP8266_TCP_Disconnect_Cb_JX);	// 注册成功断开TCP连接的回调函数

	os_printf("\n--------------- ESP8266_TCP_Connect_OK ---------------\n");

}

五、请问数据发送成功回调函数

在“ 服务器连接成功回调函数 ”中,注册了数据发送成功回调函数,对应的回调函数,如下所示:


// 网络数据发送成功的回调函数
void ICACHE_FLASH_ATTR
ESP8266_WIFI_Send_Cb_JX(void *arg){
	struct espconn * T_arg = arg;		// 缓存网络连接结构体指针
	os_printf("\nESP8266_Send_OK \r\n");
}

六、接收服务器数据成功回调函数

在“ 服务器连接成功回调函数 ”中,注册了接收服务器数据成功回调函数,对应的回调函数,如下所示:

// 成功接收网络数据的回调函数【参数1:网络传输结构体espconn指针、参数2:网络传输数据指针、参数3:数据长度】
void ICACHE_FLASH_ATTR
ESP8266_WIFI_Recv_Cb_JX(void * arg, char * pdata, unsigned short len){
	struct espconn * T_arg = arg;		// 缓存网络连接结构体指针
	os_printf("ESP8266_Receive_Data_len = %d \r\n",len);		// 串口打印接收到的数据长度
	os_printf("ESP8266_Receive_Data = %s \r\n",pdata);		// 串口打印接收到的数据

}

七、断开服务器成功回调函数

在“ 服务器连接成功回调函数 ”中,注册了断开服务器成功回调函数,对应的回调函数,如下所示:

// TCP连接断开成功的回调函数
void ICACHE_FLASH_ATTR
ESP8266_TCP_Disconnect_Cb_JX(void *arg){
	struct espconn * T_arg = arg;		// 缓存网络连接结构体指针
	os_printf("\nESP8266_TCP_Disconnect_OK \r\n");


	// 连接 TCP server
	espconn_connect(&espconn_user);	// 连接TCP-server
}

八、总代码

直接替换SDK的user_main.c文件,清除缓存,重新进行编译下载即可。代码下载地址:https://download.csdn.net/download/qq_26043945/85312127

 类似资料: