我的 ESP32 连接到 NRF24L01 芯片,通过它接收音频数据流。然后我通过 WiFi 将此信息中继到 MQTT 代理。
这是我第一次尝试的 arduino IDE 草图代码中的一些部分(我将在问题末尾显示完整代码):
void onReceiveRadio(void * param) {
esp_task_wdt_add(nullptr);
while(1)
{
bool n = !whichBuff;
if(!buffFull[n] && radio.available() )
{
radio.read(&buffer[n][loadBufferN],buffSize); // Read the payload from the radio
loadBufferN++;
}
if(loadBufferN >= bucketTotal)
{
loadBufferN = 0;
buffFull[n] = true;
whichBuff = n;
}
}
}
void setup() {
Serial.begin(115200); // Enable Arduino serial library
radio.begin();
radio.setChannel(1); // Set RF channel to 1
radio.setAutoAck(0); // Disable ACKnowledgement packets
radio.setDataRate(RF_SPEED); // Set data rate as specified in user options
radio.setCRCLength(RF24_CRC_8);
radio.openWritingPipe(pipes[0]); // Set up reading and writing pipes
radio.openReadingPipe(1,pipes[1]);
radio.startListening(); // Exit sending mode
setup_wifi();
client.setServer(mqtt_server, 1883);
reconnect();
esp_task_wdt_init(2,false);
xTaskCreatePinnedToCore(
onReceiveRadio, /* pvTaskCode */
"Workload1", /* pcName */
1000, /* usStackDepth */
NULL, /* pvParameters */
1, /* uxPriority */
&TaskA, /* pxCreatedTask */
0); /* xCoreID */
}
void loop() {
if (!client.connected()) {
reconnect();
}
if(buffFull[whichBuff])
{
byte payload[bucketTotal*buffSize];
int w=0;
for(int x=0;x<bucketTotal;x++)
{
for(int y=0;y<buffSize;y++)
{
payload[w++] = buffer[whichBuff][x][y];
}
}
client.publish("/esp32/output",payload,bucketTotal*buffSize); // mqtt transmission
buffFull[whichBuff] = false;
}
}
当我运行完整代码时,我收到以下看门狗错误:
E (6608) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (6608) task_wdt: - IDLE0 (CPU 0)
E (6608) task_wdt: Tasks currently running:
E (6608) task_wdt: CPU 0: Workload1
E (6608) task_wdt: CPU 1: loopTask
E (6608) task_wdt: Aborting.
abort() was called at PC 0x400db86f on core 0
通过在我将在下面显示else { vTaskDelay(1); }的第一个if语句之后放入一个,我能够摆脱这个错误onReceiveRadio。虽然代码运行没有错误,但问题是延迟是不可取的,因为我需要以更高的频率接收有效载荷。所以我然后试图通过喂养看门狗来摆脱我原来的问题,但这让我回到了我最初遇到的同样错误。下面是我设置了看门狗的完整代码。
#include <RF24.h>
#include <SPI.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <esp_task_wdt.h>
// Replace the next variables with your SSID/Password combination
const char* ssid = "mynetwork";
const char* password = "mypass";
const char* mqtt_server = "192.168.0.29";
/***********************************************
//******* MANDATORY User Variables **************/
// Maximum Range: Sample rate 16000, RF_SPEED RF24_250KBPS
// Maximum Quality: Sample rate 44000, RF_SPEED RF24_2MBPS
#define SAMPLE_RATE 24000 // The sample rate to use for transferring audio samples Note: 44khz+ sample rate requires 8-bits per sample
#define RF_SPEED RF24_1MBPS // RF24_250KBPS will do 13-20khz+ sample rate, RF24_1MBPS up to 24-44khz+, RF24_2MBPS for higher. These are not limits, just a guide.
/***************** Optional/Advanced User Variables ******/
#define bucketTotal 3
#define buffSize 32 // The size of the memory buffer to use. Not really configurable.
/********* Automated pin selections, override by defining above ************/
//********Radio Defines ****************************
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[14] = { 0xABCDABCD71LL, 0x544d52687CLL, 0x544d526832LL, 0x544d52683CLL,0x544d526846LL, 0x544d526850LL,0x544d52685ALL, 0x544d526820LL, 0x544d52686ELL, 0x544d52684BLL, 0x544d526841LL, 0x544d526855LL,0x544d52685FLL,0x544d526869LL};
/* BEGIN PROJECT */
volatile boolean buffFull[2] = {false,false}, whichBuff = false;
int loadBufferN=0, intCount = 0;
byte buffer[2][bucketTotal][buffSize+1];
TaskHandle_t TaskA;
RF24 radio(12,14); // Set radio up using pins 7 (CE) 8 (CS)
WiFiClient espClient;
PubSubClient client(espClient);
void onTimer(void * param) {
esp_task_wdt_add(nullptr);
while(1)
{
bool n = !whichBuff;
if(!buffFull[n] && radio.available() )
{
radio.read(&buffer[n][loadBufferN],buffSize); // Read the payload from the radio
loadBufferN++;
}
else
{
//vTaskDelay(1);
delayMicroseconds(50); // Maybe delaying things help a bit?
esp_task_wdt_reset();
}
if(loadBufferN >= bucketTotal)
{
loadBufferN = 0;
buffFull[n] = true;
whichBuff = n;
}
}
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Subscribe
//client.subscribe("esp32/output");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
Serial.begin(115200); // Enable Arduino serial library
radio.begin();
radio.setChannel(1); // Set RF channel to 1
radio.setAutoAck(0); // Disable ACKnowledgement packets
radio.setDataRate(RF_SPEED); // Set data rate as specified in user options
radio.setCRCLength(RF24_CRC_8);
radio.openWritingPipe(pipes[0]); // Set up reading and writing pipes
radio.openReadingPipe(1,pipes[1]);
radio.startListening(); // Exit sending mode
setup_wifi();
client.setServer(mqtt_server, 1883);
reconnect();
esp_task_wdt_init(2,false);
xTaskCreatePinnedToCore(
onTimer, /* pvTaskCode */
"Workload1", /* pcName */
1000, /* usStackDepth */
NULL, /* pvParameters */
1, /* uxPriority */
&TaskA, /* pxCreatedTask */
0); /* xCoreID */
}
void loop() {
if (!client.connected()) {
reconnect();
}
if(buffFull[whichBuff])
{
byte payload[bucketTotal*buffSize];
int w=0;
for(int x=0;x<bucketTotal;x++)
{
for(int y=0;y<buffSize;y++)
{
payload[w++] = buffer[whichBuff][x][y];
}
}
client.publish("/esp32/output",payload,bucketTotal*buffSize); // mqtt transmission
buffFull[whichBuff] = false;
}
}
所以我的问题是如何在没有这些看门狗问题的情况下将来自 NRF24L01 的信息流中继到 MQTT 代理?
更新
我不知道这是否真的是一个长期/耐用的解决方案,因为我还没有对其进行全面测试,但是我通过更改使错误消退
esp_task_wdt_init(2,false);
到
esp_task_wdt_init(999,false);
我的 onReceiveRadio 现在是这样的:
void onReceiveRadio(void * param) {
esp_task_wdt_add(nullptr);
while(1)
{
bool n = !whichBuff;
if(!buffFull[n] && radio.available() )
{
radio.read(&buffer[n][loadBufferN],buffSize); // Read the payload from the radio
loadBufferN++;
}
esp_task_wdt_reset();
if(loadBufferN >= bucketTotal)
{
loadBufferN = 0;
buffFull[n] = true;
whichBuff = n;
}
}
}
所以基本上,我告诉看门狗等待999几秒钟才能被喂食。