Quad X Type Multicopter
Revision 2:59ac9df97701, committed 2013-11-15
- Comitter:
- komaida424
- Date:
- Fri Nov 15 20:53:36 2013 +0000
- Parent:
- 1:caafe8935da6
- Child:
- 3:27407c4984cf
- Commit message:
- ver.1.25
Changed in this revision
--- a/I2cPeripherals/I2cPeripherals.cpp Tue Jul 16 06:37:28 2013 +0000
+++ b/I2cPeripherals/I2cPeripherals.cpp Fri Nov 15 20:53:36 2013 +0000
@@ -1,128 +1,197 @@
#include "mbed.h"
#include "I2cPeripherals.h"
-
+//Serial pc(USBTX, USBRX);
I2cPeripherals::I2cPeripherals(PinName sda, PinName scl): _i2c(sda,scl)
-{
+{
+
_i2c.frequency(400000);
- LCD_contrast = 60;
+// LCD_contrast = 60;
+ wait(0.5);
+ LCD_addr = 0;
+ Gyro_addr = 0;
+ Accel_addr = 0;
+ barometor_addr = 0;
+ find();
+ start();
+
}
-void I2cPeripherals::start(char I2cAddr,int contrast)
+void I2cPeripherals::start(int contrast)
{
- LCD_contrast = contrast;
- start(I2cAddr);
+ char tx[2];
+// find(); // I2C interface sensor detect
+#ifdef ST7032
+ LCD_addr = 0x7c;
+ LCD_data = 0x40;
+ tx[0] = 0x00;
+ tx[1] = 0x38;
+ if ( _i2c.write(LCD_addr,tx,2) == 0 ) {
+ tx[1] = 0x39;
+ _i2c.write(LCD_addr,tx,2);
+ tx[1] = 0x14; //1F
+ _i2c.write(LCD_addr,tx,2);
+ tx[1] = 0x70 | (contrast & 0x0F);
+ _i2c.write(LCD_addr,tx,2);
+ tx[1] = 0x5C | ((contrast >> 4) & 0x03);
+ _i2c.write(LCD_addr,tx,2);
+ tx[1] = 0x6A;
+ _i2c.write(LCD_addr,tx,2);
+ wait(0.3);
+ tx[1] = 0x0C;
+ _i2c.write(LCD_addr,tx,2); // display on
+ tx[1] = 0x06;
+ _i2c.write(LCD_addr,tx,2);
+ // tx[0] = 0x40;
+// tx[1] = '*';
+// _i2c.write(LCD_addr,tx,2); // Display clear
+ return;
+ }
+#endif
+#ifdef ACM1602
+ LCD_addr = 0xA0;
+ LCD_data = 0x80;
+ tx[0] = 0x00;
+ tx[1] = 0x01;
+ if ( _i2c.write(LCD_addr,tx,2) == 0 ) {
+ wait(0.005);
+ tx[1] = 0x38;
+ _i2c.write(LCD_addr,tx,2);
+ wait(0.005);
+ tx[1] = 0x0F;
+ _i2c.write(LCD_addr,tx,2);
+ wait(0.005);
+ tx[1] = 0x06;
+ _i2c.write(LCD_addr,tx,2);
+ wait(0.005);
+ return;
+ }
+#endif
+ LCD_addr = 0;
}
-void I2cPeripherals::start(char I2cAddr)
+void I2cPeripherals::find()
{
char tx[2];
+ char rx[1];
+ SensorInf sens[10] = { 0xD0,0x68,0x00, //ITG3200
+ 0xD2,0x68,0x00,
+ 0xD0,0x68,0x75, //MPU6050
+ 0xD2,0x68,0x75,
+ 0xD4,0xD4,0x0F, //L3GD20
+ 0xD6,0xD4,0x0F,
+ 0xA6,0xE5,0x00, //ADXL345
+ 0x3A,0xE5,0x00,
+ 0xB8,0xBB,0x0F, //LPS331
+ 0xBA,0xBB,0x0F
+ };
- 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;
+ for ( int num = 0; num < 10; num++ ) {
+ tx[0]= sens[num].whoaddr;
+ if ( _i2c.write(sens[num].addr,tx,1,true) != 0 ) continue;
+ _i2c.read (sens[num].addr,rx,1);
+ if ( (rx[0]&0x7E) != (sens[num].who&0x7E) ) continue;
- 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;
- }
+ switch ( num ) {
+#ifdef ITG3200
+ case 0: //ITG3200
+ case 1:
+ Gyro_addr = sens[num].addr;
+ Gyro_data = 0x1D;
+ tx[0] = 0x16;
+ tx[1] = 0x18; // 0x1D
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x3E;
+ tx[1] = 0x01;
+ _i2c.write(sens[num].addr,tx,2);
+ wait_ms(10);
+ break;
+#endif
+#ifdef MPU6050
+ case 2: //MPU6050
+ case 3:
+ Gyro_addr = sens[num].addr;
+ Gyro_data = 0x43;
+ Accel_addr = sens[num].addr;
+ Accel_data = 0x3B;
+ tx[0] = 0x6B;
+ tx[1] = 0x00; // PWR on
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x1A; // DLPF(Digitel low pass filter)
+ tx[1] = 0x02; // set 0 to 7
+ _i2c.write(sens[num].addr,tx,2);
+ wait(0.01);
+ tx[0] = 0x1B;
+ tx[1] = 0x18; // +-2000deg
+ _i2c.write(sens[num].addr,tx,2);
+ wait(0.01);
+ tx[0] = 0x1C;
+ tx[1] = 0x18; // +-16g
+ _i2c.write(sens[num].addr,tx,2);
+ wait_ms(10);
+ break;
+#endif
+#ifdef L3GD20
+ case 4: //L3GD20
+ case 5:
+ Gyro_addr = sens[num].addr;
+ Gyro_data = 0x28;
+ tx[0] = 0x20;
+ tx[1] = 0xBF; //rate 400Hz 0x8F-0xBF
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x21;
+ tx[1] = 0x09;
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x23;
+ tx[1] = 0xF0;
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x24;
+ tx[1] = 0x10;
+ _i2c.write(sens[num].addr,tx,2);
+ break;
+#endif
+#ifdef ADXL345
+ case 6: //ADXL345
+ case 7:
+ Accel_addr = sens[num].addr;
+ Accel_data = 0x32;
+ tx[0] = 0x2D;
+ tx[1] = 0x00;
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x31;
+ tx[1] = 0x0B; //full range 08:2g 09:4g 0A:8g 0B:16g
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x2C;
+ tx[1] = 0x09; //out rate 0xC:400Hz 0xD:800Hz
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x2D;
+ tx[1] = 0x08;
+ _i2c.write(sens[num].addr,tx,2);
+ break;
+#endif
+#ifdef LPS331AP
+ case 8: //barometor
+ case 9:
+ barometor_addr = sens[num].addr;
+ barometor_data = 0x2B;
+ tx[0] = 0x10; //RES_CNF
+ tx[1] = 0x7A;
+ _i2c.write(sens[num].addr,tx,2);
+ tx[0] = 0x20; // CTL_REG1
+ tx[1] = 0xB0; // power on
+ _i2c.write(sens[num].addr,tx,2);
+// tx[0]= 0x21; // CTL_REG2
+// tx[1]= 0x01; // one shot start
+// _i2c.write(sens[num].addr,tx,2);
+ wait(1);
+ break;
+#endif
+ }
+ }
}
-int I2cPeripherals::_putc(int value) {
+int I2cPeripherals::_putc(int value)
+{
+ if ( LCD_addr == 0 ) return value;
_i2c.start();
_i2c.write(LCD_addr);
_i2c.write(LCD_data);
@@ -131,12 +200,32 @@
return value;
}
-int I2cPeripherals::_getc() {
+int I2cPeripherals::_getc()
+{
return -1;
}
+void I2cPeripherals::write_reg(char I2cAddr,char reg_addr,char* data,int len)
+{
+ char tx[17];
+ if ( len >16 ) len = 16;
+ tx[0] = reg_addr;
+ if ( len > 1 ) tx[0] |= 0x80;
+ for (int i=0; i<len; i++) tx[i+1] = data[i];
+ _i2c.write(I2cAddr,tx,len+1);
+}
+
+void I2cPeripherals::read_reg(char I2cAddr,char reg_addr,char* data,int len)
+{
+ char tx[1];
+ tx[0] = reg_addr | 0x80;
+ _i2c.write(I2cAddr,tx,1,true);
+ _i2c.read(I2cAddr,data,len);
+}
+
void I2cPeripherals::cls()
{
+ if ( LCD_addr == 0 ) return;
char tx[2] = { 0x00, 0x01 };
_i2c.write(LCD_addr,tx,2);
}
@@ -144,89 +233,130 @@
void I2cPeripherals::locate(int clm,int row)
{
char tx[2];
-
+
+ if ( LCD_addr == 0 ) return;
tx[0] = 0x00;
tx[1] = 0x80 + (row * 0x40) + clm;
_i2c.write(LCD_addr,tx,2);
-
+
}
-int I2cPeripherals::angular(int *x,int *y,int *z)
-{
+int I2cPeripherals::angular(float *x,float *y,float *z)
+{
char rx[6];
char tx[1];
+ float i = 0;
tx[0] = Gyro_data | 0x80;
if ( _i2c.write(Gyro_addr,tx,1,true) != 0 ) {
- x=y=z=0;
- return false;
+ *x=*y=*z=0;
+ return Gyro_addr;
+ }
+ switch ( Gyro_addr ) {
+ case 0xD0:
+ case 0xD2:
+ i = 0.06098;
+ break;
+ case 0xD4:
+ case 0xD6:
+ i = 0.06957;
}
_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]);
+ *x = ( short(rx[0] << 8 | (uint8_t)rx[1]) ) * i;
+ *y = ( short(rx[2] << 8 | (uint8_t)rx[3]) ) * i;
+ *z = ( short(rx[4] << 8 | (uint8_t)rx[5]) ) * i;
return true;
}
-int I2cPeripherals::Acceleration(int *x,int *y,int *z)
+
+int I2cPeripherals::Acceleration(float *x,float *y,float *z)
{
- //AXDL345 Data Read
+ //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;
+ *x=*y=0;
+ *z=9.8;
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]);
+ switch ( Accel_addr ) {
+ case 0xD0:
+ case 0xD2:
+#ifdef MPU6050
+ *y = ( -(short(rx[0] << 8 | (uint8_t)rx[1])) ) * 0.0048;
+ *x = ( short(rx[2] << 8 | (uint8_t)rx[3]) ) * 0.0048;
+ *z = ( short(rx[4] << 8 | (uint8_t)rx[5]) ) * 0.0048;
+#endif
+ break;
+ case 0xA6:
+ case 0x3A:
+#ifdef ADXL345
+ *y = ( -(short(rx[1] << 8 | (uint8_t)rx[0])) ) * 0.04;
+ *x = ( short(rx[3] << 8 | (uint8_t)rx[2]) ) * 0.04;
+ *z = ( short(rx[5] << 8 | (uint8_t)rx[4]) ) * 0.04;
+#endif
+ }
return true;
}
-
+
int I2cPeripherals::pressure()
{
char tx[2];
char rx[3];
- int press;
-
- tx[0]= 0x21;
- rx[0] = 0;
+ int press = 0;
+
+ tx[0]= 0x28 | 0x80;
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);
-
+ _i2c.read (barometor_addr,rx,3);
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);
-
+ _i2c.read (barometor_addr,rx,2);
+
temp = short(rx[1]<<8 | rx[0]);
return temp;
-};
+}
+
+void I2cPeripherals::i2c_write(int i2caddr,char* tx,int len)
+{
+ char rx[1];
+ rx[0] = 0;
+ while( 1 ) {
+ _i2c.write(i2caddr,tx,len);
+ _i2c.write(i2caddr,tx,1,true);
+ _i2c.read (i2caddr,rx,1);
+ if ( tx[1] == rx[0] ) return;
+ }
+}
+
+int I2cPeripherals::GetAddr(int type)
+{
+ switch ( type ) {
+ case GYRO_ADDR:
+ return Gyro_addr;
+ case ACCEL_ADDR:
+ return Accel_addr;
+ case LCD_ADDR:
+ return LCD_addr;
+ case BARO_ADDR:
+ return barometor_addr;
+ }
+ return 0;
+}
+;
+
+
+
--- a/I2cPeripherals/I2cPeripherals.h Tue Jul 16 06:37:28 2013 +0000
+++ b/I2cPeripherals/I2cPeripherals.h Fri Nov 15 20:53:36 2013 +0000
@@ -4,33 +4,38 @@
#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
+#define LPS331AP // baro
+#define L3GD20 // gyro
+#define MPU6050 // gyro and accelameter
+#define ITG3200 // gyro
+#define ACM1602 // I2C LCD
+#define ST7032 // I2C LCD
+#define ADXL345 // accelameter
+#define GYRO_ADDR 0
+#define ACCEL_ADDR 1
+#define LCD_ADDR 3
+#define BARO_ADDR 4
class I2cPeripherals : public Stream
{
public:
- I2cPeripherals(PinName sda, PinName scl);
+ I2cPeripherals(PinName sda=p28, PinName scl=p27);
- void start(char);
- void start(char,int);
+ void start(int contrast=60);
+ void write_reg(char,char,char*,int);
+ void read_reg(char,char,char*,int);
void cls();
void locate(int,int);
- int angular(int*,int*,int*);
- int Acceleration(int*,int*,int*);
+ int GetAddr(int);
+ int angular(float*,float*,float*);
+ int Acceleration(float*,float*,float*);
int pressure();
int temperature();
private:
virtual int _putc(int value);
virtual int _getc();
+ void i2c_write(int,char*,int);
+ void find();
I2C _i2c;
int LCD_addr;
char LCD_cmd;
@@ -42,5 +47,10 @@
int barometor_addr;
char barometor_data;
int LCD_contrast;
+ struct SensorInf {
+ char addr;
+ char who; //WHO_AMI
+ char whoaddr; //WHO_AMI resister address
+ };
};
#endif
\ No newline at end of file
--- a/IAP.lib Tue Jul 16 06:37:28 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/okano/code/IAP/#ff906ad52cf9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IAP/IAP.cpp Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,272 @@
+/** IAP : internal Flash memory access library
+ *
+ * The internal Flash memory access is described in the LPC1768 and LPC11U24 usermanual.
+ * http://www.nxp.com/documents/user_manual/UM10360.pdf
+ * http://www.nxp.com/documents/user_manual/UM10462.pdf
+ *
+ * LPC1768 --
+ * Chapter 2: "LPC17xx Memory map"
+ * Chapter 32: "LPC17xx Flash memory interface and programming"
+ * refering Rev. 01 - 4 January 2010
+ *
+ * LPC11U24 --
+ * Chapter 2: "LPC11Uxx Memory mapping"
+ * Chapter 20: "LPC11Uxx Flash programming firmware"
+ * refering Rev. 03 - 16 July 2012
+ *
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * revision 1.0 09-Mar-2010 1st release
+ * revision 1.1 12-Mar-2010 chaged: to make possible to reserve flash area for user
+ * it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h
+ * revision 2.0 26-Nov-2012 LPC11U24 code added
+ * revision 2.1 26-Nov-2012 EEPROM access code imported from Suga koubou san's (http://mbed.org/users/okini3939/) library
+ * http://mbed.org/users/okini3939/code/M0_EEPROM_test/
+ */
+
+#include "mbed.h"
+#include "IAP.h"
+
+#define USER_FLASH_AREA_START_STR( x ) STR( x )
+#define STR( x ) #x
+
+//unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init));
+
+
+/*
+ * Reserve of flash area is explained by Igor. Please refer next URL
+ * http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271
+ */
+
+//unsigned char user_area[ size ] __attribute__((section(".ARM.__at_0x78000"), zero_init));
+
+/*
+ * IAP command codes
+ * Table 589. "IAP Command Summary", Chapter 8. "IAP commands", usermanual
+ */
+
+enum command_code
+ {
+ IAPCommand_Prepare_sector_for_write_operation = 50,
+ IAPCommand_Copy_RAM_to_Flash,
+ IAPCommand_Erase_sector,
+ IAPCommand_Blank_check_sector,
+ IAPCommand_Read_part_ID,
+ IAPCommand_Read_Boot_Code_version,
+ IAPCommand_Compare,
+ IAPCommand_Reinvoke_ISP,
+ IAPCommand_Read_device_serial_number,
+#if defined(TARGET_LPC11U24)
+ IAPCommand_EEPROM_Write = 61,
+ IAPCommand_EEPROM_Read,
+#endif
+ };
+
+
+/** Read part identification number
+ *
+ * @return device ID
+ * @see read_serial()
+ */
+
+int IAP::read_ID( void ) {
+ IAP_command[ 0 ] = IAPCommand_Read_part_ID;
+
+ iap_entry( IAP_command, IAP_result );
+
+ // return ( (int)IAP_result[ 0 ] );
+ return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS)
+}
+
+
+/** Read device serial number
+ *
+ * @return device serial number
+ * @see read_ID()
+ */
+
+int IAP::read_serial( void ) {
+ IAP_command[ 0 ] = IAPCommand_Read_device_serial_number;
+
+ iap_entry( IAP_command, IAP_result );
+
+ // return ( (int)IAP_result[ 0 ] );
+ return ( (int)IAP_result[ 1 ] ); // to return the number itself (this command always returns CMD_SUCCESS)
+}
+
+
+/** Blank check sector(s)
+ *
+ * @param start a Start Sector Number
+ * @param end an End Sector Number (should be greater than or equal to start sector number).
+ * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_BLANK | INVALID_SECTOR
+ */
+
+int IAP::blank_check( int start, int end ) {
+ IAP_command[ 0 ] = IAPCommand_Blank_check_sector;
+ IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
+ IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
+
+ iap_entry( IAP_command, IAP_result );
+
+ return ( (int)IAP_result[ 0 ] );
+}
+
+
+/** Erase Sector(s)
+ *
+ * @param start a Start Sector Number
+ * @param end an End Sector Number (should be greater than or equal to start sector number).
+ * @return error code: CMD_SUCCESS | BUSY | SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | INVALID_SECTOR
+ */
+
+int IAP::erase( int start, int end ) {
+ IAP_command[ 0 ] = IAPCommand_Erase_sector;
+ IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
+ IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number)
+ IAP_command[ 3 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz
+
+ iap_entry( IAP_command, IAP_result );
+
+ return ( (int)IAP_result[ 0 ] );
+}
+
+
+/** Prepare sector(s) for write operation
+ *
+ * @param start a Start Sector Number
+ * @param end an End Sector Number (should be greater than or equal to start sector number).
+ * @return error code: CMD_SUCCESS | BUSY | INVALID_SECTOR
+ */
+
+int IAP::prepare( int start, int end ) {
+ IAP_command[ 0 ] = IAPCommand_Prepare_sector_for_write_operation;
+ IAP_command[ 1 ] = (unsigned int)start; // Start Sector Number
+ IAP_command[ 2 ] = (unsigned int)end; // End Sector Number (should be greater than or equal to start sector number).
+
+ iap_entry( IAP_command, IAP_result );
+
+ return ( (int)IAP_result[ 0 ] );
+}
+
+
+/** Copy RAM to Flash
+ *
+ * @param source_addr Source RAM address from which data bytes are to be read. This address should be a word boundary.
+ * @param target_addr Destination flash address where data bytes are to be written. This address should be a 256 byte boundary.
+ * @param size Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
+ * @return error code: CMD_SUCCESS | SRC_ADDR_ERROR (Address not a word boundary) | DST_ADDR_ERROR (Address not on correct boundary) | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED | COUNT_ERROR (Byte count is not 256 | 512 | 1024 | 4096) | SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION | BUSY
+ */
+
+int IAP::write( char *source_addr, char *target_addr, int size ) {
+ IAP_command[ 0 ] = IAPCommand_Copy_RAM_to_Flash;
+ IAP_command[ 1 ] = (unsigned int)target_addr; // Destination flash address where data bytes are to be written. This address should be a 256 byte boundary.
+ IAP_command[ 2 ] = (unsigned int)source_addr; // Source RAM address from which data bytes are to be read. This address should be a word boundary.
+ IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
+ IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
+
+ iap_entry( IAP_command, IAP_result );
+
+ return ( (int)IAP_result[ 0 ] );
+}
+
+
+/** Compare <address1> <address2> <no of bytes>
+ *
+ * @param source_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary.
+ * @param target_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary.
+ * @param size Number of bytes to be compared; should be a multiple of 4.
+ * @return error code: CMD_SUCCESS | COMPARE_ERROR | COUNT_ERROR (Byte count is not a multiple of 4) | ADDR_ERROR | ADDR_NOT_MAPPED
+ */
+
+int IAP::compare( char *source_addr, char *target_addr, int size ) {
+ IAP_command[ 0 ] = IAPCommand_Compare;
+ IAP_command[ 1 ] = (unsigned int)target_addr; // Starting flash or RAM address of data bytes to be compared. This address should be a word boundary.
+ IAP_command[ 2 ] = (unsigned int)source_addr; // Starting flash or RAM address of data bytes to be compared. This address should be a word boundary.
+ IAP_command[ 3 ] = size; // Number of bytes to be compared; should be a multiple of 4.
+
+ iap_entry( IAP_command, IAP_result );
+
+ return ( (int)IAP_result[ 0 ] );
+}
+
+/** Compare <address1> <address2> <no of bytes>
+ *
+ * @param source_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary.
+ * @param target_addr Starting flash or RAM address of data bytes to be compared. This address should be a word boundary.
+ * @param size Number of bytes to be compared; should be a multiple of 4.
+ * @return error code: CMD_SUCCESS | COMPARE_ERROR | COUNT_ERROR (Byte count is not a multiple of 4) | ADDR_ERROR | ADDR_NOT_MAPPED
+ */
+
+int IAP::read_BootVer(void) {
+ IAP_command[0] = IAPCommand_Read_Boot_Code_version;
+ IAP_result[1] = 0; // not sure if in high or low bits.
+ iap_entry(IAP_command, IAP_result);
+ return ((int)IAP_result[1]);
+}
+
+/** Get user reserved flash start address
+ *
+ * @return start address of user reserved flash memory
+ * @see reserved_flash_area_size()
+ */
+
+char * IAP::reserved_flash_area_start( void )
+{
+ return ( (char *)USER_FLASH_AREA_START );
+}
+
+
+/** Get user reserved flash size
+ *
+ * @return size of user reserved flash memory
+ * @see reserved_flash_area_start()
+ */
+
+int IAP::reserved_flash_area_size( void )
+{
+ return ( USER_FLASH_AREA_SIZE );
+}
+
+#if defined(TARGET_LPC11U24)
+/** Copy RAM to EEPROM (LPC11U24)
+ *
+ * @param source_addr Source RAM address from which data bytes are to be read.
+ * @param target_addr Destination EEPROM address where data bytes are to be written.
+ * @param size Number of bytes to be written.
+ * @return error code: CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED
+ * Remark: The top 64 bytes of the EEPROM memory are reserved and cannot be written to.
+ */
+int IAP::write_eeprom( char *source_addr, char *target_addr, int size ) {
+ IAP_command[ 0 ] = IAPCommand_EEPROM_Write;
+ IAP_command[ 1 ] = (unsigned int)target_addr; // Destination EEPROM address where data bytes are to be written. This address should be a 256 byte boundary.
+ IAP_command[ 2 ] = (unsigned int)source_addr; // Source RAM address from which data bytes are to be read. This address should be a word boundary.
+ IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
+ IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
+
+ iap_entry( IAP_command, IAP_result );
+
+ return ( (int)IAP_result[ 0 ] );
+}
+
+/** Copy EEPROM to RAM (LPC11U24)
+ *
+ * @param source_addr Source EEPROM address from which data bytes are to be read.
+ * @param target_addr Destination RAM address where data bytes are to be written.
+ * @param size Number of bytes to be written.
+ * @return error code: CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED
+ * Remark: The top 64 bytes of the EEPROM memory are reserved and cannot be written to.
+ */
+int IAP::read_eeprom( char *source_addr, char *target_addr, int size ) {
+ IAP_command[ 0 ] = IAPCommand_EEPROM_Read;
+ IAP_command[ 1 ] = (unsigned int)source_addr; // Source EEPROM address from which data bytes are to be read. This address should be a word boundary.
+ IAP_command[ 2 ] = (unsigned int)target_addr; // Destination RAM address where data bytes are to be written. This address should be a 256 byte boundary.
+ IAP_command[ 3 ] = size; // Number of bytes to be written. Should be 256 | 512 | 1024 | 4096.
+ IAP_command[ 4 ] = cclk_kHz; // CPU Clock Frequency (CCLK) in kHz.
+
+ iap_entry( IAP_command, IAP_result );
+
+ return ( (int)IAP_result[ 0 ] );
+}
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IAP/IAP.h Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,287 @@
+/** IAP : internal Flash memory access library
+ *
+ * The internal Flash memory access is described in the LPC1768 and LPC11U24 usermanual.
+ * http://www.nxp.com/documents/user_manual/UM10360.pdf
+ * http://www.nxp.com/documents/user_manual/UM10462.pdf
+ *
+ * LPC1768 --
+ * Chapter 2: "LPC17xx Memory map"
+ * Chapter 32: "LPC17xx Flash memory interface and programming"
+ * refering Rev. 01 - 4 January 2010
+ *
+ * LPC11U24 --
+ * Chapter 2: "LPC11Uxx Memory mapping"
+ * Chapter 20: "LPC11Uxx Flash programming firmware"
+ * refering Rev. 03 - 16 July 2012
+ *
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * revision 1.0 09-Mar-2010 1st release
+ * revision 1.1 12-Mar-2010 chaged: to make possible to reserve flash area for user
+ * it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h
+ * revision 2.0 26-Nov.2012 LPC11U24 code added
+ * revision 2.1 26-Nov-2012 EEPROM access code imported from Suga koubou san's (http://mbed.org/users/okini3939/) library
+ * http://mbed.org/users/okini3939/code/M0_EEPROM_test/
+ */
+
+#ifndef MBED_IAP
+#define MBED_IAP
+
+#include "mbed.h"
+
+#if defined(TARGET_LPC1768)
+
+#define USER_FLASH_AREA_START FLASH_SECTOR_29
+//#define USER_FLASH_AREA_SIZE (FLASH_SECTOR_SIZE_16_TO_29 * 1)
+#define USER_FLASH_AREA_SIZE (FLASH_SECTOR_SIZE_16_TO_29 * 1)
+
+/*
+ * memory map information is available in next URL also.
+ * http://mbed.org/projects/libraries/svn/mbed/trunk/LPC1768/LPC17xx.h
+ */
+
+/** Table for start adress of sectors
+ *
+ * LPC1768 internal flash memory sector numbers and addresses
+ *
+ * LPC1768 flash memory are and sector number/size
+ * Table 568 "Sectors in a LPC17xx device", Section 5. "Sector numbers", usermanual
+ *
+ * 0x00000000 - 0x0007FFFF flash (29 sectors)
+ *
+ * Sector0: 0x00000000 - 0x00000FFF 4K
+ * Sector1: 0x00001000 - 0x00001FFF 4K
+ * Sector2: 0x00002000 - 0x00002FFF 4K
+ * Sector3: 0x00003000 - 0x00003FFF 4K
+ * Sector4: 0x00004000 - 0x00004FFF 4K
+ * Sector5: 0x00005000 - 0x00005FFF 4K
+ * Sector6: 0x00006000 - 0x00006FFF 4K
+ * Sector7: 0x00007000 - 0x00007FFF 4K
+ * Sector8: 0x00008000 - 0x00008FFF 4K
+ * Sector9: 0x00009000 - 0x00009FFF 4K
+ * Sector10: 0x0000A000 - 0x0000AFFF 4K
+ * Sector11: 0x0000B000 - 0x0000BFFF 4K
+ * Sector12: 0x0000C000 - 0x0000CFFF 4K
+ * Sector13: 0x0000D000 - 0x0000DFFF 4K
+ * Sector14: 0x0000E000 - 0x0000EFFF 4K
+ * Sector15: 0x0000F000 - 0x0000FFFF 4K
+ *
+ * Sector16: 0x00010000 - 0x00017FFF 32K
+ * Sector17: 0x00018000 - 0x0001FFFF 32K
+ * Sector18: 0x00020000 - 0x00027FFF 32K
+ * Sector19: 0x00028000 - 0x0002FFFF 32K
+ * Sector20: 0x00030000 - 0x00037FFF 32K
+ * Sector21: 0x00038000 - 0x0003FFFF 32K
+ * Sector22: 0x00040000 - 0x00047FFF 32K
+ * Sector23: 0x00048000 - 0x0004FFFF 32K
+ * Sector24: 0x00050000 - 0x00057FFF 32K
+ * Sector25: 0x00058000 - 0x0005FFFF 32K
+ * Sector26: 0x00060000 - 0x00067FFF 32K
+ * Sector27: 0x00068000 - 0x0006FFFF 32K
+ * Sector28: 0x00070000 - 0x00077FFF 32K
+ * Sector29: 0x00078000 - 0x0007FFFF 32K
+ */
+
+#define FLASH_SECTOR_0 0x00000000
+#define FLASH_SECTOR_1 0x00001000
+#define FLASH_SECTOR_2 0x00002000
+#define FLASH_SECTOR_3 0x00003000
+#define FLASH_SECTOR_4 0x00004000
+#define FLASH_SECTOR_5 0x00005000
+#define FLASH_SECTOR_6 0x00006000
+#define FLASH_SECTOR_7 0x00007000
+#define FLASH_SECTOR_8 0x00008000
+#define FLASH_SECTOR_9 0x00009000
+#define FLASH_SECTOR_10 0x0000A000
+#define FLASH_SECTOR_11 0x0000B000
+#define FLASH_SECTOR_12 0x0000C000
+#define FLASH_SECTOR_13 0x0000D000
+#define FLASH_SECTOR_14 0x0000E000
+#define FLASH_SECTOR_15 0x0000F000
+#define FLASH_SECTOR_16 0x00010000
+#define FLASH_SECTOR_17 0x00018000
+#define FLASH_SECTOR_18 0x00020000
+#define FLASH_SECTOR_19 0x00028000
+#define FLASH_SECTOR_20 0x00030000
+#define FLASH_SECTOR_21 0x00038000
+#define FLASH_SECTOR_22 0x00040000
+#define FLASH_SECTOR_23 0x00048000
+#define FLASH_SECTOR_24 0x00050000
+#define FLASH_SECTOR_25 0x00058000
+#define FLASH_SECTOR_26 0x00060000
+#define FLASH_SECTOR_27 0x00068000
+#define FLASH_SECTOR_28 0x00070000
+#define FLASH_SECTOR_29 0x00078000
+#define FLASH_SECTOR_SIZE_0_TO_15 ( 4 * 1024)
+#define FLASH_SECTOR_SIZE_16_TO_29 (32 * 1024)
+
+static char * sector_start_adress[] = {
+ (char *)FLASH_SECTOR_0,
+ (char *)FLASH_SECTOR_1,
+ (char *)FLASH_SECTOR_2,
+ (char *)FLASH_SECTOR_3,
+ (char *)FLASH_SECTOR_4,
+ (char *)FLASH_SECTOR_5,
+ (char *)FLASH_SECTOR_6,
+ (char *)FLASH_SECTOR_7,
+ (char *)FLASH_SECTOR_8,
+ (char *)FLASH_SECTOR_9,
+ (char *)FLASH_SECTOR_10,
+ (char *)FLASH_SECTOR_11,
+ (char *)FLASH_SECTOR_12,
+ (char *)FLASH_SECTOR_13,
+ (char *)FLASH_SECTOR_14,
+ (char *)FLASH_SECTOR_15,
+ (char *)FLASH_SECTOR_16,
+ (char *)FLASH_SECTOR_17,
+ (char *)FLASH_SECTOR_18,
+ (char *)FLASH_SECTOR_19,
+ (char *)FLASH_SECTOR_20,
+ (char *)FLASH_SECTOR_21,
+ (char *)FLASH_SECTOR_22,
+ (char *)FLASH_SECTOR_23,
+ (char *)FLASH_SECTOR_24,
+ (char *)FLASH_SECTOR_25,
+ (char *)FLASH_SECTOR_26,
+ (char *)FLASH_SECTOR_27,
+ (char *)FLASH_SECTOR_28,
+ (char *)FLASH_SECTOR_29
+};
+
+#elif defined(TARGET_LPC11U24) || defined(TARGET_LPC1114)
+
+#define USER_FLASH_AREA_START FLASH_SECTOR_7
+#define USER_FLASH_AREA_SIZE (FLASH_SECTOR_SIZE * 1)
+
+/** Table for start adress of sectors
+ *
+ * LPC11U24 internal flash memory sector numbers and addresses
+ *
+ * LPC11U24 flash memory are and sector number/size
+ * Table 334 "LPC11U1x/2x flash sectors", Section 20. "Sector numbers", usermanual
+ *
+ * 0x00000000 - 0x00007FFF flash (8 sectors)
+ *
+ * Sector0: 0x00000000 - 0x00000FFF 4K
+ * Sector1: 0x00001000 - 0x00001FFF 4K
+ * Sector2: 0x00002000 - 0x00002FFF 4K
+ * Sector3: 0x00003000 - 0x00003FFF 4K
+ * Sector4: 0x00004000 - 0x00004FFF 4K
+ * Sector5: 0x00005000 - 0x00005FFF 4K
+ * Sector6: 0x00006000 - 0x00006FFF 4K
+ * Sector7: 0x00007000 - 0x00007FFF 4K
+ */
+
+#define FLASH_SECTOR_0 0x00000000
+#define FLASH_SECTOR_1 0x00001000
+#define FLASH_SECTOR_2 0x00002000
+#define FLASH_SECTOR_3 0x00003000
+#define FLASH_SECTOR_4 0x00004000
+#define FLASH_SECTOR_5 0x00005000
+#define FLASH_SECTOR_6 0x00006000
+#define FLASH_SECTOR_7 0x00007000
+#define FLASH_SECTOR_SIZE (4 * 1024)
+
+static char * sector_start_adress[] = {
+ (char *)FLASH_SECTOR_0,
+ (char *)FLASH_SECTOR_1,
+ (char *)FLASH_SECTOR_2,
+ (char *)FLASH_SECTOR_3,
+ (char *)FLASH_SECTOR_4,
+ (char *)FLASH_SECTOR_5,
+ (char *)FLASH_SECTOR_6,
+ (char *)FLASH_SECTOR_7,
+};
+
+#endif
+
+
+/** Error code by IAP routine
+ *
+ * Table 588 "ISP Return Codes Summary", Section 7.15 "ISP Return Codes", usermanual
+ */
+
+enum error_code
+ {
+ CMD_SUCCESS,
+ INVALID_COMMAND,
+ SRC_ADDR_ERROR,
+ DST_ADDR_ERROR,
+ SRC_ADDR_NOT_MAPPED,
+ DST_ADDR_NOT_MAPPED,
+ COUNT_ERROR,
+ INVALID_SECTOR,
+ SECTOR_NOT_BLANK,
+ SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
+ COMPARE_ERROR,
+ BUSY,
+ PARAM_ERROR,
+ ADDR_ERROR,
+ ADDR_NOT_MAPPED,
+ CMD_LOCKED,
+ INVALID_CODE,
+ INVALID_BAUD_RATE,
+ INVALID_STOP_BIT,
+ CODE_READ_PROTECTION_ENABLED
+ };
+
+
+
+/*
+ * IAP routine entry
+ *
+ * "IAP commands"
+ */
+
+#define IAP_LOCATION 0x1fff1ff1
+typedef void (*IAP_call)(unsigned int [], unsigned int []);
+
+/** IAP class
+ *
+ * Interface for internal flash memory access
+ */
+
+
+class IAP {
+public:
+
+ /*
+ * SystemCoreClock ??? :
+ * http://mbed.org/forum/mbed/topic/229/
+ * http://mbed.org/users/simon/programs/SystemCoreClock/16mhsh/
+ */
+
+
+ /** Constructor for IAP
+ *
+ */
+
+ IAP() : iap_entry( reinterpret_cast<IAP_call>(IAP_LOCATION) ), cclk_kHz( SystemCoreClock / 1000 ) {}
+ int read_ID( void );
+ int read_serial( void );
+ int blank_check( int start, int end );
+ int erase( int start, int end );
+ int prepare( int start, int end );
+ int write( char *source_addr, char *target_addr, int size );
+ int compare( char *source_addr, char *target_addr, int size );
+ int read_BootVer( void );
+
+ char *reserved_flash_area_start( void );
+ int reserved_flash_area_size( void );
+
+#if defined(TARGET_LPC11U24)
+ int write_eeprom( char *source_addr, char *target_addr, int size );
+ int read_eeprom( char *source_addr, char *target_addr, int size );
+#endif
+
+private:
+ IAP_call iap_entry;
+ unsigned int IAP_command[ 5 ];
+ unsigned int IAP_result[ 5 ];
+ int cclk_kHz;
+
+ //int cpu_clock( void );
+}
+;
+
+#endif // #ifndef MBED_IAP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PID/PID.cpp Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,52 @@
+#include "mbed.h"
+#include "SerialLcd.h"
+#include "PID.h"
+
+PID::PID()
+{
+ interval = 0.05;
+ integral_limit = 50;
+ pid_limit = 300;
+ kp = 0.5;
+ ki = 0.5;
+ kd = 0.2;
+ integral = 0;
+ old = 0;
+}
+
+void PID::init(float KP,float KI,float KD,float PID_LIM,float INTEGRAL_LIM)
+{
+// interval = INTERVAL;
+ pid_limit = PID_LIM;
+ integral_limit = INTEGRAL_LIM;
+ kp = KP;
+ ki = KI;
+ kd = KD;
+ integral = 0;
+ old = 0;
+}
+
+float PID::calc(float value,float target,float interval)
+{
+ cur = value - target;
+// if ( (old >= 0 && cur <= 0) || (old <= 0 && cur >= 0) || fabsf(cur) < 1 )
+// integral = 0;
+ integral += ( cur + old ) * interval * 0.5f;
+ if ( integral < -integral_limit ) integral = -integral_limit;
+ if ( integral > integral_limit ) integral = integral_limit;
+ float pid = kp * cur + ki * integral + kd * ( cur - old ) / interval;
+ if ( pid < -pid_limit ) pid = -pid_limit;
+ if ( pid > pid_limit ) pid = pid_limit;
+ old = cur;
+ return pid;
+}
+
+void PID::reset()
+{
+ integral = 0;
+ old = 0;
+}
+;
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PID/PID.h Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,22 @@
+#ifndef MBED_PID_H
+#define MBED_PID_H
+
+#include "mbed.h"
+#include "stdarg.h"
+
+class PID
+{
+public:
+ PID();
+ void init(float KP,float KI,float KD,float PID_LIM,float INTGRAL_LIM);
+ float calc(float value,float target,float interval);
+ void reset();
+private:
+ float integral;
+ float interval;
+ float cur,old;
+ float kp,ki,kd;
+ float integral_limit;
+ float pid_limit;
+};
+#endif
\ No newline at end of file
--- a/PulseWidthCounter.lib Tue Jul 16 06:37:28 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/komaida424/code/PulseWidthCounter/#d37d6388c179
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PulseWidthCounter/PulseWidthCounter.cpp Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,28 @@
+#include "mbed.h"
+#include "InterruptIn.h"
+#include "PulseWidthCounter.h"
+
+PulseWidthCounter::PulseWidthCounter(PinName _interrupt,bool positive) : interrupt(_interrupt) //constructa
+{
+ if ( positive )
+ { interrupt.rise(this,&PulseWidthCounter::start);
+ interrupt.fall(this,&PulseWidthCounter::stop);
+ }
+ else
+ { interrupt.fall(this,&PulseWidthCounter::start);
+ interrupt.rise(this,&PulseWidthCounter::stop);
+ }
+}
+
+void PulseWidthCounter::start()
+{
+ _time.reset();
+ _time.start();
+}
+
+void PulseWidthCounter::stop()
+{
+ _time.stop();
+ count = _time.read_us();
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PulseWidthCounter/PulseWidthCounter.h Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,22 @@
+#ifndef PULSEWIDTHCOUNTER_H
+#define PULSEWIDTHCOUNTER_H
+#define POSITIVE true
+#define NEGATIVE false
+
+#include "mbed.h"
+
+class PulseWidthCounter
+{
+private:
+ Timer _time;
+ void start();
+ void stop();
+ InterruptIn interrupt;
+
+public:
+ // Timer time;
+ PulseWidthCounter(PinName,bool positive=true);
+
+ int count;
+};
+#endif
\ No newline at end of file
--- a/SerialLcd.lib Tue Jul 16 06:37:28 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/komaida424/code/SerialLcd/#f30bad3f815d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialLcd/SerialLcd.cpp Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,31 @@
+#include "mbed.h"
+#include "SerialLcd.h"
+
+SerialLcd::SerialLcd(PinName TX): _lcd(TX,NC)
+{
+// LCD_contrast = 60;
+}
+
+int SerialLcd::_putc(int value) {
+ _lcd.putc(value);
+ return value;
+}
+
+int SerialLcd::_getc() {
+ return -1;
+}
+
+void SerialLcd::cls()
+{
+ _lcd.putc(0xFE);
+ _lcd.putc(0x01);
+ wait(0.01);
+}
+
+void SerialLcd::locate(int clm,int row)
+{
+ _lcd.putc(0xFE);
+ _lcd.putc( 0x80 + (row * 0x40) + clm );
+ wait(0.01);
+}
+;
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialLcd/SerialLcd.h Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,23 @@
+#ifndef MBED_SERIALLCD_H
+#define MBED_SERIALLCD_H
+
+#include "mbed.h"
+#include "stdarg.h"
+
+class SerialLcd : public Stream
+{
+public:
+ SerialLcd(PinName);
+
+ void cls();
+ void locate(int,int);
+private:
+ virtual int _putc(int value);
+ virtual int _getc();
+ Serial _lcd;
+ int LCD_addr;
+ char LCD_cmd;
+ char LCD_data;
+ int LCD_contrast;
+};
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftPWM/SoftPWM.cpp Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,99 @@
+#include "mbed.h"
+#include "InterruptIn.h"
+#include "SoftPWM.h"
+
+SoftPWM::SoftPWM(PinName _outpin,bool _positive) : pulse(_outpin) //constructa
+{
+ if ( _positive )
+ pulse = 0;
+ else
+ pulse = 1;
+ positive = _positive;
+ interval = 0.02;
+ width = 0;
+ start();
+}
+
+float SoftPWM::read()
+{
+ if ( width <= 0.0 ) return 0.0;
+ if ( width > 1.0 ) return 1.0;
+ return width / interval;
+}
+
+void SoftPWM::write(float duty)
+{
+ width = interval * duty;
+ if ( duty <= 0.0 ) width = 0.0;
+ if ( duty > 1.0 ) width = interval;
+}
+
+void SoftPWM::start()
+{
+ _ticker.attach(this,&SoftPWM::TickerInterrapt,interval);
+}
+
+void SoftPWM::stop()
+{
+ _ticker.detach();
+ if ( positive )
+ pulse = 0;
+ else
+ pulse = 1;
+ wait(width);
+}
+
+void SoftPWM::period(float _period)
+{
+ interval = _period;
+ start();
+}
+
+void SoftPWM::period_ms(int _period)
+{
+ period((float)_period / 1000);
+ start();
+}
+
+void SoftPWM::period_us(int _period)
+{
+ period((float)_period / 1000000);
+ start();
+}
+
+void SoftPWM::pulsewidth(float _width)
+{
+ width = _width;
+ if ( width < 0.0 ) width = 0.0;
+}
+
+void SoftPWM::pulsewidth_ms(int _width)
+{
+ pulsewidth((float)_width / 1000);
+}
+
+void SoftPWM::pulsewidth_us(int _width)
+{
+ pulsewidth((float)_width / 1000000);
+}
+
+void SoftPWM::TickerInterrapt()
+{
+ if ( width <= 0 ) return;
+ _timeout.attach(this,&SoftPWM::end,width);
+ if ( positive )
+ pulse = 1;
+ else
+ pulse = 0;
+}
+
+void SoftPWM::end()
+{
+ if ( positive )
+ pulse = 0;
+ else
+ pulse = 1;
+// _timeout.detach();
+}
+;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftPWM/SoftPWM.h Fri Nov 15 20:53:36 2013 +0000
@@ -0,0 +1,45 @@
+#ifndef SoftPWM_H
+#define SoftPWM_H
+#define POSITIVE true
+#define NEGATIVE false
+
+#include "mbed.h"
+
+class SoftPWM
+{
+private:
+ Timeout _timeout;
+ Ticker _ticker;
+ void end();
+ DigitalOut pulse;
+ bool positive;
+ void TickerInterrapt();
+ float width;
+ float interval;
+public:
+ SoftPWM(PinName,bool mode=true);
+// void attach_us(int);
+ void start();
+ void write(float);
+ float read();
+ void pulsewidth(float);
+ void pulsewidth_ms(int);
+ void pulsewidth_us(int);
+ void period(float);
+ void period_ms(int);
+ void period_us(int);
+ void stop();
+ operator float() {
+ if ( width <= 0.0 ) return 0.0;
+ if ( width > 1.0 ) return 1.0;
+ return width / interval;
+ }
+ SoftPWM& operator=(float duty) {
+ width = interval * duty;
+ if ( duty <= 0.0 ) width = 0.0;
+ if ( duty > 1.0 ) width = interval;
+ return *this;
+ }
+
+};
+#endif
\ No newline at end of file
--- a/config.cpp Tue Jul 16 06:37:28 2013 +0000
+++ b/config.cpp Fri Nov 15 20:53:36 2013 +0000
@@ -1,81 +1,97 @@
#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"
+#include "PID.h"
+
+//Serial pc(USBTX, USBRX);
+
+#define CALIBURATE 10
+#define GYROGAIN 20
+#define GYRODIR 30
+#define ACCELCORRECT 40
+#define PIDSET 50
+#define STICKMIX 60
+#define DISPPULSE 70
+#define DISPSENSOR 80
+#define DISPPWM 90
+#define PARMSET 100
+#define CONFSTORE 110
+#define CONFRESET 120
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 Param_Set_Prompt1(char *,int *,int,int,int,int,char);
+void Param_Set_Prompt1(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 Get_Angle(float);
void PWM_Out(bool);
void WriteConfig();
void ESC_SetUp(void);
void Get_Pressure();
+void LCD_printf(char *);
+void LCD_cls();
+void LCD_locate(int,int);
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;
+extern volatile int CH[5];
+extern volatile int M[6];
+extern volatile float Gyro[3];
+extern volatile float Accel[3];
+extern volatile float Angle[3];
+extern volatile float Gyro_Ref[3];
+extern volatile int Stick[5];
+extern volatile float Press;
+extern volatile float interval;
+//extern bool tick_flag;
+extern PID pid[3];
+extern int pid_reg[3];
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];
+config init;
-#ifdef SERIAL_LCD
-SerialLcd *lcdptr;
-void SetUpPrompt(config& conf,SerialLcd& lcd)
-#else
-I2cPeripherals *lcdptr;
-void SetUpPrompt(config& conf,I2cPeripherals& lcd)
-#endif
+void SetUpPrompt(config& conf,I2cPeripherals& i2c)
{
-
- lcdptr = &lcd;
- lcd.cls();
+ float x,y,z;
+ LCD_cls();
mode = 0;
vnum = 0;
hnum = 0;
- vmax = 11;
-
+ vmax = 12;
+
while( 1 ) {
- FlashLED(1);
+// FlashLED(1);
ret_mode = 'W';
mode = vnum * 10 + hnum;
-
+
switch ( mode ) {
case 0:
- lcd.locate(0,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");
+ LCD_printf(str);
+ LCD_locate(4,1);
+ LCD_printf("By AZUKITEN");
hmax = 0;
break;
- case 10: //Calibrate Transmitter
- lcd.printf("Calibrate Transmitter");
+ case CALIBURATE: //Calibrate Transmitter
+ LCD_printf("Calibrate");
Set_Arrow(1);
hmax = 1;
break;
- case 11: //Calibrate Transmitter
- lcd.printf("Start Calibrate");
+ case CALIBURATE+1: //Calibrate Transmitter
+ LCD_printf("Start Calibrate");
for(i=0; i<4; i++) {
conf.Stick_Ref[i] = 0;
}
@@ -90,300 +106,349 @@
for(i=0; i<4; i++) {
conf.Stick_Ref[i] = conf.Stick_Ref[i]/16;
}
- lcd.cls(); //Clear LCD
- lcd.printf("Calibrate Completed");
+ CalibrateGyros();
+ CalibrateAccel();
+ LCD_cls(); //Clear LCD
+ LCD_printf("Calibrate Completed");
Set_Arrow(3);
FlashLED(5);
+ hnum = 0;
break;
- case 20: //Set Gyro Gain
- lcd.printf("Set Gyro Gain");
+ case GYROGAIN: //Set Gyro Gain
+ LCD_printf("Set Gyro Gain");
Set_Arrow(1);
hmax = 4;
break;
- case 21: //Set Gyro Gain Roll
+ case GYROGAIN+1: //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);
+ Param_Set_Prompt1("GyroGain>Roll",&conf.Gyro_Gain[3],2,-1.00f,1.00f,0.01f,sw);
break;
- case 22:
+ case GYROGAIN+2:
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:
+ case GYROGAIN+3:
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:
+ case GYROGAIN+4:
// ret_mode = 'R';
- lcd.printf("GyroGain>setting");
- lcd.locate(0,1);
+ 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");
+ LCD_printf("Controller");
else
- lcd.printf("Transmitter");
+ LCD_printf("Transmitter");
Set_Arrow(3);
break;
- case 30: //Set Gyro Direction
- lcd.printf("Gyro Direction");
+ case GYRODIR: //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");
+ case GYRODIR+1: //Set Gyro Direction Roll
+ case GYRODIR+2:
+ case GYRODIR+3:
+ case GYRODIR+4:
+// ret_mode = 'R';
+ idx = mode - (GYRODIR+1);
+ if ( mode == (GYRODIR+4) )
+ LCD_printf("Gyro>Swap X-Y");
else {
- lcd.printf("Gyro>Dir>");
- lcd.locate(9,0);
- lcd.printf(steering[idx]);
+ LCD_printf("Gyro>Dir>");
+ LCD_locate(9,0);
+ LCD_printf((char*)steering[idx]);
}
- lcd.locate(0,1);
+ LCD_locate(0,1);
switch ( sw ) {
case 'U':
case 'D':
conf.Gyro_Dir[idx] *= -1;
}
if ( conf.Gyro_Dir[idx] == 1 )
- lcd.printf("Normal ");
+ LCD_printf("Normal ");
else
- lcd.printf("Reverse");
- if ( mode == 34 )
+ LCD_printf("Reverse");
+ if ( mode == (GYRODIR+4) )
Set_Arrow(3);
else
Set_Arrow(2);
break;
- case 40: //Set Accelerometer
- lcd.printf("Acceleration");
- lcd.locate(5,1);
- lcd.printf("Gain");
+ case ACCELCORRECT:
+ LCD_printf("Acceleration");
+ LCD_locate(2,1);
+ LCD_printf("correction");
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);
+ case ACCELCORRECT+1:
+ Param_Set_Prompt1("Accel>ROL",&conf.Accel_Ref[ROL],2,-10.0,10.0f,0.01f,sw);
+ break;
+ case ACCELCORRECT+2:
+ Param_Set_Prompt1("Accel>PIT",&conf.Accel_Ref[PIT],2,-10.0,10.0f,0.01f,sw);
+ break;
+ case ACCELCORRECT+3:
+ Param_Set_Prompt1("Accel>YAW",&conf.Accel_Ref[YAW],3,-10.0,10.0f,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);
+ case PIDSET: //PID Setting
+ LCD_printf("PID Setting");
+ Set_Arrow(1);
+ hmax = 8;
+ break;
+ case PIDSET+1:
+ Param_Set_Prompt1("PID>RoolPitch>kp",&conf.kp[0],2,0.00f,5.00f,0.01f,sw);
+ conf.kp[1] = conf.kp[0];
+ break;
+ case PIDSET+2:
+ Param_Set_Prompt1("PID>RoolPitch>ki",&conf.ki[0],2,0.00f,5.00f,0.01f,sw);
+ conf.ki[1] = conf.ki[0];
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");
+ case PIDSET+3:
+ Param_Set_Prompt1("PID>RoolPitch>kd",&conf.kd[0],2,0.00f,5.00f,0.01f,sw);
+ conf.kd[1] = conf.kd[0];
+ break;
+ case PIDSET+4:
+ Param_Set_Prompt1("PID>YAW>kp",&conf.kp[2],2,0.00f,5.00f,0.01f,sw);
+ break;
+ case PIDSET+5:
+ Param_Set_Prompt1("PID>YAW>ki",&conf.ki[2],2,0.00f,5.00f,0.01f,sw);
+ break;
+ case PIDSET+6:
+ Param_Set_Prompt1("PID>YAW>kd",&conf.kd[2],2,0.00f,5.00f,0.01f,sw);
+ break;
+ case PIDSET+7:
+ Param_Set_Prompt1("PID Limit",&conf.PID_Limit,2,0.00f,400.00f,10.00f,sw);
+ break;
+ case PIDSET+8:
+ Param_Set_Prompt1("Integral Limit",&conf.Integral_Limit,3,0.00f,100.00f,1.00f,sw);
+ break;
+ case STICKMIX: //Set Stick Mixing
+ LCD_printf("Set Stick Mixing");
Set_Arrow(1);
hmax = 3;
break;
- case 51: //Set Stick Mixing
+ case STICKMIX+1: //Set Stick Mixing
Param_Set_Prompt1("Mixing>Roll",&conf.Stick_Mix[0],2,0.00f,2.00f,0.01f,sw);
break;
- case 52:
+ case STICKMIX+2:
Param_Set_Prompt1("Mixing>Pitch",&conf.Stick_Mix[1],2,0.00f,2.00f,0.01f,sw);
break;
- case 53:
+ case STICKMIX+3:
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");
+ case DISPPULSE: //Display Pulse Width
+ LCD_printf("Disp Pulse Width");
Set_Arrow(1);
hmax = 2;
break;
- case 61: //Display Pulse Width
+ case DISPPULSE+1: //Display Pulse Width
// DisplayPulseWidth(THR,AIL,ELE,RUD,AUX);
- ret_mode = 'R';
- lcd.locate(0,0);
+ ret_mode = 'R';
+ LCD_locate(0,0);
sprintf(str,"TR=%4d,AL=%4d",THR,AIL);
- lcd.printf(str);
- lcd.locate(0,1);
+ LCD_printf(str);
+ LCD_locate(0,1);
sprintf(str,"EL=%4d,RD=%4d",ELE,RUD);
- lcd.printf(str);
+ LCD_printf(str);
break;
- case 62: //Display Stick Ref
-// DisplayPulseWidth(Stick[COL],Stick[ROL],Stick[PIT],Stick[YAW],Stick[GAIN]);
- ret_mode = 'R';
+ case DISPPULSE+2: //Display Stick Ref
+ ret_mode = 'R';
Get_Stick_Pos();
- lcd.locate(0,0);
+ LCD_locate(0,0);
sprintf(str,"TR=%4d,AL=%4d",Stick[COL],Stick[ROL]);
- lcd.printf(str);
- lcd.locate(0,1);
+ 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;
+ LCD_printf(str);
break;
- case 71: //Gyro
+ case DISPSENSOR: //Display Sensor Value
+ LCD_printf("Disp Senser");
+ Set_Arrow(1);
+ hmax = 7;
+ for ( i=0; i<3; i++ ) {
+ pid[i].init(conf.kp[i],conf.ki[i],conf.kd[i]*(float)abs(Stick[GAIN])/50.0
+ ,conf.PID_Limit,conf.Integral_Limit);
+ Angle[i] = 0;
+ }
+ break;
+ case DISPSENSOR+1: //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);
+ LCD_locate(0,0);
+ sprintf(str,"[Gyro]X=%5.1f",Gyro[ROL]);
+ LCD_printf(str);
+ LCD_locate(0,1);
+ sprintf(str,"y=%5.1f,Z=%5.1f",Gyro[PIT],Gyro[YAW]);
+ LCD_printf(str);
ret_mode = 'R';
break;
- case 72: //Accelerometer
+ case DISPSENSOR+2: //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);
+ if ( conf.Gyro_Dir[3] ==1 ) i2c.Acceleration(&x,&y,&z);
+ else i2c.Acceleration(&y,&x,&z);
+ x -= conf.Accel_Ref[0];
+ y -= conf.Accel_Ref[1];
+ z -= conf.Accel_Ref[2];
+ LCD_locate(0,0);
+ sprintf(str,"[Accel]X=%5.1f",x);
+ LCD_printf(str);
+ LCD_locate(0,1);
+ sprintf(str,"Y=%5.1f,Z=%5.1f",y,z);
+ LCD_printf(str);
// Set_Arrow(2);
ret_mode = 'R';
break;
- case 73: // Pressure
+ case DISPSENSOR+3: //angle
+ PWM_Out(false);
+ LCD_locate(0,0);
+ sprintf(str,"[Angle]X=%6.1f",Angle[ROL]);
+ LCD_printf(str);
+ LCD_locate(0,1);
+ sprintf(str,"Y=%6.1f,Z=%5.1f",Angle[PIT],Angle[YAW]);
+ LCD_printf(str);
+// Set_Arrow(2);
+ ret_mode = 'R';
+ break;
+ case DISPSENSOR+4:
+ PWM_Out(false);
+ LCD_locate(0,0);
+ sprintf(str,"t=%5d,a=%6.2f",-Stick[YAW]*45/400,Angle[YAW]);
+ LCD_printf(str);
+ LCD_locate(0,1);
+ sprintf(str,"pid=%5d",pid_reg[YAW]);
+ LCD_printf(str);
+ Set_Arrow(2);
+ ret_mode = 'R';
+ break;
+ case DISPSENSOR+5: // 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);
+ LCD_locate(0,0);
+ sprintf(str,"Press=%9.3f",Press/4096);
+ LCD_printf(str);
+ LCD_locate(0,1);
sprintf(str,"Elaps=%6d",elaps.read_us());
- lcd.printf(str);
+ LCD_printf(str);
// Set_Arrow(2);
ret_mode = 'R';
+ wait(0.05);
break;
- case 74:
+ case DISPSENSOR+6:
elaps.reset();
elaps.start();
PWM_Out(false);
elaps.stop();
- lcd.locate(0,0);
- sprintf(str,"ElapsTime=%5d",elaps.read_us());
- lcd.printf(str);
+ i = elaps.read_us();
+ LCD_locate(0,0);
+ sprintf(str,"ElapsTime=%6d",i);
+ LCD_printf(str);
Set_Arrow(2);
ret_mode = 'R';
break;
- case 75: //Sensor Calibration
-// CalibrateAccel();
+ case DISPSENSOR+7: //Sensor Calibration
CalibrateGyros();
- CalibrateAccel();
- lcd.printf("Calibrate completed");
+ FlashLED(3);
+ LCD_printf("Calibrate completed");
Set_Arrow(3);
break;
- case 80: //Display PMW Condition
- lcd.printf("Display PMW ");
+ case DISPPWM: //Display PWM Condition
+ LCD_printf("Display PWM ");
Set_Arrow(1);
hmax = 1;
break;
- case 81: //Display PMW Width
+ case DISPPWM+1: //Display PWM Width
+ ret_mode = 'R';
PWM_Out(false);
-// DisplayInt(Motor_HD[0],M1,M2,M4,M3);
- ret_mode = 'R';
- lcd.locate(0,0);
+ LCD_locate(0,0);
sprintf(str,"M1=%4d,M2=%4d",M1,M2);
- lcd.printf(str);
- lcd.locate(0,1);
+ LCD_printf(str);
+ LCD_locate(0,1);
sprintf(str,"M4=%4d,M3=%4d",M4,M3);
- lcd.printf(str);
+ LCD_printf(str);
break;
- case 90: //パラメーター設定
- lcd.printf("Parameter Set");
+ case PARMSET: //パラメーター設定
+ LCD_printf("Parameter Set");
Set_Arrow(1);
- hmax = 4;
+ hmax = 6;
break;
- case 91:
+ case PARMSET+1:
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);
+ case PARMSET+2:
+ 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 ");
+ LCD_printf("ESC ");
else
- lcd.printf("Moter");
+ LCD_printf("Moter");
Set_Arrow(2);
break;
- case 93:
+ case PARMSET+3:
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 PARMSET+4:
+ Param_Set_Prompt1("Gyro>CutoffFreq",&conf.Cutoff_Freq,2,0.00f,10.0f,0.01f,sw);
+ break;
+ case PARMSET+5:
+ Param_Set_Prompt1("ESC>Low Position",&conf.ESC_Low,2,Pulse_Min,Pulse_Max,1,sw);
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);
+ case PARMSET+6:
+ Param_Set_Prompt1("Flight Timer",&conf.Flight_Time,2,0,600,10,sw);
break;
- case 100: //E2PROM Store
- lcd.printf("Config Save");
+// case PARMSET+7:
+// Param_Set_Prompt1("Cont. swap Angle",&conf.Control_Exchange_Angle,3,0.0f,40.0f,1.0f,sw);
+// break;
+ case CONFSTORE: //E2PROM Store
+ LCD_printf("Config Save");
Set_Arrow(1);
hmax = 1;
break;
- case 101:
+ case CONFSTORE+1:
WriteConfig();
- FlashLED(5);
- lcd.locate(0,0);
+ LCD_locate(0,0);
sprintf(str,"Config %3dbyte",sizeof(config));
- lcd.printf(str);
- lcd.locate(0,1);
- lcd.printf("Save Sucssesuful");
+ 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;
+ wait(0.5);
+ FlashLED(5);
+ hnum = 0;
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();
+ case CONFRESET: //E2PROM reset
+ LCD_printf("Config Reset");
+ Set_Arrow(1);
+ hmax = 3;
break;
-
+ case CONFRESET+1:
+ LCD_printf("If want to reset");
+ LCD_locate(0,1);
+ LCD_printf("Aileron right");
+ Set_Arrow(2);
+ break;
+ case CONFRESET+2: //E2PROM reset
+ conf = init;
+ LCD_printf("Rset sucssesuful");
+ Set_Arrow(3);
+ break;
default:
if ( hnum == 0 )
vnum++;
@@ -396,30 +461,30 @@
case 'L':
hnum--;
if ( hnum <= 0 ) hnum = 0;
- lcd.cls(); //Clear LCD
+ LCD_cls(); //Clear LCD
break;
case 'R':
- lcd.cls();
+ LCD_cls();
if ( hnum < hmax ) hnum++;
break;
case 'U':
if ( hnum == 0 ) {
if ( vnum < vmax ) vnum++;
else vnum = 0;
- lcd.cls(); //Clear LCD
+ LCD_cls(); //Clear LCD
}
break;
case 'D':
if ( hnum == 0 ) {
if ( vnum > 0 ) vnum--;
else vnum = vmax;
- lcd.cls(); //Clear LCD
+ LCD_cls(); //Clear LCD
}
break;
case 'E':
- lcd.cls(); //Clear LCD
- lcd.locate(0,0);
- lcd.printf("PWM Started");
+ LCD_cls(); //Clear LCD
+ LCD_locate(0,0);
+ LCD_printf("PWM Started");
return;
}
}
@@ -431,8 +496,6 @@
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 ) {
@@ -491,13 +554,14 @@
}
}
-void Param_Set_Prompt1(const char *hd,int *num,int arrow,int min,int max,int increase,char sw)
+void Param_Set_Prompt1(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);
+ LCD_locate(0,0);
+ LCD_printf(hd);
+ LCD_locate(0,1);
+ sprintf(str,"%6d",*num);
+ LCD_printf(str);
Set_Arrow(arrow);
switch ( sw ) {
case 'U':
@@ -511,14 +575,14 @@
*num = max;
}
}
-void Param_Set_Prompt1(const char *hd,float *num,int arrow,float min,float max,float increase,char sw)
+void Param_Set_Prompt1(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);
+ LCD_locate(0,0);
+ LCD_printf(hd);
+ LCD_locate(0,1);
sprintf(str,"%7.2f",*num);
- lcdptr->printf(str);
+ LCD_printf(str);
Set_Arrow(arrow);
switch ( sw ) {
case 'U':
@@ -535,16 +599,16 @@
void Set_Arrow(int dir)
{
- lcdptr->locate(12,1);
+ LCD_locate(12,1);
switch ( dir ) {
case 1:
- lcdptr->printf(" >>");
+ LCD_printf(" >>");
break;
case 2:
- lcdptr->printf("<<>>");
+ LCD_printf("<<>>");
break;
case 3:
- lcdptr->printf(" <<");
+ LCD_printf(" <<");
}
}
@@ -553,3 +617,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- a/config.h Tue Jul 16 06:37:28 2013 +0000
+++ b/config.h Fri Nov 15 20:53:36 2013 +0000
@@ -1,17 +1,18 @@
#ifndef CONFIG_H
#define CONFIG_H
-#define SERIAL_LCD
+//#define SERIAL_LCD
+//#define SOFT_PWM
//#define LPCXpresso
//#define LocalFileOut
#define TX_TYPE 0 // 0:FM 1:IR
-#define Thro_Min 25
+#define Thro_Zero 30
#define Thro_Lo 75
#define Thro_Hi 950
#define Pulse_Min 1000
#define Pulse_Max 2000
-#define Stick_Limit 150
+#define Stick_Limit 350
#define M1 M[0]
#define M2 M[1]
#define M3 M[2]
@@ -25,46 +26,53 @@
#define AUX CH[4]
#define _ITG3200 0x00
#define _L3GD20 0x01
+#define TICK_TIME 0.05
+#define GYRO_ADJUST 3
//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;
+ char StartMode; //'c':config mode 'f':flight mode
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_Ref[3];
float Accel_Gain[3];
int Gyro_Gain_Setting;
- int Gyro_Divider;
- int Gyro_LPF_Value;
- int Gyro_SamplRate_Divider;
+ float Control_Exchange_Angle;
+ float Cutoff_Freq;
+ int Flight_Time;
int LCD_Contrast;
int PWM_Mode;
- float Gyro_Stick_offset_effect;
+ int ESC_Low;
int PWM_Interval;
// int Accel_Rang;
// int Accel_Rate;
// int PWM_Resolution;
- char StartMode;
- char Gyro_Type;
+ char Angle_Control;
+ float kp[3];
+ float ki[3];
+ float kd[3];
+ float PID_Limit;
+ float Integral_Limit;
public:
config() {
- Revision = 1.03;
+ Revision = 1.25;
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;
+ Stick_Mix[0] = 0.3;
+ Stick_Mix[1] = 0.3;
+ Stick_Mix[2] = 0.65;
Gyro_Dir[0] = 1;
Gyro_Dir[1] = 1;
Gyro_Dir[2] = 1;
@@ -79,22 +87,36 @@
Accel_Dir[1] = 1;
Accel_Dir[2] = 1;
Accel_Dir[3] = 1;
+ Accel_Ref[0] = 0;
+ Accel_Ref[1] = 0;
+ Accel_Ref[2] = 0;
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;
+ Cutoff_Freq=0.15;
+ Flight_Time=360;
LCD_Contrast = 60;
PWM_Mode = 1;
- Gyro_Stick_offset_effect = 0.00;
+ ESC_Low= 1025;
PWM_Interval = 3000;
// Accel_Rang = 2;
// Accel_Rate = 14;
// PWM_Resolution = 0;
StartMode = 'C';
- Gyro_Type = _ITG3200;
+ Angle_Control = 'H'; // H:horizn A:angle
+ kp[0] = 1.5;
+ kp[1] = 1.5;
+ kp[2] = 1.5;
+ ki[0] = 0.7;
+ ki[1] = 0.7;
+ ki[2] = 0.7;
+ kd[0] = 1.2;
+ kd[1] = 1.2;
+ kd[2] = 1.2;
+ PID_Limit = 300;
+ Integral_Limit = 30;
+ Control_Exchange_Angle = 15;
}
};
#endif
@@ -104,3 +126,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- a/main.cpp Tue Jul 16 06:37:28 2013 +0000
+++ b/main.cpp Fri Nov 15 20:53:36 2013 +0000
@@ -1,74 +1,139 @@
#include "mbed.h"
+#include "math.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;
+#include "PID.h"
+#include "SoftPWM.h"
+
+//Serial pc(USBTX, USBRX);
+
+//Gravity at Earth's surface in m/s/s
+#define g0 9.812865328
+//Convert from radians to degrees.
+#define toDegrees(x) (x * 57.2957795)
+//Convert from degrees to radians.
+#define toRadians(x) (x * 0.01745329252)
+//ITG-3200 sensitivity is 14.375 LSB/(degrees/sec).
+#define GYROSCOPE_GAIN (1 / 14.375)
+//Full scale resolution on the ADXL345 is 4mg/LSB.
+#define ACCELEROMETER_GAIN (0.004 * g0)
+//Updating filter at 40Hz.
+#define FILTER_RATE 0.05
+//At rest the gyroscope is centred around 0 and goes between about
+//-5 and 5 counts. As 1 degrees/sec is ~15 LSB, error is roughly
+//5/15 = 0.3 degrees/sec.
-#ifdef LPCXpresso
-DigitalOut led1(P0_22);
-#define led2 led1
-#else
+#ifdef TARGET_LPC1114 // LPC1114
+// PulseOut pwm[4] = { dp1,dp2,dp18,dp24 );
+ #define LED1 dp28
+ #define p5 dp4
+ #define p6 dp9
+ #define p7 dp10
+ #define p8 dp11
+ #define p9 dp25
+ #define p10 dp26
+ #define p13 dp16
+ #define p21 dp1
+ #define p22 dp2
+ #define p23 dp18
+ #define p24 dp24
+ #define p27 dp27
+ #define p28 dp5
+#else //LPC1768
+ #ifdef LPCXpresso
+ #define LED1 P0_22
+ #endif
+#endif
+DigitalInOut pwmpin[] = { p21,p22,p23,p24 };
DigitalOut led1(LED1);
DigitalOut led2(LED2);
+InterruptIn ch1(p5);
+PulseWidthCounter ch[5] = { p6,p7,p8,p9,p10 };
+#if defined(SOFT_PWM) || defined(TARGET_LPC1114)
+SoftPWM pwm[4] = { p21,p22,p23,p24 };
+#else
+PwmOut pwm[4] = { p21,p22,p23,p24 };
#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 };
+SoftPWM buzz(p26);
Timer CurTime;
-Timer ElapTime;
+//Timer ElapTime;
+Timer CycleTime;
+Timer FlyghtTime;
+//Ticker tick;
+//Ticker tick100ms;
+//Ticker mixTime;
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];
+PID pid[3];
+#ifdef TARGET_LPC1114
+//LPC1114 Flash Memory read/write
+ #define MEM_SIZE 256
+ #define TARGET_SECTOR 7 // use sector 29 as target sector if it is on LPC1768
+#else
+//LPC1768 Flash Memory read/write
+ #define MEM_SIZE 256
+ #define TARGET_SECTOR 29 // use sector 29 as target sector if it is on LPC1768
+#endif
+#ifndef LocalFileOut
+IAP iap;
+#endif
+float TotalTime = 0;;
+int channel = 0;
+//int intrupt_cnt = 0;
+//int intrupt_cnt2 = 0;
+volatile int CH[5];
+volatile int M[6];
+volatile float Gyro[3];
+volatile float Accel[3];
+volatile float Angle[3];
+volatile float Gyro_Ref[3];
+volatile float Gyro_Save[3];
+volatile int Stick[5];
+volatile int Stick_Save[3];
+//int Stick_Max[3];
float Press;
char InPulseMode; //Receiver Signal Type 's':Serial, 'P':Parallel
+//volatile bool tick_flag;
+//volatile bool buzz_flag;
+float interval;
+int pid_reg[3];
+int loop_cnt;
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();
+bool Get_Accel();
+void Get_Angle(float);
void ReadConfig();
void WriteConfig();
+void Interrupt_Check(bool&,int &,DigitalOut &);
void ESC_SetUp(void);
-
+void Flight_SetUp();
+//void IMUfilter_Reset(void);
+void LCD_printf(char *);
+void LCD_cls();
+void LCD_locate(int,int);
+/*
+void tick_interrupt()
+{
+ tick_flag = true;
+}
+*/
void PulseCheck()
{
- Channel++;
+ channel++;
}
void PulseAnalysis() //Interrupt Pin5
@@ -77,10 +142,10 @@
int PulseWidth = CurTime.read_us();
CurTime.reset();
CurTime.start();
- if ( PulseWidth > 3000 ) Channel = 0; //reset pulse count
+ if ( PulseWidth > 3000 ) channel = 0; //reset pulse count
else {
if ( PulseWidth > Pulse_Min && PulseWidth < Pulse_Max ) {
- switch( Channel ) {
+ switch( channel ) {
case IR_THR:
THR = PulseWidth;
break;
@@ -99,49 +164,51 @@
}
}
}
- Channel++;
+ channel++;
}
int main()
{
- int i,j=0;
+ int i=0;
+ wait(0.5);
initialize();
- wait(0.5);
+
Get_Stick_Pos();
- while ( Stick[COL] > 30 || conf.StartMode == 'C' ) //Shrottol Low
+ while ( Stick[COL] > Thro_Zero || conf.StartMode == 'C' ) //Shrottol Low
{
- if ( Stick[COL] > 350 || conf.StartMode == 'C' ) // Shrottle High
+ if ( Stick[COL] > 890 && -Stick[YAW] < Stick_Limit ) // Shrottle High
+ ESC_SetUp();
+ if ( Stick[COL] > 890 || conf.StartMode == 'C' ) // Shrottle High
{
-#ifdef SERIAL_LCD
- SetUpPrompt(conf,lcd);
-#else
+ loop_cnt = 0;
SetUpPrompt(conf,i2c);
-#endif
- for ( i=0;i<4;i++ ) pwm[i].period_us(conf.PWM_Interval);
break;
}
FlashLED(3);
- wait(1);
+ wait(0.3);
Get_Stick_Pos();
}
- led2 = 1;
- ElapTime.start();
-
+ Flight_SetUp();
while (1)
{
- if ( Stick[COL] < 30 )
+ if ( Stick[COL] < Thro_Zero )
{
i = 0;
- ElapTime.stop();
- while ( Stick[YAW] < -Stick_Limit && Stick[COL] < 30 )
+ while ( Stick[YAW] < -Stick_Limit && Stick[COL] < Thro_Zero ) //Rudder Left
{
if ( i > 100 ) //wait 2 sec
{
+ FlyghtTime.stop();
+ if ( Stick[PIT] < -Stick_Limit ) { //Elevetor Down
+ loop_cnt = 0;
+ FlashLED(5);
+ for ( i=0;i<4;i++ ) pwm[i].pulsewidth_us(Pulse_Min);
+ i2c.start(conf.LCD_Contrast);
+ SetUpPrompt(conf,i2c);
+ }
CalibrateGyros();
- CalibrateAccel();
- FlashLED(6);
- ElapTime.start();
+ Flight_SetUp();
break;
}
wait(0.01); // wait 10 msec
@@ -149,12 +216,6 @@
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);
}
@@ -162,38 +223,33 @@
void initialize()
{
-#ifndef SERIAL_LCD
- i2c.start(ST7032_ADDR,conf.LCD_Contrast);
-#endif
+ buzz.period_us(500);
ReadConfig(); //config.inf file read
-// CurTime.start();
- Channel = 0;
+
+ i2c.start(conf.LCD_Contrast);
+ channel = 0;
ch1.rise(&PulseCheck); //input pulse count
- wait(0.1);
- if ( Channel > 30 ) {
+ wait(0.2);
+ if ( channel > 50 ) {
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);
+ led1 = 0;
+ CycleTime.start();
for ( int i=0;i<4;i++ ) pwm[i].period_us(conf.PWM_Interval);
+ FlashLED(3);
}
void FlashLED(int cnt)
{
for ( int i = 0 ; i < cnt ; i++ ) {
led1 = !led1;
- wait(0.05);
+ buzz = 0.5f;
+ wait(0.1);
led1 = !led1;
- wait(0.05);
+ buzz = 0.0f;
+ wait(0.1);
}
}
@@ -227,7 +283,8 @@
config *conf_ptr;
if ( sizeof(config) > 255 ) {
- i2c.printf("config size over");
+ LCD_printf("config size over");
+ wait(3);
return;
}
rc = iap.blank_check( TARGET_SECTOR, TARGET_SECTOR );
@@ -237,14 +294,10 @@
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
}
@@ -260,7 +313,8 @@
char *send;
int i;
if ( sizeof(config) > 255 ) {
- printf("config size over");
+ LCD_printf("config size over");
+ wait(3);
return;
}
send = (char*)&conf;
@@ -268,8 +322,10 @@
for ( i=sizeof(config);i<MEM_SIZE;i++ ) mem[i] = 0x00;
iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
iap.erase( TARGET_SECTOR, TARGET_SECTOR );
+//pc.printf("erase\n");
iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
+//pc.printf("write\n");
#endif
}
@@ -278,6 +334,10 @@
if ( InPulseMode == 'P' ) {
for (int i=0;i<5;i++) CH[i] = ch[i].count;
}
+// Stick_Save[ROL] = Stick[ROL];
+// Stick_Save[PIT] = Stick[PIT];
+// Stick_Save[YAW] = Stick[YAW];
+
Stick[ROL] = AIL - conf.Stick_Ref[ROL];
Stick[PIT] = ELE - conf.Stick_Ref[PIT];
Stick[YAW] = RUD - conf.Stick_Ref[YAW];
@@ -287,23 +347,61 @@
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;
+ float x,y,z;
+ bool err;
+ Gyro_Save[ROL] = Gyro[ROL];
+ Gyro_Save[PIT] = Gyro[PIT];
+ Gyro_Save[YAW] = Gyro[YAW];
+
+ if ( conf.Gyro_Dir[3] ==1 ) err=i2c.angular(&x,&y,&z);
+ else err=i2c.angular(&y,&x,&z);
+ if ( err == false ) return;
+ Gyro[ROL] = x - Gyro_Ref[0] ;
+ Gyro[PIT] = y - Gyro_Ref[1] ;
+ Gyro[YAW] = z - Gyro_Ref[2] ;
+
+ if ( fabs(Gyro[ROL]) > 300.0 ) Gyro[ROL] = Gyro_Save[ROL];
+ if ( fabs(Gyro[PIT]) > 300.0 ) Gyro[PIT] = Gyro_Save[PIT];
+ if ( fabs(Gyro[YAW]) > 300.0 ) Gyro[YAW] = Gyro_Save[YAW];
}
-void Get_Accel()
+bool Get_Accel()
+{
+ float x,y,z;
+ bool err;
+ if ( conf.Gyro_Dir[3] ==1 ) err=i2c.Acceleration(&x,&y,&z);
+ else err=i2c.Acceleration(&y,&x,&z);
+ if ( err == false ) return false;
+ float wx = x - conf.Accel_Ref[0];
+ float wy = y - conf.Accel_Ref[1];
+ float wz = z - conf.Accel_Ref[2];
+ Accel[ROL] = atan(wx/sqrt( pow(wy,2)+pow(wz,2)))*180/3.14;
+ Accel[PIT] = atan(wy/sqrt( pow(wx,2)+pow(wz,2)))*180/3.14;
+ Accel[YAW] = atan(sqrt( pow(wx,2)+pow(wy,2))/wz)*180/3.14;
+ return true;
+}
+
+void Get_Angle(float interval)
{
- 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] );
+ Get_Gyro();
+ Get_Accel();
+ float x,y,z;
+
+ x = ( (Gyro[ROL] + Gyro_Save[ROL]) ) * 0.5;
+ y = ( (Gyro[PIT] + Gyro_Save[PIT]) ) * 0.5;
+ z = ( (Gyro[YAW] + Gyro_Save[YAW]) ) * 0.5;
+ if ( Get_Accel() == true ) {
+ float i = 3.14 * 2 * conf.Cutoff_Freq * interval;
+ Angle[ROL] += -Angle[ROL] * i + Accel[ROL] * i + x * interval;
+ Angle[PIT] += -Angle[PIT] * i + Accel[PIT] * i + y * interval;
+ }
+ else {
+ Angle[ROL] += x * interval;
+ Angle[PIT] += y * interval;
+ }
+ Angle[YAW] += z * interval;
}
+
void Get_Pressure()
{
Press = i2c.pressure();
@@ -311,36 +409,41 @@
void CalibrateGyros(void)
{
- int i,j,x,y,z;
- int k[3]={0,0,0};
+ int i;
+ float x,y,z;
+ float k[3]={0,0,0};
wait(1);
+ Angle[0]=Angle[1]=Angle[2]=0;
for(i=0; i<16; i++) {
- if ( conf.Gyro_Dir[3] ==1 ) i2c.angular(&x,&y,&z);
- else i2c.angular(&y,&x,&z);
+ 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);
+ wait(0.01);
}
- for( j=0; j<3; j++ ) Gyro_Ref[j] = k[j]/16;
- FlashLED(3);
+ for( i=0; i<3; i++ ) Gyro_Ref[i] = k[i]/16;
+// FlashLED(3);
}
void CalibrateAccel(void)
{
- int i,j,x,y,z;
- int k[3]={0,0,0};
- wait(1);
+ int i;
+ float x,y,z;
+ float k[3]={0,0,0};
+ conf.Accel_Ref[0]=conf.Accel_Ref[1]=conf.Accel_Ref[2]=0;
for(i=0; i<16; i++) {
- if ( conf.Gyro_Dir[3] ==1 ) i2c.Acceleration(&x,&y,&z);
- else i2c.Acceleration(&y,&x,&z);
+ 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);
+ wait(0.01);
}
- for( j=0; j<3; j++ ) Accel_Ref[j] = k[j]/16;
- FlashLED(3);
+ conf.Accel_Ref[0] = k[0]/16;
+ conf.Accel_Ref[1] = k[1]/16;
+ conf.Accel_Ref[2] = k[2]/16-9.8;
+// FlashLED(3);
}
void PWM_Out(bool mode)
@@ -349,20 +452,50 @@
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++ )
- {
+ interval = CycleTime.read();
+ CycleTime.reset();
+ if ( interval > 0.1 ) return;
+ TotalTime += interval;
+ if ( TotalTime > 0.5 ) {
+ led1 = !led1;
+ if ( ( !buzz ) && ( (float)conf.Flight_Time < FlyghtTime.read() ) ) buzz=0.5f;
+ else buzz=0.0;
+ TotalTime = 0;
+ }
+
+ Get_Angle(interval);
+
+ 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];
+ if ( Stick[GAIN] > 0
+// || i == YAW
+// || (fabsf)(Angle[i]) > conf.Control_Exchange_Angle
+ ) {
+ reg[i] = Stick[i] * conf.Stick_Mix[i];
+ reg[i] += Gyro[i] * gain * GYRO_ADJUST;
+ }
+ else {
+ if ( (i == YAW) || (i2c.GetAddr(ACCEL_ADDR)==0) ) {
+ if ( abs(Stick_Save[i]) <= abs(Stick[i]>>2) ) {
+ Stick_Save[i] = Stick[i]>>2;
+ }
+ else {
+// pc.printf("PID RESET.%3d",i);wait(1);
+ Stick_Save[i] = 0;
+ pid[i].reset();
+ Angle[i] = 0;
+ }
+ }
+ reg[i] = Stick[i] * conf.Stick_Mix[i];
+ reg[i] += pid[i].calc(Angle[i],0,interval);
+// reg[i] = pid[i].calc(Angle[i],-(float)Stick[i]*60/400,interval);
+ }
+ pid_reg[i] = reg[i];
}
//Calculate Roll Pulse Width
M1 += reg[ROL];
@@ -384,25 +517,69 @@
for ( i=0;i<4;i++ )
{
+// if ( Stick[COL] > 150 && M[i] < 150 ) M[i] = 150;
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]);
-
+
+ if (Stick[COL] < Thro_Zero ) M1=M2=M3=M4=0;
+
+ if ( mode ) {
+ for ( i=0;i<4;i++ ) {
+ while ( !pwmpin[i] );
+ if ( conf.PWM_Mode == 1 )
+ pwm[i].pulsewidth_us(conf.ESC_Low+M[i]);
+ else pwm[i].pulsewidth_us(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);
+ for ( int i=0;i<4;i++ ) pwm[i].pulsewidth_us(conf.Stick_Ref[COL]+Stick[COL]);
+ wait(0.015);
}
-};
+}
+
+void Flight_SetUp(void)
+{
+ int i;
+ for ( i=0;i<4;i++ ) pwm[i].pulsewidth_us(0);
+ for ( i=0;i<4;i++ ) pwm[i].period_us(conf.PWM_Interval);
+ for ( i=0;i<4;i++ ) pwm[i].pulsewidth_us(Pulse_Min);
+ for ( i=0;i<4;i++ ) pid[i].init(conf.kp[i],conf.ki[i],conf.kd[i]*(float)abs(Stick[GAIN])*0.02
+ ,conf.PID_Limit,conf.Integral_Limit);
+ Angle[ROL]=Angle[PIT]=Angle[YAW]=0;
+ loop_cnt = 0;
+ FlyghtTime.start();
+ CycleTime.start();
+ FlashLED(5);
+}
+
+void LCD_locate(int clm,int row)
+{
+ lcd.locate(clm,row);
+ i2c.locate(clm,row);
+}
+
+void LCD_cls()
+{
+ lcd.cls();
+ i2c.cls();
+}
+
+void LCD_printf(char* str)
+{
+ lcd.printf(str);
+ i2c.printf(str);
+}
+;
+
+
--- a/mbed.bld Tue Jul 16 06:37:28 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/5e5da4a5990b \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.lib Fri Nov 15 20:53:36 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/#f37f3b9c9f0b