Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 1170 → Rev 1171

/trunk/Spectrum.c
0,0 → 1,272
/*#######################################################################################
Decodieren eines RC Summen Signals oder Spektrum Empfänger-Satellit
#######################################################################################*/
 
#include "Spectrum.h"
#include "main.h"
 
//############################################################################
// zum Decodieren des Spektrum Satelliten wird USART1 benutzt.
// USART1 initialisation from killagreg
void Uart1Init(void)
//############################################################################
{
// -- Start of USART1 initialisation for Spekturm seriell-mode
// USART1 Control and Status Register A, B, C and baud rate register
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * 115200) - 1);
// disable RX-Interrupt
UCSR1B &= ~(1 << RXCIE1);
// disable TX-Interrupt
UCSR1B &= ~(1 << TXCIE1);
// disable DRE-Interrupt
UCSR1B &= ~(1 << UDRIE1);
// set direction of RXD1 and TXD1 pins
// set RXD1 (PD2) as an input pin
PORTD |= (1 << PORTD2);
DDRD &= ~(1 << DDD2);
// USART0 Baud Rate Register
// set clock divider
UBRR1H = (uint8_t)(ubrr>>8);
UBRR1L = (uint8_t)ubrr;
// enable double speed operation
UCSR1A |= (1 << U2X1);
// enable receiver and transmitter
//UCSR1B = (1<<RXEN1)|(1<<TXEN1);
UCSR1B = (1<<RXEN1);
// set asynchronous mode
UCSR1C &= ~(1 << UMSEL11);
UCSR1C &= ~(1 << UMSEL10);
// no parity
UCSR1C &= ~(1 << UPM11);
UCSR1C &= ~(1 << UPM10);
// 1 stop bit
UCSR1C &= ~(1 << USBS1);
// 8-bit
UCSR1B &= ~(1 << UCSZ12);
UCSR1C |= (1 << UCSZ11);
UCSR1C |= (1 << UCSZ10);
// flush receive buffer explicit
while ( UCSR1A & (1<<RXC1) ) UDR1;
// enable RX-interrupts at the end
UCSR1B |= (1 << RXCIE1);
// -- End of USART1 initialisation
return;
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) Rainer Walther
// + RC-routines from original MK rc.c (c) H&I
// + Useful infos from Walter: http://www.rcgroups.com/forums/showthread.php?t=714299&page=2
// + only for non-profit use
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// 20080808 rw Modified for Spektrum AR6100 (PPM)
// 20080823 rw Add Spektrum satellite receiver on USART1 (644P only)
// 20081213 rw Add support for Spektrum DS9 Air-Tx-Module (9 channels)
// Replace AR6100-coding with original composit-signal routines
//
// ---
// Entweder Summensignal ODER Spektrum-Receiver anschließen. Nicht beides gleichzeitig betreiben!
// Binding is not implemented. Bind with external Receiver.
// Servo output J3, J4, J5 not serviced
//
// Anschuß Spektrum Receiver
// Orange: 3V von der FC (keinesfalls an 5V anschließen!)
// Schwarz: GND
// Grau: RXD1 (Pin 3) auf 10-Pol FC-Stecker
//
// ---
// Satellite-Reciever connected on USART1:
//
// DX7/DX6i: One data-frame at 115200 baud every 22ms.
// DX7se: One data-frame at 115200 baud every 11ms.
// byte1: unknown
// byte2: unknown
// byte3: and byte4: channel data (FLT-Mode)
// byte5: and byte6: channel data (Roll)
// byte7: and byte8: channel data (Nick)
// byte9: and byte10: channel data (Gier)
// byte11: and byte12: channel data (Gear Switch)
// byte13: and byte14: channel data (Gas)
// byte15: and byte16: channel data (AUX2)
//
// DS9 (9 Channel): One data-frame at 115200 baud every 11ms, alternating frame 1/2 for CH1-7 / CH8-9
// 1st Frame:
// byte1: unknown
// byte2: unknown
// byte3: and byte4: channel data
// byte5: and byte6: channel data
// byte7: and byte8: channel data
// byte9: and byte10: channel data
// byte11: and byte12: channel data
// byte13: and byte14: channel data
// byte15: and byte16: channel data
// 2nd Frame:
// byte1: unknown
// byte2: unknown
// byte3: and byte4: channel data
// byte5: and byte6: channel data
// byte7: and byte8: 0xffff
// byte9: and byte10: 0xffff
// byte11: and byte12: 0xffff
// byte13: and byte14: 0xffff
// byte15: and byte16: 0xffff
//
// Each channel data (16 bit= 2byte, first msb, second lsb) is arranged as:
//
// Bits: F 0 C3 C2 C1 C0 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
//
// 0 means a '0' bit
// F: 1 = indicates beginning of 2nd frame for CH8-9 (DS9 only)
// C3 to C0 is the channel number. 0 to 9 (4 bit, as assigned in the transmitter)
// D9 to D0 is the channel data (10 bit) 0xaa..0x200..0x356 for 100% transmitter-travel
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
//############################################################################
//Diese Routine startet und inizialisiert den USART1 für seriellen Spektrum satellite reciever
SIGNAL(USART1_RX_vect)
//############################################################################
{
static unsigned int Sync=0, FrameCnt=0, ByteHigh=0, ReSync=1, Frame2=0, FrameTimer;
unsigned int Channel, index;
signed int signal, tmp;
int bCheckDelay;
uint8_t c;
c = UDR1; // get data byte
if (ReSync == 1)
{
// wait for beginning of new frame
ReSync = 0;
FrameTimer = SetDelay(7); // minimum 7ms zwischen den frames
FrameCnt = 0;
Sync = 0;
ByteHigh = 0;
}
else
{
bCheckDelay = CheckDelay(FrameTimer);
if ( Sync == 0 )
{
if ( bCheckDelay )
{
// nach einer Pause von mind. 7ms erstes Sync-Character gefunden
// Zeichen ignorieren, da Bedeutung unbekannt
Sync = 1;
FrameCnt ++;
}
else
{
// Zeichen kam vor Ablauf der 7ms Sync-Pause
// warten auf erstes Sync-Zeichen
}
}
else if ( (Sync == 1) && !bCheckDelay )
{
// zweites Sync-Character ignorieren, Bedeutung unbekannt
Sync = 2;
FrameCnt ++;
}
else if ( (Sync == 2) && !bCheckDelay )
{
// Datenbyte high
ByteHigh = c;
if (FrameCnt == 2)
{
// is 1st Byte of Channel-data
// Frame 1 with Channel 1-7 comming next
Frame2 = 0;
if ( ByteHigh & 0x80 )
{
// DS9: Frame 2 with Channel 8-9 comming next
Frame2 = 1;
}
}
Sync = 3;
FrameCnt ++;
}
else if ( (Sync == 3) && !bCheckDelay )
{
// Datenbyte low
// High-Byte for next channel comes next
Sync = 2;
FrameCnt ++;
index = (ByteHigh >> 2) & 0x0f;
index ++;
Channel = (ByteHigh << 8) | c;
signal = Channel & 0x3ff;
signal -= 0x200; // Offset, range 0x000..0x3ff?
signal = signal/3; // scaling to fit PPM resolution
if (index >= 0 && index <= 10)
{
if(abs(signal - PPM_in[index]) < 6)
{
if(SenderOkay < 200)
{
SenderOkay += 10;
}
}
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1)
{
tmp--;
}
else
{
if(tmp < signal-1)
{
tmp++;
}
}
if(SenderOkay >= 195)
{
PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
}
else
{
PPM_diff[index] = 0;
}
PPM_in[index] = tmp;
}
}
else
{
// hier stimmt was nicht: neu synchronisieren
ReSync = 1;
FrameCnt = 0;
Frame2 = 0;
}
// 16 Bytes per frame
if (FrameCnt >= 16)
{
// Frame complete
if ( Frame2 == 0 )
{
// Null bedeutet: Neue Daten
// nur beim ersten Frame (CH 0-7) setzen
NewPpmData = 0;
}
// new frame next, nach fruehestens 7ms erwartet
FrameCnt = 0;
Frame2 = 0;
Sync = 0;
}
 
// Zeit bis zum nächsten Zeichen messen
FrameTimer = SetDelay (7);
}
}
 
 
/trunk/Spectrum.h
0,0 → 1,8
/*#######################################################################################
Dekodieren eines Spectrum Signals
#######################################################################################*/
 
