user29796: In my recent project, I have RPM Square wave from vehicle. Now, based on that I want square wave based on falling edge but only alternative pulse of RPM square wave.
I think below image clear more properly. 

Upper yellowish square wave which I need. And below pinkish square wave is RPM square wave.
I made a code for that and it's working fine but when RPM is stable. But when RPM change rapidly then it's not working fine.
const int kPinRPM = 3;        // RPM / Digital Pin 3
const int RPMInterrupt = 1;   // RPM's interrrupt pin
byte engineCylinders = 2;         // Engine cylinders = 4;
byte engineCycles = 4;            // Engine cycle = 2
int refreshInterval = 750;        // Milliseconds between sensor updates
unsigned long previousMillis = 0;
volatile int RPMpulses = 0;
int RPM, Final_RPM;

const int kPinInj = 12;

volatile uint32_t kInjTime = 0;

void setup()
{
  Serial.begin(250000);

  pinMode(kPinRPM, INPUT_PULLUP); // Enable internal pullup
  attachInterrupt(RPMInterrupt, countRPM, FALLING); //Interrupt for RPM

  pinMode(kPinInj, OUTPUT);  
}

void loop()
{
  if(millis() - previousMillis > refreshInterval)
  {
    previousMillis = millis();
    RPM =  getRPM();
  }

  Serial.println(RPM);

  if((kInjTime > 0) && ((millis() - kInjTime) >= 10))
  {
    kInjTime = 0;
    digitalWrite(kPinInj, LOW);
  }
}

void countRPM()
{
  RPMpulses++;

  if(RPMpulses % 2 == 0)           // Skip alternative pulse
  {
    kInjTime = millis();
    digitalWrite(kPinInj, HIGH);
  }
}

int getRPM()
{
  Final_RPM = int(RPMpulses * (60000.0 / float(refreshInterval)) * engineCycles / engineCylinders / 2.0);
  RPMpulses = 0;
  Final_RPM = min(99999, Final_RPM);
}

After SUGGESTION, updating my codes. But it output waveform has some problem. In white circle, you can see that problem.


user30002: There are some things you shouldn't be doing within an interrupt service routine (ISR) like countRPM():

Don't call the millis() function. It depends on other interrupts which will be disabled during the execution of your ISR.
Don't call digitalWrite or any other functions
Don't use execution cycles hungry operators like % (modulo). To obtain modulo 2, just use a bit mask for the LSB.

What you should actually be doing within the ISR is just setting/resetting a flag or variable. Then, do all your stuff in the loop() function according the value of the flag or variable.

user3917: Rather than saying
if(RPMpulses % 2 == 0)           // Skip alternative pulse
  {
    kInjTime = millis();
    digitalWrite(kPinInj, HIGH);
  }

and later setting kPinInj in the main loop, you could act as follows:
digitalWrite(kPinInj, RPMpulses & 1); // Set or clear kPinInj
if(RPMpulses & 1) 
  kInjTime = millis();  // Store alternate times

This would ensure that your trace 1 toggles properly.  If you want a shorter up-time on that trace, you could treat CHANGE interrupts rather than FALLING, and maintain RPMpulses as a number twice as big as now, ie use 120000 instead of 60000 in the RPM calculation, and could say:
digitalWrite(kPinInj, (RPMpulses & 3)==1); // Set or clear kPinInj
if((RPMpulses & 3)==1) 
  kInjTime = millis();  // Store alternate fall times

