Add dual edge roller speed sensing

master
Tom Wilson 4 years ago
parent 2ee803fa1e
commit 84402a1614

@ -8,8 +8,12 @@
#include "freertos/queue.h"
#include "soc/rtc.h"
static uint32_t roller_pulses[3] = {0, 0, 0}; // Total pulses of roller so far
static uint32_t roller_last_edge_time[3] = {0, 0, 0}; // Precision timer value of most recent edge
static uint32_t roller_pulses[3] = {0, 0, 0}; // Total pulses of roller so far
static uint32_t roller_last_neg_edge_time[3] = {0, 0, 0}; // Precision timer value of most recent falling edge
static uint32_t roller_last_pos_edge_time[3] = {0, 0, 0}; // Precision timer value of most recent rising edge
static bool roller_pos_edge_seen[3] = {false, false,
false}; // Track if if first pulse edge has been seen yet to compare to
static bool roller_neg_edge_seen[3] = {false, false, false};
// Also store timestamp as microseconds since start to avoid overflow of the precision timer when checking for stop
static int64_t roller_last_timestamp[3] = {0, 0, 0};
@ -52,18 +56,28 @@ static bool speed_pulse_isr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id
time_now = esp_timer_get_time();
new_measurement.timestamp = time_now;
new_measurement.pulses = roller_pulses[r_id];
new_measurement.period = 0; // default to 0 - no speed - if we don't actually have a period to put in but still want
// to give an update with the new pulse count
// Just make sure we have a previous edge to compare to, and that it was no more than ZERO_SPEED_TIMEOUT_US ago
if ((roller_last_timestamp[r_id] != 0) and ((time_now - roller_last_timestamp[r_id]) < ZERO_SPEED_TIMEOUT_US)) {
new_measurement.period = edata->cap_value - roller_last_edge_time[r_id];
} else {
// If there's no previous edge detected, or it's too far away, we still want to give an update with the new
// pulse count
new_measurement.period = 0;
}
if ((roller_pos_edge_seen[r_id] or roller_neg_edge_seen[r_id]) and ((time_now - roller_last_timestamp[r_id]) < ZERO_SPEED_TIMEOUT_US)) {
if ((edata->cap_edge == MCPWM_POS_EDGE) and (roller_pos_edge_seen[r_id])) {
new_measurement.period = edata->cap_value - roller_last_pos_edge_time[r_id];
} else if ((edata->cap_edge == MCPWM_NEG_EDGE) and (roller_neg_edge_seen[r_id])) {
new_measurement.period = edata->cap_value - roller_last_neg_edge_time[r_id];
}
}
xQueueOverwriteFromISR(roller_measurement_queue[r_id], &new_measurement, &high_task_wakeup);
roller_last_edge_time[r_id] = edata->cap_value;
if (edata->cap_edge == MCPWM_POS_EDGE){
roller_last_pos_edge_time[r_id] = edata->cap_value;
roller_pos_edge_seen[r_id] = true;
} else {
roller_last_neg_edge_time[r_id] = edata->cap_value;
roller_neg_edge_seen[r_id] = true;
}
roller_last_timestamp[r_id] = time_now;
return high_task_wakeup == pdTRUE;
@ -107,8 +121,8 @@ void roller_speed_setup(void) {
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM_CAP_2, GPIO_ROLLER3_SPEED);
// Configure and enable MCPWM capture units
mcpwm_capture_config_t conf = {.cap_edge = MCPWM_POS_EDGE, // trigger on riding edge
.cap_prescale = 1, // pulses per interrupt
mcpwm_capture_config_t conf = {.cap_edge = MCPWM_BOTH_EDGE, // trigger on both edges
.cap_prescale = 1, // pulses per interrupt
.capture_cb = speed_pulse_isr_handler,
.user_data = NULL};
mcpwm_capture_enable_channel(MCPWM_UNIT_0, MCPWM_SELECT_CAP0, &conf);

@ -3,12 +3,13 @@
#include "../common/shared_structs.h"
// Number of sensor pulses per roller rev. Note that this will overflow at about 4 billion pulses
#define ROLLER_PULSES_PER_REV 30
// Number of sensor pulses per roller rev. Note that this will overflow at about 4 billion pulses.
// Roller physically has 30 pulses per rev, but we're counting both rising and falling edges
#define ROLLER_PULSES_PER_REV 60
// Time without a pulse after which the speed will be considered to be 0.
// Note that with a clock at 80MHz, the pulse period counter overflows every 53 seconds
#define ZERO_SPEED_TIMEOUT_US 5000000
#define ZERO_SPEED_TIMEOUT_US 2000000 //Gives us a min speed of 0.00833 revs/sec
void roller_speed_setup(void);

Loading…
Cancel
Save