Subversion Repositories FlightCtrl

Rev

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