micros(), FALLING, RISING

I’m trying to fill a couple of arrays, the data would be from micros( ) marking the FALLING and RISING edges of a pulse train.
I have the pulse going to D2 and D3, the hardware interrupt pins; D2 is FALLING detect and D3 is RISING detect.
When there’s a falling edge then write micros to time_lo, and when there’s a rising edge then write micros to time_hi.
Once the arrays fill or if there’s a timeout (fewer pulses than array space) then I want to print out [Serial Monitor] the results.

unsigned long time_lo [40];
unsigned long time_hi [40];
unsigned int idx = 0;
unsigned long current_us;
volatile boolean underway = false;   // flag

void setup ()
{
  Serial.begin(9600);
  attachInterrupt (0,record_lo,FALLING); // INT on D2
  attachInterrupt (1,record_hi,RISING);  // INT on D3
}

void loop ()
{
  if (underway == false)  // no signal
  { 
  }
  if (underway == true)   // signal affirmed
  {
    current_us = micros();
    if if ( (current_us > (time_hi[idx] + 2000)) || (idx > 40))  // look for timeout
    {
      results_print();
    }
  }
}

void record_lo ()
{
  time_lo[idx] = micros();  // mark lo
  underway = true;
}

void record_hi ()
{
  time_hi[idx] = micros();  // mark hi
  idx ++;
}

void results_print ()
{
  for (idx = 0; idx < 40; idx ++)
  {
    Serial.print (idx);
    Serial.print ("  ");
    Serial.print (time_lo[idx]);
    Serial.print ("  ");
    Serial.print (time_hi[idx]);
    Serial.print ("\r\n");
  }
  for (idx = 0; idx < 40; idx ++) // clear arrays
  {
    time_lo[idx]=0;  
    time_hi[idx]=0;
  }
  idx = 0;
  underway = false;
}

My pulse trains are 16 each, but I don’t get displayed 40 pairs of hi-to-lo and lo-to-hi transitions, just 6 (for 0, 3, 10, 17, 29, 36)

Hi Runaway Pancake,

why don't you declare the variables time_lo and time_hi as volatile ?

It will be needed as long as you access the variables from the interrupt functions and the loop() function.

Greetinx Peter

Hi, Is it the same pulse going to both pins ? If so why not using a single interrupt with CHANGE ?

Duane B

rcarduino.blogspot.com

why don't you declare the variables time_lo and time_hi as volatile ?

I modified those, volatile unsigned long time_lo [40]; volatile unsigned long time_hi [40]; Same results.

Is it the same pulse going to both pins ? If so why not using a single interrupt with CHANGE ?

Yes, the same pulse / signal. I couldn't think of a way to increment my index (idx) counter going with CHANGE without more code which would slow it down.


Not needing to conserve the interrupt pins, I thought this way'd be faster.

How fast does it need to be, micros is not quick.

Duane B

rcarduino.blogspot.com

That could be where I'm falling down. The low times are always 700us, the high times can be either 400us or 1600us wide.

That should be fine.

I would put both parts of you code into a single ISR. I measure RC Signals which are 1000 to 2000 us long all the time, often several channels of them simultaneously as well as generating the output and there is still plenty of processing power left so I suggest a single ISR to simplify your hardware and ensure thats not the problem and then add a little logic to the ISR to do whatever it is you want depending on the pulse edge.

This is an example from one of my RC Projects -

  // rising edge, lets record it
  if(PIND&4) // int1 is high, its a rising edge so record it
  {
    m_unRiseTime = TCNT1;
  }
  else // falling edge, pulse width is TCNT1 - m_unRiseTime;
  {
    m_bSignalIn = TCNT1 - m_unRiseTime;
  }

If you don’t want to use TCNT1, just use millis()

Duane B