查看: 3900|回复: 1

ESP-NOW在Arduino中的使用

[复制链接]

该用户从未签到

发表于 2020-7-2 18:13 | 显示全部楼层 |阅读模式
本帖最后由 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用于从机,双方可以互发消息,也可以单独指定主发从收。
从机收发程序

  1. #include <WiFi.h>
  2. #include <M5Stack.h>

  3. #define WIFI_CHANNEL 1 //设置通信信道

  4. uint8_t masterDeviceMac[] = {0xD8, 0xA0, 0x1D, 0x55, 0x27, 0xA0}; //添加主机MAC地址
  5. esp_now_peer_info_t master; //声明一个主机类型
  6. const esp_now_peer_info_t *masterNode = &master;
  7. const byte maxDataFrameSize = 250;  //ESP-NOW最大支持250字节
  8. uint8_t dataToSend[maxDataFrameSize]; //消息数组
  9. byte cnt=0;

  10. void setup()
  11. {
  12.   M5.begin(true, false, true);
  13.   Serial.print("\r\n\r\n");
  14.   WiFi.mode(WIFI_AP);  //从机通常设置为AP模式
  15.   M5.Lcd.print(WiFi.softAPmacAddress()); //获取本机MAC地址
  16.   Serial.println( WiFi.softAPmacAddress() );
  17.   WiFi.disconnect();
  18.   if(esp_now_init() == ESP_OK) //初始化ESP-NOW服务
  19.   {
  20.     Serial.println("ESPNow Init Success!");
  21.   }
  22.   else
  23.   {
  24.     Serial.println("ESPNow Init Failed....");
  25.   }

  26.   //Add the master node to this slave node
  27.   memcpy( &master.peer_addr, &masterDeviceMac, 6 ); //添加主机到从机节点
  28.   master.channel = WIFI_CHANNEL;
  29.   master.encrypt = 0;
  30.   master.ifidx = ESP_IF_WIFI_AP;
  31.   //Add the remote master node to this slave node
  32.   if( esp_now_add_peer(masterNode) == ESP_OK)
  33.   {
  34.     Serial.println("Added Master Node!");
  35.   }
  36.   else
  37.   {
  38.     Serial.println("Master Node could not be added...");
  39.   }
  40.   
  41.   esp_now_register_recv_cb(OnDataRecv);  //接收回调函数
  42.   esp_now_register_send_cb(OnDataSent); //发送回调函数
  43.   
  44. }

  45. void loop()
  46. {
  47. yield();
  48. }

  49. void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)  //接收数据
  50. {
  51.   M5.Lcd.fillRect(0, 40, 320, 240, TFT_BLACK);
  52.   memcpy( dataToSend, data, data_len );  
  53.   esp_now_send(master.peer_addr, dataToSend, maxDataFrameSize);
  54.   Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
  55.   M5.Lcd.setCursor(0, 40, 2);
  56.   M5.Lcd.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
  57.   Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
  58. }

  59. void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)  //发送数据
  60. {
  61.   Serial.print("\r\nLast Packet Send Status:\t");
  62.   Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
  63. }
复制代码



