A useful code for Arduino Nano ESP32

Timer-External Interrupts - UART1 and UART2

-In this code i used Arduino Nano ESP32 to test: Timer-External Interrupts - UART1 and UART2

you can use this example code in your project it's very useful for many things in your projects.

for example you can use non blocking uart for reading incoming data and do other things in the main loop then when data is ready(end of line or carriage return is found) you can process it.

-changing between Serial1 and Serial2 hardware is very simple just change the definition name.

you can also use both uart simultaneously in your project.

-There's a function to seacrh for any text you want from the read uart data an example is used to:

serach for high to turn on LED or low to turn off LED.

-a function to clear buffer used with serial and reset all varibales used to process the data.

  • timer is used to generate an interrupt every 1ms, an example is used to count until 1s for toggling LED.

  • an external interrupt example to use pin A2 which is connected to a push button.

important: when you use serial choose any of them or both but make sure to clear the buffer by calling the reset buffer and you send the name of the uart you have used an example for searching 'high' or 'low' is provided when finishing processing the data, call the reset buffer with the appropriate name of the uart you have used.

/*
    Timer-External Interrupts - UART1 and UART2

-In this code i used Arduino Nano ESP32 to test: Timer-External Interrupts - UART1 and UART2
you can use this example code in your project it's very useful for many things in your projects
for example you can use non blocking uart for reading incoming data and do other things in
the main loop when when data is ready(end of line or carriage return is found) you can process it.

-changing between Serial1 and Serial2 hardware is very simple just change the definition name 
you can also use both uart simultaneouly in your project.
-There's a function to seacrh for any text you want from read uart an example is used to:
serach for high to turn on LED or low to turn off LED.
-a function to clear buffer used with serial and reset varibales used to process the data.
- timer is used to generate an interrupt every 1ms, an example is used to count until 1s for toggling LED.
- an external interrupt example to use pin A2 which connected to a push button.

important: when you use serial choose any of them or both but make sure to clear the buffer by calling
the reset buffer and you send the name of the serial you have used there an example for searching
high or low when finishing processing you data call the reset buffer with the appropriate name 
of the uart you have used.



Author: Sameer M, sam.123.address@gmail.com
*/

const int led = A3; //led for  pin A3 ed output
const int led_stat = D13; //led_stat for pin D13 for  output
const int int_A2 = A2; //for pin A2 external interrupt input


#define _CR  0x0D  //CR carriage return
#define _LF  0x0A  //LF line feed(new line)
#define uart1 1
const int TX1PIN = D2; //TX on pin D2
const int RX1PIN = D3; //RX on pin D3
#define uart1_buffer_size 200
static char uart1_rx_buff[uart1_buffer_size]; //stores DATA read
static char _uart1_data_ready;  //will be set if DATA is ready in buffer
static unsigned int uart1_data_len; //determines the length of buffer
static char uart1_tmp;   //tmp will store temprory received DATA(byte)
#define uart2 2
const int TX2PIN = D5; //TX on pin D5
const int RX2PIN = D6; //RX on pin D6
#define uart2_buffer_size 200
static char uart2_rx_buff[uart2_buffer_size]; //stores DATA read
static char _uart2_data_ready;  //will be set if DATA is ready in buffer
static unsigned int uart2_data_len; //determines the length of buffer
static char uart2_tmp;   //tmp will store temprory received DATA(byte)


/*
  Timer0 will generate an interrupt every 1ms.
  a variable is used to count until 1s
*/
unsigned int timer0_counter = 0; //to be used to count for 1s to toggle the led
hw_timer_t *Timer0_Cfg = NULL;  //stores the config of timer0
void IRAM_ATTR Timer0_ISR() //timer0 isr
{ 
    timer0_counter++;
    if(timer0_counter >= 1000) 
    {
      digitalWrite(led_stat, !digitalRead(led_stat));
      timer0_counter=0;
    } 
}
void config_timer0()
{
    Timer0_Cfg = timerBegin(0, 80, true); //config timer 0, pre-scalar 80, count upward
    timerAttachInterrupt(Timer0_Cfg, &Timer0_ISR, true); //config timer0 isr
    timerAlarmWrite(Timer0_Cfg, 1000, true); //config timer0 to count up to 1000us and true for auto-reload timer0
    timerAlarmEnable(Timer0_Cfg);  //enable timer0 with the config
}

