-
Notifications
You must be signed in to change notification settings - Fork 7.6k
[2.0.0] Adds the setRXInterrupt #4656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4d262c5
a4df65f
b20b3cd
725ad11
e8272c7
623796a
000482e
2e657a7
38914ff
8a27284
ba351a8
8db7e7f
96fa55f
7d84946
054c1a9
c344425
1ba43fc
cadb74d
02b29fd
d63d896
7bea5a4
def8f9c
21043d5
55ae3be
be5000b
6d7e8eb
e3298ea
3bfadf8
8cda769
36ebb83
cf98504
0b2ae4e
715f399
4f80e57
f33c332
5beb727
52b8a41
f948c78
4441190
ce3952d
d8f54ee
b3511e5
32a7446
f89b634
41a869a
12b8725
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/** Tim Koers - 2021 | ||
* | ||
* This sketch shows the usage of a semaphore to receive Serial data. | ||
* You can safely use this in a FreeRTOS environment and use the semaphore from different tasks on different CPU cores. | ||
* However, the InterruptQueue example is much more efficient, since it uses less code. | ||
* This sketch assumes that when Hi is sent, the device returns an 8 byte message. | ||
* | ||
*/ | ||
|
||
#define BUFFER_SIZE 8 | ||
|
||
// This semaphore is here to handle the interruption of the loop when the interrupt is running. | ||
SemaphoreHandle_t bufferSemaphore; | ||
|
||
static volatile char inputBuffer[BUFFER_SIZE]; | ||
static volatile size_t inputBufferLength = 0; | ||
|
||
bool messageSent = false; | ||
|
||
// Please keep in mind, since the ESP32 is dual core, | ||
// the interrupt will be running on the same core as the setRxInterrupt function was called on. | ||
static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ | ||
|
||
timkoers marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Cast the user_arg back to a array | ||
char* buffer = (char*)user_arg; | ||
|
||
BaseType_t xHighPriorityTaskWoken; | ||
|
||
if(xSemaphoreTakeFromISR(bufferSemaphore, &xHighPriorityTaskWoken) == pdTRUE){ | ||
if(inputBufferLength < BUFFER_SIZE){ | ||
buffer[inputBufferLength++] = (char)character; | ||
} | ||
xSemaphoreGiveFromISR(bufferSemaphore, &xHighPriorityTaskWoken); | ||
} | ||
} | ||
|
||
void setup() | ||
{ | ||
bufferSemaphore = xSemaphoreCreateBinary(); | ||
|
||
Serial.begin(115200); | ||
Serial2.begin(115200); | ||
|
||
// The user_arg is expected to be a void pointer (void*), | ||
// so take the reference of the variable, and it to a void* | ||
Serial2.setRxInterrupt(onSerialRX, (void*)&inputBuffer); | ||
} | ||
|
||
void loop() | ||
{ | ||
if(!messageSent){ | ||
Serial.println("Hi"); | ||
messageSent = true; | ||
} | ||
|
||
// Check if the semaphore can be taken and if the inputBuffer length is long enough. | ||
// Please keep in mind, since the variable inputBufferLength is also accessed inside the IRQ handler, | ||
// the semaphore needs to be taken BEFORE you can access that variable. | ||
if(xSemaphoreTake(bufferSemaphore, portMAX_DELAY) == pdTRUE && inputBufferLength == (BUFFER_SIZE - 1)){ | ||
for(size_t i = 0; i < inputBufferLength; i++){ | ||
Serial.write(inputBuffer[i]); | ||
|
||
// Clear the buffer | ||
inputBuffer[i] = '\0'; | ||
} | ||
// Clear the bufferLength | ||
inputBufferLength = 0; | ||
|
||
// Give back the semaphore | ||
xSemaphoreGive(bufferSemaphore); | ||
|
||
// Allow the system to request another data set | ||
messageSent = false; | ||
} | ||
|
||
delay(10); // Wait for 10ms to allow some data to come in | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/** Tim Koers - 2021 | ||
* | ||
* This sketch shows the usage of an queue, to store and read the characters that are sent to the interrupt. | ||
* You can safely use this in a FreeRTOS environment and use the queue from different tasks on different CPU cores. | ||
* This sketch assumes that when Hi is sent, the device returns an 8 byte message. | ||
* | ||
*/ | ||
|
||
#define BUFFER_SIZE 8 | ||
|
||
// This queue is here to handle the interruption of the loop when the interrupt is running. | ||
QueueHandle_t bufferQueue; | ||
|
||
bool messageSent = false; | ||
|
||
// Please keep in mind, since the ESP32 is dual core, | ||
// the interrupt will be running on the same core as the setRxInterrupt function was called on. | ||
static void IRAM_ATTR onSerialRX(uint8_t character, void* user_arg){ | ||
|
||
BaseType_t xHighPriorityTaskWoken; | ||
|
||
if(xQueueSendFromISR(bufferQueue, &character, &xHighPriorityTaskWoken) != pdTRUE){ | ||
log_e("IRQ", "Failed to put character onto the queue\n"); | ||
} | ||
} | ||
|
||
void setup() | ||
{ | ||
bufferQueue = xQueueCreate(BUFFER_SIZE * 4, sizeof(char)); // Create a queue that can hold 4 messages of 8-bytes each. | ||
|
||
assert(bufferQueue != NULL); | ||
|
||
Serial.begin(115200); | ||
Serial2.begin(115200); | ||
|
||
Serial2.setRxInterrupt(onSerialRX, NULL); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @timkoers I tested the code and it is working fine. I have only one issue at this point during Setup initilization... it sometimes stop at setrxInterrupt function. When I delete Serial2.begin and Serial2.setRxInterrupt -> upload the code -> then add Serial2.begin and Serial2.setRxInterrupt -> upload the code, everything starts to work fine again... I'm trying to figure out why this is happening... |
||
} | ||
|
||
void loop() | ||
{ | ||
if(!messageSent){ | ||
Serial.println("Hi"); | ||
messageSent = true; | ||
} | ||
|
||
// Check if data in the queue and check if there is a complete message (8-bytes) in the queue | ||
if(!(uxQueueMessagesWaiting(bufferQueue) % BUFFER_SIZE)){ | ||
char c; | ||
// Check if the queue is not empty, 0 % 8 returns 0 instead, so does 24 % 8 | ||
while(uxQueueMessagesWaiting(bufferQueue) > 0){ | ||
// Get the character from the queue, but don't block if someone else is busy with the queue | ||
if(xQueueReceive(bufferQueue, &c, 0) == pdTRUE) | ||
Serial.write(c); | ||
} | ||
|
||
// Allow the system to request another data set | ||
messageSent = false; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.