Quan Gan
Quan Gan

Reputation: 1

Serial packets causing ESP32 to randomly halt and trigger watchdog timer reboot

I'm using the ESP32-Arduino to continuously receive serial data (2400 baud on Serial1) in an RTOS task. The task tests for a certain byte sequence using a state machine and does packet validation before setting a valid packet flag.

Occasionally, when I have too much data coming in, the system will halt and trigger a watchdog reboot.

I don't have a debugger on me so I can only rely on checking the serial monitor (Serial) and put print statements.

I thought that perhaps the buffer was full and I didn't get enough time to service is but I'm not sure.

I've tried to reduce the code in the RTOS task and let the post processing be done in the main loop. I guess I could trip the task even more but I haven't tried further.

I've also tried to both increase or decrease the frequency of the task and doesn't seem to make a difference.

Here's my code:


void readSerial(void *pvParameters)
{
    for (;;)
    {
        // Serial.print("chars avail: ");        
        while (Serial1.available())
        {
            char ch = Serial1.read();
            switch (nextSerialRecieveState)
            {
            case IDLE:
            case HEADER_0:
            default:
                rxByteIndex = 0;
                checkSum = 0;
                if (ch == 0x5A)
                {
                    nextSerialRecieveState = HEADER_1;
                }
                else
                {
                    nextSerialRecieveState = IDLE;
                }
                break;
            case HEADER_1:
                if (ch == 0x54)
                {
                    nextSerialRecieveState = PACKET_LENGTH;
                }
                else
                {
                    nextSerialRecieveState = IDLE;
                }
                break;
            case PACKET_LENGTH:



            case CHECKSUM_UPPER:
                checkSumUpperByte = ch;
                nextSerialRecieveState = CHECKSUM_LOWER;
                break;
            case CHECKSUM_LOWER:
                checkSumLowerByte = ch;
                if ((((checkSumUpperByte << 8) + checkSumLowerByte) == checkSum))
                {
                    serialPrintBuffer();
                    Serial.print("VALID PACKET FROM ");
                    Serial.print(SOURCE_BYTE_0, HEX);
                    Serial.print(":");
                    Serial.print(SOURCE_BYTE_1, HEX);
                    Serial.print(":");
                    Serial.println(SOURCE_BYTE_2, HEX);
                    validPacketFlag = 1;     


        }
                }
                nextSerialRecieveState = IDLE;
                break;
            }
            //lastByteReceivedTime = millis();
        }
        delay(10);
    }
}

not why is there's some fundamental misunderstanding I have about this task.

Upvotes: 0

Views: 384

Answers (1)

Weather Vane
Weather Vane

Reputation: 34583

I thought that perhaps the buffer was full and I didn't get enough time to service is but I'm not sure.

So what happens when the input buffer is (nearly) full? Is there a protocol to signal the remote transmitter not to transmit? If not, the buffer may overrun and then the message framing can get messed up, which can confuse the logic of your code.

No debugger: at the very least, check for buffer overrun within the code itself, and make it known. If there is, the code is useless anyway.

I've tried to reduce the code in the RTOS task and let the post processing be done in the main loop. I guess I could trip the task even more but I haven't tried further.

Complete that task. As a general rule, do as little as possible within the RTOS.

I've also tried to both increase or decrease the frequency of the task and doesn't seem to make a difference.

That won't affect the rate the data is arriving. First things first: establish if there is buffer overrun.

Upvotes: 0

Related Questions