ESP8266-Arduino网络编程实例-ESP-Now点对点双向通信(Two Way)

ESP-Now点对点双向通信(Two Way)

在面的文章中,对ESP-Now做了详细的介绍和介绍了点对点单向通信,在这里,将介绍如何使用两个ESP8266在ESP-Now通信协议上进行点对点双向通信(Two Way)。

ESP-Now的Two Way通信方式,允许两个通信设备发送和接收数据。下面将演示如何在两个ESP8266设备之间对DHT11传感器数据进行发送与接收。

1、硬件准备

  • ESP8266 NodeMCU开发板两块
  • 数据线两条
  • DHT11传感器模块两个
  • 杜邦线若干

硬件接线如下:

在这里插入图片描述

2、软件准备

  • Arduino IDE或VSCode + PlatformIO

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

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

3、代码实现

在这里,两个ESP8266开发板使用相同的代码,只是与通信对象的MAC地址不同。可以通过如下代码查询本设备的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(){

}

本次实例使用到DHT11传感器,在前面文章中对DHT11的驱动做了详细的介绍,请参考:

通信驱动程序代码如下:

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <ESP8266WiFi.h>
#include <espnow.h>

#include <Adafruit\_Sensor.h>
#include <DHT.h>

// 通信对象的MAC地址
uint8\_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// DHT传感器引脚
#define DHTPIN 5

// DHT传感器类型
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

// 储存温度湿度数据
float temperature;
float humidity;

// 接收到的温度温度数据
float incomingTemp;
float incomingHum;

// 数据刷新频率(10秒)
const long interval = 10000;
unsigned long previousMillis = 0;

// 数据发送状态信息
String success;

// 传感器数据消息结构
typedef struct struct\_message {
float temp; // 温度
float hum; // 湿度
} struct_message;

// 本机DHT11数据消息
struct_message DHTReadings;

// 接收消息
struct_message incomingReadings;

// 数据发送回调
void OnDataSent(uint8\_t \*mac_addr, uint8\_t sendStatus) {
Serial.print("Last Packet Send Status: ");
if (sendStatus == 0){
Serial.println("Delivery success");
}
else{
Serial.println("Delivery fail");
}
}

// 数据接收回调
void OnDataRecv(uint8\_t \* mac, uint8\_t \*incomingData, uint8\_t len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
Serial.print("Bytes received: ");
Serial.println(len);
incomingTemp = incomingReadings.temp;
incomingHum = incomingReadings.hum;
}

// 读取DHT11传感器数据
void getReadings(){
// 读取温度
temperature = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
//float t = dht.readTemperature(true);
if (isnan(temperature)){
Serial.println("Failed to read from DHT");
temperature = 0.0;
}
humidity = dht.readHumidity();
if (isnan(humidity)){
Serial.println("Failed to read from DHT");
humidity = 0.0;
}
}

void printIncomingReadings(){
// 输出接收到的消息
Serial.println("INCOMING READINGS");
Serial.print("Temperature: ");
Serial.print(incomingTemp);
Serial.println(" ºC");
Serial.print("Humidity: ");
Serial.print(incomingHum);
Serial.println(" %");
}

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

// 初始化DHT传感器
dht.begin();

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

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

// 设置 ESP-NOW 角色
esp\_now\_set\_self\_role(ESP_NOW_ROLE_COMBO);

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

// 添加通信节点
esp\_now\_add\_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);

// 注册 ESP-Now数据接收回调函数
esp\_now\_register\_recv\_cb(OnDataRecv);
}

void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {

previousMillis = currentMillis;

getReadings();


DHTReadings.temp = temperature;
DHTReadings.hum = humidity;

// 发送数据
esp\_now\_send(broadcastAddress, (uint8\_t \*) &DHTReadings, sizeof(DHTReadings));

// 打印接收的数据
printIncomingReadings();
}
}

示例的中的演示代码,正前面介绍ESP-Now通信流程:

1)初始化ESP-Now

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

2)设置通信方式(角色)

1
2
3
// 设置 ESP-NOW 角色
esp\_now\_set\_self\_role(ESP_NOW_ROLE_COMBO);

3)注册数据发送回调

1
2
3
// 注册 ESP-Now数据发送回调函数
esp\_now\_register\_send\_cb(OnDataSent);

4)添加通信节点

1
2
3
// 添加通信节点
esp\_now\_add\_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);

5)注册数据接收回调

1
2
3
// 注册 ESP-Now数据接收回调函数
esp\_now\_register\_recv\_cb(OnDataRecv);

6)数据发送

1
2
3
// 发送数据
esp\_now\_send(broadcastAddress, (uint8\_t \*) &DHTReadings, sizeof(DHTReadings));

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