5

I have written the following code to measure the speed of a unidirectional DC Motor.I have attempted to measure the time between successive interrupts in order to calculate speed.

boolean check;
boolean start;
unsigned int angle = 5;   //angle moved per encoder tick
unsigned long volatile time1;
unsigned long volatile time_11;
unsigned long interrupt_time;

void setup() {
  Serial.begin(9600);
  while (!Serial) ;
  pinMode(21, INPUT);  //Pin#21=interrupt pin, matched to interrupt#2
  attachInterrupt(digitalPinToInterrupt(2), speed, FALLING);
  time1 = 0;
  time_11 = 0;
  interrupt_time = 0;
  check = true;
  start = false;
  time_11 = millis(); //Start Clock
}

void loop() {
  if(time1 == interrupt_time && start) //Both times same , hence bool start.
  {
    if(check)
    {
      Serial.print(millis());  //Time taken to rise to steady speed.
      check = false;
    }
    Serial.println((angle/time1)*1000);   //Display Speed.
  }
  interrupt_time = time1;
  start = false;
  while(!start)
    {}
}

void speed(void) {
  start = true;
  time1 = millis()-time_11;
  time_11 = millis();
}

I want the code to be as efficient as possible.I have around 100 ticks per 360 degrees from my encoder.Is there any chance of "missing" an interrupt?

TechPakoray
  • 51
  • 1
  • 2

2 Answers2

1

Just a couple of remarks:

  1. start should be volatile, but you can remove it and simply check that time1 != 0.

  2. there is no point in calling millis() twice inside the interrupt service routine:

void speed(void) {
  unsigned long now = millis();
  time1 = now - time_11;
  time_11 = now;
}
Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81
1

Thank you for the feedback! This is my attempt at calculating speed using the averaging method.

unsigned long volatile encodercount;
unsigned long encodercount_previous;
unsigned long volatile timer;
unsigned int angle;
boolean first;
boolean firstencodertick;
void setup() {
      angle=3;
      encodercount=0;
      encodercount_previous=0;
      Serial.begin(9600);
      while (!Serial); 
      pinMode(21,INPUT);  //Pin#21=interrupt pin, matched to interrupt#2
      attachInterrupt(digitalPinToInterrupt(2),speed,FALLING);
      first=true;
      firstecnodertick=true;
        }

  void loop() {
     delay(100); 

   if(encodercount==encodercount_previous&&encodercount!=0)
    {
   if(first)
     {
   Serial.println(millis()-timer);  //Steady State Time Taken 
   first=false;
     }
  Serial.println((encodercount); //Angle Moved in 0.1second.  
    }
  encodercount_previous=encodercount;
  encodercount=0;   
   }


  void speed(void)
 {
 if(firstencodertick)
 {
 timer=millis();
 firstencodertick=false;
  }
 encodercount++; 
}