Files
ESPDocs/public/exemplos/zh-CN/esp-now.c
T

93 lines
2.8 KiB
C

/*
* 面向 ESP32 的 ESP-NOW 示例
* 无需 Wi-Fi 路由器的点对点无线通信和广播
*
* ESP-IDF 内置的原生协议
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_now.h"
#include "esp_log.h"
#include "nvs_flash.h"
static const char *TAG = "esp_now_demo";
// 数据包中发送的数据结构
typedef struct {
uint32_t sensor_id;
float temperatura;
float umidade;
uint32_t tempo_ms;
} __attribute__((packed)) dados_pacote_t;
// 广播 MAC 地址(发送给附近所有 ESP-NOW 节点)
static const uint8_t broadcast_mac[ESP_NOW_ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/* 发送数据包时执行的回调 */
static void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
ESP_LOGI(TAG, "Send complete: %s", status == ESP_NOW_SEND_SUCCESS ? "SUCCESS (ACK)" : "FAILURE");
}
/* 接收其他 ESP32 数据包时执行的回调 */
static void on_data_recv(const esp_now_recv_info_t *recv_info, const uint8_t *data, int len)
{
if (len == sizeof(dados_pacote_t)) {
dados_pacote_t *pct = (dados_pacote_t *)data;
ESP_LOGI(TAG, "Pacote recebido de [%02X:%02X:%02X:%02X:%02X:%02X]: Sensor #%ld | Temp: %.1f C | Umid: %.1f %%",
recv_info->src_addr[0], recv_info->src_addr[1], recv_info->src_addr[2],
recv_info->src_addr[3], recv_info->src_addr[4], recv_info->src_addr[5],
pct->sensor_id, pct->temperatura, pct->umidade);
}
}
void app_main(void)
{
// 以 Station 模式初始化 NVS 和 Wi-Fi
nvs_flash_init();
esp_netif_init();
esp_event_loop_create_default();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_start();
// 初始化 ESP-NOW 协议
ESP_ERROR_CHECK(esp_now_init());
esp_now_register_send_cb(on_data_sent);
esp_now_register_recv_cb(on_data_recv);
// 注册广播对端
esp_now_peer_info_t peer_info = {
.channel = 1,
.ifidx = WIFI_IF_STA,
.encrypt = false,
};
memcpy(peer_info.peer_addr, broadcast_mac, ESP_NOW_ETH_ALEN);
ESP_ERROR_CHECK(esp_now_add_peer(&peer_info));
ESP_LOGI(TAG, "ESP-NOW ready! Sending telemetry every 3 seconds...");
dados_pacote_t telemetria = {
.sensor_id = 101,
.temperatura = 24.8f,
.umidade = 58.2f,
};
while (1) {
telemetria.tempo_ms = esp_log_timestamp();
telemetria.temperatura += ((float)(rand() % 10) - 5.0f) / 10.0f;
esp_err_t res = esp_now_send(broadcast_mac, (uint8_t *)&telemetria, sizeof(telemetria));
if (res != ESP_OK) {
ESP_LOGE(TAG, "Failed to send ESP-NOW packet: %d", res);
}
vTaskDelay(pdMS_TO_TICKS(3000));
}
}