@@ -101,12 +101,14 @@ void Encoder::handleIndex() {
101101
102102// Sensor update function. Safely copy volatile interrupt variables into Sensor base class state variables.
103103void Encoder::update () {
104+ // Copy volatile variables in minimal-duration blocking section to ensure no interrupts are missed
104105 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);
108106 angle_prev_ts = pulse_timestamp;
107+ long copy_pulse_counter = pulse_counter;
109108 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);
110112}
111113
112114/*
@@ -123,8 +125,11 @@ float Encoder::getSensorAngle(){
123125 function using mixed time and frequency measurement technique
124126*/
125127float 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
127129 noInterrupts ();
130+ long copy_pulse_counter = pulse_counter;
131+ long copy_pulse_timestamp = pulse_timestamp;
132+ interrupts ();
128133 // timestamp
129134 long timestamp_us = _micros ();
130135 // sampling time calculation
@@ -133,8 +138,8 @@ float Encoder::getVelocity(){
133138 if (Ts <= 0 || Ts > 0 .5f ) Ts = 1e-3f ;
134139
135140 // 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;
138143
139144 // Pulse per second calculation (Eq.3.)
140145 // dN - impulses received
@@ -155,9 +160,7 @@ float Encoder::getVelocity(){
155160 prev_timestamp_us = timestamp_us;
156161 // save velocity calculation variables
157162 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;
161164 return velocity;
162165}
163166
0 commit comments