
Latest version of my quadcopter controller with an LPC1768 and MPU9250.
Currently running on a custom PCB with 30.5 x 30.5mm mounts. There are also 2 PC apps that go with the software; one to set up the PID controller and one to balance the motors and props. If anyone is interested, send me a message and I'll upload them.
main.cpp@8:981f7e2365b6, 2018-07-31 (annotated)
- Committer:
- Anaesthetix
- Date:
- Tue Jul 31 20:36:57 2018 +0000
- Revision:
- 8:981f7e2365b6
- Parent:
- 7:d86c41443f6d
Switched from Madgwick to Mahony as I'm having trouble with slow oscillations caused by the madgwick filter. Fixed an error on the PID algorithm also.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Anaesthetix | 7:d86c41443f6d | 1 | // Coded by: Erik van de Coevering |
Anaesthetix | 4:fab65ad01ab4 | 2 | |
Anaesthetix | 0:0929d3d566cf | 3 | #include "mbed.h" |
Anaesthetix | 0:0929d3d566cf | 4 | #include "MadgwickAHRS.h" |
Anaesthetix | 8:981f7e2365b6 | 5 | #include "MahonyAHRS.h" |
Anaesthetix | 0:0929d3d566cf | 6 | #include "MAfilter.h" |
Anaesthetix | 0:0929d3d566cf | 7 | #include "MPU9250_SPI.h" |
Anaesthetix | 0:0929d3d566cf | 8 | #include "calccomp.h" |
Anaesthetix | 0:0929d3d566cf | 9 | #include "SerialBuffered.h" |
Anaesthetix | 0:0929d3d566cf | 10 | #include "IAP.h" |
Anaesthetix | 0:0929d3d566cf | 11 | #include "LPfilter.h" |
Anaesthetix | 0:0929d3d566cf | 12 | |
Anaesthetix | 0:0929d3d566cf | 13 | |
Anaesthetix | 0:0929d3d566cf | 14 | #define MEM_SIZE 256 |
Anaesthetix | 0:0929d3d566cf | 15 | #define TARGET_SECTOR 29 // use sector 29 as target sector |
Anaesthetix | 0:0929d3d566cf | 16 | |
Anaesthetix | 0:0929d3d566cf | 17 | DigitalOut led2(LED2); // leds are active low |
Anaesthetix | 0:0929d3d566cf | 18 | DigitalOut ch_sw(p26); |
Anaesthetix | 0:0929d3d566cf | 19 | |
Anaesthetix | 0:0929d3d566cf | 20 | Serial pc(USBTX, USBRX); |
Anaesthetix | 0:0929d3d566cf | 21 | SerialBuffered *pc1 = new SerialBuffered( 100, USBTX, USBRX); |
Anaesthetix | 0:0929d3d566cf | 22 | |
Anaesthetix | 0:0929d3d566cf | 23 | SPI spi(p11, p12, p13); |
Anaesthetix | 0:0929d3d566cf | 24 | mpu9250_spi mpu9250(spi, p14); |
Anaesthetix | 0:0929d3d566cf | 25 | |
Anaesthetix | 8:981f7e2365b6 | 26 | //Madgwick filter; |
Anaesthetix | 8:981f7e2365b6 | 27 | Mahony filter; |
Anaesthetix | 0:0929d3d566cf | 28 | |
Anaesthetix | 0:0929d3d566cf | 29 | Timer timer; |
Anaesthetix | 0:0929d3d566cf | 30 | Timer tijd; |
Anaesthetix | 0:0929d3d566cf | 31 | Timer t; |
Anaesthetix | 0:0929d3d566cf | 32 | Timer print; |
Anaesthetix | 0:0929d3d566cf | 33 | |
Anaesthetix | 7:d86c41443f6d | 34 | LPfilter8 lp1, lp2, lp3; |
Anaesthetix | 8:981f7e2365b6 | 35 | MAfilter10 MAgx, MAgy, MAgz; |
Anaesthetix | 0:0929d3d566cf | 36 | |
Anaesthetix | 0:0929d3d566cf | 37 | IAP iap; |
Anaesthetix | 0:0929d3d566cf | 38 | |
Anaesthetix | 0:0929d3d566cf | 39 | InterruptIn rx_rud(p5); |
Anaesthetix | 0:0929d3d566cf | 40 | InterruptIn rx_elev(p6); |
Anaesthetix | 0:0929d3d566cf | 41 | InterruptIn rx_thr(p7); |
Anaesthetix | 0:0929d3d566cf | 42 | InterruptIn rx_ail(p8); |
Anaesthetix | 0:0929d3d566cf | 43 | InterruptIn rx_p1(p29); |
Anaesthetix | 0:0929d3d566cf | 44 | InterruptIn rx_p2(p30); |
Anaesthetix | 0:0929d3d566cf | 45 | |
Anaesthetix | 0:0929d3d566cf | 46 | PwmOut motor4(p24); |
Anaesthetix | 0:0929d3d566cf | 47 | PwmOut motor3(p23); |
Anaesthetix | 0:0929d3d566cf | 48 | PwmOut motor1(p22); |
Anaesthetix | 0:0929d3d566cf | 49 | PwmOut motor2(p21); |
Anaesthetix | 0:0929d3d566cf | 50 | |
Anaesthetix | 6:033ad7377fee | 51 | float KP_x, KI_x, KD_x; |
Anaesthetix | 6:033ad7377fee | 52 | float KP_y, KI_y, KD_y; |
Anaesthetix | 6:033ad7377fee | 53 | float KP_z, KI_z, KD_z; |
Anaesthetix | 0:0929d3d566cf | 54 | |
Anaesthetix | 0:0929d3d566cf | 55 | Timer trx0, trx1, trx2, trx3, trx4, trx5; |
Anaesthetix | 0:0929d3d566cf | 56 | int rx_data[6] = {0}; |
Anaesthetix | 0:0929d3d566cf | 57 | bool rxd = false; |
Anaesthetix | 0:0929d3d566cf | 58 | |
Anaesthetix | 0:0929d3d566cf | 59 | char mcommand; |
Anaesthetix | 0:0929d3d566cf | 60 | |
Anaesthetix | 8:981f7e2365b6 | 61 | void rx0() |
Anaesthetix | 8:981f7e2365b6 | 62 | { |
Anaesthetix | 8:981f7e2365b6 | 63 | trx0.start(); |
Anaesthetix | 0:0929d3d566cf | 64 | } |
Anaesthetix | 0:0929d3d566cf | 65 | |
Anaesthetix | 8:981f7e2365b6 | 66 | void rx1() |
Anaesthetix | 8:981f7e2365b6 | 67 | { |
Anaesthetix | 8:981f7e2365b6 | 68 | trx1.start(); |
Anaesthetix | 8:981f7e2365b6 | 69 | trx0.stop(); |
Anaesthetix | 8:981f7e2365b6 | 70 | if(trx0.read_us() > 900 && trx0.read_us() < 2200) rx_data[0] = trx0.read_us(); |
Anaesthetix | 8:981f7e2365b6 | 71 | trx0.reset(); |
Anaesthetix | 0:0929d3d566cf | 72 | } |
Anaesthetix | 0:0929d3d566cf | 73 | |
Anaesthetix | 8:981f7e2365b6 | 74 | void rx2() |
Anaesthetix | 8:981f7e2365b6 | 75 | { |
Anaesthetix | 8:981f7e2365b6 | 76 | trx2.start(); |
Anaesthetix | 8:981f7e2365b6 | 77 | trx1.stop(); |
Anaesthetix | 8:981f7e2365b6 | 78 | if(trx1.read_us() > 900 && trx1.read_us() < 2200) rx_data[1] = trx1.read_us(); |
Anaesthetix | 8:981f7e2365b6 | 79 | trx1.reset(); |
Anaesthetix | 0:0929d3d566cf | 80 | } |
Anaesthetix | 0:0929d3d566cf | 81 | |
Anaesthetix | 8:981f7e2365b6 | 82 | void rx3() |
Anaesthetix | 8:981f7e2365b6 | 83 | { |
Anaesthetix | 8:981f7e2365b6 | 84 | trx3.start(); |
Anaesthetix | 8:981f7e2365b6 | 85 | trx2.stop(); |
Anaesthetix | 8:981f7e2365b6 | 86 | if(trx2.read_us() > 900 && trx2.read_us() < 2200) rx_data[2] = trx2.read_us(); |
Anaesthetix | 8:981f7e2365b6 | 87 | trx2.reset(); |
Anaesthetix | 0:0929d3d566cf | 88 | } |
Anaesthetix | 0:0929d3d566cf | 89 | |
Anaesthetix | 8:981f7e2365b6 | 90 | void rx4() |
Anaesthetix | 8:981f7e2365b6 | 91 | { |
Anaesthetix | 8:981f7e2365b6 | 92 | trx4.start(); |
Anaesthetix | 8:981f7e2365b6 | 93 | trx3.stop(); |
Anaesthetix | 8:981f7e2365b6 | 94 | if(trx3.read_us() > 900 && trx3.read_us() < 2200) rx_data[3] = trx3.read_us(); |
Anaesthetix | 8:981f7e2365b6 | 95 | trx3.reset(); |
Anaesthetix | 0:0929d3d566cf | 96 | } |
Anaesthetix | 0:0929d3d566cf | 97 | |
Anaesthetix | 8:981f7e2365b6 | 98 | void rx5() |
Anaesthetix | 8:981f7e2365b6 | 99 | { |
Anaesthetix | 8:981f7e2365b6 | 100 | trx5.start(); |
Anaesthetix | 8:981f7e2365b6 | 101 | trx4.stop(); |
Anaesthetix | 8:981f7e2365b6 | 102 | if(trx4.read_us() > 900 && trx4.read_us() < 2200) rx_data[4] = trx4.read_us(); |
Anaesthetix | 8:981f7e2365b6 | 103 | trx4.reset(); |
Anaesthetix | 0:0929d3d566cf | 104 | } |
Anaesthetix | 0:0929d3d566cf | 105 | |
Anaesthetix | 8:981f7e2365b6 | 106 | void rx6() |
Anaesthetix | 8:981f7e2365b6 | 107 | { |
Anaesthetix | 8:981f7e2365b6 | 108 | trx5.stop(); |
Anaesthetix | 8:981f7e2365b6 | 109 | if(trx5.read_us() > 900 && trx5.read_us() < 2200) rx_data[5] = trx5.read_us(); |
Anaesthetix | 8:981f7e2365b6 | 110 | trx5.reset(); |
Anaesthetix | 8:981f7e2365b6 | 111 | rxd = true; |
Anaesthetix | 0:0929d3d566cf | 112 | } |
Anaesthetix | 0:0929d3d566cf | 113 | |
Anaesthetix | 0:0929d3d566cf | 114 | |
Anaesthetix | 0:0929d3d566cf | 115 | int main() |
Anaesthetix | 0:0929d3d566cf | 116 | { |
Anaesthetix | 8:981f7e2365b6 | 117 | ch_sw = 1; |
Anaesthetix | 8:981f7e2365b6 | 118 | led1 = 1; |
Anaesthetix | 8:981f7e2365b6 | 119 | led2 = 0; |
Anaesthetix | 8:981f7e2365b6 | 120 | pc1->baud(230400); |
Anaesthetix | 8:981f7e2365b6 | 121 | pc1->setTimeout(1); |
Anaesthetix | 8:981f7e2365b6 | 122 | pc.baud(230400); |
Anaesthetix | 8:981f7e2365b6 | 123 | spi.frequency(4000000); |
Anaesthetix | 8:981f7e2365b6 | 124 | |
Anaesthetix | 8:981f7e2365b6 | 125 | |
Anaesthetix | 8:981f7e2365b6 | 126 | //IAP variables |
Anaesthetix | 8:981f7e2365b6 | 127 | char* addr = sector_start_adress[TARGET_SECTOR]; |
Anaesthetix | 8:981f7e2365b6 | 128 | char mem[ MEM_SIZE ]; // memory, it should be aligned to word boundary |
Anaesthetix | 8:981f7e2365b6 | 129 | char PIDsetup = 0; |
Anaesthetix | 8:981f7e2365b6 | 130 | int r; |
Anaesthetix | 8:981f7e2365b6 | 131 | int tempval; |
Anaesthetix | 8:981f7e2365b6 | 132 | |
Anaesthetix | 8:981f7e2365b6 | 133 | //IMU variables |
Anaesthetix | 8:981f7e2365b6 | 134 | float angles[6] = {0}; |
Anaesthetix | 8:981f7e2365b6 | 135 | float time = 0; |
Anaesthetix | 8:981f7e2365b6 | 136 | float samplef = 0; |
Anaesthetix | 8:981f7e2365b6 | 137 | float gyrodata[3] = {0}; |
Anaesthetix | 8:981f7e2365b6 | 138 | float acceldata[3] = {0}; |
Anaesthetix | 8:981f7e2365b6 | 139 | float angles_temp[2] = {0}; |
Anaesthetix | 8:981f7e2365b6 | 140 | float roll, pitch; |
Anaesthetix | 8:981f7e2365b6 | 141 | float tempcomp[6] = {0}; |
Anaesthetix | 8:981f7e2365b6 | 142 | float temp = 0; |
Anaesthetix | 8:981f7e2365b6 | 143 | float temp2 = 0; |
Anaesthetix | 8:981f7e2365b6 | 144 | float temp3 = 0; |
Anaesthetix | 8:981f7e2365b6 | 145 | bool exit = true; |
Anaesthetix | 8:981f7e2365b6 | 146 | float noise = 0; |
Anaesthetix | 8:981f7e2365b6 | 147 | int count = 0; |
Anaesthetix | 8:981f7e2365b6 | 148 | |
Anaesthetix | 8:981f7e2365b6 | 149 | //Rx variables |
Anaesthetix | 8:981f7e2365b6 | 150 | int motor[4] = {0}; |
Anaesthetix | 8:981f7e2365b6 | 151 | |
Anaesthetix | 8:981f7e2365b6 | 152 | // Init pwm |
Anaesthetix | 8:981f7e2365b6 | 153 | motor1.period_ms(10); |
Anaesthetix | 8:981f7e2365b6 | 154 | motor1.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 155 | motor2.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 156 | motor3.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 157 | motor4.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 158 | |
Anaesthetix | 8:981f7e2365b6 | 159 | filter.begin(1500); |
Anaesthetix | 8:981f7e2365b6 | 160 | |
Anaesthetix | 8:981f7e2365b6 | 161 | pc.putc('c'); |
Anaesthetix | 8:981f7e2365b6 | 162 | PIDsetup = pc1->getc(); |
Anaesthetix | 8:981f7e2365b6 | 163 | if(PIDsetup == 'c') { |
Anaesthetix | 8:981f7e2365b6 | 164 | while(1) { |
Anaesthetix | 8:981f7e2365b6 | 165 | PIDsetup = pc1->getc(); |
Anaesthetix | 8:981f7e2365b6 | 166 | if(PIDsetup == 'R') { |
Anaesthetix | 8:981f7e2365b6 | 167 | for(int i=0; i<18; i++) { |
Anaesthetix | 8:981f7e2365b6 | 168 | pc1->putc(addr[i]); |
Anaesthetix | 8:981f7e2365b6 | 169 | wait_ms(1); |
Anaesthetix | 8:981f7e2365b6 | 170 | } |
Anaesthetix | 8:981f7e2365b6 | 171 | } |
Anaesthetix | 8:981f7e2365b6 | 172 | |
Anaesthetix | 8:981f7e2365b6 | 173 | if(PIDsetup == 'W') { |
Anaesthetix | 8:981f7e2365b6 | 174 | for(int i=0; i<18; i++) { |
Anaesthetix | 8:981f7e2365b6 | 175 | mem[i] = pc1->getc(); |
Anaesthetix | 8:981f7e2365b6 | 176 | } |
Anaesthetix | 8:981f7e2365b6 | 177 | iap.prepare( TARGET_SECTOR, TARGET_SECTOR ); |
Anaesthetix | 8:981f7e2365b6 | 178 | r = iap.erase( TARGET_SECTOR, TARGET_SECTOR ); |
Anaesthetix | 8:981f7e2365b6 | 179 | iap.prepare( TARGET_SECTOR, TARGET_SECTOR ); |
Anaesthetix | 8:981f7e2365b6 | 180 | r = iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE ); |
Anaesthetix | 5:0f4204941604 | 181 | } |
Anaesthetix | 5:0f4204941604 | 182 | } |
Anaesthetix | 8:981f7e2365b6 | 183 | } |
Anaesthetix | 5:0f4204941604 | 184 | |
Anaesthetix | 8:981f7e2365b6 | 185 | |
Anaesthetix | 8:981f7e2365b6 | 186 | if(PIDsetup == 'W') { |
Anaesthetix | 8:981f7e2365b6 | 187 | mpu9250.init2(1,BITS_DLPF_CFG_188HZ); |
Anaesthetix | 8:981f7e2365b6 | 188 | pc1->setTimeout(0.01); |
Anaesthetix | 8:981f7e2365b6 | 189 | |
Anaesthetix | 8:981f7e2365b6 | 190 | rx_rud.rise(&rx0); |
Anaesthetix | 8:981f7e2365b6 | 191 | rx_elev.rise(&rx1); |
Anaesthetix | 8:981f7e2365b6 | 192 | rx_thr.rise(&rx2); |
Anaesthetix | 8:981f7e2365b6 | 193 | rx_ail.rise(&rx3); |
Anaesthetix | 8:981f7e2365b6 | 194 | rx_p1.rise(&rx4); |
Anaesthetix | 8:981f7e2365b6 | 195 | rx_p2.rise(&rx5); |
Anaesthetix | 8:981f7e2365b6 | 196 | rx_p2.fall(&rx6); |
Anaesthetix | 8:981f7e2365b6 | 197 | mcommand = 'a'; |
Anaesthetix | 8:981f7e2365b6 | 198 | |
Anaesthetix | 8:981f7e2365b6 | 199 | while(exit) { |
Anaesthetix | 8:981f7e2365b6 | 200 | wait_ms(1); |
Anaesthetix | 8:981f7e2365b6 | 201 | if(mcommand == '5') { |
Anaesthetix | 8:981f7e2365b6 | 202 | motor1.pulsewidth_us(rx_data[2] - 20); |
Anaesthetix | 8:981f7e2365b6 | 203 | motor2.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 204 | motor3.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 205 | motor4.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 206 | } else if(mcommand == '6') { |
Anaesthetix | 8:981f7e2365b6 | 207 | motor1.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 208 | motor2.pulsewidth_us(rx_data[2] - 20); |
Anaesthetix | 8:981f7e2365b6 | 209 | motor3.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 210 | motor4.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 211 | } else if(mcommand == '3') { |
Anaesthetix | 8:981f7e2365b6 | 212 | motor1.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 213 | motor2.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 214 | motor3.pulsewidth_us(rx_data[2] - 20); |
Anaesthetix | 8:981f7e2365b6 | 215 | motor4.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 216 | } else if(mcommand == '4') { |
Anaesthetix | 8:981f7e2365b6 | 217 | motor1.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 218 | motor2.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 219 | motor3.pulsewidth_us(1000); |
Anaesthetix | 8:981f7e2365b6 | 220 | motor4.pulsewidth_us(rx_data[2] - 20); |
Anaesthetix | 5:0f4204941604 | 221 | } |
Anaesthetix | 8:981f7e2365b6 | 222 | if(mcommand == 'E') exit = 0; |
Anaesthetix | 8:981f7e2365b6 | 223 | |
Anaesthetix | 8:981f7e2365b6 | 224 | if(rxd) { |
Anaesthetix | 8:981f7e2365b6 | 225 | led2 = !led2; |
Anaesthetix | 8:981f7e2365b6 | 226 | rxd = false; |
Anaesthetix | 8:981f7e2365b6 | 227 | } |
Anaesthetix | 8:981f7e2365b6 | 228 | |
Anaesthetix | 8:981f7e2365b6 | 229 | mpu9250.read_all(); |
Anaesthetix | 8:981f7e2365b6 | 230 | if(mpu9250.accelerometer_data[0] >= 0) noise = noise*0.99 + 0.01*mpu9250.accelerometer_data[0]; |
Anaesthetix | 8:981f7e2365b6 | 231 | |
Anaesthetix | 8:981f7e2365b6 | 232 | if(count>100) { |
Anaesthetix | 8:981f7e2365b6 | 233 | count = 0; |
Anaesthetix | 8:981f7e2365b6 | 234 | pc.printf("%.2f\n", noise); |
Anaesthetix | 8:981f7e2365b6 | 235 | mcommand = pc1->getc(); |
Anaesthetix | 8:981f7e2365b6 | 236 | } |
Anaesthetix | 8:981f7e2365b6 | 237 | count++; |
Anaesthetix | 5:0f4204941604 | 238 | } |
Anaesthetix | 8:981f7e2365b6 | 239 | } |
Anaesthetix | 8:981f7e2365b6 | 240 | |
Anaesthetix | 8:981f7e2365b6 | 241 | tempval = addr[0]; |
Anaesthetix | 5:0f4204941604 | 242 | tempval = tempval + (addr[1] << 8); |
Anaesthetix | 6:033ad7377fee | 243 | KP_x = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 244 | tempval = addr[2]; |
Anaesthetix | 5:0f4204941604 | 245 | tempval = tempval + (addr[3] << 8); |
Anaesthetix | 6:033ad7377fee | 246 | KI_x = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 247 | tempval = addr[4]; |
Anaesthetix | 5:0f4204941604 | 248 | tempval = tempval + (addr[5] << 8); |
Anaesthetix | 6:033ad7377fee | 249 | KD_x = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 250 | |
Anaesthetix | 8:981f7e2365b6 | 251 | tempval = addr[6]; |
Anaesthetix | 6:033ad7377fee | 252 | tempval = tempval + (addr[7] << 8); |
Anaesthetix | 6:033ad7377fee | 253 | KP_y = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 254 | tempval = addr[8]; |
Anaesthetix | 6:033ad7377fee | 255 | tempval = tempval + (addr[9] << 8); |
Anaesthetix | 6:033ad7377fee | 256 | KI_y = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 257 | tempval = addr[10]; |
Anaesthetix | 6:033ad7377fee | 258 | tempval = tempval + (addr[11] << 8); |
Anaesthetix | 6:033ad7377fee | 259 | KD_y = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 260 | |
Anaesthetix | 8:981f7e2365b6 | 261 | tempval = addr[12]; |
Anaesthetix | 6:033ad7377fee | 262 | tempval = tempval + (addr[13] << 8); |
Anaesthetix | 6:033ad7377fee | 263 | KP_z = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 264 | tempval = addr[14]; |
Anaesthetix | 6:033ad7377fee | 265 | tempval = tempval + (addr[15] << 8); |
Anaesthetix | 6:033ad7377fee | 266 | KI_z = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 267 | tempval = addr[16]; |
Anaesthetix | 6:033ad7377fee | 268 | tempval = tempval + (addr[17] << 8); |
Anaesthetix | 6:033ad7377fee | 269 | KD_z = ((float)tempval) / 100; |
Anaesthetix | 8:981f7e2365b6 | 270 | |
Anaesthetix | 8:981f7e2365b6 | 271 | mpu9250.init(1,BITS_DLPF_CFG_188HZ); |
Anaesthetix | 8:981f7e2365b6 | 272 | /* |
Anaesthetix | 8:981f7e2365b6 | 273 | pc.printf("%.2f %.2f %.2f\r\n", KP_x, KI_x, KD_x); |
Anaesthetix | 8:981f7e2365b6 | 274 | pc.printf("%.2f %.2f %.2f\r\n", KP_y, KI_y, KD_y); |
Anaesthetix | 8:981f7e2365b6 | 275 | pc.printf("%.2f %.2f %.2f\r\n", KP_z, KI_z, KD_z); |
Anaesthetix | 8:981f7e2365b6 | 276 | */ |
Anaesthetix | 8:981f7e2365b6 | 277 | rx_rud.rise(&rx0); |
Anaesthetix | 8:981f7e2365b6 | 278 | rx_elev.rise(&rx1); |
Anaesthetix | 8:981f7e2365b6 | 279 | rx_thr.rise(&rx2); |
Anaesthetix | 8:981f7e2365b6 | 280 | rx_ail.rise(&rx3); |
Anaesthetix | 8:981f7e2365b6 | 281 | rx_p1.rise(&rx4); |
Anaesthetix | 8:981f7e2365b6 | 282 | rx_p2.rise(&rx5); |
Anaesthetix | 8:981f7e2365b6 | 283 | rx_p2.fall(&rx6); |
Anaesthetix | 8:981f7e2365b6 | 284 | |
Anaesthetix | 8:981f7e2365b6 | 285 | t.start(); |
Anaesthetix | 8:981f7e2365b6 | 286 | |
Anaesthetix | 5:0f4204941604 | 287 | while(1) { |
Anaesthetix | 8:981f7e2365b6 | 288 | print.start(); |
Anaesthetix | 8:981f7e2365b6 | 289 | t.stop(); |
Anaesthetix | 8:981f7e2365b6 | 290 | time = (float)t.read(); |
Anaesthetix | 8:981f7e2365b6 | 291 | t.reset(); |
Anaesthetix | 8:981f7e2365b6 | 292 | t.start(); |
Anaesthetix | 8:981f7e2365b6 | 293 | filter.invSampleFreq = time; |
Anaesthetix | 8:981f7e2365b6 | 294 | samplef = 1/time; |
Anaesthetix | 8:981f7e2365b6 | 295 | |
Anaesthetix | 8:981f7e2365b6 | 296 | mpu9250.read_all(); |
Anaesthetix | 8:981f7e2365b6 | 297 | if(mpu9250.Temperature < 6.0f) temp = 6.0f; |
Anaesthetix | 8:981f7e2365b6 | 298 | else if(mpu9250.Temperature > 60.0f) temp = 60.0f; |
Anaesthetix | 8:981f7e2365b6 | 299 | else temp = 0.999*temp + 0.001*mpu9250.Temperature; |
Anaesthetix | 8:981f7e2365b6 | 300 | temp2 = temp*temp; |
Anaesthetix | 8:981f7e2365b6 | 301 | temp3 = temp2*temp; |
Anaesthetix | 8:981f7e2365b6 | 302 | |
Anaesthetix | 8:981f7e2365b6 | 303 | // Temperature compensation |
Anaesthetix | 8:981f7e2365b6 | 304 | tempcomp[0] = -1.77e-6*temp2 + 0.000233*temp + 0.02179; |
Anaesthetix | 8:981f7e2365b6 | 305 | tempcomp[1] = 0.0005727*temp - 0.01488; |
Anaesthetix | 8:981f7e2365b6 | 306 | tempcomp[2] = -2.181e-7*temp3 + 1.754e-5*temp2 - 0.0004955*temp; |
Anaesthetix | 8:981f7e2365b6 | 307 | tempcomp[3] = -0.0002814*temp2 + 0.005545*temp - 1.4; |
Anaesthetix | 8:981f7e2365b6 | 308 | tempcomp[4] = -3.011e-5*temp3 + 0.002823*temp2 - 0.1073*temp + 3.618; |
Anaesthetix | 8:981f7e2365b6 | 309 | tempcomp[5] = 9.364e-5*temp2 + 0.009138*temp - 0.8939; |
Anaesthetix | 8:981f7e2365b6 | 310 | |
Anaesthetix | 8:981f7e2365b6 | 311 | // Low pass filters on accelerometer data (calculated with the help of Matlab's FDAtool) |
Anaesthetix | 8:981f7e2365b6 | 312 | acceldata[0] = lp1.run(mpu9250.accelerometer_data[0] - tempcomp[0]); |
Anaesthetix | 8:981f7e2365b6 | 313 | acceldata[1] = lp2.run(mpu9250.accelerometer_data[1] - tempcomp[1]); |
Anaesthetix | 8:981f7e2365b6 | 314 | acceldata[2] = lp3.run((mpu9250.accelerometer_data[2] - tempcomp[2])*-1); |
Anaesthetix | 8:981f7e2365b6 | 315 | |
Anaesthetix | 8:981f7e2365b6 | 316 | // 10-term moving average to remove some noise |
Anaesthetix | 8:981f7e2365b6 | 317 | gyrodata[0] = MAgx.run((mpu9250.gyroscope_data[0] - tempcomp[3])*-1); |
Anaesthetix | 8:981f7e2365b6 | 318 | gyrodata[1] = MAgy.run((mpu9250.gyroscope_data[1] - tempcomp[4])*-1); |
Anaesthetix | 8:981f7e2365b6 | 319 | gyrodata[2] = MAgz.run((mpu9250.gyroscope_data[2] - tempcomp[5])*-1); |
Anaesthetix | 8:981f7e2365b6 | 320 | |
Anaesthetix | 8:981f7e2365b6 | 321 | // Madgwick's quaternion algorithm |
Anaesthetix | 8:981f7e2365b6 | 322 | filter.updateIMU(gyrodata[0], gyrodata[1], gyrodata[2], acceldata[0], |
Anaesthetix | 8:981f7e2365b6 | 323 | acceldata[1], acceldata[2]); |
Anaesthetix | 8:981f7e2365b6 | 324 | |
Anaesthetix | 8:981f7e2365b6 | 325 | // filter.update(gyrodata[0], gyrodata[1], gyrodata[2], acceldata[0], acceldata[1], acceldata[2], mpu9250.Magnetometer[0], mpu9250.Magnetometer[1], mpu9250.Magnetometer[2]); |
Anaesthetix | 8:981f7e2365b6 | 326 | // |
Anaesthetix | 8:981f7e2365b6 | 327 | roll = filter.getRoll(); |
Anaesthetix | 8:981f7e2365b6 | 328 | pitch = filter.getPitch(); |
Anaesthetix | 8:981f7e2365b6 | 329 | |
Anaesthetix | 8:981f7e2365b6 | 330 | angles[3] = gyrodata[1]; |
Anaesthetix | 8:981f7e2365b6 | 331 | angles[4] = gyrodata[0]; |
Anaesthetix | 8:981f7e2365b6 | 332 | angles[5] = gyrodata[2]; |
Anaesthetix | 5:0f4204941604 | 333 | |
Anaesthetix | 8:981f7e2365b6 | 334 | //Simple first order complementary filter -> TODO: CHECK STEP RESPONSE |
Anaesthetix | 8:981f7e2365b6 | 335 | angles[0] = 0.95f*(angles[0] + (gyrodata[1]*time)) + 0.05f*pitch; |
Anaesthetix | 8:981f7e2365b6 | 336 | angles[1] = 0.95f*(angles[1] + (gyrodata[0]*time)) + 0.05f*roll; |
Anaesthetix | 8:981f7e2365b6 | 337 | |
Anaesthetix | 8:981f7e2365b6 | 338 | // angles[0] = pitch; |
Anaesthetix | 8:981f7e2365b6 | 339 | // angles[1] = roll; |
Anaesthetix | 8:981f7e2365b6 | 340 | |
Anaesthetix | 8:981f7e2365b6 | 341 | // If [VAR] is NaN use previous value |
Anaesthetix | 8:981f7e2365b6 | 342 | if(angles[0] != angles[0]) angles[0] = angles_temp[0]; |
Anaesthetix | 8:981f7e2365b6 | 343 | if(angles[1] != angles[1]) angles[1] = angles_temp[1]; |
Anaesthetix | 8:981f7e2365b6 | 344 | if(angles[0] == angles[0]) angles_temp[0] = angles[0]; |
Anaesthetix | 8:981f7e2365b6 | 345 | if(angles[1] == angles[1]) angles_temp[1] = angles[1]; |
Anaesthetix | 8:981f7e2365b6 | 346 | |
Anaesthetix | 8:981f7e2365b6 | 347 | tijd.stop(); |
Anaesthetix | 8:981f7e2365b6 | 348 | tijd.reset(); |
Anaesthetix | 8:981f7e2365b6 | 349 | tijd.start(); |
Anaesthetix | 8:981f7e2365b6 | 350 | |
Anaesthetix | 8:981f7e2365b6 | 351 | /* |
Anaesthetix | 8:981f7e2365b6 | 352 | if(print.read_ms() > 100) { |
Anaesthetix | 8:981f7e2365b6 | 353 | print.stop(); |
Anaesthetix | 8:981f7e2365b6 | 354 | print.reset(); |
Anaesthetix | 8:981f7e2365b6 | 355 | print.start(); |
Anaesthetix | 8:981f7e2365b6 | 356 | //led2 = !led2; |
Anaesthetix | 8:981f7e2365b6 | 357 | // pc.printf("X: %.2f Y: %.2f %.0f\r\n", angles[0], angles[1], samplef); |
Anaesthetix | 8:981f7e2365b6 | 358 | pc.printf("%.2f %.0f\r\n", angles[1], samplef); |
Anaesthetix | 8:981f7e2365b6 | 359 | } |
Anaesthetix | 8:981f7e2365b6 | 360 | */ |
Anaesthetix | 8:981f7e2365b6 | 361 | pc.printf("%.0f %.0f\r\n", pitch, roll); |
Anaesthetix | 8:981f7e2365b6 | 362 | if(rxd) { |
Anaesthetix | 8:981f7e2365b6 | 363 | led2 = !led2; |
Anaesthetix | 8:981f7e2365b6 | 364 | rxd = false; |
Anaesthetix | 8:981f7e2365b6 | 365 | // pc.printf("%d %d %d %d\r\n", rx_data[0], rx_data[1], rx_data[2], rx_data[3]); |
Anaesthetix | 8:981f7e2365b6 | 366 | } |
Anaesthetix | 8:981f7e2365b6 | 367 | |
Anaesthetix | 8:981f7e2365b6 | 368 | // To change VTX channel/band/power with the remote |
Anaesthetix | 8:981f7e2365b6 | 369 | if(rx_data[5] > 1650) ch_sw = 0; |
Anaesthetix | 8:981f7e2365b6 | 370 | else ch_sw = 1; |
Anaesthetix | 8:981f7e2365b6 | 371 | |
Anaesthetix | 8:981f7e2365b6 | 372 | calccomp(rx_data, angles, motor); |
Anaesthetix | 8:981f7e2365b6 | 373 | |
Anaesthetix | 8:981f7e2365b6 | 374 | motor1.pulsewidth_us(motor[0]); |
Anaesthetix | 8:981f7e2365b6 | 375 | motor2.pulsewidth_us(motor[1]); |
Anaesthetix | 8:981f7e2365b6 | 376 | motor3.pulsewidth_us(motor[2]); |
Anaesthetix | 8:981f7e2365b6 | 377 | motor4.pulsewidth_us(motor[3]); |
Anaesthetix | 8:981f7e2365b6 | 378 | /* |
Anaesthetix | 8:981f7e2365b6 | 379 | motor1.pulsewidth_us(rx_data[2]-20); |
Anaesthetix | 8:981f7e2365b6 | 380 | motor2.pulsewidth_us(rx_data[2]-20); |
Anaesthetix | 8:981f7e2365b6 | 381 | motor3.pulsewidth_us(rx_data[2]-20); |
Anaesthetix | 8:981f7e2365b6 | 382 | motor4.pulsewidth_us(rx_data[2]-20); |
Anaesthetix | 8:981f7e2365b6 | 383 | */ |
Anaesthetix | 0:0929d3d566cf | 384 | } |
Anaesthetix | 0:0929d3d566cf | 385 | } |