#ifndef _SPECTRUM_H
#define _SPECTRUM_H
void Uart1Init(void);
#endif //_RC_H
/trunk/_Settings.h
1,7 → 1,7
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Abstimmung
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define ACC_AMPLIFY 3
#define ACC_AMPLIFY 6
#define FAKTOR_P 1
#define FAKTOR_I 0.0001
 
/trunk/analog.c
79,6 → 79,27
Delay_ms_Mess(70);
}
 
/*
0 n
1 r
2 g
3 y
4 x
5 n
6 r
7 u
8 z
9 L
10 n
11 r
12 g
13 y
14 x
15 n
16 r
17 L
*/
 
//#######################################################################################
//
SIGNAL(SIG_ADC)
85,6 → 106,152
//#######################################################################################
{
static unsigned char kanal=0,state = 0;
static signed int gier1, roll1, nick1, nick_filter, roll_filter;
static signed int accy, accx;
switch(state++)
{
case 0:
nick1 = ADC;
kanal = AD_ROLL;
break;
case 1:
roll1 = ADC;
kanal = AD_GIER;
break;
case 2:
gier1 = ADC;
kanal = AD_ACC_Y;
break;
case 3:
Aktuell_ay = NeutralAccY - ADC;
accy = Aktuell_ay;
kanal = AD_ACC_X;
break;
case 4:
Aktuell_ax = ADC - NeutralAccX;
accx = Aktuell_ax;
kanal = AD_NICK;
break;
case 5:
nick1 += ADC;
kanal = AD_ROLL;
break;
case 6:
roll1 += ADC;
kanal = AD_UBAT;
break;
case 7:
UBat = (3 * UBat + ADC / 3) / 4;
kanal = AD_ACC_Z;
break;
case 8:
AdWertAccHoch = (signed int) ADC - 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;
Aktuell_az = ADC;
Mess_Integral_Hoch += AdWertAccHoch; // Integrieren
Mess_Integral_Hoch -= Mess_Integral_Hoch / 1024; // dämfen
kanal = AD_DRUCK;
break;
// "case 8:" fehlt hier absichtlich
case 10:
nick1 += ADC;
kanal = AD_ROLL;
break;
case 11:
roll1 += ADC;
kanal = AD_GIER;
break;
case 12:
if(PlatinenVersion == 10) AdWertGier = (ADC + gier1 + 1) / 2;
else
if(PlatinenVersion == 20) AdWertGier = 2047 - (ADC + gier1);
else AdWertGier = (ADC + gier1);
kanal = AD_ACC_Y;
break;
case 13:
Aktuell_ay = NeutralAccY - ADC;
AdWertAccRoll = (Aktuell_ay + accy);
kanal = AD_ACC_X;
break;
case 14:
Aktuell_ax = ADC - NeutralAccX;
AdWertAccNick = (Aktuell_ax + accx);
kanal = AD_NICK;
break;
case 15:
nick1 += ADC;
AdWertNick = nick1 / 2;
nick_filter = (nick_filter + 4 * nick1) / 2;
if(PlatinenVersion == 10) { AdWertNick /= 2;nick_filter /=2;}
HiResNick = nick_filter - 8 * AdNeutralNick;
AdWertNickFilter = (AdWertNickFilter + HiResNick) / 2;
// DebugOut.Analog[21] = AdWertNickFilter / 4;
kanal = AD_ROLL;
break;
case 16:
roll1 += ADC;
AdWertRoll = roll1 / 2;
roll_filter = (roll_filter + 4 * roll1) / 2;
if(PlatinenVersion == 10) { AdWertRoll /= 2;roll_filter /=2;}
HiResRoll = roll_filter - 8 * AdNeutralRoll;
AdWertRollFilter = (AdWertRollFilter + HiResRoll) / 2;
// DebugOut.Analog[22] = AdWertRollFilter / 4;
kanal = AD_DRUCK;
break;
case 17:
state = 0;
AdReady = 1;
ZaehlMessungen++;
// "break" fehlt hier absichtlich
case 9:
tmpLuftdruck += ADC;
if(++messanzahl_Druck >= 5)
{
tmpLuftdruck /= 2;
MessLuftdruck = ADC;
messanzahl_Druck = 0;
HoeheD = (31 * HoeheD + (int) Parameter_Luftdruck_D * (int)(255 * ExpandBaro + StartLuftdruck - tmpLuftdruck - HoehenWert))/32; // D-Anteil = neuerWert - AlterWert
DebugOut.Analog[24] = 255 * ExpandBaro + StartLuftdruck - tmpLuftdruck;
DebugOut.Analog[23] = HoeheD;
Luftdruck = (tmpLuftdruck + 7 * Luftdruck + 4) / 8;
HoehenWert = 255 * ExpandBaro + StartLuftdruck - Luftdruck;
tmpLuftdruck /= 2;
}
kanal = AD_NICK;
break;
default:
kanal = 0; state = 0; kanal = AD_NICK;
break;
}
ADMUX = kanal;
if(state != 0) ANALOG_ON;
}
 
 
 
