@@ -101,12 +101,14 @@ void Encoder::handleIndex() {
101
101
102
102
// Sensor update function. Safely copy volatile interrupt variables into Sensor base class state variables.
103
103
void Encoder::update () {
104
+ // Copy volatile variables in minimal-duration blocking section to ensure no interrupts are missed
104
105
noInterrupts ();
105
- // TODO: numerical precision issue here if the pulse_counter overflows the angle will be lost
106
- full_rotations = pulse_counter / (int )cpr;
107
- angle_prev = _2PI * ((pulse_counter) % ((int )cpr)) / ((float )cpr);
108
106
angle_prev_ts = pulse_timestamp;
107
+ long copy_pulse_counter = pulse_counter;
109
108
interrupts ();
109
+ // TODO: numerical precision issue here if the pulse_counter overflows the angle will be lost
110
+ full_rotations = copy_pulse_counter / (int )cpr;
111
+ angle_prev = _2PI * ((copy_pulse_counter) % ((int )cpr)) / ((float )cpr);
110
112
}
111
113
112
114
/*
@@ -123,8 +125,11 @@ float Encoder::getSensorAngle(){
123
125
function using mixed time and frequency measurement technique
124
126
*/
125
127
float Encoder::getVelocity (){
126
- // Make sure no interrupts modify the state variables in the middle of these calculations
128
+ // Copy volatile variables in minimal-duration blocking section to ensure no interrupts are missed
127
129
noInterrupts ();
130
+ long copy_pulse_counter = pulse_counter;
131
+ long copy_pulse_timestamp = pulse_timestamp;
132
+ interrupts ();
128
133
// timestamp
129
134
long timestamp_us = _micros ();
130
135
// sampling time calculation
@@ -133,8 +138,8 @@ float Encoder::getVelocity(){
133
138
if (Ts <= 0 || Ts > 0 .5f ) Ts = 1e-3f ;
134
139
135
140
// time from last impulse
136
- float Th = (timestamp_us - pulse_timestamp ) * 1e-6f ;
137
- long dN = pulse_counter - prev_pulse_counter;
141
+ float Th = (timestamp_us - copy_pulse_timestamp ) * 1e-6f ;
142
+ long dN = copy_pulse_counter - prev_pulse_counter;
138
143
139
144
// Pulse per second calculation (Eq.3.)
140
145
// dN - impulses received
@@ -155,9 +160,7 @@ float Encoder::getVelocity(){
155
160
prev_timestamp_us = timestamp_us;
156
161
// save velocity calculation variables
157
162
prev_Th = Th;
158
- prev_pulse_counter = pulse_counter;
159
- // Re-enable interrupts (ideally this would restore to the previous state rather than unconditionally enabling)
160
- interrupts ();
163
+ prev_pulse_counter = copy_pulse_counter;
161
164
return velocity;
162
165
}
163
166
0 commit comments