Skip to content

Commit 51b1cbe

Browse files
author
Richard Unger
committed
big simplification to STM32HWEncoder
1 parent 2aeb0f0 commit 51b1cbe

File tree

2 files changed

+8
-127
lines changed

2 files changed

+8
-127
lines changed

src/encoders/stm32hwencoder/STM32HWEncoder.cpp

Lines changed: 3 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -6,90 +6,17 @@
66
HardwareEncoder(int cpr)
77
*/
88
STM32HWEncoder::STM32HWEncoder(unsigned int _ppr, int8_t pinA, int8_t pinB, int8_t pinI) {
9-
rotations_per_overflow = 0;
10-
ticks_per_overflow = 0;
11-
12-
overflow_count = 0;
13-
count = 0;
14-
prev_count = 0;
15-
prev_overflow_count = 0;
16-
pulse_timestamp = 0;
17-
189
cpr = _ppr * 4; // 4x for quadrature
19-
20-
// velocity calculation variables
21-
prev_timestamp = getCurrentMicros();
22-
pulse_timestamp = getCurrentMicros();
23-
2410
_pinA = digitalPinToPinName(pinA);
2511
_pinB = digitalPinToPinName(pinB);
2612
_pinI = digitalPinToPinName(pinI);
2713
}
2814

29-
30-
31-
void STM32HWEncoder::update() {
32-
// handle overflow of the 16-bit counter here
33-
// must be called at least twice per traversal of overflow range
34-
// TODO(conroy-cheers): investigate performance impact
35-
prev_count = count;
36-
count = encoder_handle.Instance->CNT;
37-
38-
prev_timestamp = pulse_timestamp;
39-
pulse_timestamp = _micros(); // micros() rollover is handled in velocity calculation
40-
41-
prev_overflow_count = overflow_count;
42-
// if (prev_count > (ticks_per_overflow - overflow_margin) && count < overflow_margin)
43-
// ++overflow_count;
44-
// if (prev_count < overflow_margin && count >= (ticks_per_overflow - overflow_margin))
45-
// --overflow_count;
46-
if (prev_count < count && (count - prev_count > ticks_per_overflow / 2))
47-
--overflow_count;
48-
if (prev_count > count && (prev_count - count > ticks_per_overflow / 2))
49-
++overflow_count;
50-
}
51-
52-
53-
5415
/*
5516
Shaft angle calculation
5617
*/
57-
float STM32HWEncoder::getSensorAngle() { return getAngle(); }
58-
59-
float STM32HWEncoder::getMechanicalAngle() {
60-
return _2PI * (count % static_cast<int>(cpr)) / static_cast<float>(cpr);
61-
}
62-
float STM32HWEncoder::getAngle() {
63-
return _2PI * (count / static_cast<float>(cpr) +
64-
overflow_count * rotations_per_overflow);
65-
}
66-
double STM32HWEncoder::getPreciseAngle() {
67-
return _2PI * (count / static_cast<double>(cpr) +
68-
overflow_count * rotations_per_overflow);
69-
}
70-
int32_t STM32HWEncoder::getFullRotations() {
71-
return count / static_cast<int>(cpr) +
72-
overflow_count * rotations_per_overflow;
73-
}
74-
75-
/*
76-
Shaft velocity calculation
77-
*/
78-
float STM32HWEncoder::getVelocity() {
79-
// sampling time calculation
80-
float dt = (pulse_timestamp - prev_timestamp) * 1e-6f;
81-
// this also handles the moment when micros() rolls over
82-
if (dt < min_elapsed_time) return velocity; // don't update velocity if deltaT is too small
83-
84-
// time from last impulse
85-
int32_t overflow_diff = overflow_count - prev_overflow_count;
86-
int32_t dN = (count - prev_count) + (ticks_per_overflow * overflow_diff);
87-
88-
float pulse_per_second = dN / dt;
89-
90-
// velocity calculation
91-
velocity = pulse_per_second / (static_cast<float>(cpr)) * _2PI;
92-
return velocity;
18+
float STM32HWEncoder::getSensorAngle() {
19+
return _2PI * encoder_handle.Instance->CNT / static_cast<float>(cpr);
9320
}
9421

9522
// getter for index pin
@@ -99,18 +26,7 @@ int STM32HWEncoder::needsSearch() { return false; }
9926
int STM32HWEncoder::hasIndex() { return 0; }
10027

10128
// encoder initialisation of the hardware pins
102-
// and calculation variables
10329
void STM32HWEncoder::init() {
104-
// counter setup
105-
overflow_count = 0;
106-
count = 0;
107-
prev_count = 0;
108-
prev_overflow_count = 0;
109-
110-
// overflow handling
111-
rotations_per_overflow = 0xFFFF / cpr;
112-
ticks_per_overflow = cpr * rotations_per_overflow;
113-
11430
// GPIO configuration
11531
TIM_TypeDef *InstanceA = (TIM_TypeDef *)pinmap_peripheral(_pinA, PinMap_TIM);
11632
TIM_TypeDef *InstanceB = (TIM_TypeDef *)pinmap_peripheral(_pinB, PinMap_TIM);
@@ -122,7 +38,7 @@ void STM32HWEncoder::init() {
12238
pinmap_pinout(_pinB, PinMap_TIM);
12339

12440
// set up timer for encoder
125-
encoder_handle.Init.Period = ticks_per_overflow - 1;
41+
encoder_handle.Init.Period = cpr - 1;
12642
encoder_handle.Init.Prescaler = 0;
12743
encoder_handle.Init.ClockDivision = 0;
12844
encoder_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
@@ -156,8 +72,6 @@ void STM32HWEncoder::init() {
15672
return;
15773
}
15874

159-
prev_timestamp = getCurrentMicros();
160-
pulse_timestamp = getCurrentMicros();
16175
initialized = true;
16276
}
16377

src/encoders/stm32hwencoder/STM32HWEncoder.h

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <HardwareTimer.h>
1010
#include "common/base_classes/Sensor.h"
1111
#include "common/foc_utils.h"
12-
#include "common/time_utils.h"
1312

1413
class STM32HWEncoder : public Sensor {
1514
public:
@@ -19,51 +18,19 @@ class STM32HWEncoder : public Sensor {
1918
*/
2019
explicit STM32HWEncoder(unsigned int ppr, int8_t pinA, int8_t pinB, int8_t pinI=-1);
2120

22-
/** encoder initialise pins */
2321
void init() override;
24-
25-
// Encoder configuration
26-
unsigned int cpr; //!< encoder cpr number
27-
28-
// Abstract functions of the Sensor class implementation
29-
/** get current angle (rad) */
30-
float getSensorAngle() override;
31-
float getMechanicalAngle() override;
32-
/** get current angular velocity (rad/s) */
33-
float getVelocity() override;
34-
float getAngle() override;
35-
double getPreciseAngle() override;
36-
int32_t getFullRotations() override;
37-
void update() override;
38-
39-
/**
40-
* returns 0 if it does need search for absolute zero
41-
* 0 - encoder without index
42-
* 1 - ecoder with index
43-
*/
4422
int needsSearch() override;
23+
int hasIndex(); // !< function returning 1 if encoder has index pin and 0 if not.
4524

4625
bool initialized = false;
26+
uint32_t cpr; //!< encoder cpr number
4727
PinName _pinA, _pinB, _pinI;
4828

49-
private:
50-
int hasIndex(); // !< function returning 1 if encoder has index pin and 0 if not.
51-
52-
void handleOverflow();
53-
29+
protected:
30+
float getSensorAngle() override;
31+
5432
TIM_HandleTypeDef encoder_handle;
5533

56-
static constexpr uint16_t overflow_margin = 20000;
57-
uint16_t rotations_per_overflow;
58-
uint16_t ticks_per_overflow;
59-
60-
volatile int32_t overflow_count;
61-
volatile uint16_t count; //!< current pulse counter
62-
volatile uint16_t prev_count;
63-
volatile int32_t prev_overflow_count;
64-
65-
// velocity calculation variables
66-
volatile int32_t pulse_timestamp, prev_timestamp;
6734
};
6835

6936
#endif

0 commit comments

Comments
 (0)