0,0 → 1,316 |
/***************************************************************************************************************************** |
* 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) **************************************************************************************************************** |
|
|
|