RC PWM input as a switch, Code help

Hi, ive written some code to try and read the pwm of an output from an RC receiver (servo channel), typically these are between 1000 and 2000 microseconds.

In order to read the input while carrying out other tasks i have chosen to use pinchange interrupts on the rising and falling edges.
However, ive hooked it all up and im not getting the results i would like. I'd be grateful if someone could cast their eye over my code to see if its utter garbage, or almost there, many thanks!

/*

RAW rc input test

*/

// Assign Pin names
int rcPin = 11;  //make rcPin = pin 11

//Create global variable in which to store our measured pulse width
int pulseWidth = 1500;  //And initialize the variable with the value 1500

//declare unsigned long variables in which to store rising and falling micros, for us to do math with later.
unsigned long risingMicros;  
unsigned long fallingMicros;

// Interrupt Service Routine (ISR)
void pinRising ()
{
  // handle pin rising here
  //if(rcPin == HIGH){
    risingMicros = micros();// if rc pin is HIGH then store the time since the program started in risingMicros
  //}
}  // end of pinRising routine

void pinFalling ()
{
  // handle pin falling here
  //if(rcPin == LOW){
    fallingMicros = micros();// if rc pin is LOW then store the time since the program started in fallingMicros
  //}
}  // end of pinFalling routine



void setup()
{
   //setup function goes here
   pinMode(rcPin, INPUT);  //sets rcPin as an input
   
   attachInterrupt (rcPin, pinRising, RISING);  // attach interrupt handler rising edge
   attachInterrupt (rcPin, pinFalling, FALLING);  // attach interrupt handler falling edge
   
   Serial.begin(115200);  //open up a serial port for debugging and messages
      delay(1000);
      Serial.println("RAW input test");  //warm up serial port
      delay(1000);
}



void loop()
{
  
  // work out the puslewidth
  noInterrupts();// turn off interrupts while we do math
  pulseWidth = fallingMicros - risingMicros;
  
  Serial.print(fallingMicros);
   Serial.print(" - ");
   Serial.print(risingMicros);
   Serial.print(" = ");
   Serial.println(pulseWidth); //Print out values for debugging purposes
   
  interrupts();// turn  interrupts back on now math has been done
    
  Serial.println(micros());
  
  delay(1000);// wait a second
 
    
}

However, ive hooked it all up and im not getting the results i would like.

Maybe you ought to learn to like the results you get. Or maybe you could explain what results you get, and why you don't like them.

   attachInterrupt (rcPin, pinRising, RISING);  // attach interrupt handler rising edge
   attachInterrupt (rcPin, pinFalling, FALLING);  // attach interrupt handler falling edge

The second one cancelled the first one. If you need multiple interrupt handlers, you need multiple interrupt pins.

The results I get are that risingMicros and fallingMicros are always zero, or at least they appear to be zero when they are output ted on the serial monitor.

As for the interrupts cancelling each other out, I suppose I could use CHANGE instead then do work to decide if it was a rising edge or falling edge by checking to see if the pin is now high or low.

Do I require a header file in order to use interrupts? I added a PinChange library, but when I try to add it to my project it doesn't paste an #include statement into my project like what other library's do. Perhaps I need to reinstall the library.

PS this is my first proper project with the arduino. Up til now all I've done is blink LED's, read switches, and flash other peoples code! (which might be evident!)

Another thought for the interrupts, could I link the incoming signal from one pin to another then test RISING on one and FALLING on another.

Or perhaps there is a far less complicated way of achieving my desired results.

What I'm aiming to do is monitor the servo output of an RC receiver, and then change the state of an LED based on wether the Pulse width is greater than 1500ms or less than.

From there I could then divide up further to give 4 switch positions that could be mixed to different radio switches.

Eventually I want the project to evolve to be a Variometer for a RC glider to enable me to find thermals and stay aloft longer while flying FPV. The purpose of the switch is so I can turn the beeping on and off as required, I also wish to test the flight pack voltage and alarm if it gets too low.

As for the interrupts cancelling each other out, I suppose I could use CHANGE instead then do work to decide if it was a rising edge or falling edge by checking to see if the pin is now high or low.

That is the way to do it.

Do I require a header file in order to use interrupts?

No.

I added a PinChange library, but when I try to add it to my project it doesn't paste an #include statement into my project like what other library's do. Perhaps I need to reinstall the library.

A link to the library would be useful. Step-by-step details about "add it to my project" would be useful, too. Personally, I don't find it too difficult to just type #include followed by the header file name, so I've never used the tool that you seem to be referring to.

Another thought for the interrupts, could I link the incoming signal from one pin to another then test RISING on one and FALLING on another.

That's another possibility.

Eventually I want the project to evolve to be a Variometer for a RC glider to enable me to find thermals and stay aloft longer while flying FPV. The purpose of the switch is so I can turn the beeping on and off as required, I also wish to test the flight pack voltage and alarm if it gets too low.

Frankly, I'd be using a proper receiver to control the things that it is supposed to control, and the Arduino to do stuff it is suited for. It is NOT a receiver, so making it control servos and stuff doesn't eliminate the need for a real receiver.

So after a bit more work i've now got some code that works XD

