feature(Line sensor Interrupts):

Added Edge Interrupt logic with debounce algorithm
This commit is contained in:
Devoalda 2023-10-23 21:22:12 +08:00
parent 9f19621eba
commit 2b34f8c856
3 changed files with 163 additions and 89 deletions

View File

@ -20,6 +20,9 @@ monitor_left_sensor_task(__unused void *params) {
{
if (xSemaphoreTake(g_left_sensor_sem, portMAX_DELAY) == pdTRUE)
{
if (left_sensor_triggered == pdTRUE)
{
printf("left sensor triggered\n");
// Get Current State
state_t state = gpio_get(LEFT_SENSOR_PIN);
@ -27,7 +30,9 @@ monitor_left_sensor_task(__unused void *params) {
&state,
sizeof(state_t),
0);
// Reset the flag
left_sensor_triggered = pdFALSE;
}
}
}
}
@ -41,11 +46,12 @@ monitor_left_sensor_task(__unused void *params) {
* @param params
*/
void
monitor_right_sensor_task(__unused void *params) {
for (;;)
{
if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE)
{
monitor_right_sensor_task(void *params) {
for (;;) {
if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE) {
// Check the flag or receive the message
if (right_sensor_triggered == pdTRUE) {
printf("right sensor triggered\n");
// Get Current State
state_t state = gpio_get(RIGHT_SENSOR_PIN);
@ -53,9 +59,13 @@ monitor_right_sensor_task(__unused void *params) {
&state,
sizeof(state_t),
0);
// Reset the flag
right_sensor_triggered = pdFALSE;
}
}
}
}
/**
* @brief Monitor the direction and Oritentation of the car
@ -83,55 +93,55 @@ monitor_direction_task(__unused void *params) {
sizeof(state_t),
portMAX_DELAY);
g_car_state.current_direction = (left_state << 1) | right_state;
// g_car_state.current_direction = (left_state << 1) | right_state;
switch (g_car_state.current_direction)
{
case FORWARD:
break;
case RIGHT:
g_car_state.orientation = (g_car_state.orientation + 1) & 0x03;
break;
case LEFT:
g_car_state.orientation = (g_car_state.orientation - 1) & 0x03;
break;
default:
break;
}
switch (g_car_state.current_direction)
{
case FORWARD:
printf("Direction: Forward\n");
break;
case RIGHT:
printf("Direction: Right\n");
break;
case LEFT:
printf("Direction: Left\n");
break;
default:
printf("Direction: Error\n");
break;
}
switch (g_car_state.orientation)
{
case NORTH:
printf("Orientation: North\n");
break;
case EAST:
printf("Orientation: East\n");
break;
case SOUTH:
printf("Orientation: South\n");
break;
case WEST:
printf("Orientation: West\n");
break;
default:
printf("Orientation: Error\n");
break;
}
// switch (g_car_state.current_direction)
// {
// case FORWARD:
// break;
// case RIGHT:
// g_car_state.orientation = (g_car_state.orientation + 1) & 0x03;
// break;
// case LEFT:
// g_car_state.orientation = (g_car_state.orientation - 1) & 0x03;
// break;
// default:
// break;
// }
//
// switch (g_car_state.current_direction)
// {
// case FORWARD:
// printf("Direction: Forward\n");
// break;
// case RIGHT:
// printf("Direction: Right\n");
// break;
// case LEFT:
// printf("Direction: Left\n");
// break;
// default:
// printf("Direction: Error\n");
// break;
// }
//
// switch (g_car_state.orientation)
// {
// case NORTH:
// printf("Orientation: North\n");
// break;
// case EAST:
// printf("Orientation: East\n");
// break;
// case SOUTH:
// printf("Orientation: South\n");
// break;
// case WEST:
// printf("Orientation: West\n");
// break;
// default:
// printf("Orientation: Error\n");
// break;
// }
}
}

View File

@ -19,6 +19,11 @@
#include "line_sensor_config.h"
#define DEBOUNCE_DELAY_MS 100
static TickType_t lastEdgeTimeLeft = 0;
static TickType_t lastEdgeTimeRight = 0;
typedef enum { // Unused, useful for readability
LINE_DETECTED = 0,
LINE_NOT_DETECTED = 1,
@ -53,6 +58,9 @@ SemaphoreHandle_t g_right_sensor_sem = NULL;
static MessageBufferHandle_t left_sensor_msg_buffer; // Left Sensor Buffer
static MessageBufferHandle_t right_sensor_msg_buffer; // Right Sensor Buffer
static volatile BaseType_t right_sensor_triggered = pdFALSE;
static volatile BaseType_t left_sensor_triggered = pdFALSE;
// Car State Struct
static car_state_t g_car_state;
@ -115,4 +123,50 @@ bool h_right_sensor_timer_handler(repeating_timer_t *repeatingTimer) {
return true;
}
void h_line_sensor_handler(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
TickType_t currentTicks = xTaskGetTickCount();
printf("Interrupt triggered\n");
if (gpio_get_irq_event_mask(LEFT_SENSOR_PIN) & GPIO_IRQ_EDGE_FALL)
{
if ((currentTicks - lastEdgeTimeLeft) >=
pdMS_TO_TICKS(DEBOUNCE_DELAY_MS))
{
lastEdgeTimeLeft = currentTicks;
gpio_acknowledge_irq(LEFT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL);
left_sensor_triggered = pdTRUE;
xSemaphoreGiveFromISR(g_left_sensor_sem, &xHigherPriorityTaskWoken);
}
else
{
// Reset the timer to the currentTicks if the edge is ignored
lastEdgeTimeLeft = currentTicks;
}
}
if (gpio_get_irq_event_mask(RIGHT_SENSOR_PIN) & GPIO_IRQ_EDGE_FALL)
{
if ((currentTicks - lastEdgeTimeRight) >=
pdMS_TO_TICKS(DEBOUNCE_DELAY_MS))
{
lastEdgeTimeRight = currentTicks;
gpio_acknowledge_irq(RIGHT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL);
// Set the flag to notify the task
right_sensor_triggered = pdTRUE;
xSemaphoreGiveFromISR(g_right_sensor_sem,
&xHigherPriorityTaskWoken);
}
else
{
// Reset the timer to the currentTicks if the edge is ignored
lastEdgeTimeRight = currentTicks;
}
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
#endif /* LINE_SENSOR_INIT_H */

View File

@ -9,17 +9,27 @@
void
launch()
{
struct repeating_timer g_left_sensor_timer;
add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
h_left_sensor_timer_handler,
NULL,
&g_left_sensor_timer);
// isr to detect left line sensor
gpio_set_irq_enabled(LEFT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL, true);
gpio_add_raw_irq_handler(LEFT_SENSOR_PIN, h_line_sensor_handler);
struct repeating_timer g_right_sensor_timer;
add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
h_right_sensor_timer_handler,
NULL,
&g_right_sensor_timer);
// isr to detect right line sensor
gpio_set_irq_enabled(RIGHT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL, true);
gpio_add_raw_irq_handler(RIGHT_SENSOR_PIN, h_line_sensor_handler);
irq_set_enabled(IO_IRQ_BANK0, true);
// struct repeating_timer g_left_sensor_timer;
// add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
// h_left_sensor_timer_handler,
// NULL,
// &g_left_sensor_timer);
//
// struct repeating_timer g_right_sensor_timer;
// add_repeating_timer_ms(LINE_SENSOR_READ_DELAY,
// h_right_sensor_timer_handler,
// NULL,
// &g_right_sensor_timer);
TaskHandle_t h_monitor_left_sensor_task;
xTaskCreate(monitor_left_sensor_task,
@ -37,13 +47,13 @@ launch()
READ_RIGHT_SENSOR_PRIO,
&h_monitor_right_sensor_task);
TaskHandle_t h_monitor_direction_task;
xTaskCreate(monitor_direction_task,
"Monitor Direction Task",
configMINIMAL_STACK_SIZE,
NULL,
DIRECTION_TASK_PRIORITY,
&h_monitor_direction_task);
// TaskHandle_t h_monitor_direction_task;
// xTaskCreate(monitor_direction_task,
// "Monitor Direction Task",
// configMINIMAL_STACK_SIZE,
// NULL,
// DIRECTION_TASK_PRIORITY,
// &h_monitor_direction_task);
vTaskStartScheduler();
}
@ -53,7 +63,7 @@ main (void)
{
stdio_usb_init();
sleep_ms(2000);
// sleep_ms(2000);
printf("Test started!\n");
line_sensor_setup();