ESP8266-Arduino网络编程实例-ESP-Now-One-to-Many多设备通信

ESP-Now-One-to-Many多设备通信

ESP-Now的One-to-Many通信方式是ESP-Now多设备通信一种方式。在这种通信方式下,有一个主控设备(Master)与多个从设备(Slave)通信,从设备之间不能通信。可以当作ESP-Now的One-Way通信方式扩展。

在这里插入图片描述

本文将演示如何使用ESP-Now的One-to-Many通信方式。

1、硬件准备

  • ESP8266 NodeMCU开发板三块
  • 数据线三条

设备的通信方式如下:

在这里插入图片描述

2、软件准备

  • Arduino IDE或VSCode + PlatformIO

在前面的文章中,对如何搭建ESP8266开发环境做了详细的介绍,请参考:

ESP8266 NodeMCU的引脚介绍在前面的文章中做了详细的介绍,请参考:

3、代码实现

在实现设备通信之前,需要查询ESP8266本机的MAC地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <ESP8266WiFi.h>

void setup(){
Serial.begin(115200);
Serial.println();
Serial.print("ESP8266 Board MAC Address: ");
Serial.println(WiFi.macAddress());
}

void loop(){

}

1)主机通信代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <ESP8266WiFi.h>
#include <espnow.h>

// 从机MAC地址,请根据实际MAC地址替换
uint8\_t broadcastAddress1[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8\_t broadcastAddress2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// 通信消息结构体,主机和从机必须一致
typedef struct test\_struct {
int x;
int y;
} test_struct;


test_struct test;

unsigned long lastTime = 0;
unsigned long timerDelay = 2000;

// 数据发送回调函数
void OnDataSent(uint8\_t \*mac_addr, uint8\_t sendStatus) {
char macStr[18];
Serial.print("Packet to:");
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(macStr);
Serial.print(" send status: ");
if (sendStatus == 0){
Serial.println("Delivery success");
}
else{
Serial.println("Delivery fail");
}
}

void setup() {
// 初始化串口
Serial.begin(115200);

// 设置WiFi工作模式
WiFi.mode(WIFI_STA);
WiFi.disconnect();

// 初始化 ESP-NOW
if (esp\_now\_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}

// 设置通信方式
esp\_now\_set\_self\_role(ESP_NOW_ROLE_CONTROLLER);

// 注册数据发送回调函数
esp\_now\_register\_send\_cb(OnDataSent);

// 添加从机通信节点
esp\_now\_add\_peer(broadcastAddress1, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
esp\_now\_add\_peer(broadcastAddress2, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);

}

void loop() {
if ((millis() - lastTime) > timerDelay) {
// 生成随机数据
test.x = random(1, 50);
test.y = random(1, 50);

// 向所有从机发送数据
esp\_now\_send(0, (uint8\_t \*) &test, sizeof(test));

lastTime = millis();
}
}

2)从机通信代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <ESP8266WiFi.h>
#include <espnow.h>

// 通信消息结构体,主机和从机必须一致
typedef struct test\_struct {
int x;
int y;
} test_struct;

//
test_struct myData;

// 数据接收回调
void OnDataRecv(uint8\_t \* mac, uint8\_t \*incomingData, uint8\_t len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("x: ");
Serial.println(myData.x);
Serial.print("y: ");
Serial.println(myData.y);
Serial.println();
}

void setup() {
// 初始化串口
Serial.begin(115200);

// 设置WiFi工作模式
WiFi.mode(WIFI_STA);
WiFi.disconnect();

// 初始化 ESP-NOW
if (esp\_now\_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}

// 设置通信方式
esp\_now\_set\_self\_role(ESP_NOW_ROLE_SLAVE);
// 注册数据接收回调函数
esp\_now\_register\_recv\_cb(OnDataRecv);
}

文章来源: https://iotsmart.blog.csdn.net/article/details/127548277