@@ -99,29 +99,23 @@ void Encoder::handleIndex() {
9999}
100100
101101
102+ // Sensor update function. Safely copy volatile interrupt variables into Sensor base class state variables.
102103void Encoder::update () {
103- // do nothing for Encoder
104+ // Copy volatile variables in minimal-duration blocking section to ensure no interrupts are missed
105+ noInterrupts ();
106+ angle_prev_ts = pulse_timestamp;
107+ long copy_pulse_counter = pulse_counter;
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);
104112}
105113
106114/*
107115 Shaft angle calculation
108116*/
109117float Encoder::getSensorAngle (){
110- return getAngle ();
111- }
112- // TODO: numerical precision issue here if the pulse_counter overflows the angle will be lost
113- float Encoder::getMechanicalAngle (){
114- return _2PI * ((pulse_counter) % ((int )cpr)) / ((float )cpr);
115- }
116-
117- float Encoder::getAngle (){
118- return _2PI * (pulse_counter) / ((float )cpr);
119- }
120- double Encoder::getPreciseAngle (){
121- return _2PI * (pulse_counter) / ((double )cpr);
122- }
123- int32_t Encoder::getFullRotations (){
124- return pulse_counter / (int )cpr;
118+ return _2PI * (pulse_counter) / ((float )cpr);
125119}
126120
127121
@@ -131,6 +125,11 @@ int32_t Encoder::getFullRotations(){
131125 function using mixed time and frequency measurement technique
132126*/
133127float Encoder::getVelocity (){
128+ // Copy volatile variables in minimal-duration blocking section to ensure no interrupts are missed
129+ noInterrupts ();
130+ long copy_pulse_counter = pulse_counter;
131+ long copy_pulse_timestamp = pulse_timestamp;
132+ interrupts ();
134133 // timestamp
135134 long timestamp_us = _micros ();
136135 // sampling time calculation
@@ -139,8 +138,8 @@ float Encoder::getVelocity(){
139138 if (Ts <= 0 || Ts > 0 .5f ) Ts = 1e-3f ;
140139
141140 // time from last impulse
142- float Th = (timestamp_us - pulse_timestamp ) * 1e-6f ;
143- 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;
144143
145144 // Pulse per second calculation (Eq.3.)
146145 // dN - impulses received
@@ -161,7 +160,7 @@ float Encoder::getVelocity(){
161160 prev_timestamp_us = timestamp_us;
162161 // save velocity calculation variables
163162 prev_Th = Th;
164- prev_pulse_counter = pulse_counter ;
163+ prev_pulse_counter = copy_pulse_counter ;
165164 return velocity;
166165}
167166
0 commit comments