6
6
HardwareEncoder(int cpr)
7
7
*/
8
8
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
-
18
9
cpr = _ppr * 4 ; // 4x for quadrature
19
-
20
- // velocity calculation variables
21
- prev_timestamp = getCurrentMicros ();
22
- pulse_timestamp = getCurrentMicros ();
23
-
24
10
_pinA = digitalPinToPinName (pinA);
25
11
_pinB = digitalPinToPinName (pinB);
26
12
_pinI = digitalPinToPinName (pinI);
27
13
}
28
14
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
-
54
15
/*
55
16
Shaft angle calculation
56
17
*/
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);
93
20
}
94
21
95
22
// getter for index pin
@@ -99,18 +26,7 @@ int STM32HWEncoder::needsSearch() { return false; }
99
26
int STM32HWEncoder::hasIndex () { return 0 ; }
100
27
101
28
// encoder initialisation of the hardware pins
102
- // and calculation variables
103
29
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
-
114
30
// GPIO configuration
115
31
TIM_TypeDef *InstanceA = (TIM_TypeDef *)pinmap_peripheral (_pinA, PinMap_TIM);
116
32
TIM_TypeDef *InstanceB = (TIM_TypeDef *)pinmap_peripheral (_pinB, PinMap_TIM);
@@ -122,7 +38,7 @@ void STM32HWEncoder::init() {
122
38
pinmap_pinout (_pinB, PinMap_TIM);
123
39
124
40
// set up timer for encoder
125
- encoder_handle.Init .Period = ticks_per_overflow - 1 ;
41
+ encoder_handle.Init .Period = cpr - 1 ;
126
42
encoder_handle.Init .Prescaler = 0 ;
127
43
encoder_handle.Init .ClockDivision = 0 ;
128
44
encoder_handle.Init .CounterMode = TIM_COUNTERMODE_UP;
@@ -156,8 +72,6 @@ void STM32HWEncoder::init() {
156
72
return ;
157
73
}
158
74
159
- prev_timestamp = getCurrentMicros ();
160
- pulse_timestamp = getCurrentMicros ();
161
75
initialized = true ;
162
76
}
163
77
0 commit comments