//interrupt service routine for external interrupt A2
void int_A2_isr()
{
    digitalWrite(led, !digitalRead(led));
}
void setup() 
{
  pinMode(led, OUTPUT);
  pinMode(led_stat, OUTPUT);
  config_timer0(); //config timer0 
  attachInterrupt(int_A2, int_A2_isr, RISING); //config interrupt service routine for pin A2
  Serial1.begin(115200, SERIAL_8N1, RX1PIN, TX1PIN); //config uart1
  Serial2.begin(115200, SERIAL_8N1, RX2PIN, TX2PIN); //config uart2
}
/*
This function finds substring in string source.
Returns 1 if substring is found in string source.
Returns 0 if substring is not found in string source.
Returns 2 if data is not ready yet.

which_uart used to select uart1 or uart3
*/
char find_string(char *substring, char which_uart)
{
   if(which_uart == uart1 && _uart1_data_ready == 1)
   {
     if(strstr(uart1_rx_buff, substring))
     {
        //reset_buff(which_uart);
        return 1;
     }
     else
        return 0;
   }
   else if(which_uart == uart2 && _uart2_data_ready == 1)
   {
     if(strstr(uart2_rx_buff, substring))
     {
        //reset_buff(which_uart);
        return 1;
     }
     else
        return 0;
   }

   return 2; //data is not ready, not received
}
//read incoming data on uart1 until end of line is found
void uart1_process_data()
{
    uart1_tmp = Serial1.read();  //read the byte in temperory 
    //Serial1.write(uart1_rx_buff); //display the data

    if(uart1_tmp == _LF || uart1_tmp == _CR) //IF  LF or CR FOUND
    {
      if(uart1_data_len > 1)  //and if there is data
      {
        uart1_rx_buff[uart1_data_len] = '\0';    //MAKE LAST ELEMENT IN BUFFER AS NULL
        _uart1_data_ready = 1;    //SET DATA READY FLAG
      }
    }
    else  //otherwise read DATA in buffer
    {
        uart1_rx_buff[uart1_data_len] = uart1_tmp;  //READ DATA IN BUFFER
        uart1_data_len++;     //INCREMENT COUNTER TO READ NEXT BYTE
    }  
}
//read incoming data on uart2 until end of line is found
void uart2_process_data()
{
    uart2_tmp = Serial2.read();  //read the byte in temperory 
    //Serial2.write(uart2_rx_buff); //display the data

    if(uart2_tmp == _LF || uart2_tmp == _CR) //IF  LF or CR FOUND
    {
      if(uart2_data_len > 1)  //and if there is data
      {
        uart2_rx_buff[uart2_data_len] = '\0';    //MAKE LAST ELEMENT IN BUFFER AS NULL
        _uart2_data_ready = 1;    //SET DATA READY FLAG
      }
    }
    else  //otherwise read DATA in buffer
    {
        uart2_rx_buff[uart2_data_len] = uart2_tmp;  //READ DATA IN BUFFER
        uart2_data_len++;     //INCREMENT COUNTER TO READ NEXT BYTE
    }  
}
//this function resets buffers and variables used with buffer uart
void reset_buff(char which_uart)
{
  if(which_uart == uart1)
  {
    memset(uart1_rx_buff,0,uart1_data_len); //reset buffer from first index to length used
    //reset variables used with buffer
    _uart1_data_ready = 0;
    uart1_data_len=0;
  }
  if(which_uart == uart2)
  {
    memset(uart2_rx_buff,0,uart2_data_len); //reset buffer from first index to length used
    //reset variables used with buffer
    _uart2_data_ready = 0;
    uart2_data_len=0;
  }
}
void loop() 
{
    //process incoming data on uart1
    while (Serial1.available () > 0 && _uart1_data_ready != 1)
       uart1_process_data();

    //process incoming data on uart2
    while (Serial2.available () > 0 && _uart2_data_ready != 1)
       uart2_process_data();
 
    //if the data received is high turn on led
    if(find_string("high", uart1) == 1 && _uart1_data_ready == 1) 
    {digitalWrite(led,HIGH);reset_buff(uart1);} 

    //if data received is low turn off led
    if(find_string("low", uart1) == 1 && _uart1_data_ready == 1) 
    {digitalWrite(led,LOW);reset_buff(uart1);} 
}

ChatGPT is too incompetent to know "Dx" is invalid when defining DIO pins... and 100 other errors.

Why did you not verify this before posting?

I suspect the TO was simply using a 2.0.x core.

I don't know how useful the code is, but it certainly compiled for me when I selected the Nano ESP32 and compiled it using a 2.0.14 core. Aside from a couple of warnings about converting string constants to 'char *' (I had the warning level turned all the way up), it was a clean compile.

Compiled with a 3.0.1 core there were a handful of errors, but the 3.0 core seems to have had a number of breaking changes.

Current Arduino Nano ESP32 DOES define Dx, off in .../arduino_nano_nora/pins_arduino.h:


static constexpr uint8_t D0         = 0; // also RX
static constexpr uint8_t D1         = 1; // also TX
static constexpr uint8_t D2         = 2;
static constexpr uint8_t D3         = 3; // also CTS
static constexpr uint8_t D4         = 4; // also DSR
static constexpr uint8_t D5         = 5;
static constexpr uint8_t D6         = 6;
static constexpr uint8_t D7         = 7;
static constexpr uint8_t D8         = 8;
static constexpr uint8_t D9         = 9;
static constexpr uint8_t D10        = 10; // also SS
static constexpr uint8_t D11        = 11; // also MOSI
static constexpr uint8_t D12        = 12; // also MISO
static constexpr uint8_t D13        = 13; // also SCK, LED_BUILTIN
static constexpr uint8_t LED_RED    = 14;
static constexpr uint8_t LED_GREEN  = 15;
static constexpr uint8_t LED_BLUE   = 16; // also RTS
1 Like

Hello,

I have compiled the code and tested all the functionality and works as expected with no errors.

Sorry. I did not pay attention to the board... which is vital.