I’m using a SAMD21G18 microcontroller with Arduino as the development platform and I want to implement a UART interrupt service routine. Is there a way to achieve this?
Hi there,
Something like this would do.
void setup(){
Serial.begin(9600);
pinMode(7, INPUT); // Make pin 7 RXD an input
// attach our interrupt pin to it's ISR
attachInterrupt(0, recISR, CHANGE);
// we need to call this to enable interrupts
interrupts();
}
// The interrupt hardware calls this when we hit our left bumper
void recISR(){
// rec = 1;
Serial.println("interrupt!");
}
Give something like that a try.
HTH
GL PJ
I’ve successfully set up a UART-based interrupt system using the code below. The interrupt is triggered on changes to the RX pin (pin 7), and it correctly prints “interrupt!” to Serial1 when triggered.
void setup() {
Serial1.begin(115200);
pinMode(7, INPUT); // Configure pin 7 as an input
// Attach interrupt to pin 7 with ISR for CHANGE event
attachInterrupt(digitalPinToInterrupt(7), recISR, CHANGE);
// Enable interrupts
interrupts();
}
// ISR for handling interrupts
void recISR() {
Serial1.println("interrupt!");
}
I made a small change to the code by adding digitalPinToInterrupt(7)
to the attachInterrupt
function, which resolved the issue. However, I am still encountering difficulties reading the received UART data from the RX register and transmitting it via the TX line.
Could anyone provide guidance on how to read the incoming data from the RX register and send it through the TX line within the ISR, or suggest a more effective approach for handling UART communication with interrupts?
Hi there,
You almost have it…
HTH
GL PJ
Don’t forget to mark this as the solution so others may find it.
goal:
-
I want to use the same UART serial port for both receiving data via interrupts and transmitting data via
Serial1.write()
or similar. -
When a character is received on the RX line, I need to trigger an interrupt. In the interrupt handler, I will read the character directly from the RX register and store it in a character array for further processing.
Details: -
I don’t want to use another serial port (like SoftwareSerial or Serial2). I just need to work with one UART for both RX and TX.
-
How can I set up an interrupt for the RX event on the XIAO SAMD21G18? And how do I read the character from the RX register after the interrupt is triggered?
Hi there,
You just need to read the data that caused the interrupt . something like this will do it.
#define BUFFER_SIZE 50
char dataBuffer[BUFFER_SIZE]; // Buffer for storing incoming data
int dataIndex = 0; // Keep track of where to write new data
void setup() {
Serial.begin(9600); // Initialize Serial at 9600 baud rate
pinMode(7, INPUT); // Pin 7 for any other interrupts you need
// Attaching interrupt for pin 7 (e.g., for an external signal)
attachInterrupt(digitalPinToInterrupt(7), recISR, CHANGE);
// Enabling global interrupts
interrupts();
}
void loop() {
// Check if serial data is available
if (Serial.available() > 0) {
char incomingByte = Serial.read(); // Read the incoming byte
Serial.print("Received: ");
Serial.println(incomingByte); // Print it for debugging
// Add incoming byte to buffer (make sure it doesn't overflow)
if (dataIndex < BUFFER_SIZE - 1) {
dataBuffer[dataIndex] = incomingByte;
dataIndex++;
dataBuffer[dataIndex] = '\0'; // Null-terminate the string
}
// For demonstration, you can send the received data back
Serial.println(dataBuffer);
}
}
// The ISR for pin 7 (triggered when the pin changes state)
void recISR() {
Serial.println("External interrupt triggered!");
}
The Serial
library already has a built-in way to check when data arrives through the Serial.available()
function, and it’s usually better to avoid using hardware interrupts for serial data handling, as Serial
interrupts internally when data arrives.
However, if you want to stick with the interrupt approach for another reason (like reading a pin), here’s a general concept you could follow:
- Use
Serial.available()
to check if there is data to read. - Use
Serial.read()
to grab the incoming data and append it to an array. - Send that data back using
Serial.write()
orSerial.println()
.
above is a cleaner implementation without relying on an interrupt for the serial port itself:
Key Points:
-
Serial Data Handling: The code now checks for serial data in the
loop()
usingSerial.available()
. This ensures no data is missed. -
Buffering: Data is stored in a
dataBuffer[]
, and it’s printed back when new data arrives. - External Interrupt: An interrupt on pin 7 remains, but it’s for an external signal and won’t interfere with serial data reception.
This should work for your use case, handling serial data and sending it back while also using an interrupt for other purposes on pin 7.
HTH
GL PJ