Subversion Repositories FlightCtrl

Rev

Rev 2023 | Rev 2099 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2023 Rev 2096
Line 1... Line 1...
1
#ifndef _ANALOG_H
1
#ifndef _ANALOG_H
2
#define _ANALOG_H
2
#define _ANALOG_H
3
#include <inttypes.h>
3
#include <inttypes.h>
4
 
-
 
5
//#include "invenSense.h"
4
#include "configuration.h"
6
//#include "ENC-03_FC1.3.h"
-
 
7
//#include "ADXRS610_FC2.0.h"
-
 
Line 8... Line 5...
8
 
5
 
9
/*
6
/*
10
 About setting constants for different gyros:
7
 About setting constants for different gyros:
11
 Main parameters are positive directions and voltage/angular speed gain.
8
 Main parameters are positive directions and voltage/angular speed gain.
Line 14... Line 11...
14
 A gyro is considered, in this code, to be "forward" if its positive
11
 A gyro is considered, in this code, to be "forward" if its positive
15
 direction is:
12
 direction is:
16
 - Nose down for pitch
13
 - Nose down for pitch
17
 - Left hand side down for roll
14
 - Left hand side down for roll
18
 - Clockwise seen from above for yaw.
15
 - Clockwise seen from above for yaw.
19
 
16
 
20
 Setting gyro gain correctly: All sensor measurements in analog.c take
17
 Setting gyro gain correctly: All sensor measurements in analog.c take
21
 place in a cycle, each cycle comprising all sensors. Some sensors are
18
 place in a cycle, each cycle comprising all sensors. Some sensors are
22
 sampled more than ones, and the results added. The pitch and roll gyros
19
 sampled more than once (oversampled), and the results added.
23
 are sampled 4 times and the yaw gyro 2 times in the original H&I V0.74
-
 
24
 code.
-
 
25
 In the H&I code, the results for pitch and roll are multiplied by 2 (FC1.0)
20
 In the H&I code, the results for pitch and roll are multiplied by 2 (FC1.0)
26
 or 4 (other versions), offset to zero, low pass filtered and then assigned
21
 or 4 (other versions), offset to zero, low pass filtered and then assigned
27
 to the "HiResXXXX" and "AdWertXXXXFilter" variables, where XXXX is nick or
22
 to the "HiResXXXX" and "AdWertXXXXFilter" variables, where XXXX is nick or
28
 roll.
-
 
29
 So:
-
 
30
 
-
 
31
 gyro = V * (ADCValue1 + ADCValue2 + ADCValue3 + ADCValue4),
23
 roll. The factor 2 or 4 or whatever is called GYRO_FACTOR_PITCHROLL here.
32
 where V is 2 for FC1.0 and 4 for all others.
-
 
33
 
24
*/
34
 Assuming constant ADCValue, in the H&I code:
25
#define GYRO_FACTOR_PITCHROLL 1
35
 
-
 
36
 gyro = I * ADCValue.
-
 
37
 
-
 
38
 where I is 8 for FC1.0 and 16 for all others.
-
 
Line -... Line 26...
-
 
26
 
39
 
