[ESP-IDF系列]使用ESP32驱动NRF24L01实现单点通讯
1 简介
最近想DIY一个四轴飞行器(简易的十字形遥控飞行器),也从晚上找了很多的视频和做了相关的简易研究(如果搞出来了会分享,没有经验)。除去电机根据MPU6050的姿态计算PID进行输出不谈。还有一点比较重要的就是通讯功能。飞行器接收或者向遥控器发送指令然后执行对应的数据处理或者动作。因此考虑到多种的数据传输方式。如下是一个简要的对比。通信技术通信速率(最大)通信距离(典型)通信频段特点说明
由于之前并没有接触过飞行器相关的。因此我让GPT对常见的无人机通讯方案进行了一下分析。下述表格为GPT生成的不同通讯协议对应的无人机应用的方向。
2 场景通信技术选型
所以最后选用的是NRF24L01,根据某宝店家介绍,其在空旷场地下通讯的距离可以达到1000米左右(已经是一个非常大的距离了,再远人眼可能就不可视了)
上图为经典的NRF24L01
当然国内也有很多其他系列的2.4 G模块,比如说安信可的NF-02-PA或者NF-02-PE(使用的SI24R1 芯片)
但是考虑到本次使用的是ESP32,结合对应的库文件的丰富程度。因此我准备了两个不同的NRF24L01和ESP32来进行这次通讯实验。
3 驱动步骤
主要介绍如何在IDF框架下结合组件管理器来快速实现通过组件nopnop2002/mirf来快速驱动2.4G模块:
1.首先新建一个IDF的项目,基于HelloWorld 的项目
2.新建idf_component.yml,然后输入下面的内容view plaincopy to clipboardprint?
1.dependencies:
2.protocol_examples_common:
3.path: ${IDF_PATH}/examples/common_components/protocol_examples_common
4.nopnop2002/mirf:
5.path: components/mirf/
6.git:https://github.com/nopnop2002/esp-idfmirf.git
3.编译一次当前的项目,然后组件管理器会自动下载组件:
4.访问https://github.com/nopnop2002/esp-idfmirf.git来查找对应的example
可以使用Clone到本地,或者是直接拷贝文件内容。
5.使用Menuconfi g配置2.4G模块PIN的连接情况。
6.配置项目目录的KConfi g,在menuconfi g中进行搜索Application Confi gurationview plaincopy to clipboardprint?
1.menu “Application Confi guration”
2.
3.endmenu DIRECTION
4.prompt “Communication polarity”
5.default SENDER
6.help
7.Select Communication polarity.
8.confi g SENDER
9.bool “As the sender”
10.help
11.As the sender.
12.confi g RECEIVER
13.bool “As the receiver”
14.help
15.As the receiver.
16.endchoice
17.
18.endmenu
将两个ESP32分别以Sender和receiver的方式进行烧录。
这样的话,sender task 便会根据地址FGHIJ 进行数据发送,
view plaincopy to clipboardprint?
1.void sender(void *pvParameters)
2.{
3.ESP_LOGI(pcTaskGetName(NULL), “Start”);
4.NRF24_t dev;
5.Nrf24_init(&dev);
6.uint8_t payload = 32;
7.uint8_t channel = CONFIG_RADIO_CHANNEL;
8.Nrf24_confi g(&dev, channel, payload);
9.
10.//Set destination address using 5 characters
11.esp_err_t ret = Nrf24_setTADDR(&dev,(uint8_t *)”FGHIJ”);
12.if (ret != ESP_OK)
13.{
14.ESP_LOGE(pcTaskGetName(NULL), “nrf24l01 not installed”);
15.while (1)
16.{
17.vTaskDelay(1);
18.}
19.}
20.
21.#if CONFIG_ADVANCED
22.AdvancedSettings(&dev);
23.#endif // CONFIG_ADVANCED
24.
25.// Print settings
26.Nrf24_printDetails(&dev);
27.
28.uint8_t buf[32];
29.while (1)
30.{
31.TickType_t nowTick = xTaskGetTickCount();
32.sprintf((char *)buf, “Hello World %” PRIu32, nowTick);
33.Nrf24_send(&dev, buf);
34.// vTaskDelay(1);
35.ESP_LOGI(pcTaskGetName(NULL), “Wait for sending.....”);
36.if (Nrf24_isSend(&dev, 1000))
37.{
38.ESP_LOGI(pcTaskGetName(NULL), “Send success:%s”, buf);
39.}
40.else
41.{
42.ESP_LOGW(pcTaskGetName(NULL), “Send fail:”);
43.}
44.vTaskDelay(1000 / portTICK_PERIOD_MS);
45.}
46.}
另一个receiver的task便会进行接收.
view plaincopy to clipboardprint?
1.void receiver(void *pvParameters)
2.{
3.ESP_LOGI(pcTaskGetName(NULL), “Start”);
4.NRF24_t dev;
5.Nrf24_init(&dev);
6.uint8_t payload = 32;
7.uint8_t channel = CONFIG_RADIO_CHANNEL;
8.Nrf24_confi g(&dev, channel, payload);
9.
10.// Set my own address using 5 characters
11.esp_err_t ret = Nrf24_setRADDR(&dev,(uint8_t *)”FGHIJ”);
12.if (ret != ESP_OK)
13. {
14.ESP_LOGE(pcTaskGetName(NULL), “nrf24l01 not installed”);
15.while (1)
16. {
17.vTaskDelay(1);
18. }
19. }
20.
21.#if CONFIG_ADVANCED
22.AdvancedSettings(&dev);
23.#endif // CONFIG_ADVANCED
24.
25.//Print settings
26.Nrf24_printDetails(&dev);
27.ESP_LOGI(pcTaskGetName(NULL), “Listening...”);
28.
29.uint8_t buf[32];
30.
31.//Clear RX FiFo
32.while (1)
33.{
34.if (Nrf24_dataReady(&dev) == false)
35.break;
36.Nrf24_getData(&dev, buf);
37.}
38.
39.while (1)
40.{
41.//Wait for received data
42.if (Nrf24_dataReady(&dev))
43.{
44.Nrf24_getData(&dev, buf);
45.ESP_LOGI(pcTaskGetName(NULL), “Got data:%s”, buf);
46.// ESP_LOG_BUFFER_HEXDUMP(pcTaskGetName(NULL), buf, payload, ESP_LOG_INFO);
47. }
48.vTaskDelay(1); // AvoidWatchDog alerts
49.}
50.}
4 实验现象
5 总结
在上文中,我们主要是用nopnop2002/mirf库快速实现和调试了2.G模块的通讯和调试,目前来看效果还是非常不错的,符合预期。但是对于通讯的距离和稳定性还需要进一步进行拉锯测试。
(本文来源于《EEPW》202506)
评论