Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2246 | - | 1 | /***************************************************************************************************************************** |
2 | * File: analog.c |
||
3 | * |
||
4 | * Purpose: collecting ADC analog inputs from PORTA |
||
5 | * |
||
6 | * Functions: void ADC_Init(void) |
||
7 | * void SucheLuftruckOffset(void) |
||
8 | * void SucheGyroOffset(void) |
||
9 | * ISR(ADC_vect) |
||
10 | * |
||
11 | *****************************************************************************************************************************/ |
||
12 | #include "analog.h" |
||
13 | #include "main.h" |
||
14 | |||
15 | volatile int Aktuell_Nick, Aktuell_Roll, Aktuell_Gier, Aktuell_ax, Aktuell_ay, Aktuell_az, UBat = 100; |
||
16 | volatile int AdWertNickFilter = 0, AdWertRollFilter = 0, AdWertGierFilter = 0; |
||
17 | volatile int HiResNick = 2500, HiResRoll = 2500; |
||
18 | volatile int AdWertNick = 0, AdWertRoll = 0, AdWertGier = 0; |
||
19 | volatile int AdWertAccRoll = 0, AdWertAccNick = 0, AdWertAccHoch = 0; |
||
20 | volatile char messanzahl_AccHoch = 0; |
||
21 | volatile long Luftdruck = 32000; |
||
22 | volatile long SummenHoehe = 0; |
||
23 | volatile int StartLuftdruck; |
||
24 | volatile unsigned int MessLuftdruck = 1023; |
||
25 | unsigned char DruckOffsetSetting; |
||
26 | signed char ExpandBaro = 0; |
||
27 | volatile int VarioMeter = 0; |
||
28 | volatile unsigned int ZaehlMessungen = 0; |
||
29 | unsigned char AnalogOffsetNick = 115, AnalogOffsetRoll = 115, AnalogOffsetGier = 115; |
||
30 | unsigned char GyroDefektN = 0, GyroDefektR = 0, GyroDefektG = 0; |
||
31 | volatile unsigned char AdReady = 1; |
||
32 | |||
33 | |||
34 | // ************************************************************************************************************************************* |
||
35 | // initialize the analog digital converter ADC |
||
36 | // ------------------------------------------------------------------------------------------------------------------------------------- |
||
37 | void ADC_Init(void) |
||
38 | { |
||
39 | // ADMUX = ADC Multiplexer Selection Register –> REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 |
||
40 | // ----------------------------------------------------------------------------------------- |
||
41 | // REFS1:0 = Reference Selection Bits |
||
42 | // ADLAR = ADC Left Adjust Result |
||
43 | // MUX4:0 = Analog Channel and Gain Selection Bits |
||
44 | // |
||
45 | ADMUX = 0; // AREF, Internal Vref is turned off |
||
46 | // // the result is right adjusted |
||
47 | // // MUX = 00000 = ADC0 |
||
48 | |||
49 | |||
50 | // ADCSRA = Analog Digital Conversion Status Register A -> ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 |
||
51 | // --------------------------------------------------------------------------------------------------- |
||
52 | // ADEN = Writing this bit to one enables the ADC |
||
53 | // ADSC = start conversion |
||
54 | // ADATE = When this bit is written to one, Auto Triggering of the ADC is enabled |
||
55 | // ADIE = ADC Interrupt Enable. When this bit is written to one and the I-bit in SREG is set, the ADC Conversion Complete Interrupt is activated. |
||
56 | // ADPS = These bits determine the division factor between the XTAL frequency and the input clock to the ADC. |
||
57 | // Prescaler with ADPS2 ADPS1 ADPS0 = 111 = Division Factor 128 = 156.25 kHz |
||
58 | // |
||
59 | ANALOG_ON; // #define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) |
||
60 | } |
||
61 | // *** EOF: void ADC_Init(void) ************************************************************************************ |
||
62 | |||
63 | |||
64 | #define DESIRED_H_ADC 800 |
||
65 | |||
66 | |||
67 | |||
68 | // ********************************************************************************************************************************* |
||
69 | // initialize the air pressure offset |
||
70 | // ------------------------------------ |
||
71 | void SucheLuftruckOffset(void) |
||
72 | { |
||
73 | unsigned int off; |
||
74 | |||
75 | off = eeprom_read_byte(&EEPromArray[EEPROM_ADR_LAST_OFFSET]); |
||
76 | if(off > 20) off -= 10; |
||
77 | OCR0A = off; // Timer/Counter0 Output Compare Register A |
||
78 | ExpandBaro = 0; |
||
79 | Delay_ms_Mess(100); // -> timer0.c |
||
80 | if(MessLuftdruck < DESIRED_H_ADC) off = 0; // #define DESIRED_H_ADC 800 |
||
81 | |||
82 | for(; off < 250;off++) |
||
83 | { |
||
84 | OCR0A = off; |
||
85 | Delay_ms_Mess(50); |
||
86 | printf("."); |
||
87 | if(MessLuftdruck < DESIRED_H_ADC) break; |
||
88 | } |
||
89 | |||
90 | eeprom_write_byte(&EEPromArray[EEPROM_ADR_LAST_OFFSET], off); |
||
91 | DruckOffsetSetting = off; |
||
92 | Delay_ms_Mess(300); |
||
93 | } |
||
94 | // *** EOF: SucheLuftruckOffset(void) ********************************************************************************************** |
||
95 | |||
96 | |||
97 | |||
98 | // ********************************************************************************************************************************* |
||
99 | // initialize the Gyro-Offset |
||
100 | // --------------------------- |
||
101 | void SucheGyroOffset(void) |
||
102 | { |
||
103 | unsigned char i, ready = 0; |
||
104 | int timeout; |
||
105 | |||
106 | GyroDefektN = 0; GyroDefektR = 0; GyroDefektG = 0; |
||
107 | timeout = SetDelay(2000); |
||
108 | |||
109 | for(i=140; i != 0; i--) |
||
110 | { |
||
111 | if(ready==3 && i>10) i = 9; |
||
112 | ready = 0; |
||
113 | if(AdWertNick < 1020) AnalogOffsetNick--; else if(AdWertNick > 1030) AnalogOffsetNick++; else ready++; |
||
114 | if(AdWertRoll < 1020) AnalogOffsetRoll--; else if(AdWertRoll > 1030) AnalogOffsetRoll++; else ready++; |
||
115 | if(AdWertGier < 1020) AnalogOffsetGier--; else if(AdWertGier > 1030) AnalogOffsetGier++; else ready++; |
||
116 | twi_state = 8; |
||
117 | i2c_start(); |
||
118 | if(AnalogOffsetNick < 10) { GyroDefektN = 1; AnalogOffsetNick = 10;}; if(AnalogOffsetNick > 245) { GyroDefektN = 1; AnalogOffsetNick = 245;}; |
||
119 | if(AnalogOffsetRoll < 10) { GyroDefektR = 1; AnalogOffsetRoll = 10;}; if(AnalogOffsetRoll > 245) { GyroDefektR = 1; AnalogOffsetRoll = 245;}; |
||
120 | if(AnalogOffsetGier < 10) { GyroDefektG = 1; AnalogOffsetGier = 10;}; if(AnalogOffsetGier > 245) { GyroDefektG = 1; AnalogOffsetGier = 245;}; |
||
121 | while(twi_state) if(CheckDelay(timeout)) {printf("\n\r DAC or I2C ERROR! Check I2C, 3Vref, DAC and BL-Ctrl"); break;} |
||
122 | AdReady = 0; |
||
123 | |||
124 | ANALOG_ON; // #define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE) |
||
125 | while(!AdReady); |
||
126 | if(i<10) Delay_ms_Mess(10); |
||
127 | } |
||
128 | |||
129 | Delay_ms_Mess(70); |
||
130 | } |
||
131 | // *** EOF: SucheGyroOffset(void) ************************************************************************************************** |
||
132 | |||
133 | |||
134 | |||
135 | // ********************************************************************************************************************************* |
||
136 | // read analog input with the following sequence: |
||
137 | // --------------------------------------------------------------------------------------------------- |
||
138 | // case: |
||
139 | // 0 nick-gyro |
||
140 | // 1 roll-gyro |
||
141 | // 2 gier-gyro |
||
142 | // 3 y acc roll |
||
143 | // 4 x acc nick |
||
144 | // 5 nick-gyro |
||
145 | // 6 roll-gyro |
||
146 | // 7 voltage V |
||
147 | // 8 z acc |
||
148 | // 9 air pressure |
||
149 | // 10 nick-gyro |
||
150 | // 11 roll-gyro |
||
151 | // 12 gier-gyro |
||
152 | // 13 y acc roll |
||
153 | // 14 x acc nick |
||
154 | // 15 nick-gyro |
||
155 | // 16 roll-gyro |
||
156 | // 17 air pressure |
||
157 | // --------------------------------------------------------------------------------------------------- |
||
158 | ISR(ADC_vect) |
||
159 | { |
||
160 | static unsigned char kanal=0,state = 0; |
||
161 | static signed int gier1, roll1, nick1, nick_filter, roll_filter; |
||
162 | static signed int accy, accx; |
||
163 | static long tmpLuftdruck = 0; |
||
164 | static char messanzahl_Druck = 0; |
||
165 | |||
166 | switch(state++) |
||
167 | { |
||
168 | case 0: // nick gyro |
||
169 | nick1 = ADC; // Messwert Nick aus dem Gyroskop (kippen nach vorne-hinten) |
||
170 | kanal = AD_ROLL; // #define AD_ROLL 1 |
||
171 | break; |
||
172 | |||
173 | case 1: // roll gyro |
||
174 | roll1 = 512; // Messwert Roll aus dem Gyroskop (kippen nach rechts-links) |
||
175 | kanal = AD_GIER; // #define AD_GIER 0 |
||
176 | break; |
||
177 | |||
178 | case 2: // gier gyro |
||
179 | gier1 = 512; // Messwert Gier aus dem Gyroskop (drehen um Hochachse) |
||
180 | kanal = AD_ACC_Y; // #define AD_ACC_Y 6 // Rollen |
||
181 | break; |
||
182 | |||
183 | case 3: // y acc roll |
||
184 | Aktuell_ay = NeutralAccY - 512; |
||
185 | accy = Aktuell_ay; // Messwert Y=Roll des ACC Sensors |
||
186 | kanal = AD_ACC_X; // #define AD_ACC_X 7 // Nicken |
||
187 | break; |
||
188 | |||
189 | case 4: |
||
190 | Aktuell_ax = ADC - NeutralAccX; // Messwert X=Nick des ACC Sensors |
||
191 | accx = Aktuell_ax; |
||
192 | kanal = AD_NICK; // #define AD_NICK 2 |
||
193 | break; |
||
194 | |||
195 | case 5: |
||
196 | nick1 += ADC; // Messwert Nick aus dem Gyroskop (kippen nach vorne-hinten) |
||
197 | kanal = AD_ROLL; // #define AD_ROLL 1 |
||
198 | break; |
||
199 | |||
200 | case 6: |
||
201 | roll1 += 512; // Messwert Roll aus dem Gyroskop (kippen nach rechts-links) |
||
202 | kanal = AD_UBAT; // #define AD_UBAT 4 |
||
203 | break; |
||
204 | |||
205 | case 7: |
||
206 | UBat = (3 * UBat + ADC / 3) / 4; // Voltage |
||
207 | kanal = AD_ACC_Z; // #define AD_ACC_Z 5 |
||
208 | break; |
||
209 | |||
210 | case 8: // Z acc Sensor |
||
211 | AdWertAccHoch = 512 - NeutralAccZ; |
||
212 | if(AdWertAccHoch > 1) |
||
213 | { |
||
214 | if(NeutralAccZ < 750) |
||
215 | { |
||
216 | NeutralAccZ += 0.02; |
||
217 | if(modell_fliegt < 500) NeutralAccZ += 0.1; |
||
218 | } |
||
219 | } |
||
220 | else if(AdWertAccHoch < -1) |
||
221 | { |
||
222 | if(NeutralAccZ > 550) |
||
223 | { |
||
224 | NeutralAccZ-= 0.02; |
||
225 | if(modell_fliegt < 500) NeutralAccZ -= 0.1; |
||
226 | } |
||
227 | } |
||
228 | messanzahl_AccHoch = 1; // Messwert Z des ACC Sensors |
||
229 | Aktuell_az = 512; |
||
230 | Mess_Integral_Hoch += AdWertAccHoch; // Integrieren |
||
231 | Mess_Integral_Hoch -= Mess_Integral_Hoch / 1024; // dämfen |
||
232 | kanal = AD_DRUCK; |
||
233 | break; |
||
234 | |||
235 | // "case 9:" fehlt hier absichtlich |
||
236 | |||
237 | case 10: |
||
238 | nick1 += ADC; |
||
239 | kanal = AD_ROLL; // #define AD_ROLL 1 |
||
240 | break; |
||
241 | |||
242 | case 11: |
||
243 | roll1 += 512; |
||
244 | kanal = AD_GIER; // #define AD_GIER 0 |
||
245 | break; |
||
246 | |||
247 | case 12: |
||
248 | AdWertGier = (512 + gier1); // AdWertGier müsste so um die 1020 liegen |
||
249 | kanal = AD_ACC_Y; // #define AD_ACC_Y 6 |
||
250 | break; |
||
251 | |||
252 | case 13: |
||
253 | Aktuell_ay = NeutralAccY - 512; |
||
254 | AdWertAccRoll = (Aktuell_ay + accy); // Messwert Roll des ACC Sensors |
||
255 | kanal = AD_ACC_X; // #define AD_ACC_X 7 |
||
256 | break; |
||
257 | |||
258 | case 14: |
||
259 | Aktuell_ax = ADC - NeutralAccX; |
||
260 | AdWertAccNick = (Aktuell_ax + accx); // 2nd measure of ACC Nick Sensor 0...512 |
||
261 | kanal = AD_NICK; // #define AD_NICK 2 |
||
262 | break; |
||
263 | |||
264 | case 15: |
||
265 | nick1 += ADC; |
||
266 | nick1 *= 4; |
||
267 | AdWertNick = nick1 / 8; // dieser Wert ist doppelt so hoch wie ADC |
||
268 | nick_filter = (nick_filter + nick1) / 2; // nick_filter müsste mit ca 500 passen |
||
269 | HiResNick = nick_filter - AdNeutralNick; // der Wert wird hier auf den Nullpunkt normiert |
||
270 | AdWertNickFilter = (AdWertNickFilter + HiResNick) / 2; // und gefiltert |
||
271 | kanal = AD_ROLL; // #define AD_ROLL 1 |
||
272 | break; |
||
273 | |||
274 | case 16: |
||
275 | roll1 += 512; |
||
276 | roll1 *= 4; |
||
277 | AdWertRoll = roll1 / 8; // dieser Wert ist doppelt so hoch wie ADC |
||
278 | roll_filter = (roll_filter + roll1) / 2; // ähnlich wie bei Nick in case 15 |
||
279 | HiResRoll = roll_filter - AdNeutralRoll; // der Wert wird hier auf den Nullpunkt normiert |
||
280 | AdWertRollFilter = (AdWertRollFilter + HiResRoll) / 2; // und gefiltert |
||
281 | kanal = AD_DRUCK; // #define AD_DRUCK 3 |
||
282 | break; |
||
283 | |||
284 | case 17: |
||
285 | state = 0; |
||
286 | AdReady = 1; // alle Analogeingänge sind nun bedient worden |
||
287 | ZaehlMessungen++; // counts one up as all cases have been passed through |
||
288 | // "break" fehlt hier absichtlich |
||
289 | case 9: |
||
290 | MessLuftdruck = 512; |
||
291 | tmpLuftdruck += MessLuftdruck; |
||
292 | if(++messanzahl_Druck >= 18) |
||
293 | { |
||
294 | Luftdruck = (7 * Luftdruck + tmpLuftdruck - (18 * 523) * (long)ExpandBaro + 4) / 8; // -523.19 counts per 10 counts offset step |
||
295 | HoehenWert = StartLuftdruck - Luftdruck; |
||
296 | SummenHoehe -= SummenHoehe / SM_FILTER; // #define SM_FILTER 16 |
||
297 | SummenHoehe += HoehenWert; |
||
298 | VarioMeter = (15 * VarioMeter + 8 * (int)(HoehenWert - SummenHoehe/SM_FILTER))/16; |
||
299 | tmpLuftdruck /= 2; |
||
300 | messanzahl_Druck = 18/2; |
||
301 | } |
||
302 | kanal = AD_NICK; // #define AD_NICK 2 |
||
303 | break; |
||
304 | |||
305 | default: |
||
306 | kanal = 0; state = 0; kanal = AD_NICK; // #define AD_NICK 2 |
||
307 | break; |
||
308 | } |
||
309 | ADMUX = kanal; |
||
310 | if(state != 0) ANALOG_ON; // #define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE) |
||
311 | |||
312 | } |
||
313 | // EOF : ISR(ADC_vect) **************************************************************************************************************** |
||
314 | |||
315 | |||
316 |