00001 #include <WProgram.h> 00002 #include <pins_arduino.h> 00003 00004 #define rcOut 9 //pin to output ppm signal 00005 #define pushButton 2 00006 #define rightSwitch 3 00007 #define leftSwitch 4 00008 00009 unsigned int chIn[4]; //Data from pots 00010 unsigned int serOutPls[10]; //Pulse width for each channel 00011 00012 enum SERIAL_SM {HEADER1, HEADER2, MSB, LSB}; 00013 00014 //For ppm values 00015 enum PPM_STATE {PPM_FRAME_LOW, PPM_FRAME_HIGH, PPM_HIGH, PPM_LOW}; 00016 PPM_STATE ppmState = PPM_FRAME_LOW; 00017 int ppmChan = 0; 00018 00019 void setupPPMTimer() 00020 { 00021 00022 TCCR1A = 0x00; //Normal timer mode 00023 00024 //Set the timer prescaler to 2, this gives us a precision of 1/2 uS 00025 TCCR1B = (1<<CS11) | (0<<CS10); 00026 00027 //Timer2 Overflow Interrupt Enable 00028 TIMSK1 = 1<<TOIE2; 00029 00030 //load the timer for its first cycle 00031 TCNT1=0; 00032 } 00033 00034 ISR(TIMER1_OVF_vect) { 00035 //Capture the current timer value. This is how much error we 00036 //have due to interrupt latency and the work in this function 00037 //unsigned char latency=TCNT2; 00038 00039 int delay = 0; 00040 switch (ppmState) 00041 { 00042 case PPM_FRAME_LOW: 00043 digitalWrite(rcOut,LOW); 00044 delay = 304; //10 ms 00045 ppmChan = 0; 00046 ppmState = PPM_FRAME_HIGH; 00047 break; 00048 case PPM_FRAME_HIGH: 00049 digitalWrite(rcOut,HIGH); 00050 delay = 10000; //10 ms 00051 ppmState = PPM_LOW; 00052 break; 00053 case PPM_LOW: 00054 digitalWrite(rcOut,LOW); 00055 delay = 300; //304 microseconds 00056 ppmState = PPM_HIGH; 00057 break; 00058 case PPM_HIGH: 00059 digitalWrite(rcOut,HIGH); 00060 delay = serOutPls[ppmChan]; 00061 ppmChan++; 00062 if (ppmChan > 8) 00063 ppmState = PPM_FRAME_LOW; 00064 else 00065 ppmState = PPM_LOW; 00066 break; 00067 } 00068 00069 //Reload the timer and correct for latency. 00070 TCNT1=0xFFFF-((delay*2)-16); 00071 } 00072 00073 void setup() 00074 { 00075 Serial.begin(115200); 00076 pinMode(rcOut, OUTPUT); //Pin rcOut as output 00077 digitalWrite(rcOut, HIGH); 00078 00079 pinMode(rightSwitch, INPUT); 00080 pinMode(leftSwitch, INPUT); 00081 pinMode(pushButton, INPUT); 00082 digitalWrite(rightSwitch, HIGH); //enable pullup resistor 00083 digitalWrite(leftSwitch, HIGH); //enable pullup resistor 00084 digitalWrite(pushButton, HIGH); //enable pullup resistor 00085 00086 setupPPMTimer(); 00087 00088 //Reset all channel to low values 00089 for(int i=0; i<9; i++) 00090 serOutPls[i] = 500; 00091 00092 } 00093 00094 void outputData() 00095 { 00096 //Serial.print((char)255); 00097 Serial.print((char)0); 00098 Serial.print((char)9); 00099 for(int i=0; i<4; i++)//Loop to print and clear all the channel readings 00100 { 00101 Serial.print((char)chIn[i]); 00102 Serial.print((char)(chIn[i] >> 8)); 00103 //Serial.print((char) serOutPls[i]); 00104 //Serial.print((char)(serOutPls[i] >> 8)); 00105 } 00106 char switches = *portInputRegister(digitalPinToPort(0)) & 0xFC; 00107 Serial.print(switches); 00108 Serial.print((char)255); 00109 } 00110 00111 void getData() 00112 { 00113 static SERIAL_SM serialSM = HEADER1; 00114 static int data = 0; 00115 static int numDataRead = 0; 00116 #define MAX_NUM_DATA 4 00117 00118 00119 int na = Serial.available(); 00120 00121 for(int i=0; i<na; i++) 00122 { 00123 int inData = Serial.read(); 00124 if (inData == -1) break; 00125 00126 //State machine to read data 00127 switch (serialSM) 00128 { 00129 //Get headers 00130 case HEADER1: 00131 if (inData == 255) serialSM = HEADER2; 00132 break; 00133 case HEADER2: 00134 if (inData == 255) serialSM = MSB; 00135 break; 00136 case MSB: 00137 data = inData << 8; 00138 serialSM = LSB; 00139 break; 00140 case LSB: 00141 data += inData; 00142 00143 //senity check 00144 if (data > 300 && data < 2000) 00145 serOutPls[numDataRead] = data; 00146 numDataRead++; 00147 if (numDataRead < MAX_NUM_DATA) 00148 { 00149 serialSM = MSB; 00150 } else { 00151 numDataRead = 0; 00152 serialSM = HEADER1; 00153 } 00154 break; 00155 } 00156 00157 } 00158 00159 00160 } 00161 00162 void outputPPM() 00163 { 00164 //Output servo pulse 00165 for(int i=0; i<9; i++) 00166 { 00167 digitalWrite(rcOut, LOW); 00168 delayMicroseconds(304); 00169 digitalWrite(rcOut, HIGH); 00170 delayMicroseconds(serOutPls[i]); 00171 } 00172 digitalWrite(rcOut, LOW); 00173 delayMicroseconds(304); 00174 digitalWrite(rcOut, HIGH); 00175 00176 } 00177 00178 void loop() 00179 { 00180 //Get A2D Values and convert to ppm pulse width 00181 chIn[0] = 500 + analogRead(2); 00182 chIn[1] = 500 + analogRead(0); 00183 chIn[2] = 500 + analogRead(1); 00184 chIn[3] = 500 + (1023-analogRead(3)); 00185 00186 //outputPPM(); //output the ppm signal 00187 00188 ////Output serial data 00189 00190 00191 outputData(); 00192 00193 //Get data from computer if switch is enabled 00194 if (digitalRead(rightSwitch)==LOW) 00195 { 00196 getData(); 00197 } else { 00198 //Read from pots 00199 serOutPls[0] = chIn[0]; // Throtle 00200 serOutPls[1] = chIn[1]; // Ailron 00201 serOutPls[2] = chIn[2]; //Elevator 00202 serOutPls[3] = chIn[3]; // Rader 00203 } 00204 } 00205 00206 int main(void) 00207 { 00208 init(); 00209 setup(); 00210 00211 for (;;) 00212 loop(); 00213 00214 return 0; 00215 } 00216