ESP8266--學習筆記(三)AP和UDP通訊
阿新 • • 發佈:2019-01-22
ESP8266可以配置三種模式:
- station模式 : 0x01
- soft-AP模式 : 0x02
- soft-AP兼station模式 : 0x03
1、station模式
station模式可以連線其他的路由器,不能被其他的裝置連線。
2、soft-AP模式
AccessPoint即網路接入點,可以看成是路由器模式,即可以讓其他的WiFi裝置連線本模組,但是模組自己就不能連線其他的路由器。
3、station+soft-AP模式
可以看成是station和soft-AP的混合模式,即模組本身自己可以連線其他的路由器也可以被其他的裝置連線。這個模式是主要的使用模式,因為可以實現真正的路由器功能。
一、soft-AP的配置
配置流程
- 將ESP8266配置成“station+soft-AP模式”
- 使用wifi_softap_get_config獲取當前ap配置
- 更改配置引數ssid和password分別為“ESP8266”和“123456789”
- 使用wifi_softap_set_config設定ap引數
void user_init(){
struct softap_config config;//首先定義一個soft_config的結構體
uint8 opmode;
uart_init(115200,115200);
wifi_set_opmode(0x03 );//設定為AP模式
opmode = wifi_get_opmode_default();
os_printf("\r\n當前的工作模式:%d\r\n",opmode);
wifi_softap_get_config(&config);//這個函式的引數是soft_config的結構體,記得取地址
os_memcpy(config.ssid,"ESP8266",strlen("ESP8266"));//往結構體裡面初始化配置,呼叫os_memcpy函式
os_memcpy(config.password,"123456789",strlen("123456789" ));
config.ssid_len = strlen("ESP8266");
wifi_softap_set_config(&config);//完成AP模式的引數配置,記得取地址
}
然後開啟手機,就可以在WiFi搜尋裡面看到“ESP8266”了!
二、UDP通訊
配置流程
- 設定遠端IP地址為“255.255.255.255”
- 設定遠端埠為:1112
- 設定本地埠為:2525
- 註冊接收回調函式
- 註冊傳送回撥函式
- 建立UDP通訊
- 獲取station的MAC地址
- 傳送資料
- 傳送成功後使用定時器繼續傳送
一、在前面的連線WiFi程式碼基礎上進行修改Wifi_conned函式,完成基本的UDP通訊配置
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成功
wifi_set_broadcast_if(STATIONAP_MODE);//設定UDP廣播的傳送介面station+soft-AP模式傳送
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};//用於存放遠端IP地址
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);//建立UDP連線
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 user_udp_sent_cb(void *arg){//傳送回撥函式
os_printf("\r\nUDP傳送成功!\r\n");
os_timer_disarm(&test_timer);//定個時傳送
os_timer_setfn(&test_timer,user_udp_send,NULL);
os_timer_arm(&test_timer,1000,NULL);//定1秒鐘傳送一次
}
void ICACHE_FLASH_ATTR user_udp_recv_cb(void *arg,
char *pdata,
unsigned short len){//接收回調函式
os_printf("UDP已經接收資料:%s",pdata);//UDP接收到的資料打印出來
}
三、註冊UDP通訊函式,實際上我只是將本機的MAC地址進行UDP廣播
void ICACHE_FLASH_ATTR user_udp_send(void){//UDP傳送函式
char yladdr[6];
char DeviceBuffer[40]={0};//將獲取的MAC地址格式化輸出到一個buffer裡面
wifi_get_macaddr(STATION_IF,yladdr);//查詢MAC地址
os_sprintf(DeviceBuffer,"裝置地址為"MACSTR"!!!\r\n",MAC2STR(yladdr));//格式化MAC地址
espconn_sent(&user_udp_espconn,DeviceBuffer,os_strlen(DeviceBuffer));
}
四、所有程式碼
#include "osapi.h"
#include "ets_sys.h"
#include "driver/uart.h"
#include "user_interface.h"
#include "espconn.h"
#include "mem.h"
struct espconn user_udp_espconn;
ETSTimer connect_timer;
ETSTimer test_timer;
void ICACHE_FLASH_ATTR user_udp_send(void){//UDP傳送函式
char yladdr[6];
char DeviceBuffer[40]={0};//將獲取的MAC地址格式化輸出到一個buffer裡面
wifi_get_macaddr(STATION_IF,yladdr);//查詢MAC地址
os_sprintf(DeviceBuffer,"裝置地址為"MACSTR"!!!\r\n",MAC2STR(yladdr));//格式化MAC地址
espconn_sent(&user_udp_espconn,DeviceBuffer,os_strlen(DeviceBuffer));
}
void ICACHE_FLASH_ATTR user_udp_sent_cb(void *arg){//傳送回撥函式
os_printf("\r\nUDP傳送成功!\r\n");
os_timer_disarm(&test_timer);//定個時傳送
os_timer_setfn(&test_timer,user_udp_send,NULL);
os_timer_arm(&test_timer,1000,NULL);//定1秒鐘傳送一次
}
void ICACHE_FLASH_ATTR user_udp_recv_cb(void *arg,
char *pdata,
unsigned short len){//接收回調函式
os_printf("UDP已經接收資料:%s",pdata);//UDP接收到的資料打印出來
}
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成功
wifi_set_broadcast_if(STATIONAP_MODE);//設定UDP廣播的傳送介面station+soft-AP模式傳送
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};//用於存放遠端IP地址
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);//建立UDP連線
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];
char temp[128];
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_sprintf(temp,"+CWLAP:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n",
bss_link->authmode, ssid, bss_link->rssi,
MAC2STR(bss_link->bssid),bss_link->channel);
os_printf("%s",temp);
bss_link = bss_link->next.stqe_next;
}
os_memcpy(&stationConf.ssid, "MERCURY_2784", 32);
os_memcpy(&stationConf.password, "123456789", 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);
}
else
{
// os_sprintf(temp,"err, scan status %d\r\n", status);
// uart0_sendStr(temp);
os_printf("%s","Error");
}
}
void to_scan(void) { wifi_station_scan(NULL,scan_done); }
void user_init(){
struct softap_config config;
uint8 opmode;
uart_init(115200,115200);
wifi_set_opmode(0x03);//設定為AP模式
opmode = wifi_get_opmode_default();
os_printf("\r\n當前的工作模式:%d\r\n",opmode);
wifi_softap_get_config(&config);
os_memcpy(config.ssid,"ESP8266",strlen("ESP8266"));
os_memcpy(config.password,"123456789",strlen("123456789"));
config.ssid_len = strlen("ESP8266");
wifi_softap_set_config(&config);
system_init_done_cb(to_scan);//掃描WiFi需要系統初始化完成之後
}
void user_rf_pre_init(){
}
效果:
- 必須成功地連上有用的WIFi
- 配置好TCP/UDP測試工具軟體
手機APP也可以做到