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); |