主机收发程序
  1. #include <esp_now.h>
  2. #include <WiFi.h>
  3. #include <M5StickC.h>

  4. #define WIFI_CHANNEL 1
  5. esp_now_peer_info_t slave;

  6. //uint8_t remoteMac[] = {0xA4, 0xCF, 0x12, 0x6D, 0x6A, 0xD1};  //从机MAC地址
  7. uint8_t remoteMac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};  //广播MAC地址
  8. const uint8_t maxDataFrameSize=250;
  9. const esp_now_peer_info_t *peer = &slave;
  10. uint8_t dataToSend[maxDataFrameSize];
  11. byte cnt=0;
  12. long timers[3];

  13. void setup()
  14. {
  15.   M5.begin();
  16.   M5.Lcd.setRotation(1);
  17.   Serial.print("\r\n\r\n");
  18.   
  19.   WiFi.mode(WIFI_STA);
  20.   M5.Lcd.print(WiFi.softAPmacAddress());
  21.   Serial.println( WiFi.macAddress() );
  22.   WiFi.disconnect();
  23.   if(esp_now_init() == ESP_OK)
  24.   {
  25.     Serial.println("ESP NOW INIT!");
  26.   }
  27.   else
  28.   {
  29.     Serial.println("ESP NOW INIT FAILED....");
  30.   }
  31.   
  32.   memcpy( &slave.peer_addr, &remoteMac, 6 ); //添加从机
  33.   slave.channel = WIFI_CHANNEL;
  34.   slave.encrypt = 0;
  35.   if( esp_now_add_peer(peer) == ESP_OK)
  36.   {
  37.     Serial.println("Added Peer!");
  38.   }

  39.   esp_now_register_send_cb(OnDataSent);  //发送回调函数
  40.   esp_now_register_recv_cb(OnDataRecv);  //接收回调函数
  41. }

  42. void loop()
  43. {
  44.   for(cnt=0; cnt<maxDataFrameSize; cnt++)
  45.   {
  46.     dataToSend[cnt]++;
  47.   }
  48.   if( esp_now_send(slave.peer_addr, dataToSend, maxDataFrameSize) == ESP_OK)
  49.   {
  50.     timers[0] = micros();
  51.     Serial.printf("\r\nSuccess Sent Value->\t%d", dataToSend[0]);
  52.     M5.Lcd.setCursor(0, 20, 2);
  53.     M5.Lcd.printf("\r\nSuccess Sent Value->\t%d", dataToSend[0]);
  54.     M5.Lcd.println();
  55.   }
  56.   else
  57.   {
  58.     Serial.printf(".");
  59.   }
  60.   delay(1000);
  61.   M5.Lcd.fillRect(0, 20, 160, 80, TFT_BLACK);
  62. }

  63. void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
  64. {
  65.   Serial.print("\r\nLast Packet Send Status:\t");
  66.   Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
  67. }

  68. void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)
  69. {
  70.   if(data[0] == dataToSend[0])
  71.   {
  72.     timers[1] = micros();
  73.     timers[2] = timers[1]-timers[0];
  74.     Serial.printf("\r\nReceived\t%d Bytes val\t%d\tin %d micros", data_len, data[0], timers[2]);
  75.   }
  76.   else
  77.   {
  78.     Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
  79.   }
  80. }
复制代码
---------------------------------------------------------------
从机只接收
  1. #include <M5Stack.h>
  2. #include <esp_now.h>
  3. #include <WiFi.h>

  4. #define WIFI_CHANNEL 1
  5. //uint8_t localCustomMac[] = {0xD8, 0xA0, 0x1D, 0x55, 0x27, 0xA0};
  6. const byte maxDataFrameSize = 200;
  7. byte cnt=0;

  8. void setup()
  9. {
  10.   M5.begin(true, false, true);
  11. //  Serial.begin(115200);
  12.   Serial.print("\r\n\r\n");
  13.   WiFi.mode(WIFI_AP);
  14.   Serial.println( WiFi.softAPmacAddress() );
  15.   M5.Lcd.setCursor(0, 0, 2);
  16.   M5.Lcd.print("MAC: ");
  17.   M5.Lcd.print(WiFi.softAPmacAddress());
  18.   M5.Lcd.printf("   CHANNEL:%d",WIFI_CHANNEL);
  19.   WiFi.disconnect();
  20.   if(esp_now_init() == ESP_OK)
  21.   {
  22.     Serial.println("ESPNow Init Success!");
  23.   }
  24.   else
  25.   {
  26.     Serial.println("ESPNow Init Failed....");
  27.   }
  28.   esp_now_register_recv_cb(OnDataRecv);
  29.   
  30. }

  31. void loop()
  32. {
  33. yield();
  34. }

  35. void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)
  36. {
  37.   Serial.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
  38.   M5.Lcd.fillRect(0, 20, 320, 220, TFT_BLACK);
  39.   M5.Lcd.setCursor(0, 20, 2);
  40.   M5.Lcd.printf("\r\nReceived\t%d Bytes\t%d", data_len, data[0]);
  41. }
复制代码


