- #include <esp_now.h>
- #include <WiFi.h>
- #include <esp_wifi.h>
- //定义开发板载LED
- #define LED4 12
- #define LED5 13
- //定义通信通道宏,指定在通道1通信
- #define CHANNEL 1
- // Global copy of slave
- esp_now_peer_info_t slave;
- esp_err_t addStatus;
- //发送回调函数,即发送完成后通过该函数返回相关的地址与状态
- void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
- {
- for(int i = 0; i<6 ; i++ )
- {
- Serial.print("0x");Serial.print(*(mac_addr+i) , HEX);Serial.print(" ");
- }
- Serial.println();
- if( status == ESP_NOW_SEND_SUCCESS )
- {
- Serial.println("ESP_NOW_SEND_SUCCESS"); //0是成功,1是失败
- digitalWrite(LED4,!digitalRead(LED4));
- }
- }
- void setup()
- {
- pinMode( LED4 , OUTPUT );
- pinMode( LED5 , OUTPUT );
- digitalWrite(LED4,LOW);
- digitalWrite(LED5,LOW);
- Serial.begin(115200);
- WiFi.mode(WIFI_STA);
- esp_err_t erro = esp_wifi_set_channel(CHANNEL, WIFI_SECOND_CHAN_NONE);
- Serial.println("ESP_NOW_DEMO");
- Serial.print("esp_wifi_set_channel:");
- switch (erro)
- {
- case ESP_OK:Serial.println("succeed");
- break;
- case ESP_ERR_WIFI_NOT_INIT:Serial.println("WiFi is not initialized by esp_wifi_init");
- break;
- case ESP_ERR_WIFI_IF:Serial.println("invalid interface");
- break;
- case ESP_ERR_INVALID_ARG:Serial.println("invalid argument");
- break;
- }
- Serial.print("STA MAC: "); Serial.println(WiFi.macAddress());
- Serial.print("STA CHANNEL "); Serial.println(WiFi.channel());
- //初始化ESP-NOW
- if(esp_now_init() == ESP_OK)
- {
- Serial.println("ESPNow Init Success");
- }
- else
- {
- Serial.println("ESPNow Init Failed");
- ESP.restart();
- }
- // Once ESP-Now is successfully Init, we will register for Send CB to
- // get the status of Trasnmitted packet
- esp_now_register_send_cb(OnDataSent);
- int16_t scanResults = WiFi.scanNetworks(false,false,false,300,CHANNEL);
- Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices ");
- for (int i = 0; i < scanResults; ++i)
- {
- // Print SSID and RSSI for each device found
- String SSID = WiFi.SSID(i);
- int32_t RSSI = WiFi.RSSI(i);
- String BSSIDstr = WiFi.BSSIDstr(i);
- Serial.print(i + 1);Serial.print(": ");
- Serial.print(SSID);//热点名字
- Serial.print(" (");Serial.print(RSSI);Serial.print(") ");//热点信号强度
- Serial.print(" [");Serial.print(BSSIDstr);Serial.println("] ");//热点物理地址
- Serial.println(BSSIDstr.c_str());
- // Check if the current device starts with `Slave`
- if (SSID.indexOf("Slave") == 0)
- {
- // SSID of interest
- Serial.println("Found a Slave.");
- Serial.print(i + 1); Serial.print(": "); Serial.print(SSID);
- Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]");
- Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println("");
- // Get BSSID => Mac Address of the Slave
- int mac[6];
- if( 6== sscanf(BSSIDstr.c_str(), "%2x:%2x:%2x:%2x:%2x:%2x",&mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5] ))
- {
- Serial.print("<");
- for( int i = 0 ; i<6 ; i++ )
- {
- slave.peer_addr[i] = (uint8_t)mac[i];
- Serial.print(slave.peer_addr[i]);Serial.print(" ");
- }
- Serial.println(">");
- slave.channel = CHANNEL; // pick a channel,选择一个信道
- slave.encrypt = 0; // no encryption,不加密
- }
- }
- }
- addStatus = esp_now_add_peer( &slave );
- }
- uint8_t data = 0;
- void loop()
- {
- // put your main code here, to run repeatedly:
- data++;
- const uint8_t *peer_addr = slave.peer_addr;
- if(addStatus == ESP_OK)
- {
- esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data));
- Serial.print("Send Status: ");
- if (result == ESP_OK)
- {
- Serial.println("Success");
- }
- else
- {
- Serial.println("Error");
- }
- }
- delay(3000);
- }
该例子,通过主动发现存在的指定通道的热点,然后逐个判断是否是想要的那些,然后找到目标后,对该目标发送一个变量,根据需要可以将发送内容改成别的内容,可以是字符串,可以是结构体。。。
下面是接收端代码
- #include <esp_now.h>
- #include <WiFi.h>
- #include <esp_wifi.h>
- //定义开发板载LED
- #define LED4 12
- #define LED5 13
- //定义通信通道宏,指定在通道1通信
- #define CHANNEL 1
- // callback when data is recv from Master,回调返回的变量为发送设备的MAC地址,传输来的数据,数据包的长度
- void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)
- {
- char macStr[18];
- snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
- mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
- Serial.print("Last Packet Recv from: "); Serial.println(macStr);
- Serial.print("Last Packet Recv Data: "); Serial.println(*data);
- Serial.print("Last Packet Recv len:"); Serial.println(data_len);
- Serial.println("");
-
- digitalWrite(LED4,!digitalRead(LED4));
- if(*data%2 == 0)
- {
- digitalWrite(LED5,!digitalRead(LED5));
- }
-
- }
- void setup()
- {
- // put your setup code here, to run once:
- pinMode( LED4 , OUTPUT );
- pinMode( LED5 , OUTPUT );
- digitalWrite(LED4,LOW);
- digitalWrite(LED5,LOW);
- Serial.begin(115200);
- WiFi.mode(WIFI_AP);
- const char *SSID = "Slave_A";
- bool result = WiFi.softAP(SSID,"Slave_A_Password",CHANNEL,0);
- if(!result)
- {
- Serial.println("Ap Config failed.");
- }
- else
- {
- Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
- Serial.print("AP CHANNEL "); Serial.println(WiFi.channel());
- }
- // This is the mac address of the Slave in AP Mode
- Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
- WiFi.disconnect();
- //初始化ESP-NOW
- if(esp_now_init() == ESP_OK)
- {
- Serial.println("ESPNow Init Success");
- }
- else
- {
- Serial.println("ESPNow Init Failed");
- ESP.restart();
- }
- // Once ESPNow is successfully Init, we will register for recv CB to
- // get recv packer info.
- esp_now_register_recv_cb(OnDataRecv);
- }
- void loop()
- {
- // put your main code here, to run repeatedly:
- }
通过接收回调函数可以获取到发送者的MAC地址,以及发送的数据和数据长度。
该例子中根据接收的内容控制两个LED的亮灭。用于远距离测试时候作为指示标志。
本人经过接收器插入一个移动电源,在楼内走动,发现穿墙能力非常的强大,值的学习。