ESP8266相互通讯(ESP-NOW)

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会受到一组数据,和我们发送端发送的数据一样,说明通讯成功,这只是一个小的测试,两个相互通讯,或者一对多,多对一需要大家去尝试修改测试
在这里插入图片描述

  • 32
    点赞
  • 299
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值