主机只发送
  1. #include <M5StickC.h>
  2. #include <esp_now.h>
  3. #include <WiFi.h>

  4. #define WIFI_CHANNEL 1
  5. esp_now_peer_info_t slave;
  6. //uint8_t remoteMac[] = {0xA4, 0xCF, 0x12, 0x6D, 0x6A, 0xD1};  //从机地址
  7. uint8_t remoteMac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};  //广播地址
  8. const uint8_t maxDataFrameSize=200;
  9. const esp_now_peer_info_t *peer = &slave;
  10. uint8_t dataToSend[maxDataFrameSize];
  11. byte cnt=0;

  12. void setup()
  13. {
  14.   M5.begin();
  15.   M5.Lcd.setRotation(1);
  16.   Serial.begin(115200);
  17.   Serial.print("\r\n\r\n");
  18.   
  19.   WiFi.mode(WIFI_STA);
  20.   M5.Lcd.print("MAC:");
  21.   M5.Lcd.println(WiFi.softAPmacAddress());
  22.   M5.Lcd.printf("CHANNEL:%d", WIFI_CHANNEL);
  23.   M5.Lcd.println();
  24.   Serial.println(WiFi.softAPmacAddress());
  25.   WiFi.disconnect();
  26.   if(esp_now_init() == ESP_OK)
  27.   {
  28.     Serial.println("ESP NOW INIT!");
  29.   }
  30.   else
  31.   {
  32.     Serial.println("ESP NOW INIT FAILED....");
  33.   }
  34.   
  35.   
  36.   memcpy( &slave.peer_addr, &remoteMac, 6 );
  37.   slave.channel = WIFI_CHANNEL;
  38.   slave.encrypt = 0;
  39.   if( esp_now_add_peer(peer) == ESP_OK)
  40.   {
  41.     Serial.println("Added Peer!");
  42.     M5.Lcd.println("Added Peer!");
  43.   }

  44.   esp_now_register_send_cb(OnDataSent);
  45. }

  46. void loop()
  47. {
  48.   for(cnt=0; cnt<maxDataFrameSize; cnt++)
  49.   {
  50.     dataToSend[cnt]++;
  51.   }
  52.   if( esp_now_send(slave.peer_addr, dataToSend, maxDataFrameSize) == ESP_OK)
  53.   {
  54.     Serial.printf("\r\nSuccess Sent Value->\t%d", dataToSend[0]);
  55.     M5.Lcd.fillRect(0, 30, 160, 40, TFT_BLACK);
  56.     M5.Lcd.setCursor(0, 30, 2);
  57.     M5.Lcd.printf("\r\nSuccess Sent Value->\t%d", dataToSend[0]);
  58.   }
  59.   else
  60.   {
  61.     Serial.printf("\r\nDID NOT SEND....");
  62.   }
  63.   delay(250);
  64. }

  65. void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
  66. {
  67.   Serial.print("\r\nLast Packet Send Status:\t");
  68.   Serial.print(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
  69. }
复制代码


该用户从未签到

发表于 2021-10-9 12:26 | 显示全部楼层
楼主有没有 esp_now.h 的库,网上找了半天硬是没找到
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐

Arduino数字与字母字体应该如何设置?
Arduino数字与字母字体应
尝试用Arduino uno 做了个小工具,用来控制电脑水冷的运行。 洞洞板已经测试成功,完
WEMOS LOLIN32Lite(ESP32v1.0.0Rev1)入手+引脚图
WEMOS LOLIN32Lite(ESP32v
突发奇想做个精致的蓝牙遥控平衡小车(大学时做过一次,比较笨,用洞洞板焊电路做的比
【Arduino】168种传感器模块系列实验(129)---BH1750光照传感器
【Arduino】168种传感器模
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
16度双足机器人舵机驱动板pca9685连接舵机,舵机没反应
16度双足机器人舵机驱动板
各位同为arduino爱好者的大佬们大家好!想请教一下大家有关舵机驱动板pca9685
pca9685+arduino驱动舵机失败
pca9685+arduino驱动舵机
我网上别人的代码,编译通过且上传,但舵机不转,怎么解决?Arduino uno使用PCA9685模
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表