diff --git a/EncoderMod.h b/EncoderMod.h index c473df0..7ebca4a 100755 --- a/EncoderMod.h +++ b/EncoderMod.h @@ -68,6 +68,7 @@ typedef struct { float rate; float rate1; float rate2; + bool lastRateTimer; } Encoder_internal_state_t; class Encoder @@ -99,6 +100,7 @@ class Encoder encoder.rate = 0; encoder.rate1 = 0; encoder.rate2 = 0; + lastRateTimer = 0; if (DIRECT_PIN_READ(encoder.pin1_register, encoder.pin1_bitmask)) s |= 1; if (DIRECT_PIN_READ(encoder.pin2_register, encoder.pin2_bitmask)) s |= 2; encoder.state = s; @@ -131,12 +133,44 @@ class Encoder if (interrupts_in_use < 2) { noInterrupts(); update(&encoder); - } else { + } + else { noInterrupts(); } - float ret = encoder.rate; + float lastRate = encoder.rate; + float elapsedTime = encoder.stepTime; interrupts(); - return ret; + float extrapolation = lastRate * elapsedTime; + if (extrapolation > 1) { + return (1 / elapsedTime); + } + else if (extrapolation < -1) { + return (-1 / elapsedTime); + } + else { + return (lastRate); + } + } + inline float extrapolate() { + if (interrupts_in_use < 2) { + noInterrupts(); + update(&encoder); + } + else { + noInterrupts(); + } + float lastRate = encoder.rate; + int32_t lastPosition = encoder.position; + float extrapolation = encoder.stepTime; + interrupts(); + extrapolation *= lastRate; + if (extrapolation > 1) { + extrapolation = 1; + } + else if (extrapolation < -1) { + extrapolation = -1; + } + return (extrapolation + lastPosition); } #else inline int32_t read() { @@ -147,7 +181,17 @@ class Encoder encoder.position = p; } inline float stepRate() { - return encoder.rate; + return ((extrapolate() - encoder.position) / encoder.stepTime); + } + inline float extrapolate() { + float extrapolation = encoder.rate * encoder.stepTime; + if (extrapolation > 1) { + extrapolation = 1; + } + else if (extrapolation < -1) { + extrapolation = -1; + } + return (extrapolation + encoder.position); } #endif private: @@ -302,9 +346,17 @@ class Encoder case 1: case 7: case 8: case 14: if (arg->position % 2 == 0) { arg->rate1 = 0.5 / arg->stepTime; + if (arg->lastRateTimer == 0) { + arg->rate2 = 0; + } + arg->lastRateTimer = 0; } else { arg->rate2 = 0.5 / arg->stepTime; + if (arg->lastRateTimer == 1) { + arg->rate1 = 0; + } + arg->lastRateTimer = 1; } arg->stepTime = 0; arg->rate = (arg->rate1 + arg->rate2); @@ -313,9 +365,17 @@ class Encoder case 2: case 4: case 11: case 13: if (arg->position % 2 != 0) { arg->rate1 = -0.5 / arg->stepTime; + if (arg->lastRateTimer == 0) { + arg->rate2 = 0; + } + arg->lastRateTimer = 0; } else { arg->rate2 = -0.5 / arg->stepTime; + if (arg->lastRateTimer == 1) { + arg->rate1 = 0; + } + arg->lastRateTimer = 1; } arg->stepTime = 0; arg->rate = (arg->rate1 + arg->rate2); diff --git a/keywords.txt b/keywords.txt index fc03c99..dd08148 100644 --- a/keywords.txt +++ b/keywords.txt @@ -5,3 +5,4 @@ Encoder KEYWORD1 read KEYWORD2 write KEYWORDD2 stepRate KEYWORD2 +extrapolate KEYWORD2