Help with this code (for rpm calculation with attachInterrupt )

Hi ( Still newbie in Programing here )

I am making a project with the use of an arduino pro mini and oled SSD1306 128X64 display
i am using the U8glib library

my project aims to display the voltage and the rpm of an engine

i find a code for rpm and attached it to the code i had made for displaing the voltage

(here is the post for rpm code : http://forum.arduino.cc/index.php?topic=42837.0 )

As i am using for first time the attachInterrupt i am little confuse and not sure what is going wrong and cant get a reading for rpm (i am using a push button as a signal for testing it )

also i have one more Question about the attachInterrupt pin ( number 2 in pro mini)
Have to declare it in my code? also have to place any pull down resistor ?

the rpm will be from vechicles coil through optocoupler to isolate (safety) the signal from arduino input as the coil uses 12v

engine 4 stroke 4 cylinders up to 8.000 rpm maximum ( so i will have 4 signals per 1 revolution )

here is the code if anyone want to guide me.. thanks in Advance :slight_smile: :

#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);  // Display which does not send AC

bool first;

float analogA = 0.0; //  Analog reading A1

////////////////////////////////////////////////////// RPM /////////////////////////////////////////////////////////////////////
// read RPM
int Cycle = 0;                  // set to 0 for PulseStartTime and set to
                       //   1 for PulseEndTime
unsigned long PulseStartTime;   // Saves Start of pulse in ms
unsigned long PulseEndTime;     // Saves End of pulse in ms
unsigned long PulseTime;        // Stores dif between start and stop of pulse
unsigned long RPM = 0;          // RPM to ouptut (30*1000/PulseTime)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void setup(void)
{

// flip screen, if required
//u8g.setRot180();

  Serial.begin(9600);



/////////////////////////////////////////////////////// Oled DISPLAY  //////////////////////////////////////////////////////////




  // assign default color value
  if (u8g.getMode() == U8G_MODE_R3G3B2)
  {
    u8g.setColorIndex(255);     // white
  }
  else if (u8g.getMode() == U8G_MODE_GRAY2BIT)
  {
    u8g.setColorIndex(3);         // max intensity
  }
  else if (u8g.getMode() == U8G_MODE_BW)
  {
    u8g.setColorIndex(1);         // pixel on
  }
  else if (u8g.getMode() == U8G_MODE_HICOLOR)
  {
    u8g.setHiColorByRGB(255, 255, 255);
  }

  attachInterrupt(0, RPMPulse, RISING); // Attaches interrupt to Digi Pin 2
  
}

//////////////////////////////////////////////////////////////////////////// RPM //////////////////////////////////////////////


void RPMPulse()
{
 if (Cycle == 0)                // Check to see if start pulse
 {
   PulseStartTime = millis();  // stores start time
   Cycle = 1;           // sets counter for start of pulse
   return;                     // a return so it doesnt run the next if
 }
 if (Cycle == 1)             // Check to see if end pulse
 {
   detachInterrupt(0);         // Turns off inturrupt for calculations
   PulseEndTime = millis();    // stores end time
   Cycle = 0;                  // resets counter for pulse cycle
   calcRPM();                  // call to calculate pulse time
 }
}

void calcRPM()
{
 PulseTime = PulseEndTime - PulseStartTime; // Gets pulse duration
 Serial.println("PulseTime =");               // Output pulse time for debug
 Serial.println(PulseTime);                   // Pulse debug output
 Serial.println(" ");                        
 RPM = 30*1000/PulseTime*2;                 // Calculates RPM
 attachInterrupt(0, RPMPulse, RISING);      // re-attaches interrupt to Digi Pin 2
}




/////////////////////////////////////////////////////// END OF RPM CALCULATION //////////////////////////////////////////////////////////

void Meter(float* analogA)
{
  u8g.setFont(u8g_font_fub11);
  u8g.setFontRefHeightExtendedText();
  u8g.setDefaultForegroundColor();
  u8g.setFontPosTop();
  
//////////////////////////////////////////////////// printed words in display  /////////////////////////////////////////////



//////////////////////////////////////////////////////// Sensor A /////////////////////////////////////////////////////////////////
 
  u8g.drawStr(4, 20, "Volt");
  int sensorValueA = analogRead(A1);
  float x = sensorValueA * 5.0 / 1023.0 ;
  u8g.setPrintPos(80, 20);
  u8g.print(x);
  
////////////////////////////////////////////////////////Rpm Display /////////////////////////////////////////////////////////////////
  u8g.drawStr(4, 40, "RPM");
  u8g.setPrintPos(80, 40);
 
  u8g.print(RPM);


  
///////////////////////////////////////////////////////  end of printed display /////////////////////////////////////////////////////

}



void loop(void){


 if (first)
  {
   first = false;
  }
  else
  {
    u8g.firstPage();

   do
    {
      Meter(&analogA);
    }
   while (u8g.nextPage());
  }
  
////////////////////////////////// RPM SERIAL MONITOR////////////////////////////  
Serial.println("RPM = ");      // Output RPM for debug
Serial.println(int(RPM));      // RPM debug output
Serial.println(" ");
delay(2000); 
/////////////////////////////////////////////////////////////////////////

}

Don't do serial I/O in interrupt context.

Thanks for the reply

can you please make it clearer ? (English is not my Native language and cant understand what i have done wrong in the code )

are you referring to the '' Serial.begin(9600); ''
i have place serial just to monitor in serial monitor of arduino ide what is happening

thanks in advance

caslor:
cant understand what i have done wrong in the code

after understanding https://www.gammon.com.au/interrupts you probably will.

Nearly all errors that can be done with interrupts are covered by your code.