Fix direction-detection, Fix inversion - reliable now

Tested and debugged speed measurement on actual hardware.
Speed measurement is very stable now (reliable direction)
    - fix direction inverted no effect
    - fix direction detection
    - remove "invalid directions" since every combination is valid
This commit is contained in:
jonny_l480 2024-02-26 22:45:58 +01:00
parent db4e6b56a5
commit fbca35e828
2 changed files with 35 additions and 44 deletions

View File

@ -47,6 +47,11 @@ void IRAM_ATTR onEncoderRising(void *arg)
uint32_t pulse2 = sensor->pulseDurations[1]; uint32_t pulse2 = sensor->pulseDurations[1];
uint32_t pulse3 = sensor->pulseDurations[2]; uint32_t pulse3 = sensor->pulseDurations[2];
// save all recored pulses of this sequence (for logging only)
sensor->pulse1 = pulse1;
sensor->pulse2 = pulse2;
sensor->pulse3 = pulse3;
// find shortest pulse // find shortest pulse
sensor->shortestPulse = min(pulse1, min(pulse2, pulse3)); sensor->shortestPulse = min(pulse1, min(pulse2, pulse3));
@ -57,46 +62,37 @@ void IRAM_ATTR onEncoderRising(void *arg)
return; return;
} }
//-- Determine direction based on pulse order --- //--- Determine direction based on pulse order ---
int directionNew = 0; int direction = 0;
if (sensor->shortestPulse == pulse1) // short... if (sensor->shortestPulse == pulse1) // short...
{ {
if (pulse2 < pulse3) // short-medium-long if (pulse2 < pulse3) // short-medium-long -->
directionNew = 1; direction = 1;
else // short-long-medium (invaild) else // short-long-medium <--
{ direction = -1;
sensor->debug_countIgnoredSequencesInvalidOrder++;
return;
};
} }
else if (sensor->shortestPulse == pulse3) //...short else if (sensor->shortestPulse == pulse3) //...short
{ {
if (pulse1 > pulse2) // long-medium-short if (pulse1 > pulse2) // long-medium-short <--
directionNew = -1; direction = -1;
else // medium-long-short (invaild) else // medium-long-short -->
{ direction = 1;
sensor->debug_countIgnoredSequencesInvalidOrder++;
return;
};
} }
else if (sensor->shortestPulse == pulse2) //...short... else if (sensor->shortestPulse == pulse2) //...short...
{ {
// medium-short-long (invalid) if (pulse1 < pulse3) // medium-short-long
// long-short-medium (invalid) direction = -1;
sensor->debug_countIgnoredSequencesInvalidOrder++; else // long-short-medium
return; direction = 1;
} }
// save and invert direction if necessay // save and invert direction if necessay
// TODO mutex?
if (sensor->config.directionInverted) if (sensor->config.directionInverted)
sensor->direction = -directionNew; direction = -direction;
else
sensor->direction = directionNew;
// calculate rotational speed // calculate rotational speed
uint64_t pulseSum = pulse1 + pulse2 + pulse3; uint64_t pulseSum = pulse1 + pulse2 + pulse3;
sensor->currentRpm = directionNew * (sensor->config.degreePerGroup / 360.0 * 60.0 / ((double)pulseSum / 1000000.0)); sensor->currentRpm = direction * (sensor->config.degreePerGroup / 360.0 * 60.0 / ((double)pulseSum / 1000000.0));
} }
} }
@ -148,24 +144,21 @@ float speedSensor::getRpm(){
//timeout (standstill) //timeout (standstill)
//TODO variable timeout considering config.degreePerGroup //TODO variable timeout considering config.degreePerGroup
if ((currentRpm != 0) && (esp_timer_get_time() - lastEdgeTime) > TIMEOUT_NO_ROTATION*1000){ if ((currentRpm != 0) && (esp_timer_get_time() - lastEdgeTime) > TIMEOUT_NO_ROTATION*1000){
ESP_LOGW(TAG, "%s - timeout: no pulse within %dms... last pulse was %dms ago => set RPM to 0", ESP_LOGI(TAG, "%s - timeout: no pulse within %dms... last pulse was %dms ago => set RPM to 0",
config.logName, TIMEOUT_NO_ROTATION, timeElapsed/1000); config.logName, TIMEOUT_NO_ROTATION, timeElapsed/1000);
currentRpm = 0; currentRpm = 0;
} }
//debug output (also log variables when this function is called) //debug output (also log variables when this function is called)
ESP_LOGI(TAG, "[%s] getRpm: returning stored rpm=%.3f", config.logName, currentRpm); ESP_LOGD(TAG, "[%s] getRpm: returning stored rpm=%.3f", config.logName, currentRpm);
ESP_LOGV(TAG, "[%s] rpm=%f, dir=%d, pulseCount=%d, p1=%d, p2=%d, p3=%d, shortest=%d, tooShortCount=%d, invalidOrderCount=%d", ESP_LOGV(TAG, "[%s] rpm=%f, pulseCount=%d, p1=%d, p2=%d, p3=%d, shortest=%d, totalTooShortCount=%d",
config.logName, config.logName,
currentRpm, currentRpm,
direction, pulseCounter,
pulseCounter, pulse1 / 1000,
(int)pulseDurations[0]/1000, pulse2 / 1000,
(int)pulseDurations[1]/1000, pulse3 / 1000,
(int)pulseDurations[2]/1000, shortestPulse / 1000,
shortestPulse, debug_countIgnoredSequencesTooShort);
debug_countIgnoredSequencesTooShort,
debug_countIgnoredSequencesInvalidOrder);
//return currently stored rpm //return currently stored rpm
return currentRpm; return currentRpm;
} }
@ -178,7 +171,7 @@ float speedSensor::getRpm(){
//get speed in kilometers per hour //get speed in kilometers per hour
float speedSensor::getKmph(){ float speedSensor::getKmph(){
float currentSpeed = getRpm() * config.tireCircumferenceMeter * 60/1000; float currentSpeed = getRpm() * config.tireCircumferenceMeter * 60/1000;
ESP_LOGI(TAG, "%s - getKmph: returning speed=%.3fkm/h", config.logName, currentSpeed); ESP_LOGD(TAG, "%s - getKmph: returning speed=%.3fkm/h", config.logName, currentSpeed);
return currentSpeed; return currentSpeed;
} }
@ -189,6 +182,6 @@ float speedSensor::getKmph(){
//get speed in meters per second //get speed in meters per second
float speedSensor::getMps(){ float speedSensor::getMps(){
float currentSpeed = getRpm() * config.tireCircumferenceMeter / 60; float currentSpeed = getRpm() * config.tireCircumferenceMeter / 60;
ESP_LOGI(TAG, "%s - getMps: returning speed=%.3fm/s", config.logName, currentSpeed); ESP_LOGD(TAG, "%s - getMps: returning speed=%.3fm/s", config.logName, currentSpeed);
return currentSpeed; return currentSpeed;
} }

View File

@ -34,18 +34,16 @@ public:
float getMps(); //meters per second float getMps(); //meters per second
float getRpm(); //rotations per minute float getRpm(); //rotations per minute
//1=forward, -1=reverse
int direction;
//variables for handling the encoder (public because ISR needs access) //variables for handling the encoder (public because ISR needs access)
speedSensor_config_t config; speedSensor_config_t config;
uint32_t pulseDurations[3] = {}; uint32_t pulseDurations[3] = {};
uint32_t pulse1, pulse2, pulse3;
uint32_t shortestPulse = 0; uint32_t shortestPulse = 0;
uint32_t shortestPulsePrev = 0; uint32_t shortestPulsePrev = 0;
uint32_t lastEdgeTime = 0; uint32_t lastEdgeTime = 0;
uint8_t pulseCounter = 0; uint8_t pulseCounter = 0;
int debugCount = 0; int debugCount = 0;
uint32_t debug_countIgnoredSequencesTooShort = 0; uint32_t debug_countIgnoredSequencesTooShort = 0;
uint32_t debug_countIgnoredSequencesInvalidOrder = 0;
double currentRpm = 0; double currentRpm = 0;
private: private: