Quad X Type Multicopter

Dependencies:   IAP

Files at this revision

API Documentation at this revision

Comitter:
komaida424
Date:
Thu Jul 11 19:18:44 2013 +0000
Child:
1:caafe8935da6
Commit message:
version1.03

Changed in this revision

I2cPeripherals/I2cPeripherals.cpp Show annotated file Show diff for this revision Revisions of this file
I2cPeripherals/I2cPeripherals.h Show annotated file Show diff for this revision Revisions of this file
IAP.lib Show annotated file Show diff for this revision Revisions of this file
PulseWidthCounter.lib Show annotated file Show diff for this revision Revisions of this file
SerialLcd.lib Show annotated file Show diff for this revision Revisions of this file
config.cpp Show annotated file Show diff for this revision Revisions of this file
config.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2cPeripherals/I2cPeripherals.cpp	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,232 @@
+#include "mbed.h"
+#include "I2cPeripherals.h"
+
+I2cPeripherals::I2cPeripherals(PinName sda, PinName scl): _i2c(sda,scl)
+{   
+    _i2c.frequency(400000);
+    LCD_contrast = 60; 
+}
+
+void I2cPeripherals::start(char I2cAddr,int contrast)
+{
+    LCD_contrast = contrast;
+    start(I2cAddr);
+}
+
+void I2cPeripherals::start(char I2cAddr)
+{
+    char tx[2];
+
+    switch (I2cAddr)   {
+        case ST7032_ADDR:           //I2C LCD
+            LCD_addr = I2cAddr;
+            LCD_data = 0x40;
+            tx[0] = 0x00;
+            tx[1] = 0x38;
+            _i2c.write(I2cAddr,tx,2);
+            tx[1] = 0x39;
+            _i2c.write(I2cAddr,tx,2);
+            tx[1] = 0x1F;
+            _i2c.write(I2cAddr,tx,2);
+            tx[1] = 0x70 | (LCD_contrast & 0x0F);
+            _i2c.write(I2cAddr,tx,2);
+            tx[1] = 0x5C | ((LCD_contrast >> 4) & 0x03);
+            _i2c.write(I2cAddr,tx,2);
+            tx[1] = 0x6A;
+            _i2c.write(I2cAddr,tx,2);
+            wait(0.3);
+            tx[1] = 0x38;
+            _i2c.write(I2cAddr,tx,2); // function set
+            tx[1] = 0x0C;
+            _i2c.write(I2cAddr,tx,2); // Display On
+            break;
+        case ACM1602_ADDR:          //I2C LCD
+            LCD_addr = I2cAddr;
+            LCD_data = 0x80;
+            wait(0.015);
+            tx[0] = 0x00;
+            tx[1] = 0x01;
+            _i2c.write(I2cAddr,tx,2);
+            wait(0.005);
+            tx[1] = 0x38;
+            _i2c.write(I2cAddr,tx,2);
+            wait(0.005);
+            tx[1] = 0x0F;
+            _i2c.write(I2cAddr,tx,2);
+            wait(0.005);
+            tx[1] = 0x06;
+            _i2c.write(I2cAddr,tx,2);
+            wait(0.005);
+            break;
+
+        case ITG3200_ADDR0:     //gyro
+        case ITG3200_ADDR1:
+            Gyro_addr = I2cAddr;
+            Gyro_data = 0x1D;
+            tx[0] = 0x16;
+            tx[1] = 0x18;    // 0x1D
+            _i2c.write(I2cAddr,tx,2);
+            tx[0] = 0x3E;
+            tx[1] = 0x01;
+            _i2c.write(I2cAddr,tx,2);
+            wait_ms(100);
+            break;
+        
+        case L3GD20_ADDR0:      //gyro
+        case L3GD20_ADDR1:
+            Gyro_addr = I2cAddr;
+            Gyro_data = 0x28;
+            tx[0] = 0x20;
+            tx[1] = 0xFF;             
+            _i2c.write(I2cAddr,tx,2);
+            tx[0] = 0x21;
+            tx[1] = 0x09;             
+            _i2c.write(I2cAddr,tx,2);
+            tx[0] = 0x23;
+            tx[1] = 0xF0;             
+            _i2c.write(I2cAddr,tx,2);
+            break;
+        
+        case LDXL345_ADDR0:      //accelametor
+        case LDXL345_ADDR1:     
+            Accel_addr = I2cAddr;
+            Accel_data = 0x32;
+            tx[0] = 0x2D;
+            tx[1] = 0x00;             
+            _i2c.write(I2cAddr,tx,2);
+            tx[0] = 0x31;
+            tx[1] = 0x08;       //full range   08:2g 09:4g 0A:8g 0B:16g
+            _i2c.write(I2cAddr,tx,2);
+            tx[0] = 0x2C;
+            tx[1] = 0x0C;       //out rate  0xC:400Hz  0xD:800Hz                    
+            _i2c.write(I2cAddr,tx,2);
+            tx[0] = 0x2D;
+            tx[1] = 0x08;             
+            _i2c.write(I2cAddr,tx,2);
+            break;
+
+        case LPS331AP_ADDR0:        //barometor   
+        case LPS331AP_ADDR1:
+            barometor_addr = I2cAddr;
+            barometor_data = 0x2B;    
+            tx[0] = 0x10;    //RES_CNF
+            tx[1] = 0x19;
+            _i2c.write(I2cAddr,tx,2);
+            tx[0] = 0x20;    // CTL_REG1
+            tx[1] = 0x80;    // power on
+            _i2c.write(I2cAddr,tx,2);
+            tx[0]= 0x21;    // CTL_REG2
+            tx[1]= 0x01;    // one shot start
+            _i2c.write(I2cAddr,tx,2);
+            break;
+    }                    
+}
+
+int I2cPeripherals::_putc(int value) {
+    _i2c.start();
+    _i2c.write(LCD_addr);
+    _i2c.write(LCD_data);
+    _i2c.write(value);
+    _i2c.stop();
+    return value;
+}
+
+int I2cPeripherals::_getc() {
+    return -1;
+}
+
+void I2cPeripherals::cls()
+{
+    char tx[2] = { 0x00, 0x01 };
+    _i2c.write(LCD_addr,tx,2);
+}
+
+void I2cPeripherals::locate(int clm,int row)
+{
+    char tx[2];
+    
+    tx[0] = 0x00;
+    tx[1] = 0x80 + (row * 0x40) + clm;
+    _i2c.write(LCD_addr,tx,2);
+    
+}
+
+int I2cPeripherals::angular(int *x,int *y,int *z)
+{ 
+    char rx[6];
+    char tx[1];
+    tx[0] = Gyro_data | 0x80;
+    if ( _i2c.write(Gyro_addr,tx,1,true) != 0 )     {
+        x=y=z=0;
+        return false;
+    }
+    _i2c.read(Gyro_addr,rx,6);
+    *x = short(rx[0] << 8 | (uint8_t)rx[1]);  
+    *y = short(rx[2] << 8 | (uint8_t)rx[3]);
+    *z = short(rx[4] << 8 | (uint8_t)rx[5]);
+    return true;
+}
+int  I2cPeripherals::Acceleration(int *x,int *y,int *z)
+{
+   //AXDL345 Data Read
+    char rx[6];
+    char tx[1];
+    tx[0] = Accel_data | 0x80;
+    if ( _i2c.write(Accel_addr,tx,1,true) != 0 )     {
+        x=y=z=0;
+        return false;
+    }
+    _i2c.read(Accel_addr,rx,6);
+    *y = -short(rx[1] << 8 | (uint8_t)rx[0]);  
+    *x = short(rx[3] << 8 | (uint8_t)rx[2]);
+    *z = short(rx[5] << 8 | (uint8_t)rx[4]);
+    return true;
+}
+ 
+int  I2cPeripherals::pressure()
+{
+    char tx[2];
+    char rx[3];
+    int press;
+     
+    tx[0]= 0x21;
+    rx[0] = 0;
+    if ( _i2c.write(barometor_addr,tx,1,true) != 0 )
+        return 0;
+    _i2c.read (barometor_addr,rx,1);
+    while( rx[0]&0x01 )  {
+        wait(0.0001);
+        _i2c.write(barometor_addr,tx,1,true);
+        _i2c.read (barometor_addr,rx,1);
+    } 
+    
+    tx[0]= 0x28 | 0x80;
+    _i2c.write(barometor_addr,tx,1,true);
+    _i2c.read (barometor_addr,rx,3); 
+    
+    tx[0]= 0x21;    // CTL_REG2
+    tx[1]= 0x01;    // one shot start
+    _i2c.write(barometor_addr, tx, 2);
+
+    press =int( rx[2]<<16 | rx[1]<<8 | rx[0] );
+    return press;
+}
+
+
+//Update-Methode
+int I2cPeripherals::temperature()
+{
+    char tx[1];
+    char rx[2];
+    int temp;
+     
+    tx[0]= 0x2B | 0x80;
+    if ( _i2c.write(barometor_addr,tx,1,true) != 0 )
+        return 0;
+    _i2c.read (barometor_addr,rx,2); 
+    
+    temp = short(rx[1]<<8 | rx[0]);
+    return temp;
+};
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2cPeripherals/I2cPeripherals.h	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,46 @@
+#ifndef MBED_I2cPeripherals_H
+#define MBED_I2cPeripherals_H
+
+#include "mbed.h"
+#include "stdarg.h"
+
+#define LPS331AP_ADDR0 0xB8
+#define LPS331AP_ADDR1 0xBA     //select
+#define L3GD20_ADDR0 0xD4
+#define L3GD20_ADDR1 0xD6       //select
+#define ITG3200_ADDR0 0xD0      //select
+#define ITG3200_ADDR1 0xB2
+#define ACM1602_ADDR 0xA0
+#define ST7032_ADDR 0x7C
+#define LDXL345_ADDR0 0xA6      //select
+#define LDXL345_ADDR1 0x3A      
+
+class I2cPeripherals : public Stream
+{
+public:
+    I2cPeripherals(PinName sda, PinName scl);
+    
+    void start(char);
+    void start(char,int);
+    void cls();
+    void locate(int,int);
+    int angular(int*,int*,int*);
+    int Acceleration(int*,int*,int*);
+    int pressure();
+    int temperature();
+private:
+    virtual int _putc(int value);
+    virtual int _getc();
+    I2C _i2c;
+    int LCD_addr;
+    char LCD_cmd;
+    char LCD_data;
+    int Gyro_addr;
+    char Gyro_data;
+    int Accel_addr;
+    char Accel_data;
+    int barometor_addr;
+    char barometor_data;
+    int LCD_contrast;
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IAP.lib	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/okano/code/IAP/#ff906ad52cf9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PulseWidthCounter.lib	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,1 @@
+PulseWidthCounter#d37d6388c179
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialLcd.lib	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,1 @@
+SerialLcd#f30bad3f815d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.cpp	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,555 @@
+#include "mbed.h"
+#include "I2cPeripherals.h"
+//#include "I2cLCD.h"
+#include "InterruptIn.h"
+//#include "ITG3200.h"
+//#include "LPS331AP.h"
+#include "config.h"
+#include "PulseWidthCounter.h"
+#include "SerialLcd.h"
+
+void FlashLED(int);
+char Check_Stick_Dir(char);
+void Param_Set_Prompt1(const char *,int *,int,int,int,int,char);
+void Param_Set_Prompt1(const char *,float *,int,float,float,float,char);
+void Set_Arrow(int dir);
+void Get_Stick_Pos();
+void CalibrateGyros(void);
+void CalibrateAccel(void);
+void Get_Gyro();
+void Get_Accel();
+void PWM_Out(bool);
+void WriteConfig();
+void ESC_SetUp(void);
+void Get_Pressure();
+
+Timer elaps;
+
+extern int CH[5];
+extern int M[6];
+extern int Gyro[3];
+extern int Accel[3];
+extern int Gyro_Ref[3];
+extern int Stick[5];
+extern float Press;
+const char steering[3][6]= {"Roll ","Pitch","Yaw  "};
+short mode;
+char sw,ret_mode;
+short vnum,hnum,vmax,hmax;
+short idx,i;
+char str[33];
+
+#ifdef SERIAL_LCD
+SerialLcd *lcdptr;
+void SetUpPrompt(config& conf,SerialLcd& lcd)
+#else
+I2cPeripherals *lcdptr;
+void SetUpPrompt(config& conf,I2cPeripherals& lcd)
+#endif
+{
+
+    lcdptr = &lcd;
+    lcd.cls();
+    mode = 0;
+    vnum = 0;
+    hnum = 0;
+    vmax = 11;
+    
+    while( 1 ) {
+        FlashLED(1);
+        ret_mode = 'W';
+        mode = vnum * 10 + hnum;
+        
+        switch ( mode ) {
+            case 0:
+                lcd.locate(0,0);
+                sprintf(str,"Quad-X  Ver %4.2f",conf.Revision);
+                lcd.printf(str);
+                lcd.locate(4,1);
+                lcd.printf("By AZUKITEN");
+                hmax = 0;
+                break;
+            case 10:        //Calibrate Transmitter
+                lcd.printf("Calibrate Transmitter");
+                Set_Arrow(1);
+                hmax = 1;
+                break;
+            case 11:        //Calibrate Transmitter
+                lcd.printf("Start Calibrate");
+                for(i=0; i<4; i++)  {
+                    conf.Stick_Ref[i] = 0;
+                }
+                for(i=0; i<16; i++) {
+                    wait(0.3);
+                    conf.Stick_Ref[ROL] += AIL;
+                    conf.Stick_Ref[PIT] += ELE;
+                    conf.Stick_Ref[YAW] += RUD;
+                    conf.Stick_Ref[COL] += THR;
+//                    conf.Stick_Ref[GAIN] += AUX;
+                }
+                for(i=0; i<4; i++) {
+                    conf.Stick_Ref[i] = conf.Stick_Ref[i]/16;
+                }
+                lcd.cls();                 //Clear LCD
+                lcd.printf("Calibrate Completed");
+                Set_Arrow(3);
+                FlashLED(5);
+                break;
+            case 20:        //Set Gyro Gain
+                lcd.printf("Set Gyro Gain");
+                Set_Arrow(1);
+                hmax = 4;
+                break;
+            case 21:                                //Set Gyro Gain Roll
+                if ( conf.Gyro_Gain_Setting == 1 )
+                    Param_Set_Prompt1("GyroGain>Roll",&conf.Gyro_Gain[0],2,0.00f,1.00f,0.01f,sw);
+                else
+                    Param_Set_Prompt1("GyroGain>Roll",&conf.Gyro_Gain[3],2,-1.00f,1.00f,0.01f,sw);                
+                break;
+            case 22:
+                if ( conf.Gyro_Gain_Setting == 1 )
+                    Param_Set_Prompt1("GyroGain>Pitch",&conf.Gyro_Gain[1],2,0.00f,1.00f,0.01f,sw);
+                else
+                    Param_Set_Prompt1("GyroGain>Pitch",&conf.Gyro_Gain[4],2,-1.00f,1.00f,0.01f,sw);
+                break;
+            case 23:
+                if ( conf.Gyro_Gain_Setting == 1 )
+                    Param_Set_Prompt1("GyroGain>Yaw",&conf.Gyro_Gain[2],2,0.00f,1.00f,0.01f,sw);
+                else
+                    Param_Set_Prompt1("GyroGain>Yaw",&conf.Gyro_Gain[5],2,-1.00f,1.00f,0.01f,sw);
+                break;
+            case 24:
+//                ret_mode = 'R';
+                lcd.printf("GyroGain>setting");
+                lcd.locate(0,1);
+                switch ( sw ) {
+                    case 'U':
+                    case 'D':
+                        conf.Gyro_Gain_Setting *= -1;
+                }
+                if ( conf.Gyro_Gain_Setting == 1 )
+                    lcd.printf("Controller");
+                else
+                    lcd.printf("Transmitter");
+                Set_Arrow(3);
+                break;
+            case 30:        //Set Gyro Direction
+                lcd.printf("Gyro Direction");
+                Set_Arrow(1);
+                hmax = 4;
+                break;
+            case 31:                                //Set Gyro Direction Roll
+            case 32:
+            case 33:
+            case 34:
+ //              ret_mode = 'R';
+                idx = mode - 31;
+                if ( mode == 34 )
+                    lcd.printf("Gyro>Swap X-Y");
+                else {
+                    lcd.printf("Gyro>Dir>");
+                    lcd.locate(9,0);
+                    lcd.printf(steering[idx]);
+                }
+                lcd.locate(0,1);
+                switch ( sw ) {
+                    case 'U':
+                    case 'D':
+                        conf.Gyro_Dir[idx] *= -1;
+                }
+                if ( conf.Gyro_Dir[idx] == 1 )
+                    lcd.printf("Normal ");
+                else
+                    lcd.printf("Reverse");
+                if ( mode == 34 )
+                    Set_Arrow(3);
+                else
+                    Set_Arrow(2);
+                break;
+            case 40:        //Set Accelerometer
+                lcd.printf("Acceleration");
+                lcd.locate(5,1);
+                lcd.printf("Gain");
+                Set_Arrow(1);
+                hmax = 3;
+                break;
+            case 41:    
+                Param_Set_Prompt1("Accel>Roll",&conf.Accel_Gain[0],2,0.00f,1.00f,0.01f,sw);
+                break;
+            case 42:                                //Set Accelerometer
+                Param_Set_Prompt1("Accel>Pith",&conf.Accel_Gain[1],2,0.00f,1.00f,0.01f,sw);
+                break;
+            case 43:                                //Set Accelerometer
+                ret_mode = 'R';
+                Param_Set_Prompt1("Accel>Yaw",&conf.Accel_Gain[2],3,0.00f,1.00f,0.01f,sw);
+               break;
+                
+            case 50:        //Set Stick Mixing
+                lcd.printf("Set Stick Mixing");
+                Set_Arrow(1);
+                hmax = 3;
+                break;
+            case 51:                                //Set Stick Mixing
+                Param_Set_Prompt1("Mixing>Roll",&conf.Stick_Mix[0],2,0.00f,2.00f,0.01f,sw);
+                break;
+            case 52:
+                Param_Set_Prompt1("Mixing>Pitch",&conf.Stick_Mix[1],2,0.00f,2.00f,0.01f,sw);
+                break;
+            case 53:
+                Param_Set_Prompt1("Mixing>Yaw",&conf.Stick_Mix[2],3,0.00f,2.00f,0.01f,sw);
+                break;
+            case 60:        //Display Pulse Width
+                lcd.printf("Disp Pulse Width");
+                Set_Arrow(1);
+                hmax = 2;
+                break;
+            case 61:        //Display Pulse Width
+//           DisplayPulseWidth(THR,AIL,ELE,RUD,AUX);
+               ret_mode = 'R';
+                lcd.locate(0,0);
+                sprintf(str,"TR=%4d,AL=%4d",THR,AIL);
+                lcd.printf(str);
+                lcd.locate(0,1);
+                sprintf(str,"EL=%4d,RD=%4d",ELE,RUD);
+                lcd.printf(str);
+                break;
+            case 62:        //Display Stick Ref
+//            DisplayPulseWidth(Stick[COL],Stick[ROL],Stick[PIT],Stick[YAW],Stick[GAIN]);
+               ret_mode = 'R';
+                Get_Stick_Pos();
+                lcd.locate(0,0);
+                sprintf(str,"TR=%4d,AL=%4d",Stick[COL],Stick[ROL]);
+                lcd.printf(str);
+                lcd.locate(0,1);
+                sprintf(str,"EL=%4d,RD=%4d",Stick[PIT],Stick[YAW]);
+                lcd.printf(str);
+                break;
+            case 70:        //Display Sensor Value
+                lcd.printf("Disp Senser");
+                Set_Arrow(1);
+                hmax = 5;
+                break;
+            case 71:        //Gyro
+                Get_Gyro();
+                lcd.locate(0,0);
+                sprintf(str,"Gyro//X=%5d",Gyro[ROL]);
+                lcd.printf(str);
+                wait(0.02);
+                lcd.locate(0,1);
+                sprintf(str,"y=%5d,Z=%5d",Gyro[PIT],Gyro[YAW]);
+                lcd.printf(str);
+                wait(0.02);
+                ret_mode = 'R';
+                break;
+            case 72:            //Accelerometer
+                Get_Accel();
+                lcd.locate(0,0);
+                sprintf(str,"Accel//X=%5d",Accel[ROL]);
+                lcd.printf(str);
+                lcd.locate(0,1);
+                sprintf(str,"Y=%5d,Z=%5d",Accel[PIT],Accel[YAW]);
+                lcd.printf(str);
+//                Set_Arrow(2);
+                ret_mode = 'R';
+                break;
+            case 73:                // Pressure           
+                elaps.reset();
+                elaps.start();
+                Get_Pressure();
+                elaps.stop();
+                lcd.locate(0,0);
+                sprintf(str,"Pressure=%9.3f",Press/4096);
+                lcd.printf(str);
+                lcd.locate(0,1);
+                sprintf(str,"Elaps=%6d",elaps.read_us());
+                lcd.printf(str);
+//                Set_Arrow(2);
+                ret_mode = 'R';
+                break;
+            case 74:
+                elaps.reset();
+                elaps.start();
+                PWM_Out(false);
+                elaps.stop();
+                lcd.locate(0,0);
+                sprintf(str,"ElapsTime=%5d",elaps.read_us());
+                lcd.printf(str);
+                Set_Arrow(2);
+                ret_mode = 'R';
+                break;
+            case 75:        //Sensor Calibration
+//          CalibrateAccel();
+                CalibrateGyros();
+                CalibrateAccel();
+                lcd.printf("Calibrate completed");
+                Set_Arrow(3);
+                break;
+            case 80:                                //Display PMW Condition
+                lcd.printf("Display PMW ");
+                Set_Arrow(1);
+                hmax = 1;
+                break;
+            case 81:                                //Display PMW Width
+                PWM_Out(false);
+//            DisplayInt(Motor_HD[0],M1,M2,M4,M3);
+               ret_mode = 'R';
+                lcd.locate(0,0);
+                sprintf(str,"M1=%4d,M2=%4d",M1,M2);
+                lcd.printf(str);
+                lcd.locate(0,1);
+                sprintf(str,"M4=%4d,M3=%4d",M4,M3);
+                lcd.printf(str);
+                break;
+            case 90:    //パラメーター設定
+                lcd.printf("Parameter Set");
+                Set_Arrow(1);
+                hmax = 4;
+                break;
+            case 91:
+                Param_Set_Prompt1("LCD>Contrast",&conf.LCD_Contrast,2,0,63,1,sw);
+                break;
+            case 92:
+                lcd.locate(0,0);
+                lcd.printf("PWM>Mode");
+                lcd.locate(0,1);
+                switch ( sw ) {
+                    case 'U':
+                    case 'D':
+                        conf.PWM_Mode *= -1;
+                }
+                if ( conf.PWM_Mode == 1 )
+                    lcd.printf("ESC  ");
+                else
+                    lcd.printf("Moter");
+                Set_Arrow(2);
+                break;
+            case 93:
+                Param_Set_Prompt1("PWM>Interval",&conf.PWM_Interval,2,Thro_Hi,10000,10,sw);
+//                for ( i=0;i<4;i++ ) pwm[i].period_us(conf.PWM_Interval);
+                break;
+            case 94:
+                lcd.locate(0,0);
+                lcd.printf("Gyro>Type");
+                lcd.locate(0,1);
+                switch ( sw ) {
+                    case 'U':
+                    case 'D':
+                        if ( conf.Gyro_Type == _L3GD20 )
+                            conf.Gyro_Type = _ITG3200;
+                        else
+                            conf.Gyro_Type = _L3GD20;
+                }
+                if ( conf.Gyro_Type == _L3GD20 )    
+                    lcd.printf("L3GD20");
+                else    
+                    lcd.printf("ITG3200");
+                Set_Arrow(2);
+                break;
+            case 100:       //E2PROM Store
+                lcd.printf("Config Save");
+                Set_Arrow(1);
+                hmax = 1;
+                break;
+            case 101:
+                WriteConfig();
+                FlashLED(5);
+                lcd.locate(0,0);
+                sprintf(str,"Config %3dbyte",sizeof(config));
+                lcd.printf(str);
+                lcd.locate(0,1);
+                lcd.printf("Save Sucssesuful");
+                Set_Arrow(3);
+                wait(2);
+                break;
+            case 110:                               //ESC Set up
+                lcd.locate(0,0);
+                lcd.printf("ESC Set UP");
+                Set_Arrow(1);
+                hmax = 1;
+                break;
+            case 111:
+                if ( conf.PWM_Mode == -1 ) {
+                    hnum = 0;
+                    break;
+                }
+                lcd.locate(0,0);
+                lcd.printf("Setup Start");
+                wait(1.5);
+                lcd.cls();                 //Clear LCD
+                lcd.locate(0,0);
+                lcd.printf("Please power-off");
+                lcd.locate(1,0);
+                lcd.printf(" after Setup");
+                
+                ESC_SetUp();
+                break;
+
+            default:
+                if ( hnum == 0 )
+                    vnum++;
+        }
+
+
+        sw = Check_Stick_Dir(ret_mode);             //Wait Mode
+
+        switch ( sw ) {
+            case 'L':
+                hnum--;
+                if ( hnum <= 0 ) hnum = 0;
+                lcd.cls();                 //Clear LCD
+                break;
+            case 'R':
+                lcd.cls();
+                if ( hnum < hmax ) hnum++;
+                break;
+            case 'U':
+                if ( hnum == 0 ) {
+                    if ( vnum < vmax ) vnum++;
+                    else vnum = 0;
+                    lcd.cls();                 //Clear LCD
+                }
+                break;
+            case 'D':
+                if ( hnum == 0 ) {
+                    if ( vnum > 0 ) vnum--;
+                    else vnum = vmax;
+                    lcd.cls();                 //Clear LCD
+                }
+                break;
+            case 'E':
+                lcd.cls();                 //Clear LCD
+                lcd.locate(0,0);
+                lcd.printf("PWM Started");
+                return;
+        }
+    }
+
+}
+
+char Check_Stick_Dir(char act)
+{
+    int i;
+    while ( 1 ) {
+        Get_Stick_Pos();
+//  DisplayInt(Stick[0],Stick[1],Stick[2],Stick[3]);
+//  wait(0.2);
+        if ( Stick[YAW] > Stick_Limit ) {
+            i = 0;
+            while ( Stick[YAW] > Stick_Limit && Stick[COL] < 30 ) {
+                if ( i > 2000 ) return 'E';     //wait 2 sec
+                wait(0.001);                            // wait 1 msec
+                Get_Stick_Pos();
+                i++;
+            }
+        }
+        if ( Stick[ROL] > Stick_Limit ) {
+            wait(0.03);
+            Get_Stick_Pos();
+            if ( !(Stick[ROL] > Stick_Limit) ) continue;
+            while ( Stick[ROL] > Stick_Limit ) {
+                Get_Stick_Pos();
+            }
+            return 'R';
+        }
+        if ( Stick[ROL] < -Stick_Limit ) {
+            wait(0.03);
+            Get_Stick_Pos();
+            if ( !(Stick[ROL] < -Stick_Limit) ) continue;
+            while ( Stick[ROL] < -Stick_Limit ) {
+                Get_Stick_Pos();
+            }
+            return 'L';
+        }
+        if ( Stick[PIT] < -Stick_Limit ) {
+            wait(0.03);
+            Get_Stick_Pos();
+            if ( !(Stick[PIT] < -Stick_Limit) ) continue;
+            if ( act == 'R' ) {
+                wait(0.03);
+                return 'D';
+            }
+            while ( Stick[PIT] < -Stick_Limit ) {
+                Get_Stick_Pos();
+            }
+            return 'D';
+        }
+        if ( Stick[PIT] > Stick_Limit ) {
+            wait(0.03);
+            Get_Stick_Pos();
+            if ( !( Stick[PIT] > Stick_Limit) ) continue;
+            if ( act == 'R' ) {
+                wait(0.03);
+                return 'U';
+            }
+            while ( Stick[PIT] > Stick_Limit ) {
+                Get_Stick_Pos();
+            }
+            return 'U';
+        }
+        if ( act == 'R' )
+            return ' ';
+    }
+}
+
+void Param_Set_Prompt1(const char *hd,int *num,int arrow,int min,int max,int increase,char sw)
+{
+    ret_mode = 'R';
+    lcdptr->locate(0,0);
+    lcdptr->printf(hd);
+    lcdptr->locate(0,1);
+    lcdptr->printf("%d",*num);
+    Set_Arrow(arrow);
+    switch ( sw ) {
+        case 'U':
+            *num -= increase;
+            if ( *num <= min )
+                *num = min;
+            break;
+        case 'D':
+            *num += increase;
+            if ( *num >= max )
+                *num = max;
+    }
+}
+void Param_Set_Prompt1(const char *hd,float *num,int arrow,float min,float max,float increase,char sw)
+{
+    ret_mode = 'R';
+    lcdptr->locate(0,0);
+    lcdptr->printf(hd);
+    lcdptr->locate(0,1);
+    sprintf(str,"%7.2f",*num);
+    lcdptr->printf(str);
+    Set_Arrow(arrow);
+    switch ( sw ) {
+        case 'U':
+            *num -= increase;
+            if ( *num <= min )
+                *num = min;
+            break;
+        case 'D':
+            *num += increase;
+            if ( *num >= max )
+                *num = max;
+    }
+}
+
+void Set_Arrow(int dir)
+{
+    lcdptr->locate(12,1);
+    switch ( dir ) {
+        case 1:
+            lcdptr->printf("  >>");
+            break;
+        case 2:
+            lcdptr->printf("<<>>");
+            break;
+        case 3:
+            lcdptr->printf("  <<");
+    }
+}
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.h	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,106 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define SERIAL_LCD
+//#define LPCXpresso
+//#define LocalFileOut
+
+#define TX_TYPE 0               // 0:FM 1:IR
+#define Thro_Min 25
+#define Thro_Lo 75
+#define Thro_Hi 950
+#define Pulse_Min 1000
+#define Pulse_Max 2000
+#define Stick_Limit 150
+#define M1 M[0]
+#define M2 M[1]
+#define M3 M[2]
+#define M4 M[3]
+#define M5 M[4]
+#define M6 M[5]
+#define THR CH[0]
+#define AIL CH[1]
+#define ELE CH[2]
+#define RUD CH[3]
+#define AUX CH[4]
+#define _ITG3200  0x00
+#define _L3GD20   0x01
+
+//enum PortNum{Port_THR=1,Port_AIL=3,Port_ELE=5,Port_RUD=7,Port_AUX=6};
+enum IRNum{IR_THR=1,IR_AIL,IR_ELE,IR_RUD,IR_AUX};       //Input Pulse Sequence
+enum channel{ROL=0,PIT,YAW,COL,GAIN};
+
+
+struct config {
+    float Revision;
+    int Struct_Size;
+    int Stick_Ref[5];            //Stick Neutral Position
+    float Stick_Mix[3];               //Mixing ratio of stick operation
+    signed char Gyro_Dir[4];
+    float Gyro_Gain[6];
+    signed char Accel_Dir[4];
+    float Accel_Gain[3];
+    int Gyro_Gain_Setting;
+    int Gyro_Divider;
+    int Gyro_LPF_Value;
+    int Gyro_SamplRate_Divider;
+    int LCD_Contrast;
+    int PWM_Mode;
+    float Gyro_Stick_offset_effect;
+    int PWM_Interval; 
+//    int Accel_Rang;
+//    int Accel_Rate;
+//    int PWM_Resolution;
+    char StartMode;
+    char Gyro_Type;
+public:
+    config() {
+        Revision = 1.03;
+        Struct_Size = sizeof(config);
+        Stick_Ref[0] = 1500;
+        Stick_Ref[1] = 1500;
+        Stick_Ref[2] = 1500;
+        Stick_Ref[3] = 1100;
+        Stick_Ref[4] = 1500;
+        Stick_Mix[0] = 0.5;
+        Stick_Mix[1] = 0.5;
+        Stick_Mix[2] = 1.0;
+        Gyro_Dir[0] = 1;
+        Gyro_Dir[1] = 1;
+        Gyro_Dir[2] = 1;
+        Gyro_Dir[3] = -1;
+        Gyro_Gain[0] = 0.40;
+        Gyro_Gain[1] = 0.40;
+        Gyro_Gain[2] = 0.40;
+        Gyro_Gain[3] = 0.00;
+        Gyro_Gain[4] = 0.00;
+        Gyro_Gain[5] = 0.00;
+        Accel_Dir[0] = 1;
+        Accel_Dir[1] = 1;
+        Accel_Dir[2] = 1;
+        Accel_Dir[3] = 1;
+        Accel_Gain[0] = 0.50;
+        Accel_Gain[1] = 0.50;
+        Accel_Gain[2] = 0.50;
+        Gyro_Gain_Setting = -1;
+        Gyro_Divider=7;
+        Gyro_LPF_Value=0;
+        Gyro_SamplRate_Divider=1;
+        LCD_Contrast = 60;
+        PWM_Mode = 1;
+        Gyro_Stick_offset_effect = 0.00;
+        PWM_Interval = 3000; 
+//        Accel_Rang = 2;
+//        Accel_Rate = 14;
+//        PWM_Resolution = 0;
+        StartMode = 'C';
+        Gyro_Type = _ITG3200;
+    }
+};
+#endif
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,408 @@
+#include "mbed.h"
+#include "I2cPeripherals.h"
+//#include "I2cLCD.h"
+#include "InterruptIn.h"
+//#include "ITG3200.h"
+//#include "L3GD20.h"
+#include "config.h"
+#include "PulseWidthCounter.h"
+#include "string"
+#include "SerialLcd.h"
+#include  "IAP.h"
+//LPC1768 Flash Memory read/write
+#define     MEM_SIZE        256
+#define     TARGET_SECTOR    29     //  use sector 29 as target sector if it is on LPC1768
+IAP iap;
+
+#ifdef LPCXpresso
+DigitalOut led1(P0_22);
+#define led2 led1
+#else
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+#endif
+InterruptIn ch1(p5);
+PulseWidthCounter ch[5] = { PulseWidthCounter(p6,POSITIVE),
+                       PulseWidthCounter(p7,POSITIVE),
+                       PulseWidthCounter(p8,POSITIVE),
+                       PulseWidthCounter(p9,POSITIVE),
+                       PulseWidthCounter(p10,POSITIVE)
+                     };
+PwmOut pwm[4] = { p21,p22,p23,p24 };
+Timer CurTime;
+Timer ElapTime;
+I2cPeripherals i2c(p28,p27); //sda scl
+#ifdef SERIAL_LCD
+SerialLcd lcd(p13);
+#endif
+config conf;
+int StartTime;
+int Channel = 0;
+int CH[5];
+int M[6];
+int Gyro[3];
+int Accel[3];
+int Gyro_Ref[3];
+int Accel_Ref[3];
+int Stick[5];
+float Press;
+char InPulseMode;               //Receiver Signal Type    's':Serial, 'P':Parallel
+
+void initialize();
+void FlashLED(int );
+void SetUp();
+#ifdef SERIAL_LCD
+void SetUpPrompt(config&,SerialLcd&);
+#else
+void SetUpPrompt(config&,I2cPeripherals&);
+#endif
+void PWM_Out(bool);
+void Get_Stick_Pos();
+void CalibrateGyros(void);
+void CalibrateAccel(void);
+void Get_Gyro();
+void Get_Accel();
+void ReadConfig();
+void WriteConfig();
+void ESC_SetUp(void);
+
+void PulseCheck()
+{
+    Channel++;
+}
+
+void PulseAnalysis()            //Interrupt Pin5
+{
+    CurTime.stop();
+    int PulseWidth =  CurTime.read_us();
+    CurTime.reset();
+    CurTime.start();
+    if ( PulseWidth > 3000 ) Channel = 0;      //reset pulse count
+    else {
+        if ( PulseWidth > Pulse_Min && PulseWidth < Pulse_Max ) {
+            switch( Channel ) {
+                case IR_THR:
+                    THR = PulseWidth;
+                    break;
+                case IR_AIL:
+                    AIL = PulseWidth;
+                    break;
+                case IR_ELE:
+                    ELE = PulseWidth;
+                    break;
+                case IR_RUD:
+                    RUD = PulseWidth;
+                    break;
+                case IR_AUX:
+                    AUX = PulseWidth;
+                    break;
+            }
+        }
+    }
+    Channel++;
+}
+
+int main()
+{
+    int i,j=0;
+    
+    initialize();
+    wait(0.5);
+    Get_Stick_Pos();
+    while (  Stick[COL] > 30 || conf.StartMode == 'C' )          //Shrottol Low
+    {
+        if ( Stick[COL] > 350 || conf.StartMode == 'C' )              // Shrottle High
+        {
+#ifdef SERIAL_LCD
+            SetUpPrompt(conf,lcd);
+#else
+            SetUpPrompt(conf,i2c);
+#endif                          
+            for ( i=0;i<4;i++ ) pwm[i].period_us(conf.PWM_Interval);
+            break;
+        }
+        FlashLED(3);
+        wait(1);
+        Get_Stick_Pos();
+    }
+    led2 = 1;
+    ElapTime.start();
+
+    while (1)
+    {
+        if ( Stick[COL] < 30 )
+        {
+            i = 0;
+            ElapTime.stop();
+            while ( Stick[YAW] < -Stick_Limit && Stick[COL] < 30 )
+            {
+                if ( i > 100 )                          //wait 2 sec
+                {
+                    CalibrateGyros();
+                    CalibrateAccel();
+                    FlashLED(6);
+                    ElapTime.start();
+                    break;
+                }
+                wait(0.01);                           // wait 10 msec
+                Get_Stick_Pos();
+                i++;
+            }
+        }
+        j++;
+        if (j>100) { j=0; led2 = !led2;}
+        ElapTime.stop();
+        wait(float(conf.PWM_Interval-ElapTime.read_us()-2)/1000000);
+        ElapTime.reset();
+        ElapTime.start();
+        PWM_Out(true);
+    }
+
+}
+
+void  initialize()
+{
+#ifndef SERIAL_LCD
+    i2c.start(ST7032_ADDR,conf.LCD_Contrast);
+#endif         
+    ReadConfig();               //config.inf file read
+//    CurTime.start();
+    Channel = 0;
+    ch1.rise(&PulseCheck);      //input pulse count
+    wait(0.1);
+    if ( Channel > 30 )    {
+        ch1.rise(&PulseAnalysis);
+        InPulseMode = 'S';
+    }
+    else InPulseMode = 'P';
+    if ( conf.Gyro_Type == _ITG3200 )
+        i2c.start(ITG3200_ADDR0);
+    else
+        i2c.start(L3GD20_ADDR1);
+    CalibrateGyros();
+    i2c.start(LDXL345_ADDR0);
+    CalibrateGyros();
+    CalibrateAccel();
+    i2c.start(LPS331AP_ADDR1);
+    for ( int i=0;i<4;i++ ) pwm[i].period_us(conf.PWM_Interval);
+}
+
+void FlashLED(int cnt)
+{
+    for ( int i = 0 ; i < cnt ; i++ ) {
+        led1 = !led1;
+        wait(0.05);
+        led1 = !led1;
+        wait(0.05);
+    }
+}
+
+void ReadConfig()
+{
+#ifdef LocalFileOut
+    LocalFileSystem local("local");               // Create the local filesystem under the name "local"
+    FILE *fp = fopen("/local/setup.inf", "rb");  // Open "out.txt" on the local file system for writing
+    if ( fp != NULL )  {
+        float rev = conf.Revision;
+        int len = fread(&conf,1,sizeof(config),fp);
+        switch ( len ) {
+            case  sizeof(config):    // File size ok
+                if ( rev == conf.Revision ) break;
+            default:
+                fclose(fp);
+                config init;
+                conf = init;
+                fp = fopen("/local/setup.inf", "wb");
+                fwrite(&conf,1,sizeof(config),fp);
+        }
+        fclose(fp);
+    } else  {
+        WriteConfig();
+        wait(2);
+    }
+#else
+    char *send;
+    char *recv;
+    int i,rc;
+    config *conf_ptr;
+    
+    if ( sizeof(config) > 255 ) {
+        i2c.printf("config size over");
+        return;
+    }
+    rc = iap.blank_check( TARGET_SECTOR, TARGET_SECTOR );
+    if ( rc == SECTOR_NOT_BLANK ) {
+        send = sector_start_adress[TARGET_SECTOR];
+        recv = (char*)&conf;
+        conf_ptr = (config*)sector_start_adress[TARGET_SECTOR];
+        if ( conf_ptr->Revision == conf.Revision && conf_ptr->Struct_Size == sizeof(config) ) {
+            for ( i=0;i<sizeof(config);i++ ) recv[i] = send[i];
+//            i2c.printf("config read OK");
+//            wait(1);
+            return;
+        }
+    }
+    WriteConfig();
+//    i2c.printf("config write OK");
+//    wait(1);
+#endif
+}
+
+void WriteConfig()
+{
+#ifdef LocalFileOut
+    LocalFileSystem local("local");               // Create the local filesystem under the name "local"
+    FILE *fp = fopen("/local/setup.inf", "wb");
+    fwrite(&conf,1,sizeof(config),fp);
+    fclose(fp);
+#else
+    char mem[MEM_SIZE];
+    char *send;
+    int i;
+    if ( sizeof(config) > 255 ) {
+        printf("config size over");
+        return;
+    }
+    send = (char*)&conf;
+    for ( i=0;i<sizeof(config);i++ ) mem[i] = send[i];
+    for ( i=sizeof(config);i<MEM_SIZE;i++ ) mem[i] = 0x00;
+    iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
+    iap.erase( TARGET_SECTOR, TARGET_SECTOR );
+    iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
+    iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
+#endif
+}
+
+void Get_Stick_Pos(void)
+{
+    if ( InPulseMode == 'P' ) {
+        for (int i=0;i<5;i++) CH[i] = ch[i].count;
+    }
+    Stick[ROL] = AIL - conf.Stick_Ref[ROL];
+    Stick[PIT] = ELE - conf.Stick_Ref[PIT];
+    Stick[YAW] = RUD - conf.Stick_Ref[YAW];
+    Stick[COL] = THR - conf.Stick_Ref[COL];
+    Stick[GAIN] = ( AUX - conf.Stick_Ref[GAIN] ) / 4;
+}
+
+void Get_Gyro()
+{
+    int x,y,z;
+    if ( conf.Gyro_Dir[3] ==1 ) i2c.angular(&x,&y,&z);
+    else i2c.angular(&y,&x,&z);
+    Gyro[ROL] = ( x - Gyro_Ref[0] ) / 5;
+    Gyro[PIT] = ( y - Gyro_Ref[1] ) / 5;
+    Gyro[YAW] = ( z - Gyro_Ref[2] ) / 5;
+}
+
+void Get_Accel()
+{
+    int x,y,z;
+    if ( conf.Gyro_Dir[3] ==1 ) i2c.Acceleration(&x,&y,&z);
+    else i2c.Acceleration(&y,&x,&z);
+    Accel[ROL] = ( x - Accel_Ref[0] );
+    Accel[PIT] = ( y - Accel_Ref[1] );
+    Accel[YAW] = ( z - Accel_Ref[2] );      
+}
+void Get_Pressure()
+{
+    Press = i2c.pressure();
+}
+
+void CalibrateGyros(void)
+{
+    int i,j,x,y,z;
+    int k[3]={0,0,0};
+    wait(1);
+    for(i=0; i<16; i++) {
+    if ( conf.Gyro_Dir[3] ==1 ) i2c.angular(&x,&y,&z);
+    else i2c.angular(&y,&x,&z);
+        k[0] += x;
+        k[1] += y;
+        k[2] += z;
+        wait(0.005);
+    }
+    for( j=0; j<3; j++ ) Gyro_Ref[j] = k[j]/16;
+    FlashLED(3);
+}
+
+void CalibrateAccel(void)
+{
+    int i,j,x,y,z;
+    int k[3]={0,0,0};
+    wait(1);
+    for(i=0; i<16; i++) {
+    if ( conf.Gyro_Dir[3] ==1 ) i2c.Acceleration(&x,&y,&z);
+    else i2c.Acceleration(&y,&x,&z);
+        k[0] += x;
+        k[1] += y;
+        k[2] += z;
+        wait(0.005);
+    }
+    for( j=0; j<3; j++ ) Accel_Ref[j] = k[j]/16;
+    FlashLED(3);
+}
+
+void PWM_Out(bool mode)
+{
+   int reg[3];
+    int i;
+    float gain;
+    
+//    wait(0.002);
+    Get_Stick_Pos();
+    Get_Gyro();
+//    Get_Accel();
+
+    M1 = M2 = M3 = M4 = Stick[COL];
+    for ( i=0;i<3;i++ )
+    {
+//      Stick Angle Mixing
+        if ( conf.Gyro_Gain_Setting == 1 ) gain = conf.Gyro_Gain[i] * conf.Gyro_Dir[i];
+        else gain = ( (float)abs(Stick[GAIN])/100 + conf.Gyro_Gain[i+3] ) * conf.Gyro_Dir[i];
+        reg[i] = ( Stick[i] * conf.Stick_Mix[i] ) + ( Gyro[i] * gain );
+//        if ( Stick[GAIN] < 0 )
+//            reg[i] += Accel[i] * conf.Accel_Gain[i];
+    }
+    //Calculate Roll Pulse Width
+    M1 += reg[ROL];
+    M2 -= reg[ROL];
+    M3 -= reg[ROL];
+    M4 += reg[ROL];
+
+    //Calculate Pitch Pulse Width
+    M1 += reg[PIT];
+    M2 += reg[PIT];
+    M3 -= reg[PIT];
+    M4 -= reg[PIT];
+
+    //Calculate Yaw Pulse Width
+    M1 -= reg[YAW];
+    M2 += reg[YAW];
+    M3 -= reg[YAW];
+    M4 += reg[YAW];
+    
+    for ( i=0;i<4;i++ )
+    {
+        if ( M[i] > Thro_Hi )   M[i] = Thro_Hi; 
+        if ( M[i] < Thro_Lo )   M[i] = Thro_Lo;     // this is the motor idle level
+    }
+
+    if (Stick[COL] < 20 ) M1=M2=M3=M4=0;
+    if ( mode )
+        for ( i=0;i<4;i++ ) pwm[i].pulsewidth_us(conf.Stick_Ref[COL]+M[i]);
+
+}
+
+void ESC_SetUp(void)    {
+    while(1)    {
+        Get_Stick_Pos();
+        for ( int i=0;i<4;i++ ) pwm[i].pulsewidth_us(Stick[COL]);
+        wait(0.01);
+    }
+};
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Jul 11 19:18:44 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/5e5da4a5990b
\ No newline at end of file