|
本帖最后由 vany5921 于 2020-7-3 14:22 编辑
简单来说,ESP-NOW是乐鑫自主研发的一种基于WiFi的无线通讯技术,借助自身的STA/AP进行连接,特别适合建立快速连接,传输短数据。在ESP32的ESP-NOW协议中有主从机的定义,但在实际使用中除了建立连接外没有明确的主从机关系,双方是对等的,都可具备双向收发能力。在ESP-NOW中有几项是需要明确的,1、主机的mac地址 2、保证主从机在同一个信道 3、是否需要加密 4、从机的MAC地址或者广播。了解了以上4项,使用ESP-NOW是很简单的,基本上就是添加主机/从机,添加发送回调函数,发送成功回调函数,接收回调函数。以下将使用M5StackCore和M5StickC来进行通讯实验,M5StickC用于主机,M5StackCore用于从机,双方可以互发消息,也可以单独指定主发从收。
从机收发程序
- #include <WiFi.h>
- #include <M5Stack.h>
- #define WIFI_CHANNEL 1 //设置通信信道
- uint8_t masterDeviceMac[] = {0xD8, 0xA0, 0x1D, 0x55, 0x27, 0xA0}; //添加主机MAC地址
- esp_now_peer_info_t master; //声明一个主机类型
- const esp_now_peer_info_t *masterNode = &master;
- const byte maxDataFrameSize = 250; //ESP-NOW最大支持250字节
- uint8_t dataToSend[maxDataFrameSize]; //消息数组
- byte cnt=0;
- void setup()
- {
- M5.begin(true, false, true);
- Serial.print("\r\n\r\n");
- WiFi.mode(WIFI_AP); //从机通常设置为AP模式
- M5.Lcd.print(WiFi.softAPmacAddress()); //获取本机MAC地址
- Serial.println( WiFi.softAPmacAddress() );
- WiFi.disconnect();
- if(esp_now_init() == ESP_OK) //初始化ESP-NOW服务
- {
- Serial.println("ESPNow Init Success!");
- }
- else
- {
- Serial.println("ESPNow Init Failed....");
- }
- //Add the master node to this slave node
- memcpy( &master.peer_addr, &masterDeviceMac, 6 ); //添加主机到从机节点
- master.channel = WIFI_CHANNEL;
- master.encrypt = 0;
- master.ifidx = ESP_IF_WIFI_AP;
- //Add the remote master node to this slave node
- if( esp_now_add_peer(masterNode) == ESP_OK)
- {
- Serial.println("Added Master Node!");
- }
- else
- {
- Serial.println("Master Node could not be added...");
- }
-
- esp_now_register_recv_cb(OnDataRecv); //接收回调函数
- esp_now_register_send_cb(OnDataSent); //发送回调函数
-
- }
- void loop()
- {
- yield();
- }
- void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) //接收数据
- {
- M5.Lcd.fillRect(0, 40, 320, 240, TFT_BLACK);
- memcpy( dataToSend, data, data_len );
- esp_now_send(master.peer_addr, dataToSend, maxDataFrameSize);
- Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
- M5.Lcd.setCursor(0, 40, 2);
- M5.Lcd.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
- Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
- }
- void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) //发送数据
- {
- Serial.print("\r\nLast Packet Send Status:\t");
- Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
- }
复制代码
主机收发程序
- #include <esp_now.h>
- #include <WiFi.h>
- #include <M5StickC.h>
- #define WIFI_CHANNEL 1
- esp_now_peer_info_t slave;
- //uint8_t remoteMac[] = {0xA4, 0xCF, 0x12, 0x6D, 0x6A, 0xD1}; //从机MAC地址
- uint8_t remoteMac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //广播MAC地址
- const uint8_t maxDataFrameSize=250;
- const esp_now_peer_info_t *peer = &slave;
- uint8_t dataToSend[maxDataFrameSize];
- byte cnt=0;
- long timers[3];
- void setup()
- {
- M5.begin();
- M5.Lcd.setRotation(1);
- Serial.print("\r\n\r\n");
-
- WiFi.mode(WIFI_STA);
- M5.Lcd.print(WiFi.softAPmacAddress());
- Serial.println( WiFi.macAddress() );
- WiFi.disconnect();
- if(esp_now_init() == ESP_OK)
- {
- Serial.println("ESP NOW INIT!");
- }
- else
- {
- Serial.println("ESP NOW INIT FAILED....");
- }
-
- memcpy( &slave.peer_addr, &remoteMac, 6 ); //添加从机
- slave.channel = WIFI_CHANNEL;
- slave.encrypt = 0;
- if( esp_now_add_peer(peer) == ESP_OK)
- {
- Serial.println("Added Peer!");
- }
- esp_now_register_send_cb(OnDataSent); //发送回调函数
- esp_now_register_recv_cb(OnDataRecv); //接收回调函数
- }
- void loop()
- {
- for(cnt=0; cnt<maxDataFrameSize; cnt++)
- {
- dataToSend[cnt]++;
- }
- if( esp_now_send(slave.peer_addr, dataToSend, maxDataFrameSize) == ESP_OK)
- {
- timers[0] = micros();
- Serial.printf("\r\nSuccess Sent Value->\t%d", dataToSend[0]);
- M5.Lcd.setCursor(0, 20, 2);
- M5.Lcd.printf("\r\nSuccess Sent Value->\t%d", dataToSend[0]);
- M5.Lcd.println();
- }
- else
- {
- Serial.printf(".");
- }
- delay(1000);
- M5.Lcd.fillRect(0, 20, 160, 80, TFT_BLACK);
- }
- void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
- {
- Serial.print("\r\nLast Packet Send Status:\t");
- Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
- }
- void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)
- {
- if(data[0] == dataToSend[0])
- {
- timers[1] = micros();
- timers[2] = timers[1]-timers[0];
- Serial.printf("\r\nReceived\t%d Bytes val\t%d\tin %d micros", data_len, data[0], timers[2]);
- }
- else
- {
- Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
- }
- }
复制代码 ---------------------------------------------------------------
从机只接收
- #include <M5Stack.h>
- #include <esp_now.h>
- #include <WiFi.h>
- #define WIFI_CHANNEL 1
- //uint8_t localCustomMac[] = {0xD8, 0xA0, 0x1D, 0x55, 0x27, 0xA0};
- const byte maxDataFrameSize = 200;
- byte cnt=0;
- void setup()
- {
- M5.begin(true, false, true);
- // Serial.begin(115200);
- Serial.print("\r\n\r\n");
- WiFi.mode(WIFI_AP);
- Serial.println( WiFi.softAPmacAddress() );
- M5.Lcd.setCursor(0, 0, 2);
- M5.Lcd.print("MAC: ");
- M5.Lcd.print(WiFi.softAPmacAddress());
- M5.Lcd.printf(" CHANNEL:%d",WIFI_CHANNEL);
- WiFi.disconnect();
- if(esp_now_init() == ESP_OK)
- {
- Serial.println("ESPNow Init Success!");
- }
- else
- {
- Serial.println("ESPNow Init Failed....");
- }
- esp_now_register_recv_cb(OnDataRecv);
-
- }
- void loop()
- {
- yield();
- }
- void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)
- {
- Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
- M5.Lcd.fillRect(0, 20, 320, 220, TFT_BLACK);
- M5.Lcd.setCursor(0, 20, 2);
- M5.Lcd.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
- }
复制代码
主机只发送
- #include <M5StickC.h>
- #include <esp_now.h>
- #include <WiFi.h>
- #define WIFI_CHANNEL 1
- esp_now_peer_info_t slave;
- //uint8_t remoteMac[] = {0xA4, 0xCF, 0x12, 0x6D, 0x6A, 0xD1}; //从机地址
- uint8_t remoteMac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //广播地址
- const uint8_t maxDataFrameSize=200;
- const esp_now_peer_info_t *peer = &slave;
- uint8_t dataToSend[maxDataFrameSize];
- byte cnt=0;
- void setup()
- {
- M5.begin();
- M5.Lcd.setRotation(1);
- Serial.begin(115200);
- Serial.print("\r\n\r\n");
-
- WiFi.mode(WIFI_STA);
- M5.Lcd.print("MAC:");
- M5.Lcd.println(WiFi.softAPmacAddress());
- M5.Lcd.printf("CHANNEL:%d", WIFI_CHANNEL);
- M5.Lcd.println();
- Serial.println(WiFi.softAPmacAddress());
- WiFi.disconnect();
- if(esp_now_init() == ESP_OK)
- {
- Serial.println("ESP NOW INIT!");
- }
- else
- {
- Serial.println("ESP NOW INIT FAILED....");
- }
-
-
- memcpy( &slave.peer_addr, &remoteMac, 6 );
- slave.channel = WIFI_CHANNEL;
- slave.encrypt = 0;
- if( esp_now_add_peer(peer) == ESP_OK)
- {
- Serial.println("Added Peer!");
- M5.Lcd.println("Added Peer!");
- }
- esp_now_register_send_cb(OnDataSent);
- }
- void loop()
- {
- for(cnt=0; cnt<maxDataFrameSize; cnt++)
- {
- dataToSend[cnt]++;
- }
- if( esp_now_send(slave.peer_addr, dataToSend, maxDataFrameSize) == ESP_OK)
- {
- Serial.printf("\r\nSuccess Sent Value->\t%d", dataToSend[0]);
- M5.Lcd.fillRect(0, 30, 160, 40, TFT_BLACK);
- M5.Lcd.setCursor(0, 30, 2);
- M5.Lcd.printf("\r\nSuccess Sent Value->\t%d", dataToSend[0]);
- }
- else
- {
- Serial.printf("\r\nDID NOT SEND....");
- }
- delay(250);
- }
- void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
- {
- Serial.print("\r\nLast Packet Send Status:\t");
- Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
- }
复制代码
|
|