int AI_Pin0 = 0; // Ana In Ch.0 pin - Aeleron potentiometer
int AI_Pin1 = 1; // Ana In Ch.1 pin - Elevator potentiometer
int AI_Pin2 = 2; // Ana In Ch.2 pin - Throttle potentiometer
int AI_Pin3 = 3; // Ana In Ch.3 pin - Rudder potentiometer
int AI_Raw0; // Ana In Ch.0 raw var - 0->1023
int AI_Raw1; // Ana In Ch.1 raw var - 0->1023
int AI_Raw2; // Ana In Ch.2 raw var - 0->1023
int AI_Raw3; // Ana In Ch.3 raw var - 0->1023
int AI_0; // Ana In Ch.0 raw var - 0->1023 compensated
int AI_1; // Ana In Ch.1 raw var - 0->1023 compensated
int AI_2; // Ana In Ch.2 raw var - 0->1023 compensated
int AI_3; // Ana In Ch.3 raw var - 0->1023 compensated
int Aeleron_uS = 700; // Ana In Ch.0 uS var - Aeleron
int Elevator_uS = 700; // Ana In Ch.1 uS var - Elevator
int Throttle_uS = 700; // Ana In Ch.2 uS var - Throttle
int Rudder_uS = 724; // Ana In Ch.3 uS var - Rudder
int Spare1_uS = 1225; // uS var - Spare1 (set to mid)
int Spare2_uS = 1225; // uS var - Spare2 (set to mid)
int Fixed_uS = 300; // PPM frame fixed LOW phase
unsigned long SynchroFrameAdj = 0; // Timing adjustment for Synchro blank time in uS
unsigned long SynchroFrameAdjDiff = 0; // Timing adjustment for Synchro blank time in uS
unsigned long TotalFrameLengthAllowed = 20000; // Total Frame Length allowed in uS
int pulseMin = 750; // pulse minimum width minus start in uS
int pulseMax = 1700; // pulse maximum width in uS
float DualrateMultAel = 0.9; // Dual rate mult
float DualrateMultEle = 0.9; // Dual rate mult
float DualrateMultThr = 0.9; // Dual rate mult
float DualrateMultRud = 0.9; // Dual rate mult
int DualrateAdjAel = 0; // Dual rate mid adjustment
int DualrateAdjEle = 0; // Dual rate mid adjustment
int DualrateAdjThr = 0; // Dual rate mid adjustment
int DualrateAdjRud = 0; // Dual rate mid adjustment
int outPin = 10; // digital pin 10
int inPinD6 = 6; // digital pin 6
void setup() {
pinMode(outPin, OUTPUT); // sets the digital pin as output
pinMode(inPinD6, INPUT); // sets the digital pin as input
digitalWrite(inPinD6, HIGH); // turn on pull-up resistor
}
void loop() { // Main loop
// Frame start save, used to determine required 20mS PPM frame interval
SynchroFrameAdj = micros();
// Read 4 analogue ports and convert to mS
AI_Raw0 = analogRead(AI_Pin0);
AI_Raw1 = analogRead(AI_Pin1);
AI_Raw2 = analogRead(AI_Pin2);
AI_Raw3 = analogRead(AI_Pin3);
// Compensate for discrepancy in pot inputs, also use this to invert inputs if necessary
AI_0 = map(AI_Raw0, 0, 1023, 0, 1023) - 0; // y=mx+c, x to y scales to x1 to y1
AI_1 = map(AI_Raw1, 0, 1023, 0, 1023) - 0; // y=mx+c, x to y scales to x1 to y1
AI_2 = map(AI_Raw2, 0, 1023, 0, 1023) + 0; // y=mx+c, x to y scales to x1 to y1
AI_3 = map(AI_Raw3, 0, 1023, 0, 1023) + 0; // y=mx+c, x to y scales to x1 to y1
// Map analogue inputs to PPM rates for each of the channels
Aeleron_uS = (AI_0 * DualrateMultAel) + pulseMin + DualrateAdjAel;
Elevator_uS = (AI_1 * DualrateMultEle) + pulseMin + DualrateAdjEle;
Throttle_uS = (AI_2 * DualrateMultThr) + pulseMin + DualrateAdjThr;
Rudder_uS = (AI_3 * DualrateMultRud) + pulseMin + DualrateAdjRud;
// Check limits
if (Aeleron_uS <= 750) Aeleron_uS = 750; // Min
if (Aeleron_uS >= 1700) Aeleron_uS = 1700; // Max
if (Elevator_uS <= 750) Elevator_uS = 750; // Min
if (Elevator_uS >= 1700) Elevator_uS = 1700; // Max
if (Throttle_uS <= 750) Throttle_uS = 750; // Min
if (Throttle_uS >= 1700) Throttle_uS = 1700; // Max
if (Rudder_uS <= 750) Rudder_uS = 750; // Min
if (Rudder_uS >= 1700) Rudder_uS = 1700; // Max
// Channel 1
digitalWrite(outPin, LOW);
delayMicroseconds(Fixed_uS); // Hold for 300 uS
digitalWrite(outPin, HIGH);
delayMicroseconds(Aeleron_uS); // Hold for Aeleron_uS microseconds
// Channel 2
digitalWrite(outPin, LOW);
delayMicroseconds(Fixed_uS); // Hold for 300 uS
digitalWrite(outPin, HIGH);
delayMicroseconds(Elevator_uS); // Hold for Elevator_uS microseconds
// Channel 3
digitalWrite(outPin, LOW);
delayMicroseconds(Fixed_uS); // Hold for 300 uS
digitalWrite(outPin, HIGH);
delayMicroseconds(Throttle_uS); // Hold for Throttle_uS microseconds
// Channel 4
digitalWrite(outPin, LOW);
delayMicroseconds(Fixed_uS); // Hold for 300 uS
digitalWrite(outPin, HIGH);
delayMicroseconds(Rudder_uS); // Hold for Rudder_uS microseconds
// Channel 5
digitalWrite(outPin, LOW);
delayMicroseconds(Fixed_uS); // Hold for 300 uS
digitalWrite(outPin, HIGH);
delayMicroseconds(Spare1_uS); // Hold for xxxx microseconds
// Channel 6
digitalWrite(outPin, LOW);
delayMicroseconds(Fixed_uS); // Hold for 300 uS
digitalWrite(outPin, HIGH);
delayMicroseconds(Spare2_uS); // Hold for xxxx microseconds
// Synchro pulse
digitalWrite(outPin, LOW);
delayMicroseconds(Fixed_uS); // Hold for 300 microseconds
digitalWrite(outPin, HIGH); // Start Synchro pulse
SwitchesRates(); // Now is the time to jump to subroutine whilst we have some free time
SynchroFrameAdjDiff = micros() - SynchroFrameAdj; // Calculate remainder and adjust (fails after 70mins, but more than enough as who flies that long?)
SynchroFrameAdj = TotalFrameLengthAllowed - SynchroFrameAdjDiff;
delayMicroseconds(SynchroFrameAdj); // Hold for remainder (uS), Synchro blank time
}
void SwitchesRates() {
if (digitalRead(inPinD6) == 0) { // Normal/high rate
DualrateMultAel = 0.9;
DualrateMultEle = 0.9;
DualrateMultThr = 0.9;
DualrateMultRud = 0.9;
DualrateAdjAel = 0;
DualrateAdjEle = 0;
DualrateAdjThr = 0;
DualrateAdjRud = 0;
}
}