I want to know why a code written by ChatGPT is working

Hi everyone! I don’t know whether providing help to beginners is among the purposes of this forum. Sorry if this isn’t the case.

My board: ESP32-C3 mini

I asked ChatGpt to write a sketch to send a UDP multicast message whenever I press a button.

The provided code was clear and simple:

  • ISR on the negative edge for the button
  • FreeRTOS queue (size 10)
  • ISR routine enqueue a message to the queue
  • A FreeRTOS task for reading the queue
  • No weird stuff on the ISR… just a straight call to xQueueSendFromISR

The code for the ISR routine is:

static void gpio_task(void* arg) {
    int io_num;
    while (1) {
        if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
            vTaskDelay(pdMS_TO_TICKS(50));  // Debounce delay
            if (gpio_get_level(io_num) == 0) {  // Button pressed
                udp_send_packet();
            }
        }
    }
}

It worked out of the box but hosts reading the UDP multicast were getting multiple messages.

The first thing I did was to increase the delay to 150 and so far it’s working (no bouncing)

But something kept bouncing (I know, bad joke) inside my head… How is that delay preventing the ISR from enqueueing multiple messages and just not just “delaying” the multiple send?

Further chatting with GPT didn’t lead anywhere.

I’d love to know why it’s working.

Thanks in advance for any enlightenment.

Best!

Pablo

How is the queue created? If it has a depth of one, then the isr attempting to post several messages will lead to the excess messages being dropped.

Most likely ISR enqueued multiple messages. You can confirm that by adding a log or counter in your task after xQueueReceive. If it turns out to be true, you may need to do debouncing in your ISR.

Hi RAc! Than you so much for taking the timer to read me. The queue is created with size 10. Here is the exact line:
gpio_evt_queue = xQueueCreate(10, sizeof(int));

Best!

Pablo

Hi aggarg! Thank you for looking at this! Do you know why just increasing the delay could have solved my issue? As I said, “sleeping” on the task doesn’t seem like a valid solution… At least on OSs/Archs I have experience with… because it won’t prevent the ISR to enqueue multiple messages. But I don’t know esp32 nor FreeRTOS internals so here I’m asking… I don’t like to “fix” things without understanding what is happening.

Best!

Pablo

please publish the entire code. In particular, what is the payload that the isr passes via the queue?

One possible reason is that the check if (gpio_get_level(io_num) == 0) fails and you end up dropping the message here. It should be possible to confirm by adding a log/counter/breakpoint.

Your message made me realize I was missing the point. The delay in the task doesn’t avoid the bouncing but nullifies its effect. Forcing the task to sleep makes sure that by the time the messages from bounces are read from the queue, the GPIO state is already stabilized in 1.

Thank you!

One thing that we have done for cases like that is have the ISR disable itself, and then the task re-enables it after the time out. Thus really debouncing the system.

1 Like