From 248f9fea2c2d7a3ce80a09538712a89b94615dbc Mon Sep 17 00:00:00 2001 From: Alastair Hughes Date: Thu, 8 May 2025 16:32:15 +0200 Subject: [PATCH] Fix hall sensor velocity estimation The hall sensor velocity estimation could end up returning a nonzero value if the timer "wrapped" between runs, even if the motor was actually stationary. If using the velocity regulator the motor may then fail to start. To solve this: - Switch to using unsigned types so that wrapping is defined. - When timing out the pulse value, also reset it so that the velocity won't be briefly treated as valid again when the timer wraps. Seen on a platform with 32 bit long, so running the motor and then waiting ~40 minutes is enough to observe this bug. Note that the pulse_diff variable is reset if the hall sensor direction changes, which may happen naturally when the motor stops, depending on what it is attached to. --- src/sensors/HallSensor.cpp | 15 ++++++++++++--- src/sensors/HallSensor.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/sensors/HallSensor.cpp b/src/sensors/HallSensor.cpp index 38767d59..37730251 100644 --- a/src/sensors/HallSensor.cpp +++ b/src/sensors/HallSensor.cpp @@ -122,10 +122,19 @@ float HallSensor::getSensorAngle() { */ float HallSensor::getVelocity(){ noInterrupts(); - long last_pulse_timestamp = pulse_timestamp; - long last_pulse_diff = pulse_diff; + unsigned long last_pulse_timestamp = pulse_timestamp; + unsigned long last_pulse_diff = pulse_diff; interrupts(); - if (last_pulse_diff == 0 || ((long)(_micros() - last_pulse_timestamp) > last_pulse_diff*2) ) { // last velocity isn't accurate if too old + if (last_pulse_diff == 0) { + return 0; + } else if ((_micros() - last_pulse_timestamp) > last_pulse_diff*2) { + // Last velocity isn't accurate if too old. + // Reset to avoid the diff being used again when the time wraps. + noInterrupts(); + if (pulse_diff == last_pulse_diff) { + pulse_diff = 0; + } + interrupts(); return 0; } else { return direction * (_2PI / (float)cpr) / (last_pulse_diff / 1000000.0f); diff --git a/src/sensors/HallSensor.h b/src/sensors/HallSensor.h index ad50c7d5..11194b3e 100644 --- a/src/sensors/HallSensor.h +++ b/src/sensors/HallSensor.h @@ -90,7 +90,7 @@ class HallSensor: public Sensor{ // function pointer for on sector change call back void (*onSectorChange)(int sector) = nullptr; - volatile long pulse_diff; + volatile unsigned long pulse_diff; };