27
/*
40
 The relation between rotation rate and ADCValue:
28
 GYRO_HW_FACTOR is the relation between rotation rate and ADCValue:
41
 ADCValue [units] =
29
 ADCValue [units] =
42
 rotational speed [deg/s] *
30
 rotational speed [deg/s] *
43
 gyro sensitivity [V / deg/s] *
31
 gyro sensitivity [V / deg/s] *
44
 amplifier gain [units] *
32
 amplifier gain [units] *
45
 1024 [units] /
33
 1024 [units] /
Line 46... Line -...
46
 3V full range [V]
-
 
47
 
34
 3V full range [V]
48
 or: H is the number of steps the ADC value changes with,
-
 
49
 for a 1 deg/s change in rotational velocity:
35
 
50
 H = ADCValue [units] / rotation rate [deg/s] =
36
 GYRO_HW_FACTOR is:
51
 gyro sensitivity [V / deg/s] *
37
 gyro sensitivity [V / deg/s] *
52
 amplifier gain [units] *
38
 amplifier gain [units] *
Line 53... Line 39...
53
 1024 [units] /
39
 1024 [units] /
54
 3V full range [V]
40
 3V full range [V]
55
 
41
 
-
 
42
 Examples:
56
 Examples:
43
 FC1.3 has 0.67 mV/deg/s gyros and amplifiers with a gain of 5.7:
57
 FC1.3 has 0.67 mV/deg/s gyros and amplifiers with a gain of 5.7:
44
 GYRO_HW_FACTOR = 0.00067 V / deg / s * 5.7 * 1024 / 3V = 1.304 units/(deg/s).
-
 
45
 
58
 H = 0.00067 V / deg / s * 5.7 * 1024 / 3V = 1.304 units/(deg/s).
46
 FC2.0 has 6*(3/5) mV/deg/s gyros (they are ratiometric) and no amplifiers:
59
 FC2.0 has 6*(3/5) mV/deg/s gyros (they are ratiometric) and no amplifiers:
47
 GYRO_HW_FACTOR = 0.006 V / deg / s * 1 * 1024 * 3V / (3V * 5V) = 1.2288 units/(deg/s).
60
 H = 0.006 V / deg / s * 1 * 1024 * 3V / (3V * 5V) = 1.2288 units/(deg/s).
48
 
61
 My InvenSense copter has 2mV/deg/s gyros and no amplifiers:
49
 My InvenSense copter has 2mV/deg/s gyros and no amplifiers:
Line 62... Line 50...
62
 H = 0.002 V / deg / s * 1 * 1024 / 3V = 0.6827 units/(deg/s)
50
 GYRO_HW_FACTOR = 0.002 V / deg / s * 1 * 1024 / 3V = 0.6827 units/(deg/s)
63
 (only about half as sensitive as V1.3. But it will take about twice the
51
 (only about half as sensitive as V1.3. But it will take about twice the
Line 64... Line 52...
64
 rotation rate!)
52
 rotation rate!)
65
 
-
 
66
 All together: gyro = I * H * rotation rate [units / (deg/s)].
-
 
67
 */
-
 
68
 
-
 
69
/*
-
 
70
 * A factor that the raw gyro values are multiplied by,
-
 
71
 * before being filtered and passed to the attitude module.
-
 
72
 * A value of 1 would cause a little bit of loss of precision in the
-
 
73
 * filtering (on the other hand the values are so noisy in flight that
-
 
74
 * it will not really matter - but when testing on the desk it might be
-
 
75
 * noticeable). 4 is fine for the default filtering.
-
 
76
 * Experiment: Set it to 1.
53
 
77
 */
54
 GYRO_HW_FACTOR is given in the makefile.
78
#define GYRO_FACTOR_PITCHROLL 1
55
*/
79
 
56
 
80
/*
57
/*
81
 * How many samples are summed in one ADC loop, for pitch&roll and yaw,
58
 * How many samples are added in one ADC loop, for pitch&roll and yaw,
Line 82... Line 59...
82
 * respectively. This is = the number of occurences of each channel in the
59
 * respectively. This is = the number of occurences of each channel in the
83
 * channelsForStates array in analog.c.
60
 * channelsForStates array in analog.c.
Line 84... Line 61...
84
 */
61
 */
85
#define GYRO_SUMMATION_FACTOR_PITCHROLL 4
-
 
86
#define GYRO_SUMMATION_FACTOR_YAW 2
-
 
87
 
-
 
88
#define ACC_SUMMATION_FACTOR_PITCHROLL 2
-
 
89
#define ACC_SUMMATION_FACTOR_Z 1
-
 
90
 
-
 
