Merge branch 'feature/modify_espnow' into 'master'

modify espnow example

See merge request idf/esp-idf!3144
This commit is contained in:
Jiang Jiang Jian 2018-09-04 13:09:43 +08:00
commit 76669ca817
3 changed files with 117 additions and 32 deletions

View file

@ -1,30 +1,115 @@
# ESPNOW Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example shows how to use ESPNOW of wifi. Example does the following steps:
1. Start WiFi.
* Start WiFi.
* Initialize ESPNOW.
* Register ESPNOW sending or receiving callback function.
* Add ESPNOW peer information.
* Send and receive ESPNOW data.
2. Initialize ESPNOW.
This example need at least two ESP devices:
3. Register ESPNOW sending or receiving callback function.
4. Add ESPNOW peer information.
5. Send and receive ESPNOW data.
In order to get the MAC address of the other device, firstly send broadcast ESPNOW data to each other with 'state' set as 0. When receiving
broadcast ESPNOW data with 'state' as 0, add the device from which the data comes to the peer list. Then start sending broadcast ESPNOW
data with 'state' set as 1. When receiving broadcast ESPNOW data with 'state' as 1, compare the local magic number with that in the data.
If the local one is bigger than that one, stop sending broadcast ESPNOW data and start sending unicast ESPNOW data. If receive unicast
ESPNOW data, also stop sending broadcast ESPNOW data. That is what happens in this example. It shows how to send/receive broadcast/unicast
ESPNOW data. In practice, if the MAC address of the other device is known, it's not required to send/receive broadcast ESPNOW data first,
just add the device to the peer list and send/receive unicast ESPNOW data.
* In order to get the MAC address of the other device, Device1 firstly send broadcast ESPNOW data with 'state' set as 0.
* When Device2 receiving broadcast ESPNOW data from Device1 with 'state' as 0, adds Device1 into the peer list.
Then start sending broadcast ESPNOW data with 'state' set as 1.
* When Device1 receiving broadcast ESPNOW data with 'state' as 1, compares the local magic number with that in the data.
If the local one is bigger than that one, stop sending broadcast ESPNOW data and starts sending unicast ESPNOW data to Device2.
* If Device2 receives unicast ESPNOW data, also stop sending broadcast ESPNOW data.
In practice, if the MAC address of the other device is known, it's not required to send/receive broadcast ESPNOW data first,
just add the device into the peer list and send/receive unicast ESPNOW data.
There are a lot of "extras" on top of ESPNOW data, such as type, state, sequence number, CRC and magic in this example. These "extras" are
not required to use ESPNOW. They are only used to make this example to run correctly. However, it is recommended that users add some "extras"
to make ESPNOW data more safe and more reliable.
*Note:* The two devices can be set as either station or softap or station+softap mode. If the receiving device is in station mode only
and it connects to an AP, modem sleep should be disabled.
## How to use example
More info in the code [espnow_example_main.c](./main/espnow_example_main.c).
### Configure the project
```
make menuconfig
```
* Set serial port under Serial Flasher Options.
* Set WiFi mode (station or SoftAP) under Example Configuration Options.
* Set ESPNOW primary master key under Example Configuration Options.
This parameter must be set to the same value for sending and recving devices.
* Set ESPNOW local master key under Example Configuration Options.
This parameter must be set to the same value for sending and recving devices.
* Set Channel under Example Configuration Options.
The sending device and the recving device must be on the same channel.
* Set Send count and Send delay under Example Configuration Options.
* Set Send len under Example Configuration Options.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
make -j4 flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
Here is the example of ESPNOW receiving device console output.
```
I (898) phy: phy_version: 3960, 5211945, Jul 18 2018, 10:40:07, 0, 0
I (898) wifi: mode : sta (30:ae:a4:80:45:68)
I (898) espnow_example: WiFi started
I (898) ESPNOW: espnow [version: 1.0] init
I (5908) espnow_example: Start sending broadcast data
I (6908) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (7908) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (52138) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (52138) espnow_example: Receive 0th broadcast data from: 30:ae:a4:0c:34:ec, len: 200
I (53158) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (53158) espnow_example: Receive 1th broadcast data from: 30:ae:a4:0c:34:ec, len: 200
I (54168) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (54168) espnow_example: Receive 2th broadcast data from: 30:ae:a4:0c:34:ec, len: 200
I (54168) espnow_example: Receive 0th unicast data from: 30:ae:a4:0c:34:ec, len: 200
I (54678) espnow_example: Receive 1th unicast data from: 30:ae:a4:0c:34:ec, len: 200
I (55668) espnow_example: Receive 2th unicast data from: 30:ae:a4:0c:34:ec, len: 200
```
Here is the example of ESPNOW sending device console output.
```
I (915) phy: phy_version: 3960, 5211945, Jul 18 2018, 10:40:07, 0, 0
I (915) wifi: mode : sta (30:ae:a4:0c:34:ec)
I (915) espnow_example: WiFi started
I (915) ESPNOW: espnow [version: 1.0] init
I (5915) espnow_example: Start sending broadcast data
I (5915) espnow_example: Receive 41th broadcast data from: 30:ae:a4:80:45:68, len: 200
I (5915) espnow_example: Receive 42th broadcast data from: 30:ae:a4:80:45:68, len: 200
I (5925) espnow_example: Receive 44th broadcast data from: 30:ae:a4:80:45:68, len: 200
I (5935) espnow_example: Receive 45th broadcast data from: 30:ae:a4:80:45:68, len: 200
I (6965) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (6965) espnow_example: Receive 46th broadcast data from: 30:ae:a4:80:45:68, len: 200
I (7975) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (7975) espnow_example: Receive 47th broadcast data from: 30:ae:a4:80:45:68, len: 200
I (7975) espnow_example: Start sending unicast data
I (7975) espnow_example: send data to 30:ae:a4:80:45:68
I (9015) espnow_example: send data to 30:ae:a4:80:45:68
I (9015) espnow_example: Receive 48th broadcast data from: 30:ae:a4:80:45:68, len: 200
I (10015) espnow_example: send data to 30:ae:a4:80:45:68
I (16075) espnow_example: send data to 30:ae:a4:80:45:68
I (17075) espnow_example: send data to 30:ae:a4:80:45:68
I (24125) espnow_example: send data to 30:ae:a4:80:45:68
```
## Troubleshooting
If ESPNOW data can not be received from another device, maybe the two devices are not
on the same channel or the primary key and local key are different.
In real application, if the receiving device is in station mode only and it connects to an AP,
modem sleep should be disabled. Otherwise, it may fail to revceive ESPNOW data from other devices.

