Frequency / RPM Counter

Is it possible to make this work code with millis(), I have been playing with code for hours with no luck. It doesn't seem to count any more. I don't want the one second delay to disrupt the rest of the program. I have attached the working code, and modified code with millis() which doesn't. Any help would be appreciated.

FYI I am using a mega board with pin 10 at 50% pwm to feed in to interrupt 3 to give a frequency.

Thanks Chris

This works.

volatile unsigned long firstPulseTime;
volatile unsigned long lastPulseTime;
volatile unsigned long numPulses;

void isr()
{
  unsigned long now = micros();
  if (numPulses == 1)
  {
    firstPulseTime = now;
  }
  else
  {
    lastPulseTime = now;
  }
  ++numPulses;
}

void setup()
{
  Serial.begin(9600);    // this is here so that we can print the result
  pinMode(10, OUTPUT);     // put a PWM signal on pin 10, then we can connect pin 10 to pin int 2 to test the counter
  analogWrite(10, 128);
}

void readFrequency()
{
  numPulses = 0;                      // prime the system to start a new reading
  attachInterrupt(3, isr, RISING);    // enable the interrupt
  delay(1000);
  detachInterrupt(3);
  Serial.println(numPulses);
}

void loop()
{
  readFrequency();
}

This doesn't.

volatile unsigned long firstPulseTime;
volatile unsigned long lastPulseTime;
volatile unsigned long numPulses;

long previousMillis = 0;

void isr()
{
  unsigned long now = micros();
  if (numPulses == 1)
  {
    firstPulseTime = now;
  }
  else
  {
    lastPulseTime = now;
  }
  ++numPulses;
}

void setup()
{
  Serial.begin(9600);    // this is here so that we can print the result
  pinMode(10, OUTPUT);     // put a PWM signal on pin 10, then we can connect pin 10 to pin int 2 to test the counter
  analogWrite(10, 128);
}

void readFrequency()
{
  numPulses = 0;  // prime the system to start a new reading
  unsigned long currentMillis = millis();
  attachInterrupt(3, isr, RISING);    // enable the interrupt
  if(currentMillis - previousMillis > 1000) {
    previousMillis = currentMillis;
    detachInterrupt(3);
    Serial.println(numPulses);
  }
}

void loop()
{
  readFrequency();
}

This doesn't.

What does it do when you run it ?

Thanks for the rapid reply, I should have added that!

The working sketch returns with 490 The sketch that doesn't returns a 0

Thanks Chris

Why not just have the isr increment a variable to count the pulses then every 1000 milliseconds, timed with millis(), print the number of pulses and reset it and the start time to zero ?

I can't believe I was so close and couldn't see it! Just move the numPulses = 0; to the end. Only taken 1hr 45 to work that out - what a muppet!

Thanks for helping. Chris

This is simpler

volatile int pulseCounter = 0;
unsigned long interval = 1000;
unsigned long startTime;
const byte pwmOut = 10;

void setup() 
{
  Serial.begin(115200);
  attachInterrupt(0, countPulses, RISING);
  pinMode(pwmOut, OUTPUT);
  analogWrite(pwmOut, 128);
}

void loop() 
{
  unsigned long timeNow = millis();
  if (timeNow - startTime >= interval)
  {
    Serial.println(pulseCounter);
    pulseCounter = 0; 
    startTime = timeNow;
  }
}

void countPulses()
{
  pulseCounter++;
}