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);}
}