View file

@ -21,7 +21,7 @@
#define ESPNOW_QUEUE_SIZE 6
#define IS_BROADCAST_ADDR(addr) (memcmp(addr, example_broadcast_mac, ESP_NOW_ETH_ALEN) == 0)
#define IS_BROADCAST_ADDR(addr) (memcmp(addr, s_example_broadcast_mac, ESP_NOW_ETH_ALEN) == 0)
typedef enum {
EXAMPLE_ESPNOW_SEND_CB,

View file

@ -32,9 +32,9 @@
static const char *TAG = "espnow_example";
static xQueueHandle example_espnow_queue;
static xQueueHandle s_example_espnow_queue;
static uint8_t example_broadcast_mac[ESP_NOW_ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
static uint8_t s_example_broadcast_mac[ESP_NOW_ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
static uint16_t s_example_espnow_seq[EXAMPLE_ESPNOW_DATA_MAX] = { 0, 0 };
static void example_espnow_deinit(example_espnow_send_param_t *send_param);
@ -85,7 +85,7 @@ static void example_espnow_send_cb(const uint8_t *mac_addr, esp_now_send_status_
evt.id = EXAMPLE_ESPNOW_SEND_CB;
memcpy(send_cb->mac_addr, mac_addr, ESP_NOW_ETH_ALEN);
send_cb->status = status;
if (xQueueSend(example_espnow_queue, &evt, portMAX_DELAY) != pdTRUE) {
if (xQueueSend(s_example_espnow_queue, &evt, portMAX_DELAY) != pdTRUE) {
ESP_LOGW(TAG, "Send send queue fail");
}
}
@ -109,7 +109,7 @@ static void example_espnow_recv_cb(const uint8_t *mac_addr, const uint8_t *data,
}
memcpy(recv_cb->data, data, len);
recv_cb->data_len = len;
if (xQueueSend(example_espnow_queue, &evt, portMAX_DELAY) != pdTRUE) {
if (xQueueSend(s_example_espnow_queue, &evt, portMAX_DELAY) != pdTRUE) {
ESP_LOGW(TAG, "Send receive queue fail");
free(recv_cb->data);
}
@ -177,7 +177,7 @@ static void example_espnow_task(void *pvParameter)
vTaskDelete(NULL);
}
while (xQueueReceive(example_espnow_queue, &evt, portMAX_DELAY) == pdTRUE) {
while (xQueueReceive(s_example_espnow_queue, &evt, portMAX_DELAY) == pdTRUE) {
switch (evt.id) {
case EXAMPLE_ESPNOW_SEND_CB:
{
@ -299,8 +299,8 @@ static esp_err_t example_espnow_init(void)
{
example_espnow_send_param_t *send_param;
example_espnow_queue = xQueueCreate(ESPNOW_QUEUE_SIZE, sizeof(example_espnow_event_t));
if (example_espnow_queue == NULL) {
s_example_espnow_queue = xQueueCreate(ESPNOW_QUEUE_SIZE, sizeof(example_espnow_event_t));
if (s_example_espnow_queue == NULL) {
ESP_LOGE(TAG, "Create mutex fail");
return ESP_FAIL;
}
@ -317,7 +317,7 @@ static esp_err_t example_espnow_init(void)
esp_now_peer_info_t *peer = malloc(sizeof(esp_now_peer_info_t));
if (peer == NULL) {
ESP_LOGE(TAG, "Malloc peer information fail");
vSemaphoreDelete(example_espnow_queue);
vSemaphoreDelete(s_example_espnow_queue);
esp_now_deinit();
return ESP_FAIL;
}
@ -325,7 +325,7 @@ static esp_err_t example_espnow_init(void)
peer->channel = CONFIG_ESPNOW_CHANNEL;
peer->ifidx = ESPNOW_WIFI_IF;
peer->encrypt = false;
memcpy(peer->peer_addr, example_broadcast_mac, ESP_NOW_ETH_ALEN);
memcpy(peer->peer_addr, s_example_broadcast_mac, ESP_NOW_ETH_ALEN);
ESP_ERROR_CHECK( esp_now_add_peer(peer) );
free(peer);
@ -334,7 +334,7 @@ static esp_err_t example_espnow_init(void)
memset(send_param, 0, sizeof(example_espnow_send_param_t));
if (send_param == NULL) {
ESP_LOGE(TAG, "Malloc send parameter fail");
vSemaphoreDelete(example_espnow_queue);
vSemaphoreDelete(s_example_espnow_queue);
esp_now_deinit();
return ESP_FAIL;
}
@ -349,11 +349,11 @@ static esp_err_t example_espnow_init(void)
if (send_param->buffer == NULL) {
ESP_LOGE(TAG, "Malloc send buffer fail");
free(send_param);
vSemaphoreDelete(example_espnow_queue);
vSemaphoreDelete(s_example_espnow_queue);
esp_now_deinit();
return ESP_FAIL;
}
memcpy(send_param->dest_mac, example_broadcast_mac, ESP_NOW_ETH_ALEN);
memcpy(send_param->dest_mac, s_example_broadcast_mac, ESP_NOW_ETH_ALEN);
example_espnow_data_prepare(send_param);
xTaskCreate(example_espnow_task, "example_espnow_task", 2048, send_param, 4, NULL);
@ -365,7 +365,7 @@ static void example_espnow_deinit(example_espnow_send_param_t *send_param)
{
free(send_param->buffer);
free(send_param);
vSemaphoreDelete(example_espnow_queue);
vSemaphoreDelete(s_example_espnow_queue);
esp_now_deinit();
}