I am using the TimerOne library and its in the include file on top. The whole program didn't fit. I didn't think you need to initialize classes defined in a xxx.h file if they are defined there.
#include <Arduino.h>
#include <..\libraries\PinChangeInt\PinChangeInt.h>
#include <..\libraries\TimerOne\TimerOne.h>
// #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
#define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts
#define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
#define NO_PIN_STATE // to indicate that you don't need the pinState
#define NO_PIN_NUMBER // to indicate that you don't need the arduinoPin
// define DISABLE_PCINT_MULTI_SERVICE below to limit the handler to servicing a single interrupt per invocation.
#define DISABLE_PCINT_MULTI_SERVICE
/*
Copyright 2011 Lex Talionis (Lex.V.Talionis at gmail)
This program is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any
later version.
This code uses pin change interrupts and timer 1 to mesure the
time between the rise and fall of 3 channels of PPM
(Though often called PWM, see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253149521/all)
on a typical RC car reciver. It could be extended to as
many channels as you like. It uses the PinChangeInt library
to notice when the signal pin goes high and low, and the
Timer1 library to record the time between.
*/
#define PIN_IN_COUNT 3 //number of channels attached to the reciver
#define MAX_CHANGE_PINS PIN_IN_COUNT
#define PIN_OUT_COUNT 4
#define MAX_PINS 7
#define MaxPulseWait 22000
#define RC_Lights_Pin 13
#define CH5Rec 0
#define CH6Rec 1
#define CH7Rec 2 //Main loop state assignments
#define CH8Send 3
#define CH9Send 4
#define CH10Send 5
#define DETECTState 0 // RC_DETECTState (D_State) Assignments
#define READINGState 1
#define DETECTEDState 2
#define CONFIGOUTState 0 // RC_CONTROLSENDState (O_State) Assignments
#define FINISHEDState 1
struct RC_Channel
{
byte Pin;
int RecVal;
int SendVal;
byte IncVal;
int MinVal;
int MaxVal;
boolean UpdatedFlag;
boolean SentFlag;
};
RC_Channel RC_Ch[6];
byte Offset_Value = 0;
byte State = 0;//CH1Rec
byte D_State = DETECTState;
byte O_State = CONFIGOUTState;
byte PW_Out = 0;
byte BeaconBrightness = 0;
byte BeaconLoop =0;
byte Beacon_Period = 60; //maximum number of Pulse loop cycles in one Beacon Period (60 decimal)
float Pi = 3.1415926535897932384; //Constant Pi used to convert to radians
boolean Beacon_ON = false;
float SinValue = 0; //Sinewave value for sinstep degrees
void setup()
{
//longest pulse rep period in PPM is usally 20 milliseconds,
// initialize timer1, and set a 22ms second period(22000us)
Timer1.initialize(MaxPulseWait);
// Configure Timer2 for Fast PWM with max 256 count continuously running
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS22) | _BV(CS21) |_BV(CS20);// prescaler to 1024 change freq of 61Hz
//OCR2A = 0; //Pin D3 if you include _BV(COM2AB1) in TCCR2A otherwise set up for normal pin use
OCR2B = 0; //Pin D11
// end timer2 configure
// Set initial values for all of RC_Ch[], Pin will be assigned in for loop below
RC_Ch[0].Pin = 4;
RC_Ch[0].RecVal = RC_Ch[0].SendVal = 1500;
RC_Ch[0].IncVal = 2;
RC_Ch[0].MinVal = 1000;
RC_Ch[0].MaxVal = 2000;
RC_Ch[0].SentFlag = RC_Ch[0].UpdatedFlag = false;
RC_Ch[1] = RC_Ch[0];
RC_Ch[2] = RC_Ch[0];
RC_Ch[3] = RC_Ch[0];
RC_Ch[4] = RC_Ch[0];
RC_Ch[5] = RC_Ch[0];
for(byte i = 0; i < PIN_IN_COUNT; i++ ) // set receive pins to RC_Ch[]
{
//RC_Receive Pins Ch1:4, Ch2:5, Ch3:6
RC_Ch[i].Pin = (i+4);
pinMode( RC_Ch[i].Pin, INPUT); //set the pin to input
digitalWrite(RC_Ch[i].Pin, HIGH); //use the internal pullup resistor
};
for(byte i = PIN_IN_COUNT; i < (MAX_PINS-1); i++) //set send pins tp RC_Ch[]
{
//RCSend Pins Ch4:9, Ch5:10, Ch6:11 note that CH6 corresponds to Pin 11 and is the PWM ch
RC_Ch[i].Pin = (i+6);
pinMode(RC_Ch[i].Pin, OUTPUT); //set the pin to input
digitalWrite(RC_Ch[i].Pin, LOW); //
};
//Configure the extra running lights pin (13)
pinMode(RC_Lights_Pin,OUTPUT);
digitalWrite(RC_Lights_Pin,LOW);
} // End setup()
void RISING_ISR()
{
Timer1.start();
} //End RISING_ISR()
void FALLING_ISR()
{
Timer1.stop(); //Stop Timer1
RC_Ch[State].RecVal = TCNT1;
++D_State;
} // End FALLING_ISR()
void FINISHED_ISR()
{
Timer1.stop(); //stop Timer1
++O_State;
} //FINISHED_ISR()
void RC_DETECT()
{
switch (D_State)
{
case DETECTState: //Configure to capture a pulse width
attachInterrupt(RC_Ch[State].Pin, RISING_ISR, RISING);
Timer1.initialize(2200);
delay(20); //Wait for interrupt 20ms
break;
case READINGState: //We have detected a pulse and are reading the PulseWidth.
detachInterrupt(RC_Ch[State].Pin); //detach falling edge
attachInterrupt(RC_Ch[State].Pin, FALLING_ISR, FALLING); //attach the falling edge
delay(4); //Wait for interrupt 4ms
break;
case DETECTEDState: //We have captured the PulseWidth and have a value to transmit
detachInterrupt(RC_Ch[State].Pin); //detatch interrupts
RC_Ch[State].UpdatedFlag = true;
RC_Ch[State].SentFlag = false;
break;
} //End Switch D_State
}//End RC_DETECT()
void RC_CONTROLSEND()
{
switch (O_State)
{
case CONFIGOUTState: //Configure to Transmit a pulse width
Timer1.attachInterrupt(FINISHED_ISR,RC_Ch[State].SendVal); // Define EndCount Interrupt
RC_Ch[State].Pin = HIGH;
delay(3); //wait for interrupt and timeout in 3ms to send pulse
break;
case FINISHEDState: //We have sent the Pulse and need to reconfigure
//need to verify settings
Timer1.detachInterrupt();
Timer1.stop(); //Stop Timer1
RC_Ch[State].Pin = LOW;
RC_Ch[State].SentFlag = true;
RC_Ch[State].UpdatedFlag = false;
break;
}//End Switch (O_State)
}// End RC_CONTROLSEND()
void Limit_Range()
{
if(RC_Ch[State].SendVal > RC_Ch[State].MaxVal) RC_Ch[State].SendVal = RC_Ch[State].MaxVal; // Increase value if control is higher than flap value
else if(RC_Ch[State].SendVal < RC_Ch[State].MinVal) RC_Ch[State].SendVal = RC_Ch[State].MinVal; // Decrease value if control is less than flap value
}//End Limit_Range()
void Increment()
{
RC_Ch[State].SendVal = RC_Ch[State].SendVal + RC_Ch[State].IncVal;
Limit_Range();
} //End Increment()
void Decrement()
{
RC_Ch[State].SendVal = RC_Ch[State].SendVal - RC_Ch[State].IncVal;
Limit_Range();
return;
} //End Decrement()
void GET_OFFSET()
{
//First determine the offset between the control servo and the Slowed control value in ms
if(RC_Ch[State].UpdatedFlag == true)
{
Offset_Value = RC_Ch[State].SendVal - RC_Ch[State].RecVal;
if(Offset_Value > 2) Increment(); // Increase value if control is higher than flap value
else if(Offset_Value < 2) Decrement(); // Decrease value if control is less than flap value
RC_Ch[State].UpdatedFlag = false;
}//End If
} //End GET_OFFSET()
void BeaconON()
{
RC_Ch[State].RecVal = 2000;
digitalWrite(RC_Lights_Pin,HIGH);
Beacon_ON = true;
} //End BeaconON()
void BeaconOFF()
{
RC_Ch[State].RecVal = 1000;
digitalWrite(RC_Lights_Pin,LOW);
Beacon_ON =false;
} //End BeaconOFF()
void Calc_Beacon_Brightness() // setup Beacon blink brightness value: NOT UPDATESD
{
// determine sinewave value for sinstep angle
SinValue = sin((BeaconLoop*2*Pi)/Beacon_Period); //convert sinestep to radians, then divides by number of steps about one Sec
//determines LED brightness value for the PWM
BeaconBrightness = 127 + byte(128 * SinValue) ; //offset value to midpoint and scale sinewave from 0 to 255 range
//Limit_Range();
PW_Out = byte(BeaconBrightness);
++BeaconLoop % Beacon_Period; // Modulo Beacon_Period
} // End Calc_Beacon_Brightness()
void Calc_Beacon()
{
if(RC_Ch[State].UpdatedFlag == true)
{
if(RC_Ch[State].RecVal >= 1500) BeaconON();// Check for Beacon ON status
else BeaconOFF();
RC_Ch[State].UpdatedFlag = false;
}//end if RC_Ch[State}.Updated == true
if(Beacon_ON == true) Calc_Beacon_Brightness();// Check for Beacon ON status
else PW_Out = 0x00;
OCR2B = PW_Out;
D_State = DETECTState;
} //End Calc_Beacon()
void Transition() //Entered TransitionState: Change Mode from Capture to Output
{
Timer1.stop(); //Stop Timer1
//Configure Timer1 for Pulse period send
Timer1.setPeriod(2200);
Timer1.stop(); //Stop Timer1
O_State = CONFIGOUTState;
} //End Transition()