Using count for a minute.

Dear Arduino Forum,
The following code is being used to try to count the RPM of a motor with an magnetic encoder.

I wanted the code to count the number of hits I get in a period of 1 minute.
However in Serial Monitor the code will do this for the first minute and then constantly print out the “velocity”. I need a way so that it will reset the time so that after the first minute it will count for the following minute.

I have also noticed that the velocity value gradually increases after the first reading. I’ve tried unsuccessfully to reset the hits value to resolve this problem.

Please find attacked screen shot of the Serial Monitor.

int hits;
float wheel_radius = (8.5/2);


volatile unsigned long current_time;
long time_interval = 60000; //how often do you want to know velocity (milliseconds)

float velocity; //this is the velocity in length units / time_interval



void setup ()
{
  Serial.begin(9600);
  
 
  attachInterrupt(digitalPinToInterrupt(2), count, RISING);
   
  current_time = millis();

  
}

void loop ()
{

   
   
  if ( millis() >= current_time + time_interval)
  {
  
    velocity = (hits*(wheel_radius * 523.6))/time_interval;//the constant is 2*pi*1000/12

    Serial.print(" velocity ");
    Serial.print(velocity);
     Serial.println("   RPM ");


 
   }
  if (current_time > 60000){
    current_time = 0;
  }

}  

void count()
{
  detachInterrupt(2); 
  noInterrupts();
 
  hits ++;
  
  attachInterrupt(2,count,RISING);
  interrupts();
 
  
}

You made 'currentTime' volatile when it wasn't necessary, yet you didn't make 'hits' volatile, when it was necessary?

You're not resetting 'hits' either. (You said you tried but didn't succeed?)

Also, do you really mean to reset this to zero?:-

current_time = 0

And do you really need to detach/attach interrupts and turn interruipts on/off all the time in the ISR?

I removed the reseting hits command as I would only get velocity = 0,
Also when I tried setting a current_time =0 command, there again I would only get velocity =0

paul_8976_10:
I removed the reseting hits command as I would only get velocity = 0,

Perhaps you reset it in the wrong place. You need to reset it at the end of the 60 seconds, before beginning the next cycle of measurements. If you don't ever reset it, it will only get higher and higher, minute by minute.
Since you actually removed that statement before posting, we can only guess what you really did wrong now.

Also when I tried setting a current_time =0 command, there again I would only get velocity =0

That was my point. I was actually asking the question, "Also, do you really mean to reset this to zero?", but I originally left out the question mark, sorry. (Edited now)
What I meant was that you needed to set it to 'millis()' at the beginning of the new cycle, not to zero.

It's getting late here and I'm prettty tired and likely to make mistakes, so I can't help further tonight.

Edit: Just a final point - a bit less superfluous white space, (blank lines), would make your code far more readable. :slight_smile:

Thank you for your reply and I hope you sleep well. I tried what you suggested and placed the code in various locations but nothing changed.

Ill bare the spacing in mind. I like to have some space between my code as it helps me read it but next time I post on the forum I'll make sure that there are minimal spacings

  if ( millis() >= current_time + time_interval)

millis() is the current time.

millis() is the current time.

Better? Still doesn't seem to have any effect on the outcome

  if ( millis() >= time_interval)
  {
  
    velocity = (hits*(wheel_radius * 523.6))/time_interval;//the constant is 2*pi*1000/12

    Serial.print(" velocity ");
    Serial.print(velocity);
     Serial.println("   RPM ");

 // Serial.print("  hits   ");
   // Serial.print(hits);


   }
  if (current_time >= time_interval){
    current_time = 0;
  }

}  

[Code]

[/code]

I need a way so that it will reset the time so that after the first minute it will count for the following minute.

You are on the wrong track. Take a look at the IDE examples >02Digital> "BlinkWithoutDelay.

Here is some basic code to read a count from an interrupt every minute. The interrupts management uses volatile variables and protected transfers.

volatile unsigned long  count = 0;
unsigned long copyCount = 0;

unsigned long lastRead = 0;
unsigned long interval = 60000;//one minute

void setup()
{
  Serial.begin(115200);
  Serial.println("start...");

  attachInterrupt(0, isrCount, RISING); //interrupt signal to pin 2
}

void loop()
{
  if (millis() - lastRead >= interval) //read interrupt count every interval
  {
    lastRead  += interval;
    // disable interrupts,make copy of count,reenable interrupts
    noInterrupts();
    copyCount = count;
    count = 0;
    interrupts();
 
    Serial.println(copyCount);

  }
}

void isrCount()
{
  count++;
}