Note, the floating point arithmetic in getRPM() is slow.  At a 750 ms refresh interval, that may not matter much.  But you probably can get good enough results rather more quickly using just integer arithmetic, if you parenthesize the expression somewhat as follows:
Final_RPM = ((RPMpulses * (60000UL / 2) * (engineCycles/engineCylinders)) / refreshInterval;

That is, do any remainderless divisions early; multiply all the remaining numerator terms together into a large number; then divide by the comparatively small refreshInterval, ending up with numerous significant digits without the use of floating point arithmetic, which takes many milliseconds on typical Arduino systems.
Edit 2: If your modified code still says RPMpulses = 0; within getRPM(), you may get a glitch at the end or beginning of each   refresh interval.  You may instead need to say RPMpulses = 1;, or RPMpulses &= 1;, or some such.  Also, to avoid an extra count when the latter expression is 1 instead of 0, say RPM0 = RPMpulses &= 1; and use (RPMpulses-RPM0) instead of RPMpulses in calculating Final_RPM.

29796: <p>In my recent project, I have RPM Square wave from vehicle. Now, based on that I want square wave based on falling edge but only alternative pulse of RPM square wave.</p>

<p>I think below image clear more properly. </p>

<p><a href="https://i.stack.imgur.com/d3iXZ.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/d3iXZ.jpg" alt="Pulse"></a></p>

<p>Upper yellowish square wave which I need. And below pinkish square wave is RPM square wave.</p>

<p>I made a code for that and it's working fine but when RPM is stable. But when RPM change rapidly then it's not working fine.</p>

<pre><code>const int kPinRPM = 3;        // RPM / Digital Pin 3
const int RPMInterrupt = 1;   // RPM's interrrupt pin
byte engineCylinders = 2;         // Engine cylinders = 4;
byte engineCycles = 4;            // Engine cycle = 2
int refreshInterval = 750;        // Milliseconds between sensor updates
unsigned long previousMillis = 0;
volatile int RPMpulses = 0;
int RPM, Final_RPM;

const int kPinInj = 12;

volatile uint32_t kInjTime = 0;

void setup()
{
  Serial.begin(250000);

  pinMode(kPinRPM, INPUT_PULLUP); // Enable internal pullup
  attachInterrupt(RPMInterrupt, countRPM, FALLING); //Interrupt for RPM

  pinMode(kPinInj, OUTPUT);  
}

void loop()
{
  if(millis() - previousMillis &gt; refreshInterval)
  {
    previousMillis = millis();
    RPM =  getRPM();
  }

  Serial.println(RPM);

  if((kInjTime &gt; 0) &amp;&amp; ((millis() - kInjTime) &gt;= 10))
  {
    kInjTime = 0;
    digitalWrite(kPinInj, LOW);
  }
}

void countRPM()
{
  RPMpulses++;

  if(RPMpulses % 2 == 0)           // Skip alternative pulse
  {
    kInjTime = millis();
    digitalWrite(kPinInj, HIGH);
  }
}

int getRPM()
{
  Final_RPM = int(RPMpulses * (60000.0 / float(refreshInterval)) * engineCycles / engineCylinders / 2.0);
  RPMpulses = 0;
  Final_RPM = min(99999, Final_RPM);
}
</code></pre>

<p>After SUGGESTION, updating my codes. But it output waveform has some problem. In white circle, you can see that problem.</p>

<p><a href="https://i.stack.imgur.com/8tEuN.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8tEuN.jpg" alt="Waveforms"></a></p>
 30002: <p>There are some things you shouldn't be doing within an interrupt service routine (ISR) like <code>countRPM()</code>:</p>

<ol>
<li><p>Don't call the <code>millis()</code> function. It depends on other interrupts which will be disabled during the execution of your ISR.</p></li>
<li><p>Don't call <code>digitalWrite</code> or any other functions</p></li>
<li><p>Don't use execution cycles hungry operators like <code>%</code> (modulo). To obtain modulo 2, just use a bit mask for the LSB.</p></li>
</ol>

<p>What you should actually be doing within the ISR is just setting/resetting a flag or variable. Then, do all your stuff in the <code>loop()</code> function according the value of the flag or variable.</p>
 3917: <p>Rather than saying</p>

<pre><code>if(RPMpulses % 2 == 0)           // Skip alternative pulse
  {
    kInjTime = millis();
    digitalWrite(kPinInj, HIGH);
  }
</code></pre>

<p>and later setting <code>kPinInj</code> in the main loop, you could act as follows:</p>

<pre><code>digitalWrite(kPinInj, RPMpulses &amp; 1); // Set or clear kPinInj
if(RPMpulses &amp; 1) 
  kInjTime = millis();  // Store alternate times
</code></pre>

<p>This would ensure that your trace 1 toggles properly.  If you want a shorter up-time on that trace, you could treat <code>CHANGE</code> interrupts rather than <code>FALLING</code>, and maintain <code>RPMpulses</code> as a number twice as big as now, ie use 120000 instead of 60000 in the RPM calculation, and could say:</p>

<pre><code>digitalWrite(kPinInj, (RPMpulses &amp; 3)==1); // Set or clear kPinInj
if((RPMpulses &amp; 3)==1) 
  kInjTime = millis();  // Store alternate fall times
</code></pre>

<p>Note, the floating point arithmetic in <code>getRPM()</code> is slow.  At a 750 ms refresh interval, that may not matter much.  But you probably can get good enough results rather more quickly using just integer arithmetic, if you parenthesize the expression somewhat as follows:</p>

<pre><code>Final_RPM = ((RPMpulses * (60000UL / 2) * (engineCycles/engineCylinders)) / refreshInterval;
</code></pre>

<p>That is, do any remainderless divisions early; multiply all the remaining numerator terms together into a large number; then divide by the comparatively small <code>refreshInterval</code>, ending up with numerous significant digits without the use of floating point arithmetic, which takes many milliseconds on typical Arduino systems.</p>

<p><em>Edit 2:</em> If your modified code still says <code>RPMpulses = 0;</code> within <code>getRPM()</code>, you may get a glitch at the end or beginning of each   refresh interval.  You may instead need to say <code>RPMpulses = 1;</code>, or <code>RPMpulses &amp;= 1;</code>, or some such.  Also, to avoid an extra count when the latter expression is 1 instead of 0, say <code>RPM0 = RPMpulses &amp;= 1;</code> and use <code>(RPMpulses-RPM0)</code> instead of <code>RPMpulses</code> in calculating <code>Final_RPM</code>.</p>