91
/*
62
#define GYRO_OVERSAMPLING_PITCHROLL 4
92
 Integration:
-
 
93
 The HiResXXXX values are divided by 8 (in H&I firmware) before integration.
-
 
94
 In the Killagreg rewrite of the H&I firmware, the factor 8 is called
-
 
95
 HIRES_GYRO_AMPLIFY. In this code, it is called HIRES_GYRO_INTEGRATION_FACTOR,
-
 
96
 and care has been taken that all other constants (gyro to degree factor, and
-
 
97
 180 degree flip-over detection limits) are corrected to it. Because the
-
 
98
 division by the constant takes place in the flight attitude code, the
-
 
99
 constant is there.
-
 
100
 
-
 
101
 The control loop executes every 2ms, and for each iteration
-
 
102
 gyro_ATT[PITCH/ROLL] is added to gyroIntegral[PITCH/ROLL].
-
 
103
 Assuming a constant rotation rate v and a zero initial gyroIntegral
-
 
104
 (for this explanation), we get:
-
 
105
 
-
 
106
 gyroIntegral =
-
 
107
 N * gyro / HIRES_GYRO_INTEGRATION_FACTOR =
-
 
108
 N * I * H * v / HIRES_GYRO_INTEGRATION_FACTOR
-
 
109
 
-
 
110
 where N is the number of summations; N = t/2ms.
-
 
111
 
-
 
112
 For one degree of rotation: t*v = 1:
-
 
113
 
-
 
114
 gyroIntegralXXXX = t/2ms * I * H * 1/t = INTEGRATION_FREQUENCY * I * H / HIRES_GYRO_INTEGRATION_FACTOR.
-
 
115
 
63
#define GYRO_OVERSAMPLING_YAW 2
-
 
64
 
-
 
65
#define ACC_OVERSAMPLING_XY 2
Line 116... Line 66...
116
 This number (INTEGRATION_FREQUENCY * I * H) is the integral-to-degree factor.
66
#define ACC_OVERSAMPLING_Z 1
117
 
67
 
118
 Examples:
68
/*
119
 FC1.3: I=2, H=1.304, HIRES_GYRO_INTEGRATION_FACTOR=8 --> integralDegreeFactor = 1304
69
 * The product of the 3 above constants. This represents the expected change in ADC value sums for 1 deg/s of rotation rate.
120
 FC2.0: I=2, H=2.048, HIRES_GYRO_INTEGRATION_FACTOR=13 --> integralDegreeFactor = 1260
-
 
121
 My InvenSense copter: HIRES_GYRO_INTEGRATION_FACTOR=4, H=0.6827 --> integralDegreeFactor = 1365
-
 
Line 122... Line 70...
122
 */
70
 */
123
 
71
#define GYRO_RATE_FACTOR_PITCHROLL (GYRO_HW_FACTOR * GYRO_OVERSAMPLING_PITCHROLL * GYRO_FACTOR_PITCHROLL)
124
/*
72
#define GYRO_RATE_FACTOR_YAW (GYRO_HW_FACTOR * GYRO_OVERSAMPLING_YAW)
125
 * The value of gyro[PITCH/ROLL] for one deg/s = The hardware factor H * the number of samples * multiplier factor.
73
 
126
 * Will be about 10 or so for InvenSense, and about 33 for ADXRS610.
74
/*
127
 */
75
 * The value of gyro[PITCH/ROLL] for one deg/s = The hardware factor H * the number of samples * multiplier factor.
128
#define GYRO_RATE_FACTOR_PITCHROLL (GYRO_HW_FACTOR * GYRO_SUMMATION_FACTOR_PITCHROLL * GYRO_FACTOR_PITCHROLL)
76
 * Will be about 10 or so for InvenSense, and about 33 for ADXRS610.
129
#define GYRO_RATE_FACTOR_YAW (GYRO_HW_FACTOR * GYRO_SUMMATION_FACTOR_YAW)
77
 */
130
 
78
 
131
/*
79
/*
132
 * Gyro saturation prevention.
80
 * Gyro saturation prevention.
Line 157... Line 105...
157
 * integration to angles. For the same axis, the PID and ATT variables
105
 * integration to angles. For the same axis, the PID and ATT variables
158
 * generally have about the same values. There are just some differences
106
 * generally have about the same values. There are just some differences
159
 * in filtering, and when a gyro becomes near saturated.
107
 * in filtering, and when a gyro becomes near saturated.
160
 * Maybe this distinction is not really necessary.
108
 * Maybe this distinction is not really necessary.
161
 */
109
 */
162
extern volatile int16_t gyro_PID[2];
110
extern int16_t gyro_PID[2];
163
extern volatile int16_t gyro_ATT[2];
111
extern int16_t gyro_ATT[2];
164
extern volatile int16_t gyroD[3];
112
#define GYRO_D_WINDOW_LENGTH 8
165
extern volatile int16_t yawGyro;
113
extern int16_t gyroD[3];
166
extern volatile uint16_t ADCycleCount;
114
extern int16_t yawGyro;
167
extern volatile int16_t UBat;
115
extern int16_t UBat;
Line 168... Line 116...
168
 
116
 
169
// 1:11 voltage divider, 1024 counts per 3V, and result is divided by 3.
117
// 1:11 voltage divider, 1024 counts per 3V, and result is divided by 3.
Line -... Line 118...
-
 
118
#define UBAT_AT_5V (int16_t)((5.0 * (1.0/11.0)) * 1024 / (3.0 * 3))
-
 
119
 
-
 
120
extern sensorOffset_t gyroOffset;
-
 
121
extern sensorOffset_t accOffset;
170
#define UBAT_AT_5V (int16_t)((5.0 * (1.0/11.0)) * 1024 / (3.0 * 3))
122
extern sensorOffset_t gyroAmplifierOffset;
171
 
123
 
172
/*
124
/*
173
 * This is not really for external use - but the ENC-03 gyro modules needs it.
125
 * This is not really for external use - but the ENC-03 gyro modules needs it.
Line 174... Line 126...
174
 */
126
 */
175
extern volatile int16_t rawGyroSum[3];
127
//extern volatile int16_t rawGyroSum[3];
176
 
128
 
177
/*
129
/*
178
 * The acceleration values that this module outputs. They are zero based.
130
 * The acceleration values that this module outputs. They are zero based.
179
 */
131
 */
Line 180... Line 132...
180
extern volatile int16_t acc[3];
132
extern int16_t acc[3];
181
extern volatile int16_t filteredAcc[2];
133
extern int16_t filteredAcc[3];
182
// extern volatile int32_t stronglyFilteredAcc[3];
134
// extern volatile int32_t stronglyFilteredAcc[3];
183
 
135
 
184
/*
136
/*
185
 * Diagnostics: Gyro noise level because of motor vibrations. The variables
137
 * Diagnostics: Gyro noise level because of motor vibrations. The variables
186
 * only really reflect the noise level when the copter stands still but with
138
 * only really reflect the noise level when the copter stands still but with
Line 187... Line 139...
187
 * its motors running.
139
 * its motors running.
188
 */
140
 */
189
extern volatile uint16_t gyroNoisePeak[2];
141
extern uint16_t gyroNoisePeak[3];
190
extern volatile uint16_t accNoisePeak[2];
142
extern uint16_t accNoisePeak[3];
-
 
143
 
-
 
144
/*
-
 
145
 * Air pressure.
191
 
146
 * The sensor has a sensitivity of 45 mV/kPa.
192
/*
147
 * An approximate p(h) formula is = p(h[m])[kPa] = p_0 - 11.95 * 10^-3 * h
-
 
148
 * p(h[m])[kPa] = 101.3 - 11.95 * 10^-3 * h
-
 
149
 * 11.95 * 10^-3 * h = 101.3 - p[kPa]
-
 
150
 * h = (101.3 - p[kPa])/0.01195
-
 
151
 * That is: dV = -45 mV * 11.95 * 10^-3 dh = -0.53775 mV / m.
-
 
152
 * That is, with 38.02 * 1.024 / 3 steps per mV: -7 steps / m
-
 
153
 
-
 
154
Display pressures
-
 
155
4165 mV-->1084.7
-
 
156
4090 mV-->1602.4   517.7
-
 
157
3877 mV-->3107.8  1503.4
-
 
158
 
-
 
159
4165 mV-->1419.1
-
 
160
3503 mV-->208.1
-
 
161
Diff.:   1211.0
-
 
162
 
-
 
163
Calculated  Vout = 5V(.009P-0.095) --> 5V .009P = Vout + 5V 0.095 --> P = (Vout + 5V 0.095)/(5V 0.009)
-
 
164
4165 mV = 5V(0.009P-0.095)  P = 103.11 kPa  h = -151.4m
-
 
165
4090 mV = 5V(0.009P-0.095)  P = 101.44 kPa  h = -11.7m   139.7m
-
 
166
3877 mV = 5V(0.009P-0.095)  P = 96.7   kPa  h = 385m     396.7m
193
 * Air pressure.
167
 
-
 
168
4165 mV = 5V(0.009P-0.095)  P = 103.11 kPa  h = -151.4m
194
 * The sensor has a sensitivity of 46 mV/kPa.
169
3503 mV = 5V(0.009P-0.095)  P = 88.4   kPa  h = 384m  Diff: 1079.5m
195
 * An approximate p(h) formula is = p(h[m])[Pa] = p_0 - 11.95 * 10^-3 * h
170
Pressure at sea level: 101.3 kPa. voltage: 5V * (0.009P-0.095) = 4.0835V
196
 * That is: dV = 46 mV * 11.95 * 10^-3 dh = 0.5497 mV / m.
171
This is OCR2 = 143.15 at 1.5V in --> simple pressure =
197
 * That is, with 2 * 1.024 / 3 steps per mV: 0.037 steps / m
172
*/
198
 */