/*
//#######################################################################################
//
SIGNAL(SIG_ADC)
//#######################################################################################
{
static unsigned char kanal=0,state = 0;
static signed int gier1, roll1, nick1;
static signed long nick_filter, roll_filter;
static signed int accy, accx;
291,4 → 458,4
ADMUX = kanal;
if(state != 0) ANALOG_ON;
}
 
*/
/trunk/analog.h
40,6 → 40,6
 
#define ANALOG_OFF ADCSRA=0
 
#define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)|(1<<ADIE)
#define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE)
//Signle trigger Mode, Interrupt on
#endif //_ANALOG_H
/trunk/fc.c
178,6 → 178,7
{
unsigned char i;
unsigned int gier_neutral=0, nick_neutral=0, roll_neutral=0;
ServoActive = 0; HEF4017R_ON;
NeutralAccX = 0;
NeutralAccY = 0;
NeutralAccZ = 0;
211,8 → 212,8
StartNeutralNick = AdNeutralNick;
if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK]) > 4)
{
NeutralAccY = abs(Mittelwert_AccRoll) / (4*ACC_AMPLIFY);
NeutralAccX = abs(Mittelwert_AccNick) / (4*ACC_AMPLIFY);
NeutralAccY = abs(Mittelwert_AccRoll) / (2*ACC_AMPLIFY);
NeutralAccX = abs(Mittelwert_AccNick) / (2*ACC_AMPLIFY);
NeutralAccZ = Aktuell_az;
}
else
248,6 → 249,12
FromNaviCtrl_Value.Kalman_K = -1;
FromNaviCtrl_Value.Kalman_MaxDrift = EE_Parameter.Driftkomp * 16;
FromNaviCtrl_Value.Kalman_MaxFusion = 32;
if(Poti1 = PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 110);
if(Poti2 = PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 110);
if(Poti3 = PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 110);
if(Poti4 = PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 110);
ServoActive = 1;
SenderOkay = 100;
}
 
//############################################################################
257,12 → 264,12
{
static signed long tmpl,tmpl2,tmpl3,tmpl4;
static signed int oldNick, oldRoll, d2Roll, d2Nick;
signed int tmp_int;
signed long winkel_nick, winkel_roll;
 
MesswertGier = (signed int) AdNeutralGier - AdWertGier;
// MesswertGierBias = (signed int) AdNeutralGierBias - AdWertGier;
MesswertNick = (signed int) AdWertNickFilter / 20;
MesswertRoll = (signed int) AdWertRollFilter / 20;
MesswertNick = (signed int) AdWertNickFilter / 8;
MesswertRoll = (signed int) AdWertRollFilter / 8;
RohMesswertNick = MesswertNick;
RohMesswertRoll = MesswertRoll;
//DebugOut.Analog[21] = MesswertNick;
284,8 → 291,8
 
//++++++++++++++++++++++++++++++++++++++++++++++++
// ADC einschalten
ANALOG_ON;
AdReady = 0;
ANALOG_ON;
//++++++++++++++++++++++++++++++++++++++++++++++++
 
if(Mess_IntegralRoll > 93000L) winkel_roll = 93000L;
367,8 → 374,8
 
#define D_LIMIT 128
 
MesswertNick = HiResNick / 20;
MesswertRoll = HiResRoll / 20;
MesswertNick = HiResNick / 8;
MesswertRoll = HiResRoll / 8;
 
if(AdWertNick < 15) MesswertNick = -1000; if(AdWertNick < 7) MesswertNick = -2000;
if(PlatinenVersion == 10) { if(AdWertNick > 1010) MesswertNick = +1000; if(AdWertNick > 1017) MesswertNick = +2000; }
869,10 → 876,10
}
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(!Looping_Nick && !Looping_Roll)
if(!Looping_Nick && !Looping_Roll && Aktuell_az > 600)
{
long tmp_long, tmp_long2;
if(FromNaviCtrl_Value.Kalman_K != -1 && !TrichterFlug)
if(FromNaviCtrl_Value.Kalman_K != -1 /*&& !TrichterFlug*/)
{
tmp_long = (long)(IntegralNick / EE_Parameter.GyroAccFaktor - (long)Mittelwert_AccNick);
tmp_long2 = (long)(IntegralRoll / EE_Parameter.GyroAccFaktor - (long)Mittelwert_AccRoll);
903,7 → 910,7
{
tmp_long /= 3;
tmp_long2 /= 3;
}
}
if(abs(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]) > 25)
{
tmp_long /= 3;
1113,7 → 1120,7
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Kompass
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//DebugOut.Analog[29] = (MaxStickNick + MaxStickRoll);
DebugOut.Analog[16] = KompassSignalSchlecht;
 
if(KompassValue && (EE_Parameter.GlobalConfig & CFG_KOMPASS_AKTIV))
{
1123,11 → 1130,18
if(v > w) w = v; // grösste Neigung ermitteln
korrektur = w / 8 + 1;
fehler = ((540 + KompassValue - (ErsatzKompass/GIER_GRAD_FAKTOR)) % 360) - 180;
if(NeueKompassRichtungMerken)
if(abs(MesswertGier) > 128)
{
fehler = 0;
ErsatzKompass = KompassValue * GIER_GRAD_FAKTOR;
}
 
if(NeueKompassRichtungMerken)
{
// ErsatzKompass += (fehler * 32) / korrektur;
// fehler = 0;
// fehler /= 4;
// ErsatzKompass = KompassValue * GIER_GRAD_FAKTOR;
}
if(!KompassSignalSchlecht && w < 25)
{
GierGyroFehler += fehler;
1135,6 → 1149,7
{
beeptime = 200;
// KompassStartwert = KompassValue;
ErsatzKompass = KompassValue * GIER_GRAD_FAKTOR;
KompassStartwert = (ErsatzKompass/GIER_GRAD_FAKTOR);
NeueKompassRichtungMerken = 0;
}
1169,13 → 1184,13
{
TimerWerteausgabe = 24;
 
DebugOut.Analog[0] = IntegralNick / EE_Parameter.GyroAccFaktor;
DebugOut.Analog[1] = IntegralRoll / EE_Parameter.GyroAccFaktor;
DebugOut.Analog[2] = Mittelwert_AccNick;
DebugOut.Analog[3] = Mittelwert_AccRoll;
DebugOut.Analog[0] = IntegralNick / (EE_Parameter.GyroAccFaktor * 4);
DebugOut.Analog[1] = IntegralRoll / (EE_Parameter.GyroAccFaktor * 4);
DebugOut.Analog[2] = Mittelwert_AccNick / 4;
DebugOut.Analog[3] = Mittelwert_AccRoll / 4;
DebugOut.Analog[4] = MesswertGier;
DebugOut.Analog[5] = HoehenWert;
DebugOut.Analog[6] = Aktuell_az;//(Mess_Integral_Hoch / 512);
DebugOut.Analog[6] = (Mess_Integral_Hoch / 512);//Aktuell_az;
DebugOut.Analog[8] = KompassValue;
DebugOut.Analog[9] = UBat;
DebugOut.Analog[11] = ErsatzKompass / GIER_GRAD_FAKTOR;
1185,8 → 1200,8
//DebugOut.Analog[18] = (int)FromNaviCtrl_Value.OsdBar;
DebugOut.Analog[19] = WinkelOut.CalcState;
DebugOut.Analog[20] = ServoValue;
DebugOut.Analog[24] = MesswertNick/2;
DebugOut.Analog[25] = MesswertRoll/2;
// DebugOut.Analog[24] = MesswertNick/2;
// DebugOut.Analog[25] = MesswertRoll/2;
DebugOut.Analog[27] = (int)FromNaviCtrl_Value.Kalman_MaxDrift;
DebugOut.Analog[29] = (int)FromNaviCtrl_Value.Kalman_K;
DebugOut.Analog[30] = GPS_Nick;
1225,8 → 1240,8
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(TrichterFlug) { SummeRoll = 0; SummeNick = 0;};
 
if(!Looping_Nick) IntegralNickMalFaktor = (IntegralNick * IntegralFaktor) / (44000 / STICK_GAIN); else IntegralNickMalFaktor = 0;
if(!Looping_Roll) IntegralRollMalFaktor = (IntegralRoll * IntegralFaktor) / (44000 / STICK_GAIN); else IntegralRollMalFaktor = 0;
if(!Looping_Nick) IntegralNickMalFaktor = (IntegralNick * IntegralFaktor) / (44000 / STICK_GAIN); else IntegralNickMalFaktor = 0;
if(!Looping_Roll) IntegralRollMalFaktor = (IntegralRoll * IntegralFaktor) / (44000 / STICK_GAIN); else IntegralRollMalFaktor = 0;
 
#define TRIM_MAX 200
if(TrimNick > TRIM_MAX) TrimNick = TRIM_MAX; else if(TrimNick <-TRIM_MAX) TrimNick =-TRIM_MAX;
1329,7 → 1344,6
}
if(GasMischanteil > (MAX_GAS - 20) * STICK_GAIN) GasMischanteil = (MAX_GAS - 20) * STICK_GAIN;
 
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Mischer und PI-Regler
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1456,7 → 1470,7
motorwert /= STICK_GAIN; CHECK_MIN_MAX(motorwert,MIN_GAS,MAX_GAS);
Motor2 = motorwert;
 
motorwert = GasMischanteil + - pd_ergebnis_roll + GierMischanteil;
motorwert = GasMischanteil - pd_ergebnis_roll + GierMischanteil;
motorwert /= STICK_GAIN; CHECK_MIN_MAX(motorwert,MIN_GAS,MAX_GAS);
Motor3 = motorwert;
 
/trunk/flight.pnproj
1,0 → 0,0
<Project name="Flight-Ctrl"><File path="uart.h"></File><File path="main.c"></File><File path="main.h"></File><File path="makefile"></File><File path="uart.c"></File><File path="printf_P.h"></File><File path="printf_P.c"></File><File path="timer0.c"></File><File path="timer0.h"></File><File path="old_macros.h"></File><File path="twimaster.c"></File><File path="version.txt"></File><File path="twimaster.h"></File><File path="rc.c"></File><File path="rc.h"></File><File path="fc.h"></File><File path="menu.h"></File><File path="menu.c"></File><File path="_Settings.h"></File><File path="analog.c"></File><File path="analog.h"></File><File path="GPS.c"></File><File path="gps.h"></File><File path="License.txt"></File><File path="eeprom.c"></File><File path="spi.h"></File><File path="spi.c"></File><File path="led.h"></File><File path="led.c"></File><File path="fc.c"></File></Project>
<Project name="Flight-Ctrl"><File path="uart.h"></File><File path="main.c"></File><File path="main.h"></File><File path="makefile"></File><File path="uart.c"></File><File path="printf_P.h"></File><File path="printf_P.c"></File><File path="timer0.c"></File><File path="timer0.h"></File><File path="old_macros.h"></File><File path="twimaster.c"></File><File path="version.txt"></File><File path="twimaster.h"></File><File path="rc.c"></File><File path="rc.h"></File><File path="fc.h"></File><File path="menu.h"></File><File path="menu.c"></File><File path="_Settings.h"></File><File path="analog.c"></File><File path="analog.h"></File><File path="GPS.c"></File><File path="gps.h"></File><File path="License.txt"></File><File path="eeprom.c"></File><File path="spi.h"></File><File path="spi.c"></File><File path="led.h"></File><File path="led.c"></File><File path="fc.c"></File><File path="Spectrum.c"></File><File path="Spectrum.h"></File></Project>
/trunk/main.c
70,6 → 70,8
if(number > 5) number = 5;
if(number < 1) return;
eeprom_write_block(buffer, &EEPromArray[EEPROM_ADR_PARAM_BEGIN + length * (number - 1)], length);
eeprom_write_byte(&EEPromArray[EEPROM_ADR_PARAM_LENGTH], length); // Länge der Datensätze merken
eeprom_write_block(buffer, &EEPromArray[EEPROM_ADR_CHANNELS], 8); // 8 Kanäle merken
SetActiveParamSetNumber(number);
LED_Init();
}
142,7 → 144,7
DDRD = 0x3E; // Speaker & TXD & J3 J4 J5
DDRD |=0x80; // J7 -> Servo signal
PORTD = 0x47; // LED
 
HEF4017R_ON;
MCUSR &=~(1<<WDRF);
WDTCSR |= (1<<WDCE)|(1<<WDE);
WDTCSR = 0;
156,6 → 158,7
Timer_Init();
TIMER2_Init();
UART_Init();
Uart1Init();
rc_sum_init();
ADC_Init();
i2c_init();
167,20 → 170,12
printf("\n\r==============================");
 
GRN_ON;
 
ReadParameterSet(3, (unsigned char *) &EE_Parameter.Kanalbelegung[0], 9); // read only the first bytes
// valid Stick-Settings?
if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) == 255 || eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) < EE_DATENREVISION ||
EE_Parameter.Kanalbelegung[0] > 9 || EE_Parameter.Kanalbelegung[1] > 9 || EE_Parameter.Kanalbelegung[2] > 9 || EE_Parameter.Kanalbelegung[3] > 9)
{
printf("\n\rInit. EEPROM");
DefaultStickMapping();
}
else if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) != EE_DATENREVISION) printf("\n\rInit. EEPROM: Generating Default-Parameter using old Stick Settings");
 
if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) != EE_DATENREVISION)
{
DefaultKonstanten1();
printf("\n\rInit. EEPROM");
for (unsigned char i=1;i<6;i++)
{
if(i==2) DefaultKonstanten2(); // Kamera
193,8 → 188,20
EE_Parameter.GyroAccFaktor = 27;
EE_Parameter.WinkelUmschlagNick = 78;
EE_Parameter.WinkelUmschlagRoll = 78;
}
// valid Stick-Settings?
if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS]) < 12 && eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+1]) < 12 && eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+2]) < 12 && eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+3]) < 12)
{
EE_Parameter.Kanalbelegung[0] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+0]);
EE_Parameter.Kanalbelegung[1] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+1]);
EE_Parameter.Kanalbelegung[2] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+2]);
EE_Parameter.Kanalbelegung[3] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+3]);
EE_Parameter.Kanalbelegung[4] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+4]);
EE_Parameter.Kanalbelegung[5] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+5]);
EE_Parameter.Kanalbelegung[6] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+6]);
EE_Parameter.Kanalbelegung[7] = eeprom_read_byte(&EEPromArray[EEPROM_ADR_CHANNELS+7]);
if(i==1) printf(": Generating Default-Parameter using old Stick Settings");
} else DefaultStickMapping();
WriteParameterSet(i, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
}
SetActiveParamSetNumber(3); // default-Setting
240,13 → 247,13
{
if(UpdateMotor && AdReady) // ReglerIntervall
{
UpdateMotor=0;
J3High;
UpdateMotor=0;
if(WinkelOut.CalcState) CalMk3Mag();
else MotorRegler();
J3Low;
SendMotorData();
ROT_OFF;
J3Low;
if(PcZugriff) PcZugriff--;
else
{
/trunk/main.h
13,9 → 13,12
 
#if defined (__AVR_ATmega644__)
#define SYSCLK 20000000L //Quarz Frequenz in Hz
//#define SYSCLK 16000000L //Quarz Frequenz in Hz
#endif
 
#if defined (__AVR_ATmega644P__)
#define SYSCLK 20000000L //Quarz Frequenz in Hz
#endif
 
// neue Hardware
#define ROT_OFF {if((PlatinenVersion == 10)||(PlatinenVersion == 20)) PORTB &=~0x01; else PORTB |= 0x01;}
#define ROT_ON {if((PlatinenVersion == 10)||(PlatinenVersion == 20)) PORTB |= 0x01; else PORTB &=~0x01;}
39,6 → 42,9
#define EEPROM_ADR_ACC_ROLL 6
#define EEPROM_ADR_ACC_Z 8
 
#define EEPROM_ADR_CHANNELS 80
 
#define EEPROM_ADR_PARAM_LENGTH 98
#define EEPROM_ADR_PARAM_BEGIN 100
 
#define CFG_HOEHENREGELUNG 0x01
/trunk/makefile
1,15 → 1,15
#--------------------------------------------------------------------
# MCU name
MCU = atmega644
MCU = atmega644p
F_CPU = 20000000
#-------------------------------------------------------------------
VERSION_MAJOR = 0
VERSION_MINOR = 72
VERSION_PATCH = 12
VERSION_PATCH = 14
 
VERSION_SERIAL_MAJOR = 10 # Serial Protocol
VERSION_SERIAL_MINOR = 0 # Serial Protocol
NC_SPI_COMPATIBLE = 4 # Navi-Kompatibilität
NC_SPI_COMPATIBLE = 5 # Navi-Kompatibilität
#-------------------------------------------------------------------
 
ifeq ($(MCU), atmega32)
30,7 → 30,6
HEX_NAME = MEGA644
endif
 
 
ifeq ($(F_CPU), 16000000)
QUARZ = 16MHZ
endif
87,15 → 86,24
ifeq ($(VERSION_PATCH), 13)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)n
endif
ifeq ($(VERSION_PATCH), 14)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)o
endif
ifeq ($(VERSION_PATCH), 15)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)p
endif
ifeq ($(VERSION_PATCH), 16)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)q
endif
 
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
OPT = 2
 
##########################################################################################################
# List C source files here. (C dependencies are automatically generated.)
SRC = main.c uart.c printf_P.c timer0.c analog.c menu.c
SRC += twimaster.c rc.c fc.c GPS.c spi.c led.c
SRC += twimaster.c rc.c fc.c GPS.c spi.c led.c Spectrum.c
 
##########################################################################################################
 
293,14 → 301,13
 
 
# Display size of file.
# Display size of file.
sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
 
@if [ -f $(TARGET).elf ]; then echo Size before:; $(ELFSIZE); $(HEXSIZE); echo; fi
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
@if [ -f $(TARGET).elf ]; then echo Size after:; $(ELFSIZE); $(HEXSIZE); echo; fi
 
 
 
# Display compiler version information.
gccversion :
@$(CC) --version
/trunk/rc.c
22,6 → 22,7
//############################################################################
{
TCCR1B=(1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);//|(1 << WGM12); //timer1 prescale 64
// TCCR1B=(1<<CS11)|(0<<CS10)|(1<<ICES1)|(1<<ICNC1); //timer1 prescale 64
TIMSK1 |= _BV(ICIE1);
AdNeutralGier = 0;
AdNeutralRoll = 0;
64,14 → 65,58
PPM_in[index] = tmp;
}
index++;
// if(index == 5) J3High; else J3Low; // Servosignal an J3 anlegen
// if(index == 6) J4High; else J4Low; // Servosignal an J4 anlegen
// if(index == 7) J5High; else J5Low; // Servosignal an J5 anlegen
}
}
}
 
/*
//############################################################################
//Diese Routine startet und inizialisiert den Timer für RC
SIGNAL(SIG_INPUT_CAPTURE1)
//############################################################################
 
{
static unsigned int AltICR=0;
signed int signal = 0,tmp;
static int index;
signal = (unsigned int) ICR1 - AltICR;
DebugOut.Analog[16] = signal;
signal /= 2;
AltICR = ICR1;
//Syncronisationspause?
if((signal > 1100*2) && (signal < 8000*2))
{
if(index >= 4) NewPpmData = 0; // Null bedeutet: Neue Daten
index = 1;
}
else
{
if(index < 10)
{
if((signal > 250) && (signal < 687*2))
{
signal -= 962;
// Stabiles Signal
if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10;}
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
else PPM_diff[index] = 0;
PPM_in[index] = tmp;
}
index++;
if(index == 5) J3High; else J3Low; // Servosignal an J3 anlegen
if(index == 6) J4High; else J4Low; // Servosignal an J4 anlegen
if(index == 2) J4High; else J4Low; // Servosignal an J4 anlegen
if(index == 7) J5High; else J5Low; // Servosignal an J5 anlegen
}
}
}
*/
 
 
 
 
 
/trunk/rc.h
11,12 → 11,13
#endif
 
#if defined (__AVR_ATmega644__)
//#define TIMER_TEILER CK64
#define TIMER_RELOAD_VALUE 250
//#define TIMER_TEILER CK256 // bei 20MHz
//#define TIMER_RELOAD_VALUE -78 // bei 20MHz
#endif
 
#if defined (__AVR_ATmega644P__)
#define TIMER_RELOAD_VALUE 250
#endif
 
#define GAS PPM_in[2]
 
 
/trunk/spi.c
161,11 → 161,11
signed int tmp;
cli();
 
ToNaviCtrl.IntegralNick = (int) (IntegralNick / 130);
ToNaviCtrl.IntegralRoll = (int) (IntegralRoll / 130);
ToNaviCtrl.GyroCompass = ErsatzKompass / GIER_GRAD_FAKTOR;
ToNaviCtrl.AccNick = (int) ACC_AMPLIFY * (NaviAccNick / NaviCntAcc);
ToNaviCtrl.AccRoll = (int) ACC_AMPLIFY * (NaviAccRoll / NaviCntAcc);
ToNaviCtrl.IntegralNick = (int) (IntegralNick / (long)(EE_Parameter.GyroAccFaktor * 4));
ToNaviCtrl.IntegralRoll = (int) (IntegralRoll / (long)(EE_Parameter.GyroAccFaktor * 4));
ToNaviCtrl.GyroCompass = (10 * ErsatzKompass) / GIER_GRAD_FAKTOR;
ToNaviCtrl.AccNick = ((int) ACC_AMPLIFY * (NaviAccNick / NaviCntAcc))/4;
ToNaviCtrl.AccRoll = ((int) ACC_AMPLIFY * (NaviAccRoll / NaviCntAcc))/4;
NaviCntAcc = 0; NaviAccNick = 0; NaviAccRoll = 0;
// ToNaviCtrl.User8 = Parameter_UserParam8;
// ToNaviCtrl.CalState = WinkelOut.CalcState;
235,6 → 235,7
ToNaviCtrl.Param.Byte[1] = SPI_VersionInfo.Minor;
ToNaviCtrl.Param.Byte[2] = SPI_VersionInfo.Patch;
ToNaviCtrl.Param.Byte[3] = SPI_VersionInfo.Compatible;
ToNaviCtrl.Param.Byte[4] = PlatinenVersion;
break;
}
 
/trunk/timer0.c
5,8 → 5,7
volatile unsigned char UpdateMotor = 0;
volatile unsigned int cntKompass = 0;
volatile unsigned int beeptime = 0;
volatile unsigned char SendSPI = 0;
volatile unsigned int ServoState = 40;
volatile unsigned char SendSPI = 0, ServoActive = 0;
 
unsigned int BeepMuster = 0xffff;
int ServoValue = 0;
14,10 → 13,7
volatile int16_t ServoNickValue = 0;
volatile int16_t ServoRollValue = 0;
 
#define HEF4017R_ON PORTC |= (1<<PORTC6)
#define HEF4017R_OFF PORTC &= ~(1<<PORTC6)
 
 
enum {
STOP = 0,
CK = 1,
143,8 → 139,7
PORTD &= ~(1<<PORTD7); // set PD7 to low
 
DDRC |= (1<<DDC6); // set PC6 as output (Reset for HEF4017)
PORTC &= ~(1<<PORTC6); // set PC6 to low
 
HEF4017R_ON;
// Timer/Counter 2 Control Register A
 
// Timer Mode is FastPWM with timer reload at OCR2A (Bits: WGM22 = 1, WGM21 = 1, WGM20 = 1)
209,7 → 204,7
#define IRS_RUNTIME 127
#define PPM_STOPPULSE 188
// #define PPM_FRAMELEN (14063
#define PPM_FRAMELEN (1757 * EE_Parameter.ServoNickRefresh)
#define PPM_FRAMELEN (1757 * EE_Parameter.ServoNickRefresh)
#define MINSERVOPULSE 375
#define MAXSERVOPULSE 1500
#define SERVORANGE (MAXSERVOPULSE - MINSERVOPULSE)
222,7 → 217,6
#define MULTIPLYER 4
static int16_t ServoNickOffset = (255 / 2) * MULTIPLYER; // initial value near center positon
 
 
if(PlatinenVersion < 20)
{
//---------------------------
344,7 → 338,7
RemainingPulse = PPM_STOPPULSE;
// accumulate time for correct sync gap
ServoFrameTime += RemainingPulse;
HEF4017R_OFF; // disable HEF4017 reset
if(ServoActive && SenderOkay > 180) HEF4017R_OFF; // disable HEF4017 reset
ServoIndex++; // change to next servo channel
if(ServoIndex > EE_Parameter.ServoNickRefresh) ServoIndex = 0; // reset to the sync gap
}
/trunk/timer0.h
1,7 → 1,7
 
#define TIMER_TEILER CK8
#define TIMER_RELOAD_VALUE 250
#define HEF4017R_ON PORTC ^= (1<<PORTC6)
#define HEF4017R_ON PORTC |= (1<<PORTC6)
#define HEF4017R_OFF PORTC &= ~(1<<PORTC6)
 
void Timer_Init(void);
16,4 → 16,4
extern volatile unsigned int cntKompass;
extern int ServoValue;
extern unsigned int BeepMuster;
extern volatile unsigned char SendSPI;
extern volatile unsigned char SendSPI, ServoActive;
/trunk/uart.c
38,9 → 38,10
struct str_ExternControl ExternControl;
struct str_VersionInfo VersionInfo;
struct str_WinkelOut WinkelOut;
struct str_Data3D Data3D;
 
int Debug_Timer,Kompass_Timer;
unsigned int DebugDataIntervall = 200;
int Debug_Timer,Kompass_Timer,Timer3D;
unsigned int DebugDataIntervall = 200, Intervall3D = 0;
 
const unsigned char ANALOG_TEXT[32][16] =
{
364,21 → 365,23
memcpy((unsigned char *)&KompassValue , (unsigned char *)pRxData, sizeof(KompassValue));
KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
break;
 
case 'a':// Texte der Analogwerte
DebugTextAnforderung = pRxData[0];
if (DebugTextAnforderung > 31) DebugTextAnforderung = 31;
PcZugriff = 255;
break;
 
case 'b':
memcpy((unsigned char *)&ExternControl, (unsigned char *)pRxData, sizeof(ExternControl));
ConfirmFrame = ExternControl.Frame;
PcZugriff = 255;
break;
case 'c': // Poll the 3D-Data
if(!Intervall3D) { if(pRxData[0]) Timer3D = SetDelay(pRxData[0] * 10);}
Intervall3D = pRxData[0] * 10;
break;
case 'd': // Poll the debug data
DebugDataIntervall = pRxData[0] * 10;
if (DebugDataIntervall > 0) DebugDataAnforderung = 1;
if(DebugDataIntervall > 0) DebugDataAnforderung = 1;
break;
 
case 'h':// x-1 Displayzeilen
495,11 → 498,10
SendOutData('G',MeineSlaveAdresse, 1, (unsigned char *) &ExternControl, sizeof(ExternControl));
GetExternalControl = 0;
}
 
if((CheckDelay(Kompass_Timer)) && UebertragungAbgeschlossen)
{
WinkelOut.Winkel[0] = (int) (IntegralNick / 130); // etwa in 0.1 Grad
WinkelOut.Winkel[1] = (int) (IntegralRoll / 130); // etwa in 0.1 Grad
WinkelOut.Winkel[0] = (int) (IntegralNick / (EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad
WinkelOut.Winkel[1] = (int) (IntegralRoll / (EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad
WinkelOut.UserParameter[0] = Parameter_UserParam1;
WinkelOut.UserParameter[1] = Parameter_UserParam2;
SendOutData('w', MK3MAG_ADDRESS, 1, (unsigned char *) &WinkelOut,sizeof(WinkelOut));
506,12 → 508,20
if(WinkelOut.CalcState > 4) WinkelOut.CalcState = 6; // wird dann in SPI auf Null gesetzt
Kompass_Timer = SetDelay(99);
}
if((( DebugDataIntervall>0 && CheckDelay(Debug_Timer)) || DebugDataAnforderung) && UebertragungAbgeschlossen)
if(((DebugDataIntervall>0 && CheckDelay(Debug_Timer)) || DebugDataAnforderung) && UebertragungAbgeschlossen)
{
SendOutData('D', FC_ADDRESS, 1, (unsigned char *) &DebugOut,sizeof(DebugOut));
DebugDataAnforderung = 0;
if(DebugDataIntervall>0) Debug_Timer = SetDelay(DebugDataIntervall);
}
if(Intervall3D > 0 && CheckDelay(Timer3D) && UebertragungAbgeschlossen)
{
Data3D.Winkel[0] = (int) (IntegralNick / (EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad
Data3D.Winkel[1] = (int) (IntegralRoll / (EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad
Data3D.Winkel[2] = (int) ((10 * ErsatzKompass) / GIER_GRAD_FAKTOR);
SendOutData('C', FC_ADDRESS, 1, (unsigned char *) &Data3D,sizeof(Data3D));
Timer3D = SetDelay(Intervall3D);
}
if(DebugTextAnforderung != 255) // Texte für die Analogdaten
{
SendOutData('A', FC_ADDRESS, 2, (unsigned char *)&DebugTextAnforderung, sizeof(DebugTextAnforderung),(unsigned char *) ANALOG_TEXT[DebugTextAnforderung], 16);
/trunk/uart.h
40,6 → 40,13
};
extern struct str_WinkelOut WinkelOut;
 
struct str_Data3D
{
signed int Winkel[3]; // nick, roll, compass in 0,1°
signed char reserve[8];
};
extern struct str_Data3D Data3D;
 
struct str_ExternControl
{
unsigned char Digital[2];
108,5 → 115,21
# define INT_VEC_TX SIG_USART_TRANS
#endif
 
#if defined (__AVR_ATmega644P__)
# define USR UCSR0A
# define UCR UCSR0B
# define UDR UDR0
# define UBRR UBRR0L
# define EICR EICR0B
# define TXEN TXEN0
# define RXEN RXEN0
# define RXCIE RXCIE0
# define TXCIE TXCIE0
# define U2X U2X0
# define UCSRB UCSR0B
# define UDRE UDRE0
# define INT_VEC_RX SIG_USART_RECV
# define INT_VEC_TX SIG_USART_TRANS
#endif
 
#endif //_UART_H
/trunk/version.txt
225,4 → 225,12
0.72M: H.Buss 13.02.2009
- Code Cleanup
 
0.72o: H.Buss 24.02.2009
- Abtastrate auf 2kHz
- HW-Version an Navi
- neuer Datensatz 'c' -> Lagedaten für 3D-Grafik
- Auswerteroutine für Spectrum-Satteliten implementiert
- Kanalsettings werden beim Parameterreset nicht mehr gelöscht