Can't get hardware interrupt 0 to work on Pro Mini

Hi all:
You've probably had this question a lot, so I'm sorry if repeating. I am trying to use pin 2 to read pulse width from an RC receiver on a quadcopter, and set the lights accordingly. The ISR should read the system clock in microseconds when the pulse starts and when it completes followed by simple subtraction to get pulsewidth in microseconds. The pulses range from perhaps 900 to 2100 microseconds, with approximately a 22 millisecond delay between them. The logic is pulse high. All of the light patterns work when tested in the code (by setting the initial value of the pulseWidth variable to a range accomodated by the logic (900-2100 microseconds). The interrupt does not trigger, however, when driven with a pulse generator. The code is attached here:

#define   PULSE_PIN   2

#define   LED0       10  // left front led
#define   LED1       11  // right front led
#define   LED2       12  // right rear led
#define   LED3       13  // left rear led

//Times are in ms
#define   STROBE_ON    20
#define   STROBE_OFF  800
#define   STROBE_DLY  100
#define   ALT_PD      350

#define FRONT_BACK      0
#define SIDE_SIDE       1
#define DIAGONAL        3

#define CW              1
#define CCW             0

#define CYCLES          5

//tell the compiler that these WILL change
volatile int lights[4] = { LED0, LED1, LED2, LED3 };

volatile long pulseStart = 0;
volatile long pulseWidth = 1700;


//Do setup routine...define pin functions
void setup(){
  
 pinMode ( PULSE_PIN, INPUT );

 pinMode ( LED0, OUTPUT ); 
 pinMode ( LED1, OUTPUT ); 
 pinMode ( LED2, OUTPUT ); 
 pinMode ( LED3, OUTPUT ); 
 
 attachInterrupt( (PULSE_PIN - 2),ISRpwTrigger, CHANGE );
}

void ISRpwTrigger() {
  if( digitalRead( PULSE_PIN == HIGH ) )
     pulseStart = micros(); 
  else
     pulseWidth = micros() - pulseStart;
}

//light all of the leds simultaneously
void allLight(){

  digitalWrite ( LED0, HIGH ); 
  digitalWrite ( LED1, HIGH ); 
  digitalWrite ( LED2, HIGH ); 
  digitalWrite ( LED3, HIGH ); 

}

//turn all lights off
void allDark(){
  
  digitalWrite ( LED0, LOW );
  digitalWrite ( LED1, LOW ); 
  digitalWrite ( LED2, LOW ); 
  digitalWrite ( LED3, LOW ); 
}

void allBlink(){
    allLight();
    delay ( STROBE_ON );
    allDark();
    delay ( STROBE_OFF );
}

void wingtipStrobe( int count ) {
    for ( int counter = 0; counter < count; counter++ ) {
      allLight();
      delay ( STROBE_ON );
      allDark();
      delay ( STROBE_DLY );
    }
    delay ( STROBE_OFF );
}

//alternate blinks--pass in pin order and delay ms
void altBlink ( int mode, int dly ) {
  
//remember...LED0 is always in the first position
// we are going to always use the pattern [1] and [2],then [3] and [4];

  lights[0] = LED0;
  
  switch( mode ) {
    case  FRONT_BACK:
      lights[1] = LED1;
      lights[2] = LED2;
      lights[3] = LED3;
    break;
    case  SIDE_SIDE:
      lights[1] = LED3;
      lights[2] = LED1;
      lights[3] = LED2;
    break;
    case  DIAGONAL:
      lights[1] = LED2;
      lights[2] = LED1;
      lights[3] = LED3;
    break;
    default:
      allLight();
      return;
  }

     digitalWrite ( lights[0], HIGH );
     digitalWrite ( lights[1], HIGH );
     digitalWrite ( lights[2], LOW  );
     digitalWrite ( lights[3], LOW  );
     delay ( dly );
     
     digitalWrite ( lights[0], LOW  );
     digitalWrite ( lights[1], LOW  );
     digitalWrite ( lights[2], HIGH );
     digitalWrite ( lights[3], HIGH );
     delay ( dly );
  allDark();
}

void ringBlink( int dir, int dly ) {
    
  int index;
  
  if ( dir != CCW ){
    lights[0] = LED0;
    lights[1] = LED1;
    lights[2] = LED2;
    lights[3] = LED3;
  } else {
    lights[0] = LED3;
    lights[1] = LED2;
    lights[2] = LED1;
    lights[3] = LED0;    
  }
   
      for (index = 0; index < 4; index++){
         digitalWrite ( lights[index],       HIGH );
         digitalWrite ( lights[(index +1)%4], LOW );
         digitalWrite ( lights[(index +2)%4], LOW );
         digitalWrite ( lights[(index +3)%4], LOW );
         delay(dly);
    }
  allDark();  
}


//loop will run forever, but the system is interrupt driven
void loop(){
  
  if ( pulseWidth > 900 ) {
      if          ( pulseWidth < 1100 )    allDark();
      else if ( pulseWidth < 1250 )    wingtipStrobe( 2 );
      else if ( pulseWidth < 1400 )    altBlink( FRONT_BACK, ALT_PD );
      else if ( pulseWidth < 1550 )    altBlink( SIDE_SIDE,  ALT_PD );
      else if ( pulseWidth < 1700 )    altBlink( DIAGONAL,   ALT_PD );
      else if ( pulseWidth < 1850 )    ringBlink( CW,           100 ); 
      } else                           allLight(); 
    
}

Pin 2 is held low by a 10k resistor to ground with the pulse being delivered at the pin 2 side of the resistor ;). I have also tried a 330 ohm resistor with the same results.

I have run similar programs on a UNO development board and it accurately reports the pulsewidth to an LED monitor.

What am I doing wrong :expressionless:

//tell the compiler that these WILL change
volatile int lights[4] = { LED0, LED1, LED2, LED3 };

Why are these volatile? Why are they variable? Do you really intend to be changing pin numbers in the code?

What am I doing wrong

Don't know. Perhaps you could simply turn an LED on or off in the ISR to confirm that it actually gets called.

The array is volatile because the code (someday) will be rewritten to allow for tricopters, quadcopters, hexcopters, octacopters, etc. Of course, the array will need to be defined differently then. Also, the order of LEDs change with blink patterns. Probably hamhanded, but it seemed the easiest way to do it.

I've already tried to attach a pushbutton to the interrupt to toggle an LED. No joy. I likely need to set up serial commo with the linux box to see what is going on inside. Maybe it is just the cheap Chinese boards???? I plan to go to my local pusher--er hardware parts store--to get an authentic part tomorrow. I do find programming addicting :slight_smile: