ESP8266
一.简介
这篇给大家分享一下多个ESP8266直接相互通讯,因为想做智能家居系统,但是想了一下,不止一个产品,比如测量温湿度的,检测人体的各种传感器,而且所处的位置也不一样,最后想到这个办法,可以用一个ESP8266模块作为一个总的控制,就像一个管家,来和其他ESP8266通讯,来实现我们想要的功能。
先说一下ESP-NOW,它是Espressif开发的一种协议,它使多个设备无需使用Wi-Fi即可相互通信。该协议类似于低功率的2.4GHz无线连接。设备之间需要进行配对,然后才能进行通信。配对完成后,连接安全且点对点,无需握手。”这意味着在将设备彼此配对后,连接将保持不变。换句话说,如果您的一块板突然断电或重置,则在重新启动时,它将自动连接到其对等端以继续通信。
简而言之,ESP-NOW是一种快速通信协议,可用于在ESP8266板之间交换小消息(最大250字节)。
ESP-NOW有多种用途
- 可以在不同的设置中进行单向或双向通信
- 一个 主 ESP8266向多个ESP8266 从 发送数据
一块ESP8266板向不同的ESP8266板发送相同或不同的命令。此配置是构建遥控器之类的理想选择 - 一个ESP8266从站从多个主站接收数据
如果要将多个传感器节点的数据收集到一个ESP8266板中,则此配置非常理想 - ESP-NOW双向通讯
使用ESP-NOW,每个板可以同时是发送者和接收者。因此,您可以在板之间建立双向通信。
总而言之,ESP-NOW是构建网络的理想选择,在该网络中,您可以有多个ESP8266板相互交换数据,这篇只是测试单方向的发送数据和接受数据
代码地址
ESP8266相互通讯
二.获取MAC
首先获取MAC地址,将下列程序烧入开发板,然后打开窗口,按ESP8266的复位按键,在串口助手就会打印MAC
#include <ESP8266WiFi.h>
void setup(){
Serial.begin(115200);
Serial.println();
Serial.print("ESP8266 Board MAC Address: ");
Serial.println(WiFi.macAddress());
}
void loop()
{
}
烧录程序时候也会显示该ESP8266的MAC
三.发送端代码
MAC需要改为接受的ESP8266的MAC
//发送
#include <ESP8266WiFi.h>
#include <espnow.h>
//接收方MAC地址 根据自己的板子修改
uint8_t broadcastAddress[] = {0x50, 0x02, 0x91, 0x67, 0xF5, 0xF4};
//发送数据的结构体
typedef struct struct_message {
char a[32];
int b;
float c;
String d;
bool e;
} struct_message;
//创建一个新的类型变量
struct_message myData;
//这是一个回调函数,将在发送消息时执行。
//在这种情况下,无论是否成功发送该消息,都会简单地打印出来
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 setup() {
//初始化串行监视器以进行调试
Serial.begin(115200);
//将设备设置为Wi-Fi站点
WiFi.mode(WIFI_STA);
//立即初始化ESP
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
//设置ESP8266角色 ESP_NOW_ROLE_CONTROLLER, ESP_NOW_ROLE_SLAVE,
//ESP_NOW_ROLE_COMBO, ESP_NOW_ROLE_MAX。
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
//先前创建的功能。
esp_now_register_send_cb(OnDataSent);
//与另一个ESP-NOW设备配对以发送数据
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
void loop() {
//配置要发送的值
strcpy(myData.a, "THIS IS A CHAR");
myData.b = random(1,20); //随机数
myData.c = 1.2;
myData.d = "Hello";
myData.e = false;
//发送消息
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
//延时两秒
delay(2000);
}
四.接受端代码
//接收
#include <ESP8266WiFi.h>
#include <espnow.h>
//接收数据保存的结构体和发送方一致
typedef struct struct_message {
char a[32];
int b;
float c;
String d;
bool e;
} struct_message;
//创建结构体变量
struct_message 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("Char: ");
Serial.println(myData.a);
Serial.print("Int: ");
Serial.println(myData.b);
Serial.print("Float: ");
Serial.println(myData.c);
Serial.print("String: ");
Serial.println(myData.d);
Serial.print("Bool: ");
Serial.println(myData.e);
Serial.println();
}
void setup() {
//初始化窗口
Serial.begin(115200);
//设置ESP8266模式
WiFi.mode(WIFI_STA);
//初始化 ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
//设置ESP8266角色:
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
//先前创建的功能 测试ESP-NOW通信
esp_now_register_recv_cb(OnDataRecv);
}
void loop(){
}
五.调试结果
将两个ESP8266上电,打开接受端的串口助手,看一看到每隔2s会受到一组数据,和我们发送端发送的数据一样,说明通讯成功,这只是一个小的测试,两个相互通讯,或者一对多,多对一需要大家去尝试修改测试