函数逻辑
设置串口速率
设置wifi模式
设置连接WiFi信息
连接路由器
启动定时器函数
检测状态
解析HTTP网址
返回数据
每隔一段时间启动定时器 更新数据
执行调用函数时须关闭定时器
user_main.c
#include "driver/uart.h"
#include "user_main.h"
os_timer_t checkTimer_wifistate;
void Check_WifiState(void) {
uint8 getState;
getState = wifi_station_get_connect_status();
//如果状态正确,证明已经成功连接到路由器
if (getState == STATION_GOT_IP) {
os_printf("WIFI连接成功!");
os_timer_disarm(&checkTimer_wifistate); //取消定时器定时
os_timer_disarm(&connect_timer);
uint8 status = wifi_station_get_connect_status();
if (status == STATION_GOT_IP) {
uart0_sendStr("WIFI连接成功!");
startHttpQuestByGET(
"https://api.seniverse.com/v3/weather/now.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c");
return;
}
}
}
void user_init() {
uart_init(57600, 57600);
wifi_set_opmode(0x01); //设置为STATION模式
struct station_config stationConf;
os_strcpy(stationConf.ssid, "IAmYourFather"); //改成你自己的 路由器的用户名
os_strcpy(stationConf.password, "666666666"); //改成你自己的 路由器的密码
wifi_station_set_config(&stationConf); //设置WiFi station接口配置,并保存到 flash
wifi_station_connect(); //连接路由器
os_timer_disarm(&checkTimer_wifistate); //取消定时器定时
os_timer_setfn(&checkTimer_wifistate, (os_timer_func_t *) Check_WifiState,
NULL); //设置定时器回调函数
os_timer_arm(&checkTimer_wifistate, 500, true); //启动定时器,单位:毫秒
os_printf("57600 end... \n\r");
}
void user_rf_pre_init()
{
}
示例:
void ICACHE_FLASH_ATTR
user_set_station_config(void)
{
char ssid[32] = SSID;
char password[64] = PASSWORD;
struct station_config stationConf;
stationConf.bssid_set = 0; //need not check MAC address of AP
os_memcpy(&stationConf.ssid, ssid, 32);
os_memcpy(&stationConf.password, password, 64);
wifi_station_set_config(&stationConf);
}
void user_init(void)
{
wifi_set_opmode(STATIONAP_MODE); //Set softAP + station mode
user_set_station_config();
}
my_http.c
#include "my_http.h"
#include "c_types.h"
#include "client.h"
//剖析URL
void ICACHE_FLASH_ATTR http_parse_request_url(char *URL, char *host,char *filename, unsigned short *port)
{
char *PA;
char *PB;
memset(host, 0, sizeof(host));//填充值 内存块指针 填充值 填充大小
memset(filename, 0, sizeof(filename));//填充值 内存块指针 填充值 填充大小
*port = 0;
if (!(*URL)){
uart0_sendStr("\r\n ----- URL return ----- \r\n");
return;
}
PA = URL;
if (!strncmp(PA, "http://", strlen("http://"))) //字符串比较函数 1 2 比较3的位数 如果相等 执行
{
PA = URL + strlen("http://");
}
else if (!strncmp(PA, "https://", strlen("https://")))
{
PA = URL + strlen("https://");
}
PB = strchr(PA, '/'); //字符串1为一个字符串的指针,字符2为一个待查找字符 该函数返回在字符串 str 中第一次出现字符2 的位置,如果未找到该字符则返回 NULL。
if (PB)
{
uart0_sendStr("\r\n ----- PB=true ----- \r\n");
memcpy(host, PA, strlen(PA) - strlen(PB)); //内存拷贝 目标内存块指针 拷贝内存大小
if (PB + 1) {
memcpy(filename, PB + 1, strlen(PB - 1));
filename[strlen(PB) - 1] = 0;
}
host[strlen(PA) - strlen(PB)] = 0;
uart0_sendStr(host,strlen(host));
}
else
{
uart0_sendStr("\r\n ----- PB=false ----- \r\n");
memcpy(host, PA, strlen(PA));
host[strlen(PA)] = 0;
uart0_sendStr(host,strlen(host));
}
PA = strchr(host, ':');
if (PA)
{
*port = atoi(PA + 1);
}
else
{
*port = 80;
}
}
//寻找DNS解析,并且配置
void ICACHE_FLASH_ATTR user_esp_dns_found(const char *name, ip_addr_t *ipaddr,void *arg)
{
struct ip_info info;
wifi_get_ip_info(STATION_IF, &info);
my_station_init(ipaddr, &info.ip, port);
}
//定义Get请求的实现
void ICACHE_FLASH_ATTR startHttpQuestByGET(char *URL)
{
struct ip_addr addr;
memset(buffer,0,1024); //填充值 内存块指针 填充值 填充大小
http_parse_request_url(URL,host,filename,&port); //HTTP解析
os_sprintf(buffer,GET,filename,host);//注释见后面
espconn_gethostbyname(&user_tcp_conn,host, &addr,
user_esp_dns_found);//注释见后面
}
//定义Post请求的实现
void ICACHE_FLASH_ATTR startHttpQuestByPOST(char *URL,char *method,char *postdata)
{
struct ip_addr addr;
memset(buffer,0,1024);
http_parse_request_url(URL,host,filename,&port);
os_sprintf(buffer,POST,filename,strlen(postdata),host,postdata);
espconn_gethostbyname(&user_tcp_conn,host, &addr,
user_esp_dns_found);
}
原型
os_sprintf( char *buffer, const char *format, [ argument] … );
参数列表
buffer:char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]…:可选参数,可以是任何类型的数据。
返回值
返回写入buffer 的字符数,出错则返回-1. 如果 buffer 或 format 是空指针,且不出错而继续,函数将返回-1,并且 errno 会被设置为 EINVAL。
sprintf 返回以format为格式argument为内容组成的结果被写入buffer 的字节数,结束字符‘\0’不计入内。即,如果“Hello”被写入空间足够大的buffer后,函数sprintf 返回5。 [1]
同时buffer的内容将被改变。
/****************************************************************************
*FunctionName:espconn_gethostbyname
*描述:将主机名(字符串)解析为IP地址。
*参数:pespconn——espconn解析主机名
-
hostname——要查询的主机名
扫描二维码关注公众号,回复: 4702324 查看本文章 -
addr——指向ip_addr_t的指针,如果
*它已经缓存在dns_table中(仅在ESPCONN_OK时有效)。
*返回!)
*.找到.——成功或失败时调用的回调函数
*或超时(仅当返回ERR_INPROGRESS时!)
*返回:err_t返回代码
*.–如果主机名是有效的IP地址字符串或主机,则ESPCONN_OK
*.name已经在本地名称表中。
*.–ESPCONN_INPROGRESS对要发送到DNS服务器的请求进行排队
*如果没有出现错误,则进行解析。
*-ESPCONN_ARG:dns客户端未初始化或主机名无效
*******************************************************************************/
err_t espconn_gethostbyname(struct espconnpespconn、const charhostname、ip_addr_t*addr、dns_find_callback.);
客户端
client.c
#include "client.h"
#include "iconv.h"
#include "stdio.h"
#include "string.h"
//成功接收到服务器返回数据函数
void ICACHE_FLASH_ATTR user_tcp_recv_cb(void *arg, char *pdata,
unsigned short len) {
uart0_sendStr("\r\n ----- 开始接受数据----- \r\n ");
uart0_tx_buffer(pdata, strlen(pdata));
uart0_sendStr("\r\n -----结束接受数据----- \r\n ");
}
//发送数据到服务器成功的回调函数
void ICACHE_FLASH_ATTR user_tcp_sent_cb(void *arg) {
uart0_sendStr("发送数据成功!\r\n ");
}
//断开服务器成功的回调函数
void ICACHE_FLASH_ATTR user_tcp_discon_cb(void *arg) {
uart0_sendStr("断开连接成功!\r\n ");
}
//连接失败的回调函数,err为错误代码
void ICACHE_FLASH_ATTR user_tcp_recon_cb(void *arg, sint8 err) {
uart0_sendStr("连接错误,错误代码为%d\r\n", err);
espconn_connect((struct espconn *) arg);
}
//成功连接到服务器的回调函数
void ICACHE_FLASH_ATTR user_tcp_connect_cb(void *arg) {
struct espconn *pespconn = arg;
espconn_regist_recvcb(pespconn, user_tcp_recv_cb);
espconn_regist_sentcb(pespconn, user_tcp_sent_cb);
espconn_regist_disconcb(pespconn, user_tcp_discon_cb);
uart0_sendStr("\r\n ----- 请求数据开始----- \r\n");
uart0_tx_buffer(buffer, strlen(buffer));
uart0_sendStr("\r\n -----请求数据结束----- \r\n");
espconn_sent(pespconn, buffer, strlen(buffer));
}
void ICACHE_FLASH_ATTR my_station_init(struct ip_addr *remote_ip,
struct ip_addr *local_ip, int remote_port) {
//配置
user_tcp_conn.type = ESPCONN_TCP;
user_tcp_conn.state = ESPCONN_NONE;
user_tcp_conn.proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp));
os_memcpy(user_tcp_conn.proto.tcp->local_ip, local_ip, 4); //目标内存块指针 源内存块指针 拷贝内存大小
os_memcpy(user_tcp_conn.proto.tcp->remote_ip, remote_ip, 4);
user_tcp_conn.proto.tcp->local_port = espconn_port(); //客户端的访问端口值,这样我们就不会跳转
user_tcp_conn.proto.tcp->remote_port = remote_port; //远程端口
//注册
espconn_regist_connectcb(&user_tcp_conn, user_tcp_connect_cb);//成功连接到服务器的回调函数
espconn_regist_reconcb(&user_tcp_conn, user_tcp_recon_cb); //连接失败的回调函数,err为错误代码
//连接服务器
espconn_connect(&user_tcp_conn);
}