RPM motor readings - proof there is no misses or mistakes

Hello experts.

I am building DC motor driver with special requirements - Low rpm ( 200-300 ) , constant speed, PID.
I am using Funduino Mega 2560 board as system brain.

Currently, I have part that measuring RPM with optical encoder disk with 24 slots on it. Arduino is measuring RPM and printing that on serial monitor. Code ( see below ) is pretty obvious - I took it from some other discussions here.

My question is: is there any way programmatically, or by any other means - HW/SW , to check if I am not missing any interrupt, or time tick or anything else - requirements to speed sustaining are quite tough.

// read RPM and calculate average every then readings.
const int numreadings = 10;
float readings[numreadings];
unsigned long average = 0;
int index = 0;
unsigned long total; 

volatile int rpmcount = 0;
unsigned long rpm = 0;
unsigned long lastmillis = 0;

void setup(){
 Serial.begin(115200); 
 attachInterrupt(0, rpm_fan, FALLING);
}


void loop(){
 
  
 if (millis() - lastmillis >= 1000){  /*Uptade every one second, this will be equal to reading frecuency (Hz).*/
 
 detachInterrupt(0);    //Disable interrupt when calculating
 total = 0;  
 readings[index] = rpmcount * 2.5;  /* Convert frecuency to RPM, note: ther are 24 slots in the optical encoder  - for 1 slot it shoudl be rpmcount * 60 */
 
 for (int x=0; x<=9; x++){
   total = total + readings[x];
 }
 
 average = total / numreadings;
 rpm = average;
 
 rpmcount = 0; // Restart the RPM counter
 index++;
 if(index >= numreadings){
  index=0; 
 } 
 
 
if (millis() > 11000){  // wait for RPMs average to get stable

 Serial.print(" RPM = ");
 Serial.println(rpm);
}
 
 lastmillis = millis(); // Update lasmillis
  attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
}


void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
  rpmcount++;
}

You could add an additional, completely independent shaft encoder and rpm measurement system.

An oscilloscope might be able to show missing pulses.

If you record the time for each pulse (with micros() ) and compare the intervals between pulse you should be able to identify missing pulses. But that extra work may not be appropriate with a 24 pulse encoder if you are detecting a high RPM.

What are you trying to achieve? I can control the speed of a small DC motor very closely with a detector that only generates one pulse per revolution.

…R

Thanks Robin2, jremington for quick answers.

I am building coil winding machine with CNC control. Main motor (coil rotating) is geared mechanically down, but speed still fluctuates significantly and this makes coil winding uneven or wire tearing. I am trying to stabilise and control motor speed with PID and prevent speed fluctuating and jerking.

Robin2. It would be great if you could share your solution ? Much appreciated.

Gene.

geshka:
Robin2. It would be great if you could share your solution ?

I’m not quite sure what you want from me. My optical detector is a QRE1113 reflective sensor that detects a spot of white paint on a black disk on the motor shaft.

The PID program I am using is essentially the same as posted here

If that is not what you want then let me know.

…R

Thanks Robin2.

Robin2:
I'm not quite sure what you want from me. My optical detector is a QRE1113 reflective sensor that detects a spot of white paint on a black disk on the motor shaft.

I guess it is exactly what I wanted.