173
 
199
#define AIRPRESSURE_SUMMATION_FACTOR 16
174
#define AIRPRESSURE_OVERSAMPLING 14
Line 207... Line 182...
207
#define MAX_RANGES_EXTRAPOLATION 240
182
#define MAX_RANGES_EXTRAPOLATION 240
Line 208... Line 183...
208
 
183
 
209
#define PRESSURE_EXTRAPOLATION_COEFF 25L
184
#define PRESSURE_EXTRAPOLATION_COEFF 25L
Line -... Line 185...
-
 
185
#define AUTORANGE_WAIT_FACTOR 1
-
 
186
 
210
#define AUTORANGE_WAIT_FACTOR 1
187
#define ABS_ALTITUDE_OFFSET 108205
211
 
188
 
212
extern volatile uint16_t simpleAirPressure;
189
extern uint16_t simpleAirPressure;
213
/*
190
/*
214
 * At saturation, the filteredAirPressure may actually be (simulated) negative.
191
 * At saturation, the filteredAirPressure may actually be (simulated) negative.
-
 
192
 */
-
 
193
extern int32_t filteredAirPressure;
-
 
194
 
-
 
195
extern int16_t magneticHeading;
Line 215... Line 196...
215
 */
196
 
216
extern volatile int32_t filteredAirPressure;
197
extern uint32_t gyroActivity;
217
 
198
 
218
/*
199
/*
Line -... Line 200...
-
 
200
 * Flag: Interrupt handler has done all A/D conversion and processing.
219
 * Flag: Interrupt handler has done all A/D conversion and processing.
201
 */
Line -... Line 202...
-
 
202
extern volatile uint8_t analogDataReady;
-
 
203
 
220
 */
204
 
-
 
205
void analog_init(void);
-
 
206
 
-
 
207
/*
-
 
208
 * This is really only for use for the ENC-03 code module, which needs to get the raw value
221
extern volatile uint8_t analogDataReady;
209
 * for its calibration. The raw value should not be used for anything else.
-
 
210
 */
-
 
211
uint16_t rawGyroValue(uint8_t axis);
Line -... Line 212...
-
 
212
 
222
 
213
/*
-
 
214
 * Start the conversion cycle. It will stop automatically.
223
void analog_init(void);
215
 */
Line 224... Line 216...
224
 
216
void startAnalogConversionCycle(void);
225
// clear ADC enable & ADC Start Conversion & ADC Interrupt Enable bit
217
 
226
#define analog_stop() (ADCSRA &= ~((1<<ADEN)|(1<<ADSC)|(1<<ADIE)))
218
/*
227
 
219
 * Process the sensor data to update the exported variables. Must be called after each measurement cycle and before the data is used.
Line 228... Line 220...
228
// set ADC enable & ADC Start Conversion & ADC Interrupt Enable bit
220
 */
-
 
221
void analog_update(void);
-
 
222
 
-
 
223
/*
-
 
224
 * Read gyro and acc.meter calibration from EEPROM.
-
 
225
 */
229
#define analog_start() (ADCSRA |= (1<<ADEN)|(1<<ADSC)|(1<<ADIE))
226
void analog_setNeutral(void);
230
 
227
 
231
/*
228
/*
-
 
229
 * Zero-offset gyros and write the calibration data to EEPROM.
-
 
230
 */
-
 
231
void analog_calibrateGyros(void);
-
 
232
 
-
 
233
/*
-
 
234
 * Zero-offset accelerometers and write the calibration data to EEPROM.
-
 
235
 */
232
 * "Warm" calibration: Zero-offset gyros.
236
void analog_calibrateAcc(void);