66 HardwareEncoder(int cpr)
77*/
88STM32HWEncoder::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; }
9926int STM32HWEncoder::hasIndex () { return 0 ; }
10027
10128// encoder initialisation of the hardware pins
102- // and calculation variables
10329void 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
0 commit comments