程序實現內容:
1.在station模式下,ESP8266作為client、server進行TCP連接
2.實現數據的發送、接收(同時回傳)
實現思路:
TCP網絡通信分層為:應用層、網絡層、數據鏈路層、物理層;
1. 設置ESP8266為station模式,在數據鏈路層連接AP,獲取IP地址;
2. 在網絡層進行TCP連接:作為client連接遠程server,作為server監聽遠程client信息;
數據鏈路層:
1. 設置ESP8266為station模式:wifi_set_opmode(STATION_MODE);
2. 配置連接到AP的相關參數,在該步驟中,需要知道AP的名稱( ssid )、密碼( password ): 官方所給的SDK中,該配置執行后,wifi模塊自動與AP進行連接
1 void user_set_station_config(){ 2
3 struct station_config stationconf; 4
5 char ssid[32] = "Hello world"; 6 char password[64] = "chenyuping"; 7
8 stationconf.bssid_set = 0; 9 memset(stationconf.ssid, 0, sizeof(stationconf.ssid)); 10 memset(stationconf.password, 0, sizeof(stationconf.password)); 11
12 memcpy(stationconf.ssid, ssid, sizeof(ssid)); 13 memcpy(stationconf.password, password, sizeof(password)); 14
15 wifi_station_set_config(&stationconf); 16
17 return ; 18 }
為確保ESP8266已同AP建立穩定的連接並且已獲取到IP地址,可注冊該事件的回調函數進行判定:
1.注冊回調函數
1 wifi_set_event_handler_cb(wifi_handle_even_cb); 2
3 void wifi_handle_even_cb(System_Event_t *evt){ 4 switch(evt->event_id){ 5 case EVENT_STAMODE_GOT_IP: 6 flag_sta_conip = TRUE; 7 printf("Have got IP!!\n"); 8 break; 9 defaut: printf("Have'n got IP\n"); 10 break; 11 } 12 }
2.注冊定時器,對回調函數中的flag_sta_conip進行判定以確定是否已獲得IP地址
1 os_timer_disarm(&ser_timer); 2 os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL); 3 os_timer_arm(&ser_timer, 900, 0); 4
5 os_timer_disarm(&cli_timer); 6 os_timer_setfn(&cli_timer, espconn_cli_timer_cb, NULL); 7 os_timer_arm(&cli_timer, 500, 0);
網絡層:
1. 檢測ESP8266是否已同AP建立穩定連接,若是,則開始建立TCP client連接:
1 void espconn_cli_timer_cb(void *timer_arg) 2 { 3 struct ip_info ipconfig; 4
5 os_timer_disarm(&cli_timer); 6 wifi_get_ip_info(STATION_IF, &ipconfig); 7
8 if (flag_sta_conip){ 9 printf("connect successful !!!\n"); 10 espconn_tcp_client_connect(); 11 } 12 else { 13 printf("connect fail !!!\n"); 14 os_timer_setfn(&cli_timer, espconn_cli_timer_cb, NULL); 15 os_timer_arm(&cli_timer, 500, 0); 16 } 17 }
建立TCP client連接(在該設置中,需要知道遠程server的IP地址及端口號),同時注冊連接、收發數據的回調函數:
1 void espconn_tcp_client_connect(){ 2
3 user_tcp_conn.proto.tcp = &user_tcp; 4 user_tcp_conn.type = ESPCONN_TCP; 5 user_tcp_conn.state = ESPCONN_NONE; 6
7 const char esp_tcp_server_ip[4] = {192, 168, 31, 155}; // remote IP of TCP server
8
9 memcpy(user_tcp_conn.proto.tcp->remote_ip, esp_tcp_server_ip, 4); 10 user_tcp_conn.proto.tcp->remote_port = 9003; 11
12 espconn_regist_connectcb(&user_tcp_conn, espconn_connect_cb); 13 espconn_regist_reconcb(&user_tcp_conn, espconn_reconnect_cb); 14
15 espconn_regist_sentcb(&user_tcp_conn, espconn_sent_cb); 16 espconn_regist_recvcb(&user_tcp_conn, espconn_recv_data_cb); 17
18 espconn_connect(&user_tcp_conn); 19
20 }
2. ESP8266開啟server服務(在該步驟中,通過對espconn_accept()函數返回值的判定,TRUE則關閉設置server開啟的定時器,FALSE則繼續保持開通,直到開啟成功)
1 void espconn_ser_timer_cb(void *timer_arg) 2 { 3 user_tcp_conn.proto.tcp = &user_tcp; 4 user_tcp_conn.type = ESPCONN_TCP; 5 user_tcp_conn.state = ESPCONN_NONE; 6
7 os_timer_disarm(&ser_timer); 8
9 user_tcp_conn.proto.tcp->local_port = espconn_port(); 10 printf("The local port is %d\n",user_tcp_conn.proto.tcp->local_port); 11
12 sint8 ret = espconn_accept(&user_tcp_conn); 13 printf("%d\n", ret); 14 if(!ret){ 15 printf("Begin to listen!!!\n"); 16 } 17 else{ 18 printf("Fail to listen!!!\n"); 19 os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL); 20 os_timer_arm(&ser_timer, 900, 0); 21 } 22 }
接收數據的回調函數:
1 espconn_regist_recvcb(&user_tcp_conn, espconn_recv_data_cb); 2
3 void espconn_recv_data_cb(void *arg, char *pdata, unsigned short len) 4 { 5 uint8 *pDat; 6 const char str[] = "Light ON"; 7
8 pDat = (uint8 *)malloc(len + 1); 9 memcpy(pDat, pdata, len); 10 *(pDat+len) = 0; 11 // pDat[len] = 0;
12
13 printf("The receiver data is %s",pDat); 14 printf("\n\n"); 15
16 if(memcmp(pDat, str, sizeof(str)) == 0) { 17 printf("Now Light is Run!\n"); 18 espconn_send(&user_tcp_conn, "Now Light is Run!\n", 18); 19 } 20
21 free(pDat); 22 }
發送數據的回調函數:
1 espconn_regist_sentcb(&user_tcp_conn, espconn_sent_cb); 2
3 void espconn_ser_timer_cb(void *timer_arg) 4 { 5 user_tcp_conn.proto.tcp = &user_tcp; 6 user_tcp_conn.type = ESPCONN_TCP; 7 user_tcp_conn.state = ESPCONN_NONE; 8
9 os_timer_disarm(&ser_timer); 10 user_tcp_conn.proto.tcp->local_port = espconn_port(); 11 printf("The local port is %d\n",user_tcp_conn.proto.tcp->local_port); 12
13 sint8 ret = espconn_accept(&user_tcp_conn); 14 printf("%d\n", ret); 15 if(!ret){ 16 printf("Begin to listen!!!\n"); 17 } 18 else{ 19 printf("Fail to listen!!!\n"); 20 os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL); 21 os_timer_arm(&ser_timer, 900, 0); 22 } 23 }
實現效果: