Blame |
Last modification |
View Log
| RSS feed
/*****************************************************************************************************************************
* File: analog.c
*
* Purpose: collecting ADC analog inputs from PORTA
*
* Functions: void ADC_Init(void)
* void SucheLuftruckOffset(void)
* void SucheGyroOffset(void)
* ISR(ADC_vect)
*
*****************************************************************************************************************************/
#include "analog.h"
#include "main.h"
volatile int Aktuell_Nick
, Aktuell_Roll
, Aktuell_Gier
, Aktuell_ax
, Aktuell_ay
, Aktuell_az
, UBat
= 100;
volatile int AdWertNickFilter
= 0, AdWertRollFilter
= 0, AdWertGierFilter
= 0;
volatile int HiResNick
= 2500, HiResRoll
= 2500;
volatile int AdWertNick
= 0, AdWertRoll
= 0, AdWertGier
= 0;
volatile int AdWertAccRoll
= 0, AdWertAccNick
= 0, AdWertAccHoch
= 0;
volatile char messanzahl_AccHoch
= 0;
volatile long Luftdruck
= 32000;
volatile long SummenHoehe
= 0;
volatile int StartLuftdruck
;
volatile unsigned int MessLuftdruck
= 1023;
unsigned char DruckOffsetSetting
;
signed char ExpandBaro
= 0;
volatile int VarioMeter
= 0;
volatile unsigned int ZaehlMessungen
= 0;
unsigned char AnalogOffsetNick
= 115, AnalogOffsetRoll
= 115, AnalogOffsetGier
= 115;
unsigned char GyroDefektN
= 0, GyroDefektR
= 0, GyroDefektG
= 0;
volatile unsigned char AdReady
= 1;
// *************************************************************************************************************************************
// initialize the analog digital converter ADC
// -------------------------------------------------------------------------------------------------------------------------------------
void ADC_Init
(void)
{
// ADMUX = ADC Multiplexer Selection Register > REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
// -----------------------------------------------------------------------------------------
// REFS1:0 = Reference Selection Bits
// ADLAR = ADC Left Adjust Result
// MUX4:0 = Analog Channel and Gain Selection Bits
//
ADMUX
= 0; // AREF, Internal Vref is turned off
// // the result is right adjusted
// // MUX = 00000 = ADC0
// ADCSRA = Analog Digital Conversion Status Register A -> ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
// ---------------------------------------------------------------------------------------------------
// ADEN = Writing this bit to one enables the ADC
// ADSC = start conversion
// ADATE = When this bit is written to one, Auto Triggering of the ADC is enabled
// 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.
// ADPS = These bits determine the division factor between the XTAL frequency and the input clock to the ADC.
// Prescaler with ADPS2 ADPS1 ADPS0 = 111 = Division Factor 128 = 156.25 kHz
//
ANALOG_ON
; // #define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)
}
// *** EOF: void ADC_Init(void) ************************************************************************************
#define DESIRED_H_ADC 800
// *********************************************************************************************************************************
// initialize the air pressure offset
// ------------------------------------
void SucheLuftruckOffset
(void)
{
unsigned int off
;
off
= eeprom_read_byte
(&EEPromArray
[EEPROM_ADR_LAST_OFFSET
]);
if(off
> 20) off
-= 10;
OCR0A
= off
; // Timer/Counter0 Output Compare Register A
ExpandBaro
= 0;
Delay_ms_Mess
(100); // -> timer0.c
if(MessLuftdruck
< DESIRED_H_ADC
) off
= 0; // #define DESIRED_H_ADC 800
for(; off
< 250;off
++)
{
OCR0A
= off
;
Delay_ms_Mess
(50);
printf(".");
if(MessLuftdruck
< DESIRED_H_ADC
) break;
}
eeprom_write_byte
(&EEPromArray
[EEPROM_ADR_LAST_OFFSET
], off
);
DruckOffsetSetting
= off
;
Delay_ms_Mess
(300);
}
// *** EOF: SucheLuftruckOffset(void) **********************************************************************************************
// *********************************************************************************************************************************
// initialize the Gyro-Offset
// ---------------------------
void SucheGyroOffset
(void)
{
unsigned char i
, ready
= 0;
int timeout
;
GyroDefektN
= 0; GyroDefektR
= 0; GyroDefektG
= 0;
timeout
= SetDelay
(2000);
for(i
=140; i
!= 0; i
--)
{
if(ready
==3 && i
>10) i
= 9;
ready
= 0;
if(AdWertNick
< 1020) AnalogOffsetNick
--; else if(AdWertNick
> 1030) AnalogOffsetNick
++; else ready
++;
if(AdWertRoll
< 1020) AnalogOffsetRoll
--; else if(AdWertRoll
> 1030) AnalogOffsetRoll
++; else ready
++;
if(AdWertGier
< 1020) AnalogOffsetGier
--; else if(AdWertGier
> 1030) AnalogOffsetGier
++; else ready
++;
twi_state
= 8;
i2c_start
();
if(AnalogOffsetNick
< 10) { GyroDefektN
= 1; AnalogOffsetNick
= 10;}; if(AnalogOffsetNick
> 245) { GyroDefektN
= 1; AnalogOffsetNick
= 245;};
if(AnalogOffsetRoll
< 10) { GyroDefektR
= 1; AnalogOffsetRoll
= 10;}; if(AnalogOffsetRoll
> 245) { GyroDefektR
= 1; AnalogOffsetRoll
= 245;};
if(AnalogOffsetGier
< 10) { GyroDefektG
= 1; AnalogOffsetGier
= 10;}; if(AnalogOffsetGier
> 245) { GyroDefektG
= 1; AnalogOffsetGier
= 245;};
while(twi_state
) if(CheckDelay
(timeout
)) {printf("\n\r DAC or I2C ERROR! Check I2C, 3Vref, DAC and BL-Ctrl"); break;}
AdReady
= 0;
ANALOG_ON
; // #define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE)
while(!AdReady
);
if(i
<10) Delay_ms_Mess
(10);
}
Delay_ms_Mess
(70);
}
// *** EOF: SucheGyroOffset(void) **************************************************************************************************
// *********************************************************************************************************************************
// read analog input with the following sequence:
// ---------------------------------------------------------------------------------------------------
// case:
// 0 nick-gyro
// 1 roll-gyro
// 2 gier-gyro
// 3 y acc roll
// 4 x acc nick
// 5 nick-gyro
// 6 roll-gyro
// 7 voltage V
// 8 z acc
// 9 air pressure
// 10 nick-gyro
// 11 roll-gyro
// 12 gier-gyro
// 13 y acc roll
// 14 x acc nick
// 15 nick-gyro
// 16 roll-gyro
// 17 air pressure
// ---------------------------------------------------------------------------------------------------
ISR
(ADC_vect
)
{
static unsigned char kanal
=0,state
= 0;
static signed int gier1
, roll1
, nick1
, nick_filter
, roll_filter
;
static signed int accy
, accx
;
static long tmpLuftdruck
= 0;
static char messanzahl_Druck
= 0;
switch(state
++)
{
case 0: // nick gyro
nick1
= ADC
; // Messwert Nick aus dem Gyroskop (kippen nach vorne-hinten)
kanal
= AD_ROLL
; // #define AD_ROLL 1
break;
case 1: // roll gyro
roll1
= 512; // Messwert Roll aus dem Gyroskop (kippen nach rechts-links)
kanal
= AD_GIER
; // #define AD_GIER 0
break;
case 2: // gier gyro
gier1
= 512; // Messwert Gier aus dem Gyroskop (drehen um Hochachse)
kanal
= AD_ACC_Y
; // #define AD_ACC_Y 6 // Rollen
break;
case 3: // y acc roll
Aktuell_ay
= NeutralAccY
- 512;
accy
= Aktuell_ay
; // Messwert Y=Roll des ACC Sensors
kanal
= AD_ACC_X
; // #define AD_ACC_X 7 // Nicken
break;
case 4:
Aktuell_ax
= ADC
- NeutralAccX
; // Messwert X=Nick des ACC Sensors
accx
= Aktuell_ax
;
kanal
= AD_NICK
; // #define AD_NICK 2
break;
case 5:
nick1
+= ADC
; // Messwert Nick aus dem Gyroskop (kippen nach vorne-hinten)
kanal
= AD_ROLL
; // #define AD_ROLL 1
break;
case 6:
roll1
+= 512; // Messwert Roll aus dem Gyroskop (kippen nach rechts-links)
kanal
= AD_UBAT
; // #define AD_UBAT 4
break;
case 7:
UBat
= (3 * UBat
+ ADC
/ 3) / 4; // Voltage
kanal
= AD_ACC_Z
; // #define AD_ACC_Z 5
break;
case 8: // Z acc Sensor
AdWertAccHoch
= 512 - NeutralAccZ
;
if(AdWertAccHoch
> 1)
{
if(NeutralAccZ
< 750)
{
NeutralAccZ
+= 0.02;
if(modell_fliegt
< 500) NeutralAccZ
+= 0.1;
}
}
else if(AdWertAccHoch
< -1)
{
if(NeutralAccZ
> 550)
{
NeutralAccZ
-= 0.02;
if(modell_fliegt
< 500) NeutralAccZ
-= 0.1;
}
}
messanzahl_AccHoch
= 1; // Messwert Z des ACC Sensors
Aktuell_az
= 512;
Mess_Integral_Hoch
+= AdWertAccHoch
; // Integrieren
Mess_Integral_Hoch
-= Mess_Integral_Hoch
/ 1024; // dämfen
kanal
= AD_DRUCK
;
break;
// "case 9:" fehlt hier absichtlich
case 10:
nick1
+= ADC
;
kanal
= AD_ROLL
; // #define AD_ROLL 1
break;
case 11:
roll1
+= 512;
kanal
= AD_GIER
; // #define AD_GIER 0
break;
case 12:
AdWertGier
= (512 + gier1
); // AdWertGier müsste so um die 1020 liegen
kanal
= AD_ACC_Y
; // #define AD_ACC_Y 6
break;
case 13:
Aktuell_ay
= NeutralAccY
- 512;
AdWertAccRoll
= (Aktuell_ay
+ accy
); // Messwert Roll des ACC Sensors
kanal
= AD_ACC_X
; // #define AD_ACC_X 7
break;
case 14:
Aktuell_ax
= ADC
- NeutralAccX
;
AdWertAccNick
= (Aktuell_ax
+ accx
); // 2nd measure of ACC Nick Sensor 0...512
kanal
= AD_NICK
; // #define AD_NICK 2
break;
case 15:
nick1
+= ADC
;
nick1
*= 4;
AdWertNick
= nick1
/ 8; // dieser Wert ist doppelt so hoch wie ADC
nick_filter
= (nick_filter
+ nick1
) / 2; // nick_filter müsste mit ca 500 passen
HiResNick
= nick_filter
- AdNeutralNick
; // der Wert wird hier auf den Nullpunkt normiert
AdWertNickFilter
= (AdWertNickFilter
+ HiResNick
) / 2; // und gefiltert
kanal
= AD_ROLL
; // #define AD_ROLL 1
break;
case 16:
roll1
+= 512;
roll1
*= 4;
AdWertRoll
= roll1
/ 8; // dieser Wert ist doppelt so hoch wie ADC
roll_filter
= (roll_filter
+ roll1
) / 2; // ähnlich wie bei Nick in case 15
HiResRoll
= roll_filter
- AdNeutralRoll
; // der Wert wird hier auf den Nullpunkt normiert
AdWertRollFilter
= (AdWertRollFilter
+ HiResRoll
) / 2; // und gefiltert
kanal
= AD_DRUCK
; // #define AD_DRUCK 3
break;
case 17:
state
= 0;
AdReady
= 1; // alle Analogeingänge sind nun bedient worden
ZaehlMessungen
++; // counts one up as all cases have been passed through
// "break" fehlt hier absichtlich
case 9:
MessLuftdruck
= 512;
tmpLuftdruck
+= MessLuftdruck
;
if(++messanzahl_Druck
>= 18)
{
Luftdruck
= (7 * Luftdruck
+ tmpLuftdruck
- (18 * 523) * (long)ExpandBaro
+ 4) / 8; // -523.19 counts per 10 counts offset step
HoehenWert
= StartLuftdruck
- Luftdruck
;
SummenHoehe
-= SummenHoehe
/ SM_FILTER
; // #define SM_FILTER 16
SummenHoehe
+= HoehenWert
;
VarioMeter
= (15 * VarioMeter
+ 8 * (int)(HoehenWert
- SummenHoehe
/SM_FILTER
))/16;
tmpLuftdruck
/= 2;
messanzahl_Druck
= 18/2;
}
kanal
= AD_NICK
; // #define AD_NICK 2
break;
default:
kanal
= 0; state
= 0; kanal
= AD_NICK
; // #define AD_NICK 2
break;
}
ADMUX
= kanal
;
if(state
!= 0) ANALOG_ON
; // #define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE)
}
// EOF : ISR(ADC_vect) ****************************************************************************************************************