ESP8266 从UDP到TCP

来源:互联网 发布:windows 预览计划 编辑:程序博客网 时间:2024/05/21 17:41

-1. UDP
- 1.1配置

(1)UDP连接,需要将模式改为0x03(station + soft-AP 模式)
(2)利用wifi_softap_get_config(struct softap_config* config)获取当前配置
(3)拷贝默认设置,os_memcpy(congfig.ssid,”*“,strlen(“*“))
os_memcpy(congfig.password,”#######”,strlen(“#######”))
(4)config.ssid_len=strlen(“ESP8266”)
(5)利用wifi_softap_set_config(struct softap_config *config)函数,将之前的配置放入函数 wifi_softap_set_config(&config)

  • 1.2通讯:

(1)wifi_set_broadcast_if(uint8 interface) uint8 interface:1(station) 2(soft-ap) 3(station+soft-ap)
用来设置发送UDP广播包时,是从什么接口发送
(2)UDP连接一定离不开连接字符串(参考手册6.4 espconn参数) 该字符串为结构体,设为:user_udp_espconn
user_udp_espconn.type=ESPCONN_UDP;
user_udp_espconn.proto.udp= (esp_udp*)os_zalloc(sizeof(esp_udp));
user_udp_espconn.proto.udp->local_port=2525;
user_udp_espconn.proto.udp->remote_port=1112;

 const char udp_remote_ip[1]={255,255,255,255};(这样可以连接到所以IP) os_memcpy(user_udp_espconn.proto.udp->remote_ip,udp_remote_ip) 以上参数为固定设置

(3)注册 接收回调函数
espconn_regist_recvcb(struct espconn *espconn,espconn_recv_callback recvcb)
(4)注册 发送回调函数
espconn_regist_sentcb(struct espconn *espconn,espconn_sent_callback sent_cb)
(5)建立UDP通信
espconn_create(user_udp_espconn)

 建立 接收回调函数:recv_callback recvcb 建立 发送回调函数:espconn_sent_callback sent_cb

(6)获取station的MAC地址
(7)发送数据
(8)发送成功后使用定时器继续发送
以下为代码:

#include "driver/uart.h"#include "user_main.h"void ICACHE_FLASH_ATTR user_udp_send(void){    char hwaddr[6];    char DeviceBuffer[40]={0};    wifi_get_macaddr(STATION_IF,hwaddr);    os_sprintf(DeviceBuffer,"设备MAC地址为"MACSTR"!!\r\n",MAC2STR(hwaddr));    espconn_sent(&user_udp_espconn,DeviceBuffer,os_strlen(DeviceBuffer));}void ICACHE_FLASH_ATTR user_udp_sent_cb(void *arg){os_printf("发送成功!");os_timer_disarm(&test_timer);os_timer_setfn(&test_timer,user_udp_send,NULL);os_timer_arm(&test_timer,1000,NULL);}void ICACHE_FLASH_ATTR user_udp_recv_cb(void *arg,char *pdata,unsigned short len){os_printf("udp已经接收数据:%s",pdata);}void ICACHE_FLASH_ATTR Wifi_conned(void *arg){static uint8 count=0;uint8 status;os_timer_disarm(&connect_timer);count++;status=wifi_station_get_connect_status();if(status==STATION_GOT_IP){os_printf("Wifi connect success!");wifi_set_broadcast_if(STATIONAP_MODE);user_udp_espconn.type=ESPCONN_UDP;user_udp_espconn.proto.udp=(esp_udp *)os_zalloc(sizeof(esp_udp));user_udp_espconn.proto.udp->local_port=2525;user_udp_espconn.proto.udp->remote_port=1112;const char udp_remote_ip[4]={255,255,255,255};os_memcpy(user_udp_espconn.proto.udp->remote_ip,udp_remote_ip,4);espconn_regist_recvcb(&user_udp_espconn,user_udp_recv_cb);espconn_regist_sentcb(&user_udp_espconn,user_udp_sent_cb);espconn_create(&user_udp_espconn);user_udp_send();return;}else{if(count>=7){os_printf("Wifi connect fail!");return;}}os_timer_arm(&connect_timer,2000,NULL);}void ICACHE_FLASH_ATTR scan_done(void *arg,STATUS status){    uint8 ssid[33];    struct station_config stationConf;      if (status == OK)      {        struct bss_info *bss_link = (struct bss_info *)arg;        bss_link = bss_link->next.stqe_next;//ignore first        while (bss_link != NULL)        {          os_memset(ssid, 0, 33);          if (os_strlen(bss_link->ssid) <= 32)          {            os_memcpy(ssid, bss_link->ssid, os_strlen(bss_link->ssid));          }          else          {            os_memcpy(ssid, bss_link->ssid, 32);          }          os_printf("+CWLAP:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n",                     bss_link->authmode, ssid, bss_link->rssi,                     MAC2STR(bss_link->bssid),bss_link->channel);          bss_link = bss_link->next.stqe_next;        }        os_memcpy(&stationConf.ssid, "TP-LINK", 32);        os_memcpy(&stationConf.password, "1122334455", 64);        wifi_station_set_config_current(&stationConf);        wifi_station_connect();        os_timer_setfn(&connect_timer,Wifi_conned,NULL);        os_timer_arm(&connect_timer,2000,NULL);      }}void to_scan(void) { wifi_station_scan(NULL,scan_done); }void user_init(){    struct softap_config config;uart_init(115200,115200);wifi_set_opmode(0x03);wifi_softap_get_config(&config);os_memcpy(config.ssid,"ESP8226",strlen("ESP8226"));os_memcpy(config.password,"123456789",strlen("123456789"));config.ssid_len=strlen("ESP8226");wifi_softap_set_config(&config);system_init_done_cb(to_scan);}void user_rf_pre_init(){}

-2. TCP
-2.1 TCP通信分类:

(1)station: TCP Client
(2)station: TCP Sever
(3)AP: TCP Client
(4)AP: TCP Sever

  • 2.2TCP Client模式:

(1)ESP8266工作在station模式下。需要确认ESP8266已经连接AP(路由)分配到地址IP,启用client连接
(2)ESP8266工作在softap模式下。需要确认连接ESP8266的设备已经被分配到地址IP,启用client连接
步骤:
(1)依据工作协议初始化espconn参数(初始化过程见UDP初始化过程)
(2)注册连接成功的回调函数和连接失败重连的回调函数
(调用espconn_regist_connectcb和espconn_regist_reconcb)
(3)调用espconn_connect建立与TCP Sever的连接
(4)TCP连接建立成功后,在连接的回调函数(espconn_regist_connectcb)中,注册接收数据的回调函数,发送数据成 功的回调函数和断开连接的回调函数
(espconn_regist_recvcb和espconn_regist_sentcb和espconn_regist_disconcb)
(5)在接收数据的回调函数或者发送数据成功的回调函数中,执行断开连接操作时,建议适当延时一定时间,确保底层函数执行结束。

#include "client.h"void ICACHE_FLASH_ATTR user_tcp_sent_cb(void *arg){    os_printf("发送数据成功!");}void ICACHE_FLASH_ATTR user_tcp_discon_cb(void *arg){    os_printf("断开连接成功!");}void ICACHE_FLASH_ATTR user_tcp_recv_cb(void *arg,        char *pdata,        unsigned short len){    os_printf("收到数据:%s\r\n",pdata);    os_delay_us(300);    espconn_disconnect((struct espconn *)arg);}void ICACHE_FLASH_ATTR user_tcp_recon_cb(void *arg, sint8 err){    os_printf("连接错误,错误代码为%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);     espconn_sent(pespconn,"这是esp8226",strlen("这是esp8226"));}void ICACHE_FLASH_ATTR my_station_init(struct ip_addr *remote_ip,struct ip_addr *local_ip,int remote_port){    //espconn参数配置    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);    //启用连接    espconn_connect(&user_tcp_conn);}
  • 2.3TCP Sever模式:

(1)ESP8266工作在station模式下。需要确认ESP8266已经分配到IP地址,再启用sever连接
(2)ESP8266工作在softap模式下,可以直接启用sever侦听
步骤:
步骤:
(1)依据工作协议初始化espconn参数(初始化过程见3.UDP)
(2)注册连接成功的回调函数和连接失败重连的回调函数 (调用espconn_regist_connectcb和espconn_regist_reconcb)
(3)调用espconn_regist侦听TCP连接(server_listen())
(4)TCP连接建立成功后,在侦听TCP连接的回调函数(server_listen())中注册接收数据的回调函数,发送数据 成功的回调函数和断开连接的回调函数
(espconn_regist_recvcb和espconn_regist_sentcb和espconn_regist_disconcb)

#include "server.h"void ICACHE_FLASH_ATTR server_recv(void *arg,        char *pdata,        unsigned short len){    os_printf("收到PC发来的数据:%s",pdata);    espconn_sent((struct espconn *)arg,"已经收到",strlen("已经收到"));}void ICACHE_FLASH_ATTR server_sent(void *arg){    os_printf("发送成功!");}void ICACHE_FLASH_ATTR server_discon*arg){    os_printf("连接已经断开!");}void ICACHE_FLASH_ATTR server_listen(void *arg){    struct espconn *pespconn=arg;    espconn_regist_recvcb(pespconn,server_recv);     espconn_regist_sentcb(pespconn,server_sent);     espconn_regist_disconcb(pespconn,server_discon);}void ICACHE_FLASH_ATTR server_recon(void *arg,sint8 err){    os_printf("连接错误,错误代码为:%d\r\n",err);}void ICACHE_FLASH_ATTR server_init(struct ip_addr *local_ip,int port){    LOCAL struct espconn esp_conn;    //初始化espconn参数    esp_conn.type=ESPCONN_TCP;    esp_conn.state=ESPCONN_NONE;    esp_conn.proto.tcp=(esp_tcp *)os_malloc(sizeof(esp_tcp));    os_memcpy(esp_conn.proto.tcp->local_ip,local_ip,4);    esp_conn.proto.tcp->local_port=port;    //注册连接成功回调函数和重新连接回调函数    espconn_regist_connectcb(&esp_conn,server_listen);    espconn_regist_reconcb(&esp_conn,server_recon);    espconn_accept(&esp_conn)

如果有任何疑问或者技术交流可以加我qq1279915333,告诉我来自CSDN,欢迎指教!

0 0
原创粉丝点击