controller.cpp

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 
Generated on Sun May 8 08:41:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3