Instead of using PinChangeInt() i am now using the two hardware interupt pins on my arduino UNO.
These receive the servo signal from my RC Receiver. The two inputs are connected via a jumper.

One of the inputs is used to detect an interrupt on a RISING edge, The other on a FALLING edge.

Works pretty good, occasionally my math gets an erronous result, so if its outside the expected range the math is done again.

#include <PinChangeInt.h>

/*
Radio controlled switch

Using an RC PWM receiver out put to turn a LED on and off

When there is a rising edge on rcPin, pin 11, the ISR stores the time since the program started running in
the variable risingMicros.

Then, when a falling edge is detected on rcPin, the ISR stores the time since program started running in the
Variable fallingMicros.

To find the pulseWidth the program subtracts rising time from falling time. While this math is done we prevent
the values changing by turning interrupts off.

We can then test pulseWidth to decide if the switch should be on or off.
*/


// Assign Pin names
int ledPin = 13; // make ledPin = pin 13
int rcPin = 2;  //make rcPin = pin 2 (hardware interrupt 0)
int rcPin2 = 3;  //make rcPin = pin 3 (hardware interrupt 1)

//Create global variable in which to store our measured pulse width
int pulseWidth = 1500;  //And initialize the variable with the value 1500

//declare unsigned long variables in which to store rising and falling micros, for us to do math with later.
unsigned long risingMicros;  
unsigned long fallingMicros;

// Interrupt Service Routine (ISR)
void pinRising ()
{
  // handle pin rising here
  //if(rcPin == HIGH){
    risingMicros = micros();// if rc pin is HIGH then store the time since the program started in risingMicros
  //}
}  // end of pinRising routine

void pinFalling ()
{
  // handle pin falling here
  //if(rcPin == LOW){
    fallingMicros = micros();// if rc pin is LOW then store the time since the program started in fallingMicros
  //}
}  // end of pinFalling routine



void setup()
{
  
   pinMode(ledPin, OUTPUT);  //sets ledPin as an output
   pinMode(rcPin, INPUT);  //sets rcPin as an input
   pinMode(rcPin2, INPUT);  //sets rcPin2 as an input
   
   attachInterrupt (0, pinRising, RISING);  // attach interrupt handler rising edge
   attachInterrupt (1, pinFalling, FALLING);  // attach interrupt handler falling edge
   
   Serial.begin(115200);  //open up a serial port for debugging and messages
      delay(1000);
      Serial.println("RC Switch Project");  //warm up serial port
      delay(1000);
}



void loop()
{
  //pulseWidth is already primed at 1500 for the first loop.
  
    if(pulseWidth >= 1500){
    digitalWrite(ledPin, HIGH);            //turn on the LED
    Serial.print("PWM is ");
      Serial.print(pulseWidth);
      Serial.println(" so turn led on");  //shout it out
    
  }else{
    digitalWrite(ledPin, LOW);                         // turn LED off
    Serial.print("PWM is ");
      Serial.print(pulseWidth);
      Serial.println(" so turn led off"); //shout it out
  }
  
  delay(1000); //wait 1 second
  
  
  // work out the puslewidth at the end of each loop of the code
  noInterrupts();// turn off interrupts while we do math
  pulseWidth = fallingMicros - risingMicros;
  interrupts();// turn  interrupts back on now math has been done
  Serial.print(fallingMicros);
   Serial.print(" - ");
   Serial.print(risingMicros);
   Serial.print(" = ");
   Serial.println(pulseWidth); //Print out values for debugging purposes
  
  // ERROR CHECK, If the calculated values were updated before the math was completed, then the value would
  // be read wrong, to avoid this we test the result, if it is outside of expected range, we throw an error on the 
  //serial port, and then do the math again. this is repeated until the statement becomes true
  
  
  while(pulseWidth < 800 || pulseWidth > 2200){
    
    Serial.print("ERROR: PulseWidth Outside expected range (");
     Serial.print(pulseWidth);
     Serial.println(") recalculating pulsewidth");
    
    noInterrupts();// interrupts off while doing math
    pulseWidth = fallingMicros - risingMicros;// do math again
    interrupts();//interrupts back on once math is done
    
    //tell us what values you got this time
    Serial.print(fallingMicros);
     Serial.print(" - ");
     Serial.print(risingMicros);
     Serial.print(" = ");
     Serial.println(pulseWidth); //Print out values for debugging purposes
    
    //wait 2 seconds before you check again
    delay(2000);
    
  }
    
}

I added a PinChange library, but when I try to add it to my project it doesn't paste an #include statement into my project like what other library's do. Perhaps I need to reinstall the library.

A link to the library would be useful. Step-by-step details about "add it to my project" would be useful, too. Personally, I don't find it too difficult to just type #include followed by the header file name, so I've never used the tool that you seem to be referring to.

Arduino Playground - HomePage this is the library i was trying to use
http://arduino.cc/en/Guide/Libraries how i was adding a library
Libraries - Arduino Reference How i was importing the library into my project

Frankly, I'd be using a proper receiver to control the things that it is supposed to control, and the Arduino to do stuff it is suited for. It is NOT a receiver, so making it control servos and stuff doesn't eliminate the need for a real receiver.

I am using a "proper receiver", the arduino is being used to convert the receivers PWM output to a digital output.