Rev 1796 | Rev 1854 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1796 | Rev 1821 | ||
---|---|---|---|
Line 92... | Line 92... | ||
92 | /* |
92 | /* |
93 | * Offset values. These are the raw gyro and acc. meter sums when the copter is |
93 | * Offset values. These are the raw gyro and acc. meter sums when the copter is |
94 | * standing still. They are used for adjusting the gyro and acc. meter values |
94 | * standing still. They are used for adjusting the gyro and acc. meter values |
95 | * to be centered on zero. |
95 | * to be centered on zero. |
96 | */ |
96 | */ |
97 | volatile int16_t gyroOffset[3] = { |
- | |
98 | 512 * GYRO_SUMMATION_FACTOR_PITCHROLL, |
97 | volatile int16_t gyroOffset[3] = { 512 * GYRO_SUMMATION_FACTOR_PITCHROLL, 512 |
99 | 512 * GYRO_SUMMATION_FACTOR_PITCHROLL, |
98 | * GYRO_SUMMATION_FACTOR_PITCHROLL, 512 * GYRO_SUMMATION_FACTOR_YAW }; |
100 | 512 * GYRO_SUMMATION_FACTOR_YAW |
- | |
101 | }; |
- | |
Line 102... | Line -... | ||
102 | - | ||
103 | volatile int16_t accOffset[3] = { |
99 | |
104 | 512 * ACC_SUMMATION_FACTOR_PITCHROLL, |
100 | volatile int16_t accOffset[3] = { 512 * ACC_SUMMATION_FACTOR_PITCHROLL, 512 |
105 | 512 * ACC_SUMMATION_FACTOR_PITCHROLL, |
- | |
106 | 512 * ACC_SUMMATION_FACTOR_Z |
- | |
Line 107... | Line 101... | ||
107 | }; |
101 | * ACC_SUMMATION_FACTOR_PITCHROLL, 512 * ACC_SUMMATION_FACTOR_Z }; |
108 | 102 | ||
109 | /* |
103 | /* |
110 | * This allows some experimentation with the gyro filters. |
104 | * This allows some experimentation with the gyro filters. |
Line 174... | Line 168... | ||
174 | * re-enabling ADC, the real limit is (how much?) lower. |
168 | * re-enabling ADC, the real limit is (how much?) lower. |
175 | * The acc. sensor is sampled even if not used - or installed |
169 | * The acc. sensor is sampled even if not used - or installed |
176 | * at all. The cost is not significant. |
170 | * at all. The cost is not significant. |
177 | */ |
171 | */ |
Line 178... | Line 172... | ||
178 | 172 | ||
179 | const uint8_t channelsForStates[] PROGMEM = { |
- | |
180 | AD_GYRO_PITCH, |
- | |
181 | AD_GYRO_ROLL, |
173 | const uint8_t channelsForStates[] PROGMEM = { AD_GYRO_PITCH, AD_GYRO_ROLL, |
Line 182... | Line -... | ||
182 | AD_GYRO_YAW, |
- | |
183 | - | ||
184 | AD_ACC_PITCH, |
174 | AD_GYRO_YAW, |
185 | AD_ACC_ROLL, |
175 | |
186 | AD_AIRPRESSURE, |
- | |
187 | - | ||
188 | AD_GYRO_PITCH, |
176 | AD_ACC_PITCH, AD_ACC_ROLL, AD_AIRPRESSURE, |
189 | AD_GYRO_ROLL, |
177 | |
190 | AD_ACC_Z, // at 8, measure Z acc. |
- | |
191 | - | ||
192 | AD_GYRO_PITCH, |
178 | AD_GYRO_PITCH, AD_GYRO_ROLL, AD_ACC_Z, // at 8, measure Z acc. |
Line 193... | Line 179... | ||
193 | AD_GYRO_ROLL, |
179 | |
194 | AD_GYRO_YAW, // at 11, finish yaw gyro |
180 | AD_GYRO_PITCH, AD_GYRO_ROLL, AD_GYRO_YAW, // at 11, finish yaw gyro |
195 | 181 | ||
Line 220... | Line 206... | ||
220 | ADMUX &= ~((1 << REFS1)|(1 << REFS0)|(1 << ADLAR)); |
206 | ADMUX &= ~((1 << REFS1) | (1 << REFS0) | (1 << ADLAR)); |
221 | // set muxer to ADC adc_channel 0 (0 to 7 is a valid choice) |
207 | // set muxer to ADC adc_channel 0 (0 to 7 is a valid choice) |
222 | ADMUX = (ADMUX & 0xE0) | AD_GYRO_PITCH; |
208 | ADMUX = (ADMUX & 0xE0) | AD_GYRO_PITCH; |
223 | //Set ADC Control and Status Register A |
209 | //Set ADC Control and Status Register A |
224 | //Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz |
210 | //Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz |
225 | ADCSRA = (0<<ADEN)|(0<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(0<<ADIE); |
211 | ADCSRA = (0 << ADEN) | (0 << ADSC) | (0 << ADATE) | (1 << ADPS2) | (1 |
- | 212 | << ADPS1) | (1 << ADPS0) | (0 << ADIE); |
|
226 | //Set ADC Control and Status Register B |
213 | //Set ADC Control and Status Register B |
227 | //Trigger Source to Free Running Mode |
214 | //Trigger Source to Free Running Mode |
228 | ADCSRB &= ~((1 << ADTS2)|(1 << ADTS1)|(1 << ADTS0)); |
215 | ADCSRB &= ~((1 << ADTS2) | (1 << ADTS1) | (1 << ADTS0)); |
229 | // Start AD conversion |
216 | // Start AD conversion |
230 | analog_start(); |
217 | analog_start(); |
231 | // restore global interrupt flags |
218 | // restore global interrupt flags |
232 | SREG = sreg; |
219 | SREG = sreg; |
233 | } |
220 | } |
Line -... | Line 221... | ||
- | 221 | ||
234 | 222 | void measureNoise(const int16_t sensor, |
|
235 | void measureNoise(const int16_t sensor, volatile uint16_t* const noiseMeasurement, const uint8_t damping) { |
223 | volatile uint16_t* const noiseMeasurement, const uint8_t damping) { |
236 | if (sensor > (int16_t)(*noiseMeasurement)) { |
224 | if (sensor > (int16_t) (*noiseMeasurement)) { |
237 | *noiseMeasurement = sensor; |
225 | *noiseMeasurement = sensor; |
238 | } else if (-sensor > (int16_t)(*noiseMeasurement)) { |
226 | } else if (-sensor > (int16_t) (*noiseMeasurement)) { |
239 | *noiseMeasurement = -sensor; |
227 | *noiseMeasurement = -sensor; |
Line 256... | Line 244... | ||
256 | * Interrupt Service Routine for ADC |
244 | * Interrupt Service Routine for ADC |
257 | * Runs at 312.5 kHz or 3.2 µs. When all states are |
245 | * Runs at 312.5 kHz or 3.2 µs. When all states are |
258 | * processed the interrupt is disabled and further |
246 | * processed the interrupt is disabled and further |
259 | * AD conversions are stopped. |
247 | * AD conversions are stopped. |
260 | *****************************************************/ |
248 | *****************************************************/ |
261 | ISR(ADC_vect) { |
249 | ISR(ADC_vect) |
- | 250 | { |
|
262 | static uint8_t ad_channel = AD_GYRO_PITCH, state = 0; |
251 | static uint8_t ad_channel = AD_GYRO_PITCH, state = 0; |
263 | static uint16_t sensorInputs[8] = {0,0,0,0,0,0,0,0}; |
252 | static uint16_t sensorInputs[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
264 | static uint16_t pressureAutorangingWait = 25; |
253 | static uint16_t pressureAutorangingWait = 25; |
265 | uint16_t rawAirPressure; |
254 | uint16_t rawAirPressure; |
266 | uint8_t i, axis; |
255 | uint8_t i, axis; |
Line 296... | Line 285... | ||
296 | if (ACC_REVERSED[PITCH]) |
285 | if (ACC_REVERSED[PITCH]) |
297 | acc[PITCH] = accOffset[PITCH] - sensorInputs[AD_ACC_PITCH]; |
286 | acc[PITCH] = accOffset[PITCH] - sensorInputs[AD_ACC_PITCH]; |
298 | else |
287 | else |
299 | acc[PITCH] = sensorInputs[AD_ACC_PITCH] - accOffset[PITCH]; |
288 | acc[PITCH] = sensorInputs[AD_ACC_PITCH] - accOffset[PITCH]; |
Line 300... | Line 289... | ||
300 | 289 | ||
- | 290 | filteredAcc[PITCH] = (filteredAcc[PITCH] * (ACC_FILTER - 1) + acc[PITCH]) |
|
301 | filteredAcc[PITCH] = (filteredAcc[PITCH] * (ACC_FILTER-1) + acc[PITCH]) / ACC_FILTER; |
291 | / ACC_FILTER; |
302 | measureNoise(acc[PITCH], &accNoisePeak[PITCH], 1); |
292 | measureNoise(acc[PITCH], &accNoisePeak[PITCH], 1); |
Line 303... | Line 293... | ||
303 | break; |
293 | break; |
304 | 294 | ||
305 | case 13: // roll axis acc. |
295 | case 13: // roll axis acc. |
306 | if (ACC_REVERSED[ROLL]) |
296 | if (ACC_REVERSED[ROLL]) |
307 | acc[ROLL] = accOffset[ROLL] - sensorInputs[AD_ACC_ROLL]; |
297 | acc[ROLL] = accOffset[ROLL] - sensorInputs[AD_ACC_ROLL]; |
308 | else |
298 | else |
- | 299 | acc[ROLL] = sensorInputs[AD_ACC_ROLL] - accOffset[ROLL]; |
|
309 | acc[ROLL] = sensorInputs[AD_ACC_ROLL] - accOffset[ROLL]; |
300 | filteredAcc[ROLL] = (filteredAcc[ROLL] * (ACC_FILTER - 1) + acc[ROLL]) |
310 | filteredAcc[ROLL] = (filteredAcc[ROLL] * (ACC_FILTER-1) + acc[ROLL]) / ACC_FILTER; |
301 | / ACC_FILTER; |
Line 311... | Line 302... | ||
311 | measureNoise(acc[ROLL], &accNoisePeak[ROLL], 1); |
302 | measureNoise(acc[ROLL], &accNoisePeak[ROLL], 1); |
312 | break; |
303 | break; |
Line 354... | Line 345... | ||
354 | DebugOut.Analog[31] = simpleAirPressure; |
345 | DebugOut.Analog[31] = simpleAirPressure; |
Line 355... | Line 346... | ||
355 | 346 | ||
356 | if (simpleAirPressure < MIN_RANGES_EXTRAPOLATION * rangewidth) { |
347 | if (simpleAirPressure < MIN_RANGES_EXTRAPOLATION * rangewidth) { |
357 | // Danger: pressure near lower end of range. If the measurement saturates, the |
348 | // Danger: pressure near lower end of range. If the measurement saturates, the |
358 | // copter may climb uncontrolledly... Simulate a drastic reduction in pressure. |
349 | // copter may climb uncontrolledly... Simulate a drastic reduction in pressure. |
- | 350 | airPressureSum += (int16_t) MIN_RANGES_EXTRAPOLATION * rangewidth |
|
- | 351 | + (simpleAirPressure - (int16_t) MIN_RANGES_EXTRAPOLATION |
|
359 | airPressureSum += (int16_t)MIN_RANGES_EXTRAPOLATION * rangewidth + (simpleAirPressure - (int16_t)MIN_RANGES_EXTRAPOLATION * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF; |
352 | * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF; |
360 | } else if (simpleAirPressure > MAX_RANGES_EXTRAPOLATION * rangewidth) { |
353 | } else if (simpleAirPressure > MAX_RANGES_EXTRAPOLATION * rangewidth) { |
361 | // Danger: pressure near upper end of range. If the measurement saturates, the |
354 | // Danger: pressure near upper end of range. If the measurement saturates, the |
362 | // copter may descend uncontrolledly... Simulate a drastic increase in pressure. |
355 | // copter may descend uncontrolledly... Simulate a drastic increase in pressure. |
- | 356 | airPressureSum += (int16_t) MAX_RANGES_EXTRAPOLATION * rangewidth |
|
- | 357 | + (simpleAirPressure - (int16_t) MAX_RANGES_EXTRAPOLATION |
|
363 | airPressureSum += (int16_t)MAX_RANGES_EXTRAPOLATION * rangewidth + (simpleAirPressure - (int16_t)MAX_RANGES_EXTRAPOLATION * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF; |
358 | * rangewidth) * PRESSURE_EXTRAPOLATION_COEFF; |
364 | } else { |
359 | } else { |
365 | // normal case. |
360 | // normal case. |
366 | // If AIRPRESSURE_SUMMATION_FACTOR is an odd number we only want to add half the double sample. |
361 | // If AIRPRESSURE_SUMMATION_FACTOR is an odd number we only want to add half the double sample. |
367 | // The 2 cases above (end of range) are ignored for this. |
362 | // The 2 cases above (end of range) are ignored for this. |
Line 372... | Line 367... | ||
372 | } |
367 | } |
Line 373... | Line 368... | ||
373 | 368 | ||
374 | // 2 samples were added. |
369 | // 2 samples were added. |
375 | pressureMeasurementCount += 2; |
370 | pressureMeasurementCount += 2; |
376 | if (pressureMeasurementCount >= AIRPRESSURE_SUMMATION_FACTOR) { |
371 | if (pressureMeasurementCount >= AIRPRESSURE_SUMMATION_FACTOR) { |
- | 372 | filteredAirPressure = (filteredAirPressure * (AIRPRESSURE_FILTER - 1) |
|
377 | filteredAirPressure = (filteredAirPressure * (AIRPRESSURE_FILTER-1) + airPressureSum + AIRPRESSURE_FILTER/2) / AIRPRESSURE_FILTER; |
373 | + airPressureSum + AIRPRESSURE_FILTER / 2) / AIRPRESSURE_FILTER; |
378 | pressureMeasurementCount = airPressureSum = 0; |
374 | pressureMeasurementCount = airPressureSum = 0; |
Line 379... | Line 375... | ||
379 | } |
375 | } |
Line 392... | Line 388... | ||
392 | // gyro with a wider range, and helps counter saturation at full control. |
388 | // gyro with a wider range, and helps counter saturation at full control. |
Line 393... | Line 389... | ||
393 | 389 | ||
394 | if (staticParams.GlobalConfig & CFG_ROTARY_RATE_LIMITER) { |
390 | if (staticParams.GlobalConfig & CFG_ROTARY_RATE_LIMITER) { |
395 | if (tempGyro < SENSOR_MIN_PITCHROLL) { |
391 | if (tempGyro < SENSOR_MIN_PITCHROLL) { |
396 | tempGyro = tempGyro * EXTRAPOLATION_SLOPE - EXTRAPOLATION_LIMIT; |
- | |
397 | } |
392 | tempGyro = tempGyro * EXTRAPOLATION_SLOPE - EXTRAPOLATION_LIMIT; |
398 | else if (tempGyro > SENSOR_MAX_PITCHROLL) { |
393 | } else if (tempGyro > SENSOR_MAX_PITCHROLL) { |
- | 394 | tempGyro = (tempGyro - SENSOR_MAX_PITCHROLL) * EXTRAPOLATION_SLOPE |
|
399 | tempGyro = (tempGyro - SENSOR_MAX_PITCHROLL) * EXTRAPOLATION_SLOPE + SENSOR_MAX_PITCHROLL; |
395 | + SENSOR_MAX_PITCHROLL; |
400 | } |
396 | } |
Line 401... | Line 397... | ||
401 | } |
397 | } |
402 | 398 | ||
Line 406... | Line 402... | ||
406 | } else { |
402 | } else { |
407 | tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL; |
403 | tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL; |
408 | } |
404 | } |
Line 409... | Line 405... | ||
409 | 405 | ||
410 | // 3) Scale and filter. |
406 | // 3) Scale and filter. |
- | 407 | tempOffsetGyro = (gyro_PID[axis] * (GYROS_PID_FILTER - 1) + tempOffsetGyro) |
|
Line 411... | Line 408... | ||
411 | tempOffsetGyro = (gyro_PID[axis] * (GYROS_PID_FILTER-1) + tempOffsetGyro) / GYROS_PID_FILTER; |
408 | / GYROS_PID_FILTER; |
412 | 409 | ||
- | 410 | // 4) Measure noise. |
|
Line 413... | Line 411... | ||
413 | // 4) Measure noise. |
411 | measureNoise(tempOffsetGyro, &gyroNoisePeak[axis], |
414 | measureNoise(tempOffsetGyro, &gyroNoisePeak[axis], GYRO_NOISE_MEASUREMENT_DAMPING); |
412 | GYRO_NOISE_MEASUREMENT_DAMPING); |
- | 413 | ||
Line 415... | Line 414... | ||
415 | 414 | // 5) Differential measurement. |
|
416 | // 5) Differential measurement. |
415 | gyroD[axis] = (gyroD[axis] * (GYROS_D_FILTER - 1) + (tempOffsetGyro |
Line 417... | Line 416... | ||
417 | gyroD[axis] = (gyroD[axis] * (GYROS_D_FILTER-1) + (tempOffsetGyro - gyro_PID[axis])) / GYROS_D_FILTER; |
416 | - gyro_PID[axis])) / GYROS_D_FILTER; |
Line 430... | Line 429... | ||
430 | } else { |
429 | } else { |
431 | tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL; |
430 | tempOffsetGyro = (tempGyro - gyroOffset[axis]) * GYRO_FACTOR_PITCHROLL; |
432 | } |
431 | } |
Line 433... | Line 432... | ||
433 | 432 | ||
434 | // 2) Filter. |
433 | // 2) Filter. |
- | 434 | gyro_ATT[axis] = (gyro_ATT[axis] * (GYROS_ATT_FILTER - 1) + tempOffsetGyro) |
|
435 | gyro_ATT[axis] = (gyro_ATT[axis] * (GYROS_ATT_FILTER-1) + tempOffsetGyro) / GYROS_ATT_FILTER; |
435 | / GYROS_ATT_FILTER; |
Line 436... | Line 436... | ||
436 | break; |
436 | break; |
437 | 437 | ||
438 | case 17: |
438 | case 17: |
Line 446... | Line 446... | ||
446 | state = 0; |
446 | state = 0; |
447 | for (i=0; i<8; i++) { |
447 | for (i = 0; i < 8; i++) { |
448 | sensorInputs[i] = 0; |
448 | sensorInputs[i] = 0; |
449 | } |
449 | } |
450 | break; |
450 | break; |
- | 451 | default: { |
|
451 | default: {} // do nothing. |
452 | } // do nothing. |
452 | } |
453 | } |
Line 453... | Line 454... | ||
453 | 454 | ||
454 | // set up for next state. |
455 | // set up for next state. |
455 | ad_channel = pgm_read_byte(&channelsForStates[state]); |
456 | ad_channel = pgm_read_byte(&channelsForStates[state]); |
Line 456... | Line 457... | ||
456 | // ad_channel = channelsForStates[state]; |
457 | // ad_channel = channelsForStates[state]; |
457 | 458 | ||
458 | // set adc muxer to next ad_channel |
459 | // set adc muxer to next ad_channel |
- | 460 | ADMUX = (ADMUX & 0xE0) | ad_channel; |
|
459 | ADMUX = (ADMUX & 0xE0) | ad_channel; |
461 | // after full cycle stop further interrupts |
460 | // after full cycle stop further interrupts |
462 | if (state) |
Line 461... | Line 463... | ||
461 | if(state) analog_start(); |
463 | analog_start(); |
462 | } |
464 | } |
463 | 465 | ||
Line 481... | Line 483... | ||
481 | deltaOffsets[axis] += rawGyroSum[axis]; |
483 | deltaOffsets[axis] += rawGyroSum[axis]; |
482 | } |
484 | } |
483 | } |
485 | } |
Line 484... | Line 486... | ||
484 | 486 | ||
485 | for (axis=PITCH; axis<=YAW; axis++) { |
487 | for (axis = PITCH; axis <= YAW; axis++) { |
- | 488 | gyroOffset[axis] = (deltaOffsets[axis] + GYRO_OFFSET_CYCLES / 2) |
|
486 | gyroOffset[axis] = (deltaOffsets[axis] + GYRO_OFFSET_CYCLES/2) / GYRO_OFFSET_CYCLES; |
489 | / GYRO_OFFSET_CYCLES; |
487 | DebugOut.Analog[20+axis] = gyroOffset[axis]; |
490 | DebugOut.Analog[20 + axis] = gyroOffset[axis]; |
Line 488... | Line 491... | ||
488 | } |
491 | } |
489 | 492 | ||
Line 521... | Line 524... | ||
521 | deltaOffset[axis] += acc[axis]; |
524 | deltaOffset[axis] += acc[axis]; |
522 | } |
525 | } |
523 | } |
526 | } |
Line 524... | Line 527... | ||
524 | 527 | ||
525 | for (axis=PITCH; axis<=YAW; axis++) { |
528 | for (axis = PITCH; axis <= YAW; axis++) { |
- | 529 | filteredDelta = (deltaOffset[axis] + ACC_OFFSET_CYCLES / 2) |
|
526 | filteredDelta = (deltaOffset[axis] + ACC_OFFSET_CYCLES / 2) / ACC_OFFSET_CYCLES; |
530 | / ACC_OFFSET_CYCLES; |
527 | accOffset[axis] += ACC_REVERSED[axis] ? -filteredDelta : filteredDelta; |
531 | accOffset[axis] += ACC_REVERSED[axis] ? -filteredDelta : filteredDelta; |
Line 528... | Line 532... | ||
528 | } |
532 | } |
529 | 533 |