Skip to content

Commit e4b600e

Browse files
committed
better ISR handling, improved bouncing/noise filter
1 parent 6317d7e commit e4b600e

File tree

4 files changed

+42
-35
lines changed

4 files changed

+42
-35
lines changed

main/Tasks/core/calcRideParamsOnISR.task.c

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static void vOnSyncFinishHandle(void *handler_args, esp_event_base_t base, int32
3737

3838
void vCalcRideParamsOnISRTask(void *data) {
3939
float currentSpeed;
40-
uint16_t msBetweenRotationTicks;
40+
uint16_t msBetweenRotationTicks = 0;
4141

4242
ESP_LOGI(TAG, "Init reed switch");
4343

@@ -46,38 +46,37 @@ void vCalcRideParamsOnISRTask(void *data) {
4646

4747
for (;;) {
4848
if (xQueueReceive(reed_evt_queue, &rideParams.rotationTickCount, portMAX_DELAY) && !ignoreReed) {
49-
// TODO create buffer for reed time impulses before calculating time and speed
50-
// TODO block rideParams while calculating?
51-
if (rideParams.prevRotationTickCount != 0) {
52-
if (!rideParams.moving) {
53-
esp_event_post_to(obc_events_loop, OBC_EVENTS, RIDE_START_EVENT, NULL, 0, portMAX_DELAY);
54-
}
55-
msBetweenRotationTicks = ((int)rideParams.rotationTickCount - (int)rideParams.prevRotationTickCount) * (int)portTICK_PERIOD_MS;
56-
rideParams.totalRideTimeMs += msBetweenRotationTicks;
57-
// TODO sometimes tick count doesn't update even with queue? prevent speed = inf for now
58-
if (msBetweenRotationTicks > 0.00) {
59-
currentSpeed = ((float)CIRCUMFERENCE / 1000000) / ((float)msBetweenRotationTicks / 3600000); // km/h
60-
// simple, soft filtering of noise (from cables?) - should't introduce any discrepancy to actual data
61-
// and also could be used to detect unplanned, immediate stops
62-
// max reasonable acceleration is 5.8 m/s/s
63-
if (abs((int)(currentSpeed - rideParams.speed)) > 30) {
64-
continue;
65-
}
66-
67-
rideParams.moving = true;
68-
rideParams.rotations++;
69-
rideParams.speed = currentSpeed;
70-
rideParams.distance += (float)CIRCUMFERENCE / 1000000;
71-
rideParams.totalDistance += (float)CIRCUMFERENCE / 1000000;
72-
rideParams.avgSpeed = rideParams.distance / ((float)rideParams.totalRideTimeMs / 3600000);
73-
if (rideParams.speed > rideParams.maxSpeed) {
74-
rideParams.maxSpeed = rideParams.speed;
75-
}
76-
}
49+
if (rideParams.rotationTickCount == rideParams.prevRotationTickCount || rideParams.rotationTickCount == 0) {
50+
continue;
51+
};
52+
53+
msBetweenRotationTicks = ((int)rideParams.rotationTickCount - (int)rideParams.prevRotationTickCount) * (int)portTICK_PERIOD_MS;
54+
55+
if (msBetweenRotationTicks <= REED_BOUNCE_MS) {
56+
continue;
7757
}
58+
7859
rideParams.prevRotationTickCount = rideParams.rotationTickCount;
60+
// ESP_LOGI(TAG, "Reed switch triggered %" PRIu32 " diff: %" PRIu16, rideParams.rotationTickCount, msBetweenRotationTicks);
61+
62+
// TODO block rideParams while calculating?
63+
if (!rideParams.moving) {
64+
esp_event_post_to(obc_events_loop, OBC_EVENTS, RIDE_START_EVENT, NULL, 0, portMAX_DELAY);
65+
}
66+
67+
currentSpeed = ((float)CIRCUMFERENCE / 1000000) / ((float)msBetweenRotationTicks / 3600000); // km/h
68+
rideParams.moving = true;
69+
rideParams.rotations++;
70+
rideParams.speed = currentSpeed;
71+
rideParams.totalRideTimeMs += msBetweenRotationTicks;
72+
rideParams.distance += (float)CIRCUMFERENCE / 1000000;
73+
rideParams.totalDistance += (float)CIRCUMFERENCE / 1000000;
74+
rideParams.avgSpeed = rideParams.distance / ((float)rideParams.totalRideTimeMs / 3600000);
75+
if (rideParams.speed > rideParams.maxSpeed) {
76+
rideParams.maxSpeed = rideParams.speed;
77+
}
7978

80-
// ESP_LOGI(TAG, "[REED] count: %d, speed: %0.2f, diff: %d, distance: %0.2f", rideParams.rotations, rideParams.speed, msBetweenRotationTicks, rideParams.distance);
79+
// ESP_LOGI(TAG, "[REED] count: %" PRIu32 ", speed: %0.2f, diff: %" PRIu16 ", distance: %0.2f", rideParams.rotations, rideParams.speed, msBetweenRotationTicks, rideParams.distance);
8180
// ESP_LOGI(TAG, "[AVGS] speed: %0.2f", rideParams.avgSpeed);
8281
}
8382
}

main/Tasks/core/calcRideParamsOnISR.task.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef TASKS_CORE_CALC_RIDE_PARAMS_ON_ISR_H
22
#define TASKS_CORE_CALC_RIDE_PARAMS_ON_ISR_H
33

4+
// will ignore reed events for this time after last event to filter out bouncing/noise
5+
#define REED_BOUNCE_MS 15
46
// calculates ride params on reed isr queue receive
57
void vCalcRideParamsOnISRTask(void* data);
68

main/Tasks/core/rideStatusWatchdog.task.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ void vRideStatusWatchdogTask(void *arg) {
2323
ESP_LOGI(TAG, "Initialization");
2424

2525
while (true) {
26-
msg_count = uxQueueMessagesWaitingFromISR(reed_evt_queue);
26+
msg_count = uxQueueMessagesWaiting(reed_evt_queue);
2727
currentTickCount = xTaskGetTickCount();
2828
timeInactive = ((int)currentTickCount - (int)rideParams.prevRotationTickCount) * (int)portTICK_PERIOD_MS;
29+
// ESP_LOGI(TAG, "msg_count: %d, timeInactive: %d", msg_count, timeInactive);
2930

3031
if (rideParams.moving && !msg_count && timeInactive > RIDE_TIMEOUT_MS) {
3132
ESP_LOGI(TAG, "[RIDE_STATUS] Stopped moving");

main/main.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,13 @@ ride_params_t rideParams = {
5555

5656
// IRAM_ATTR - function with this will be moved to RAM in order to execute faster than default from flash
5757
static void IRAM_ATTR vReedISR(void* arg) {
58-
TickType_t xLastReedTickCount = xTaskGetTickCount();
59-
xQueueSendFromISR(reed_evt_queue, &xLastReedTickCount, NULL);
58+
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
59+
TickType_t xLastReedTickCount = xTaskGetTickCountFromISR();
60+
61+
xQueueSendFromISR(reed_evt_queue, &xLastReedTickCount, &xHigherPriorityTaskWoken);
62+
if (xHigherPriorityTaskWoken) {
63+
portYIELD_FROM_ISR();
64+
}
6065
}
6166

6267
void vInitTasks() {
@@ -81,9 +86,9 @@ void vAttachInterrupts() {
8186
io_conf.intr_type = GPIO_INTR_NEGEDGE;
8287
// configure GPIO with the given settings
8388
gpio_config(&io_conf);
84-
gpio_set_intr_type(REED_IO_NUM, io_conf.intr_type);
89+
// gpio_set_intr_type(REED_IO_NUM, GPIO_INTR_NEGEDGE);
8590
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
86-
gpio_isr_handler_add(REED_IO_NUM, vReedISR, (void*)REED_IO_NUM);
91+
gpio_isr_handler_add(REED_IO_NUM, vReedISR, NULL);
8792
}
8893

8994
void vInitNVS() {

0 commit comments

Comments
 (0)