Arduino-Controlled RC Transmitter

Here is the code i use:

//Serial to PPM based on Ian´s:
//// RC Joystick 430mHz
//// For use with Arduino Nano V3.0
//// Ian Johnston 28/04/2010
////
//// If you would like to help support future projects like these then please
//// make a small PayPal donation via my website www.ianjohnston.com
//// Thanks!
////
//// Ver 1.6 - Now using Timer1 to set 22mS refresh for PPM output.
////           Dual rates are implemented but need custom setup.
////           Trimming is not working.
////           Battery monitor sub tweaked
////           Adjusted timing off various subs
////           Various tweaks to LCD & battery monitor
////
// Serial to PPM ??? SEND: S010800 to set Channel 1 to Pos 800

int tick = 0; // Used for various timing of subs
int tick2 = 0; // Used for various timing
int slowflag;

int CH1= 700;
int CH2 = 700;
int CH3 = 700;
int CH4 = 700;
int CH5 = 700;
int CH6 = 700;

int RatesHIMIDLO = 2; // Default is MID rates
int TrimSetting = 0;
int Fixed_uS = 300;       // PPM frame fixed LOW phase
int pulseMin = 700;          // pulse minimum width in uS
int pulseMax = 1700;      // pulse maximum width in uS
int outPinTEST = 8;       // digital pin 8
int outPinPPM = 10;       // digital pin 10


//*** Serial COM&Comand
const int MSG_LENGTH = 7;  // message is char 'S' followed by 6 digits
const char HEADER  = 'S';
//***

ISR(TIMER1_COMPA_vect) {

  ppmoutput(); // Jump to ppmoutput subroutine
  tick = tick + 1;  // update timing tick for subs
  tick2 = tick2 + 1;  // update tick

}

void setup() {

  // setup I/O
  pinMode(outPinPPM, OUTPUT);   // sets the digital pin as output


  // ** SERIAL SETUP
  Serial.begin(57600);         // connect to the serial port
  Serial.println("Serial to PPM");
  //****


  // Setup timer
  TCCR1A = B00110001; // Compare register B used in mode '3'
  TCCR1B = B00010010; // WGM13 and CS11 set to 1
  TCCR1C = B00000000; // All set to 0
  TIMSK1 = B00000010; // Interrupt on compare B
  TIFR1  = B00000010; // Interrupt on compare B
  OCR1A = 22000; // 22mS PPM output refresh
  OCR1B = 1000;
}


void loop() { // Main loop
  processSerial();
  //readanainputsmap(); // Run sub - read ana inputs & map
  checklimits();      // Run sub - check individual channel PPM limits
  //
  //  if (tick >= 11) {     // only run certain subs every 1/4 sec or so (22mS * 11 = 242mS)
  //      tick = 0;
  //      //switchesRates();    // Run sub - read panel switches
  //      //batterymonitor();   // Run sub - check battery
  //  }
  //  
  //  // generate slow changing flag, about 2sec on/off
  //  if (tick2 <= 50) {
  //      slowflag = 0;
  //  }
  //  if (tick2 >= 50 && tick2 <=100) {
  //      slowflag = 1;
  //  }
  //  if (tick2 >= 100) {
  //      slowflag = 0;
  //      tick2 = 0;
  //  } 

}


void processSerial() {
  // Process a message available on serial port
  while(Serial.available() >=  MSG_LENGTH )  // process messages when all characters are received: "S" as start indicator, 2 digits as channel number, 4 digits for the value
  {
    if(Serial.read() == HEADER ) //Serial.Read() will "use up" the chars, so we can forget about the "S" now...
    {
      int val = 0;
      int sval =0;
      //First 2 digits are the Channel...
      for(int i =0; i < MSG_LENGTH-5; i++)//7-5=2
      {

        char ch = Serial.read();
        if(ch >= '0' && ch <= '9'){            // is ch a number?
          sval = sval * 10 + ch - '0';           // yes, accumulate the value
        }

      }
      Serial.print("CH: ");
      Serial.println(sval); // For debug


      //Next 4 Digits should be the position/
      for(int i =0; i < MSG_LENGTH-3; i++) // 7-3=4 ... 2+4=6 ... S-12-3456
      {
        char ch = Serial.read();
        if(ch >= '0' && ch <= '9'){            // is ch a number?
          val = val * 10 + ch - '0';           // yes, accumulate the value
        }
      }
      Serial.print("POS: ");
      Serial.println(val); // for debug
      Serial.flush();//clear buffer, there might be some rubbish inside...
      //Serial.println(sval);
      //Serial.println(val);
      // For now its just Channel 1 which will get its new value.
      if (sval==1){
        CH1=val;
        Serial.print("CH1 Set to ");
        Serial.println(CH1);
      }


    }
  }

}


void checklimits() { // check limits sub
  if (CH1 < 700) CH1 = 700;     // Min
  if (CH1 > 1700) CH1 = 1700;   // Max   
  if (CH2 < 700) CH2 = 700;   // Min
  if (CH2 > 1700) CH2 = 1700; // Max 
  if (CH3 < 700) CH3 = 700;   // Min
  if (CH3 > 1700) CH3 = 1700; // Max 
  if (CH4 < 700) CH4 = 700;       // Min
  if (CH4 > 1700) CH4 = 1700;     // Max   
  if (CH5 < 700) CH5 = 700;               // Min
  if (CH5 > 1700) CH5 = 1700;             // Max
  if (CH6 < 700) CH6 = 700;               // Min
  if (CH6 > 1700) CH6 = 1700;             // Max 
}


void ppmoutput() { // PPM output sub
  // test pulse - used to trigger scope
  //digitalWrite(outPinTEST, LOW);
  //delayMicroseconds(100);    // Hold
  // digitalWrite(outPinTEST, HIGH);

  // Channel 1 - Aeleron
  digitalWrite(outPinPPM, LOW);
  delayMicroseconds(Fixed_uS);    // Hold
  digitalWrite(outPinPPM, HIGH);
  delayMicroseconds(CH1);  // Hold for Aeleron_uS microseconds      

  // Channel 2 - Elevator 
  digitalWrite(outPinPPM, LOW);
  delayMicroseconds(Fixed_uS);    // Hold
  digitalWrite(outPinPPM, HIGH);
  delayMicroseconds(CH2); // Hold for Elevator_uS microseconds      

  // Channel 3 - Throttle
  digitalWrite(outPinPPM, LOW);
  delayMicroseconds(Fixed_uS);    // Hold
  digitalWrite(outPinPPM, HIGH);
  delayMicroseconds(CH3); // Hold for Throttle_uS microseconds      

  // Channel 4 - Rudder
  digitalWrite(outPinPPM, LOW);
  delayMicroseconds(Fixed_uS);    // Hold
  digitalWrite(outPinPPM, HIGH);
  delayMicroseconds(CH4);   // Hold for Rudder_uS microseconds

  // Channel 5 - TI Switch
  digitalWrite(outPinPPM, LOW);
  delayMicroseconds(Fixed_uS);    // Hold
  digitalWrite(outPinPPM, HIGH);
  delayMicroseconds(CH5);     // Hold for TIsw_uS microseconds        

  // Channel 6 - TI pot
  digitalWrite(outPinPPM, LOW);
  delayMicroseconds(Fixed_uS);    // Hold
  digitalWrite(outPinPPM, HIGH);
  delayMicroseconds(CH6);       // Hold for TI_uS microseconds  

  // Synchro pulse
  digitalWrite(outPinPPM, LOW);
  delayMicroseconds(Fixed_uS);    // Hold
  digitalWrite(outPinPPM, HIGH);  // Start Synchro pulse

}