RPM counter program on MEGA2560

Hi !

I'm working on a school project where I have to measure the rounds per minute of a bicycle wheel.
I've found a lot of already existing programs but they are all runing on Arduino UNO and I use an Arduino MEGA 2560
I decided to use this program :

//Define Variables

  int ticsPerRev = 16;       // define number of tics per rev of code wheel

  float rpm = 0.0;  // I prefer float for rpm

  volatile int rpmcount =0;  // volitile because the variable is manipulated during the interrupt

  unsigned long timeold = 0; // used to calculate d_t= millis()-timeold;

  int d_t;

  int statusPin = 9;             // LED connected to digital pin (changes state with each tic of code wheel)

volatile byte status= LOW;    // set initial state of status LED

 

void setup()

 {

   Serial.begin(9600);

   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected

   //Triggers on FALLING (change from HIGH to LOW)

   attachInterrupt(0, rpm_fun, FALLING);

 

 

   pinMode(statusPin, OUTPUT); //Use statusPin to flash along with interrupts

 }

 void loop()

 {

   //Update RPM every second

 

   //Don't process interrupts during calculations

   detachInterrupt(0);

   d_t=millis()-timeold;

 

   if (d_t >= 1000)

    {

     rpm = float(60.0*1000.0)/float((d_t))*float(rpmcount)/ticsPerRev;

 

      timeold = millis();

      d_t=0; //reset d_t

 

      //Serial Port Output

      Serial.print("Time(ms) ");

      Serial.print(timeold); //time at end of interval (hence timeold=millis(); above )

      Serial.print(" TicsPerInterval ");

      Serial.print(rpmcount);

      Serial.print(" RPM ");

      Serial.println(rpm);

 

      rpmcount = 0; //reset rpmcount

 

  }

  //Restart the interrupt processing

  attachInterrupt(0, rpm_fun, FALLING);

 }

void rpm_fun()

 {

   //This interrupt is run at each codewheel tic

   detachInterrupt(0); //im not sure if this is necessary here

 

   rpmcount++; //update rpmcount

 

   //Toggle status LED  

   if (status == LOW) {

     status = HIGH;

   } else {

     status = LOW;

   }

   digitalWrite(statusPin, status);

   attachInterrupt(0, rpm_fun, FALLING);

 }

To measure I use an I.R.Led and a phototransitor (I.R. Detector).
I connect the I.R. detector to Pin2, I don't use the statuspin because it seems useless and there is no status led on MEGA2560
My problem is that RPM stands on 0 all the time and I don't know why.
It happens to change its value when i pull in/out of Pin2

I would be very thankfull if someone could help me.

nicoWeister:
I've found a lot of already existing programs but they are all runing on Arduino UNO and I use an Arduino MEGA 2560

I think you have probably passed up a lot of good information. That sort of programme should run equally well on a Uno or Mega and usually without any modification. I understand the Blink Without Delay example in the IDE is the usual place to start.

I tried a lot of programs, none of them worked.
This one for example :

 * Optical Tachometer
 *
 * Uses an IR LED and IR phototransistor to implement an optical tachometer.
 * The IR LED is connected to pin 13 and ran continually.
 * Pin 2 (interrupt 0) is connected across the IR detector.
 *
 * Code based on: www.instructables.com/id/Arduino-Based-Optical-Tachometer/
 * Coded by: arduinoprojects101.com
 */

int ledPin = 13;                // IR LED connected to digital pin 13
volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void rpm_fun()
 {
   //Each rotation, this interrupt function is run twice, so take that into consideration for 
   //calculating RPM
   //Update count
      rpmcount++;
 }

void setup()
 {
   lcd.begin(16, 2);  // intialise the LCD

   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(0, rpm_fun, FALLING);

   //Turn on IR LED
   pinMode(ledPin, OUTPUT);
   digitalWrite(ledPin, HIGH);

   rpmcount = 0;
   rpm = 0;
   timeold = 0;
 }

 void loop()
 {
   //Update RPM every second
   delay(1000);
   //Don't process interrupts during calculations
   detachInterrupt(0);
   //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
   //happened once per revolution instead of twice. Other multiples could be used
   //for multi-bladed propellers or fans
   rpm = 30*1000/(millis() - timeold)*rpmcount;
   timeold = millis();
   rpmcount = 0;

   //Print out result to lcd
   lcd.clear();
   lcd.print("RPM=");
   lcd.print(rpm);

   //Restart the interrupt processing
   attachInterrupt(0, rpm_fun, FALLING);
  }

Using this program, as soon as I connected the I.R. detector to Pin2 it freezed the whole thing..

I didn't get what you said about the delay :roll_eyes:

nicoWeister:
I didn't get what you said about the delay :roll_eyes:

It's a programme in the IDE examples which is typical for this application. I have not used it myself. I use the Jaycar flow meter programme, which counts pulses in a similar fashion.

I don't use the statuspin because it seems useless

It is used to confirm that your interrupt is being triggered, which I think is your problem.