[SOLVED] INTERRUPT UART example work only one time and after hold

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

[SOLVED] INTERRUPT UART example work only one time and after hold

Postby gpezzella » Mon Apr 01, 2019 11:51 am

Hello
I'm testing your ISR UART code and it work but ONLY ONE TIME!
After it hold and not receive nothing. Why??

Next question:
How save in string variable received data??

Code: Select all

String Received_Data = ??? (dtmp)
Please reply me soon.
Thanks in advice


  1. /*
  2.  * https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/uart.html#uart-api-setting-communication-pins
  3.  */
  4.  
  5.  
  6.  
  7.  
  8. #include "driver/uart.h"
  9.  
  10. #define NUMERO_PORTA_SERIALE UART_NUM_2
  11. #define BUF_SIZE (1024 * 2)
  12. #define RD_BUF_SIZE (1024)
  13. static QueueHandle_t uart2_queue;
  14.  
  15. static const char * TAG = "";                  
  16.  
  17. #define U2RXD 33
  18. #define U2TXD 32
  19.  
  20.  
  21. void setup() {
  22.  
  23.     Serial.begin(115200);
  24.  
  25.     //Configuro la porta Serial2 (tutti i parametri hanno anche un get per effettuare controlli)
  26.     uart_config_t Configurazione_UART2 = {
  27.         .baud_rate = 9600,
  28.         .data_bits = UART_DATA_8_BITS,
  29.         .parity = UART_PARITY_DISABLE,
  30.         .stop_bits = UART_STOP_BITS_1,
  31.         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
  32.     };
  33.     uart_param_config(NUMERO_PORTA_SERIALE, &Configurazione_UART2);
  34.  
  35.  
  36.  
  37.     //Firma: void esp_log_level_set(const char *tag, esp_log_level_tlevel)
  38.     esp_log_level_set(TAG, ESP_LOG_INFO);
  39.  
  40.  
  41.    
  42.     //Firma: esp_err_tuart_set_pin(uart_port_tuart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
  43.     uart_set_pin(NUMERO_PORTA_SERIALE, U2TXD, U2RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
  44.  
  45.  
  46.     //Firma: uart_driver_install(UART_NUM_2, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
  47.     //       uart_driver_install(Numero_porta, RXD_BUFFER, TXD_Buffer, event queue handle and size, flags to allocate an interrupt)
  48.     uart_driver_install(NUMERO_PORTA_SERIALE, BUF_SIZE, BUF_SIZE, 20, &uart2_queue, 0);
  49.  
  50.  
  51.     //Create a task to handler UART event from ISR
  52.     xTaskCreate(UART_ISR_ROUTINE, "UART_ISR_ROUTINE", 2048, NULL, 12, NULL);
  53.  
  54. }
  55.  
  56.  
  57.  
  58. void loop() {
  59.   Serial.println("Waiting data from  SERIAL 2....");
  60.   delay(1000);
  61.   }
  62.  
  63.  
  64.  
  65.  
  66. static void UART_ISR_ROUTINE(void *pvParameters){
  67.  
  68. uart_event_t event;
  69. size_t buffered_size;
  70. uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
  71.  
  72. Serial.println("INSIDE ISR");
  73.  
  74.         if(xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
  75.  
  76.             bzero(dtmp, RD_BUF_SIZE);
  77.  
  78.             ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
  79.  
  80.  
  81.                 if (event.type==UART_DATA){
  82.  
  83.                     //ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
  84.  
  85.                     uart_read_bytes(NUMERO_PORTA_SERIALE, dtmp, event.size, portMAX_DELAY);
  86.  
  87.                     Serial.println("DATA= ");
  88.  
  89.                     //ESP_LOGI(TAG, "[DATA EVT]:");
  90.  
  91.                     //uart_write_bytes(NUMERO_PORTA_SERIALE, (const char*) dtmp, event.size);
  92.                
  93.                 }// if event.type
  94.  
  95.  
  96.  
  97.         }//if xQuequeReceive
  98.  
  99.  
  100.  free(dtmp);
  101.  dtmp = NULL;
  102.  vTaskDelete(NULL);
  103.  
  104. }
  105.  
  106.  
Last edited by gpezzella on Tue Apr 02, 2019 10:15 am, edited 1 time in total.

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

Re: INTERRUPT UART example work only one time and after hold

Postby gpezzella » Mon Apr 01, 2019 2:18 pm

update 1:

I have change the code inside UART_ISR_ROUTINE in this way and it return me:
ISR Status= 0
RX FIFO LEN=0
Why?
  1. uart_event_t event;
  2. uint16_t rx_fifo_len=0, ISR_Status=0, i=0;
  3.  
  4.  
  5.         Serial.println("INSIDE ISR");
  6.  
  7.         if(xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
  8.  
  9.  
  10.  
  11.                 if (event.type==UART_DATA){
  12.  
  13.                
  14.  
  15.                    
  16.                     ISR_Status = UART2.int_st.val; // read UART interrupt Status
  17.                     Serial.print("ISR Status= ");Serial.println(ISR_Status);
  18.                    
  19.                     rx_fifo_len = UART2.status.rxfifo_cnt; // read number of bytes in UART buffer
  20.                     Serial.print("RX FIFO LEN= ");Serial.println(rx_fifo_len);
  21.                    
  22.                     while(rx_fifo_len){
  23.                      rxbuf[i++] = UART2.fifo.rw_byte; // read all bytes
  24.                      Serial.print(rxbuf[i++]);
  25.                      rx_fifo_len--;
  26.                      }
  27.  
  28.                      // after reading bytes from buffer clear UART interrupt status
  29.                      uart_clear_intr_status(NUMERO_PORTA_SERIALE, UART_RXFIFO_FULL_INT_CLR|UART_RXFIFO_TOUT_INT_CLR);
  30.                    
  31.                
  32.                 }// if event.type
  33.  
  34.  
  35.  
  36.         }//if xQuequeReceive
  37.  
  38.  vTaskDelete(NULL);

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: INTERRUPT UART example work only one time and after hold

Postby ESP_Dazz » Mon Apr 01, 2019 3:36 pm

Because you're creating a Task instead of an ISR? The task simply receives form the queue once, then deletes itself.
//Create a task to handler UART event from ISR
xTaskCreate(UART_ISR_ROUTINE, "UART_ISR_ROUTINE", 2048, NULL, 12, NULL);

...

free(dtmp);
dtmp = NULL;
vTaskDelete(NULL);
If you are implementing a task to continuously receive from a UART event queue, it should be implemented as some form of loop

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

Re: INTERRUPT UART example work only one time and after hold

Postby gpezzella » Mon Apr 01, 2019 3:46 pm

Hi ESP_dazz

could you gently show me the correct way?
I'm new with ESP32 and for this reason I reuse code of example without understand every line of code.

In any case with update 1 code my output is:
ISR_Status=0
rx_fifo_len=0

Thanks in advice

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: INTERRUPT UART example work only one time and after hold

Postby ESP_Dazz » Mon Apr 01, 2019 4:15 pm

A FreeRTOS task should be implemented as an infinite loop.
  1. static void UART_ISR_ROUTINE(void *pvParameters)
  2. {
  3.     uart_event_t event;
  4.     size_t buffered_size;
  5.     uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
  6.     bool exit_condition = false;
  7.    
  8.     //Infinite loop to run main bulk of task
  9.     while (1) {
  10.         //Loop will continually block (i.e. wait) on event messages from the event queue
  11.         if(xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
  12.             //Handle received event
  13.             if (event.type == UART_DATA) {
  14.                 //Handle your uart reading here
  15.             }
  16.             else if (event.type == UART_FRAME_ERR) {
  17.                 //Handle frame error event
  18.             }
  19.             ... //Keep adding else if statements for each UART event you want to support
  20.             else {
  21.                 //Final else statement to act as a default case
  22.             }      
  23.         }
  24.        
  25.         //If you want to break out of the loop due to certain conditions, set exit condition to true
  26.         if (exit_condition) {
  27.             break;
  28.         }
  29.     }
  30.    
  31.     //Out side of loop now. Task needs to clean up and self terminate before returning
  32.     free(dtmp);
  33.     dtmp = NULL;
  34.     vTaskDelete(NULL);
  35. }
As to why the ISR_Status=0 and rx_fifo_len=0, it could be because you are receive different events other than UART_DATA, so I suggest you check for the type of event that you are receiving.

EDIT: Didn't see you checked for ISR_Status=0 and rx_fifo_len=0 after checking UART_DATA. Are you trying to use the Arduino UART driver or the ESP-IDF UART driver?

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

Re: INTERRUPT UART example work only one time and after hold

Postby gpezzella » Mon Apr 01, 2019 4:31 pm

Hi ESP_Dazz

now it work in continuous mode!!

I use Arduino for UART0 (debug) and idf for UART2

I replace Serial.print("DATA= ") with follow code but cannot read nothing...why?
  1.   rx_fifo_len = UART2.status.rxfifo_cnt; // read number of bytes in UART buffer
  2.   Serial.print("DATA= ");
  3.   while(rx_fifo_len){
  4.    rxbuf[i++] = UART2.fifo.rw_byte; // read all bytes
  5.    Serial.print(rxbuf[i]);
  6.    rx_fifo_len--;
  7.  }

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: INTERRUPT UART example work only one time and after hold

Postby ESP_Dazz » Mon Apr 01, 2019 4:46 pm

Well I'm not exactly sure why you are checking the values of hardware registers (i.e. UART2.status.rxfifo_cnt). The driver should already handle the transfer of data from the hardware FIFO to a software ring buffer. I suggest you take a look at the existing UART examples on how to use the IDF UART driver API properly.

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

[SOLVED] INTERRUPT UART example work only one time and after hold

Postby gpezzella » Tue Apr 02, 2019 10:14 am

FINAL WORKING PROGRAM
IT READ DATA FROM UART2 IN INTERRUPT MODE AND SEND TO UART0:
  1. /*
  2.  * https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/uart.html#uart-api-setting-communication-pins
  3.  */
  4.  
  5.  
  6.  
  7.  
  8. #include "driver/uart.h"
  9.  
  10. #define NUMERO_PORTA_SERIALE UART_NUM_2
  11. #define BUF_SIZE (1024 * 2)
  12. #define RD_BUF_SIZE (1024)
  13. static QueueHandle_t uart2_queue;
  14.  
  15. static const char * TAG = "";                  
  16.  
  17. #define U2RXD 33
  18. #define U2TXD 32
  19.  
  20. uint8_t rxbuf[256];     //Buffer di ricezione
  21. uint16_t rx_fifo_len;        //Lunghezza dati
  22.  
  23.  
  24. void setup() {
  25.  
  26.     Serial.begin(115200);
  27.  
  28.     //Configuro la porta Serial2 (tutti i parametri hanno anche un get per effettuare controlli)
  29.     uart_config_t Configurazione_UART2 = {
  30.         .baud_rate = 9600,
  31.         .data_bits = UART_DATA_8_BITS,
  32.         .parity = UART_PARITY_DISABLE,
  33.         .stop_bits = UART_STOP_BITS_1,
  34.         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
  35.     };
  36.     uart_param_config(NUMERO_PORTA_SERIALE, &Configurazione_UART2);
  37.  
  38.  
  39.  
  40.     //Firma: void esp_log_level_set(const char *tag, esp_log_level_tlevel)
  41.     esp_log_level_set(TAG, ESP_LOG_INFO);
  42.  
  43.  
  44.    
  45.     //Firma: esp_err_tuart_set_pin(uart_port_tuart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
  46.     uart_set_pin(NUMERO_PORTA_SERIALE, U2TXD, U2RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
  47.  
  48.  
  49.     //Firma: uart_driver_install(UART_NUM_2, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
  50.     //       uart_driver_install(Numero_porta, RXD_BUFFER, TXD_Buffer, event queue handle and size, flags to allocate an interrupt)
  51.     uart_driver_install(NUMERO_PORTA_SERIALE, BUF_SIZE, BUF_SIZE, 20, &uart2_queue, 0);
  52.  
  53.  
  54.     //Create a task to handler UART event from ISR
  55.     xTaskCreate(UART_ISR_ROUTINE, "UART_ISR_ROUTINE", 2048, NULL, 12, NULL);
  56.  
  57. }
  58.  
  59.  
  60.  
  61. void loop() {
  62.   Serial.println("Waiting data from  SERIAL 2....");
  63.   delay(1000);
  64.   }
  65.  
  66.  
  67.  
  68.  static void UART_ISR_ROUTINE(void *pvParameters)
  69. {
  70.     uart_event_t event;
  71.     size_t buffered_size;
  72.     bool exit_condition = false;
  73.    
  74.     //Infinite loop to run main bulk of task
  75.     while (1) {
  76.      
  77.         //Loop will continually block (i.e. wait) on event messages from the event queue
  78.         if(xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
  79.          
  80.             //Handle received event
  81.             if (event.type == UART_DATA) {
  82.  
  83.                 uint8_t UART2_data[128];
  84.                 int UART2_data_length = 0;
  85.                 ESP_ERROR_CHECK(uart_get_buffered_data_len(UART_NUM_2, (size_t*)&UART2_data_length));
  86.                 UART2_data_length = uart_read_bytes(UART_NUM_2, UART2_data, UART2_data_length, 100);
  87.              
  88.                 Serial.println("LEN= ");Serial.println(UART2_data_length);
  89.  
  90.                 Serial.print("DATA= ");
  91.                 for(byte i=0; i<UART2_data_length;i++) Serial.print((char)UART2_data[i]);
  92.                 Serial.println("");
  93.              
  94.             }
  95.            
  96.             //Handle frame error event
  97.             else if (event.type == UART_FRAME_ERR) {
  98.                 //TODO...
  99.             }
  100.            
  101.             //Keep adding else if statements for each UART event you want to support
  102.             //else if (event.type == OTHER EVENT) {
  103.                 //TODO...
  104.             //}
  105.            
  106.            
  107.             //Final else statement to act as a default case
  108.             else {
  109.                 //TODO...
  110.             }      
  111.         }
  112.        
  113.         //If you want to break out of the loop due to certain conditions, set exit condition to true
  114.         if (exit_condition) {
  115.             break;
  116.         }
  117.     }
  118.    
  119.     //Out side of loop now. Task needs to clean up and self terminate before returning
  120.     vTaskDelete(NULL);
  121. }
  122.  
  123.  

IOTCure
Posts: 1
Joined: Wed Sep 11, 2019 12:54 pm

Re: [SOLVED] INTERRUPT UART example work only one time and after hold

Postby IOTCure » Wed Sep 11, 2019 1:04 pm

Hello gpezella,

I tried to run your code, it compiles successfully but UART2 is not working working in Interrupt mode for RX.

when I tried to debug with serial monitor, I found the provided ISR function static void UART_ISR_ROUTINE(void *pvParameters) is executed only one time at start rest never call again in program.

i tried to send data on UART2 and looking for same data on UART0, but it is not working.

kindly help, what i am missing here.

Thanks In Advance.

Regards,
Cure

JJ_Bras
Posts: 3
Joined: Wed Dec 01, 2021 1:30 pm

Re: [SOLVED] INTERRUPT UART example work only one time and after hold

Postby JJ_Bras » Wed Dec 01, 2021 1:34 pm

Hi everyone, I am with the same problem. I think that it is stoped into "xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)"

Who is online

Users browsing this forum: No registered users and 48 guests