终于开始接触网络了,基础不行,这个摸索了有点久,还好网上资料多,有些细节还是没有怎么吃透。哈哈,开始联网了。
ESP8266有三种模式:
简单的介绍一下这三个模式:
根据手册(手册是个好东西呀)总体思路是这样的:
wifi_set_opmode(0x03);//设置为soft-AP兼station模式
void to_scan(void) {
wifi_station_scan(NULL,scan_done);
}
wifi_station_connect();//在非user_init()入口函数中连接WiFi,需要调用这个函数
上代码
// 头文件引用
//==================================================================================
#include "user_config.h" // 用户配置
#include "driver/uart.h" // 串口
#include "c_types.h" // 变量类
#include "eagle_soc.h" // GPIO函数、宏定义
#include "ets_sys.h" // 回调函数
#include "os_type.h" // os_XXX
#include "osapi.h" // os_XXX、软件定时器
#include "user_interface.h" // 系统接口、system_param_xxx接口、WIFI、RateContro
#include "pwm.h"
#include "ip_addr.h"
#include "espconn.h"
#include "mem.h"
#include "smartconfig.h"
#include "airkiss.h"
//==================================================================================
ETSTimer connect_timer;
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!");
return;
}
else
{
if (count >= 7)
{
os_printf("Wifi connect fail!");
return;
}
}
os_timer_arm(&connect_timer, 2000, false);
}
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;
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;
}
//扫描完成以后就开始连接WiFi了
os_memcpy(&stationConf.ssid, "aaaaa", 32); //wifi名
os_memcpy(&stationConf.password, "123456789", 64); //wifi密码
wifi_station_set_config_current(&stationConf);
wifi_station_connect();
os_timer_setfn(&connect_timer, (ETSTimerFunc *)(Wifi_conned), NULL); //调用WiFi连接函数
os_timer_arm(&connect_timer, 2000, false);
}
else
{
os_printf("connect error!\n");
}
}
void to_scan(void) { wifi_station_scan(NULL, scan_done); }
void user_init()
{
uint8 opmode;
uart_init(115200, 115200);
wifi_set_opmode(0x03); //设置为soft-AP兼station模式
opmode = wifi_get_opmode_default(); //获取当前工作模式
os_printf("\r\n当前的工作模式:%d\r\n", opmode);
system_init_done_cb(to_scan); //注册系统初始化函数,等待系统初始化完成后扫描wifi
}
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void)
{
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map)
{
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
void ICACHE_FLASH_ATTR user_rf_pre_init(void) {}
void ICACHE_FLASH_ATTR user_init(void)
{
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, "12345678", strlen("12345678"));
config.ssid_len = strlen("ESP8266");
wifi_softap_set_config(&config);
}
现在就可以搜到“ESP8266”的wifi了。
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 = 2333;//本地端口
user_udp_espconn.proto.udp->remote_port = 1234;//远程端口
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, false);
}
配置发送和接收函数
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, (ETSTimerFunc *)(user_udp_send), NULL);
os_timer_arm(&test_timer, 1000, false); //每秒钟发送一次
}
void ICACHE_FLASH_ATTR user_udp_recv_cb(void *arg, char *pdata, unsigned short len) //接收回调函数
{
os_printf("UDP已经接收数据:%s", pdata); //UDP接收到的数据打印出来
}
注册udp函数,广播本机mac地址
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 "user_config.h" // 用户配置
#include "driver/uart.h" // 串口
#include "c_types.h" // 变量类
#include "eagle_soc.h" // GPIO函数、宏定义
#include "ets_sys.h" // 回调函数
#include "os_type.h" // os_XXX
#include "osapi.h" // os_XXX、软件定时器
#include "user_interface.h" // 系统接口、system_param_xxx接口、WIFI、RateContro
#include "pwm.h"
#include "ip_addr.h"
#include "espconn.h"
#include "mem.h"
#include "smartconfig.h"
#include "airkiss.h"
//==================================================================================
struct espconn user_udp_espconn;
ETSTimer connect_timer;
ETSTimer test_timer;
// 毫秒延时函数
//===========================================
void ICACHE_FLASH_ATTR delay_ms(u32 C_time)
{
for (; C_time > 0; C_time--)
os_delay_us(1000);
}
//===========================================
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, (ETSTimerFunc *)(user_udp_send), NULL);
os_timer_arm(&test_timer, 1000, false); //定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 = 2333;
user_udp_espconn.proto.udp->remote_port = 1234;
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, false);
}
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, "aaaaa", 32);
os_memcpy(&stationConf.password, "12345678", 64);
wifi_station_set_config_current(&stationConf);
wifi_station_connect();
os_timer_setfn(&connect_timer, Wifi_conned, NULL);
os_timer_arm(&connect_timer, 2000, false);
}
else
{
os_printf("connect error!\n");
}
}
void to_scan(void) { wifi_station_scan(NULL, scan_done); }
void ICACHE_FLASH_ATTR user_init(void)
{
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需要系统初始化完成之后
}
//=================================================================================================
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void)
{
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map)
{
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
void ICACHE_FLASH_ATTR user_rf_pre_init(void) {}