Software und Hardware für Solarflieger

Halbwegs bekanntes Terrain,

bleiben halt immer ein paar Fragen .. ihr macht ja immer nur "Braindumps" .. ;), wer da nicht ständig mitliest, weiss ja nu gar nicht mehr watt sache ist.
1. Spannungsteiler ist für für wieviele Solarzellen ,27k / 10k also der resultierende Spannungsmessbereich ?
2. Wozu D2-D3-D4 brücken ?
3. RX zu TX 1K2 für Hott , watt mache ich an der Stelle ohne HOTT, ?? Hmhm wohl eher gar nichts.
4. RAW 5V BEC (auf dem Bild unten links 2x Rot), ich denk du wolltest ganzen RC-Kreis mit 3.3V fahren, also doch einen Stepup oder Buck/Boost Pololu davor ?
braucht der 32u4 8 MHZ denn da 5v , sollte der nicht VCC sowie intern Signalpegel 3.3v haben ?
5. Lasst den Code bei der Schaltung, jetzt geht eine Sucherei los, die kein gutes Ende findet.
6. sind sie paar MHz nicht zu langsam ?

... sonst steuer ich den MPP wieder nach Gehör ..:D

edit: Frage 4. hat sich fast erledigt, ok ;da kann rein von - bis, was ist mit den Empfehlungen Vinput sollte 1V größer sein als die 3.3V ?
gruss rudi ...
 
Zuletzt bearbeitet:
Moin Rudi
Am WE komme ich hoffentlich dazu eine Anleitung zu schreiben.
Morgen soll ja die Sonne strahlen, dann kann ich nochmal schön testen. BETA1 ist soweit fertig :)

1) bis 9,5V (Aref 2,56V) - mit anderen Widerständen natürlich auch höher.

2) D2 (INT0) liest steigende Flanke, D3 (INT1) fallende Flanke, D4 (ICP) macht präzise Zeitstempel, man könnt auch alles auf D4 machen, und den ICP-Interrupt aufrufen, aber dann müsst man den Pin abfragen das kostet (ein ganz klein wenig) Zeit, und wäre zu einfach :rolleyes: (soll ich das ändern ???)

3) jepp, warten und hoffen das wer Jeti nachfügt. Ich kann kein Jeti:( (bin da guter Hoffnung das sich jemand für Jeti und FrSky findet)

4) 5V oder mehr Volt an RAW, damit der interne Stabi 3,3V macht, würdest man es an VCC klemmen, rennt der Prozessor mit 5V, dann funzt Telemetrie nicht.
EDIT -- der Empfänger bleibt weiterhin an den 5V.

5) Bin grad dabei eine Miniseite zu machen, wo nachher alles draufsoll, später dann ein Blogbeitrag hier im Forum.

6) Für mit ohne Telemetrie habe ich schon mit 1MHz rum-getestet, aber unter 8MHz spart ,man kaum mehr Strom. Die 16MHz dagegen merkt man schon (1Servo im Stand), 16MHz funzt nicht mit den 3,3V die wir für die Telemetrie brauchen.

7) Ruhe- ich fliege nach Gehör..... :D :p :rolleyes:


Die ungetestete Beta1 - muss noch in die Sonne, danach mach ichs noch hübsch, und dann am WE online, auf das getestet werden mag :)

Code:
//    _ __ ___  _ __  _ __   ___ 
//   | `_ ` _ \| '_ \| '_ \ / __)     (c)2018 by IsVölligWurschd 
//   | | | | | | |_) | |_) | (__
//   |_| |_| |/| .__/| .__/ \___)
//             |_|   |_|   Telemetrie MPPC-MAXIMIZER for Solarmodelling 
//
//
//++++++++++++++++ USER MENUE START +++++++++++++++++++++++++++++++++++

uint8_t TEMPCAL = 83;    // default is 100 cal in 1° steps

float   VOLTCAL = 5.44;  // defalt is 5.45 Voltage Calibration  higher is lower volt

uint8_t MPPGAIN = 5;     // default=5 1=FAST 10=SLOW that make MPP faster,

uint16_t Pdown = 1500;   // 1000=STRONG 1500=MIDLE 2000=LOW

//  #define Telemetrie_SERIAL  // Do never fly with Serialdabug !!!! 
    #define Telemetrie_HOTT   
//  #define Telemetrie_JETI
//  #define Telemetrie_OFF

//+++++++++++++++ USER MENUE ENDE ++++++++++++++++++++++++++++++++++++++

volatile uint16_t RC=0, Solarvolt, Temp_20;
uint32_t MPP;

void setup() {             
    PORTD |= 0b00010000;    // Read RC Pullup aktiviert
    TCCR1A = 0b00000000;    // Read RC Normal PWM-Mode 
    TCCR1B = 0b01000010;    // Read RC ICP aktivieren, Prescale 1/8
    EIMSK  = 0b00000011;    // Read RC Interupts INT0 + INT1 aktiviert
    EICRA  = 0b00001011;    // Read RC Interrupt INT1=falling-edge INT0=rising-edge

    DDRC  |= 0b01000000;    // PPM_OUT
    TCCR3A = 0b10000010;    // PPM_OUT
    TCCR3B = 0b00011010;    // PPM_OUT
    ICR3   = 2000;          // PPM_OUT}    
    OCR3A  = 1100;          // 1100uS zum Init an den Regler ausgeben

    TELEMETRIE_init();      // Telemetrie init, siehe Unterprogramme
    Serial.begin(500000);
    delay(2500);            // warten bis Regler initialisiert ist 
}

void loop() {
//-----------Schleife mit PWM Timer 500Hz sycronisieren-------------
  while (TIFR3  & (1<<TOV3)){               // OVF -Flag abfragen, wenn gesetzt dann
         TIFR3 |= (1<<TOV3);                // OVF1 Flag löschen, und Schleife starten
         
//------------MPP berrechnen-------------- 
//static uint8_t loopcount; loopcount++; if (loopcount == 0 ){ 
    MPP  = 2400-RC;               
    MPP -= MPP*Temp_20*3/1000;                // Temperaturkompensation            
  //MPP  = MPP*(Pdown-(2000-OCR3A)/20)/Pdown; // Leistungskompensation          
// }
 
//----------Sachen machen ----------
    TELEMETRIE_send();                     // Telemetriedaten übergeben, siehe Unterprogramm 
    analog_Read();                         // Solarspannung und Temp-Sensor lesen, siehe Unterprogramm 
//--------uuund regeln ------------------------------
if (Solarvolt > MPP) {if (OCR3A < 1900) {OCR3A += +1 + ((Solarvolt - MPP) / MPPGAIN); }} //Voltage to high -inc PWM
else                 {if (OCR3A > 1100) {OCR3A += -1 - ((MPP - Solarvolt) / MPPGAIN); }} //Voltage to high -dec PWM

//Serial.println(TCNT3);
//Serial.println(OCR3A);
}}  // # # # # # # # # # # LOOP ENDE # # # # # # # # # # //


// # # # # # # # # # # analog_Read START # # # # # # # # # # //
void  analog_Read(){
      ADMUX  = 0b11000111; //ADC Tempsensor
      ADCSRB = 0b00100000;
      ADCSRA = 0b11000110;     
      while (ADCSRA & (1<<ADSC)) ;
      Temp_20 = ADCW + TEMPCAL - 340;         //KALIBRATION
      
      ADMUX  = 0b11000110; //ADC6
      ADCSRB = 0b00000000;
      uint16_t Utemp = 0; 
for  (int i=1; i <= 5; i++){    
      ADCSRA |= (1<<ADSC);  
      while (ADCSRA & (1<<ADSC)) ;
      Utemp = Utemp + ADC; 
}     Solarvolt = Utemp / VOLTCAL;       // auf centiVolt realwert kalbrieren

}// # # # # # # # # # # analog_Read ENDE # # # # # # # # # # //


// # # # # # # # # # # Read-RC-ISR-Routinen START # # # # # # # # # # //
ISR(INT0_vect){               // Read RC- rising edge
    OCR1A  = ICR1;            // ICP-Timestamp in OCR1A zwischenspeichern
    TCCR1B = 0b00000010;      // ICP auf falling edge stellen
} 
ISR(INT1_vect){               // Read RC- falling edge,
    RC     = ICR1-OCR1A;      // RC berrechnen
    TCCR1B = 0b01000010;      // ICP auf rising edge stellen
    TCNT1  = 0b00000000;      // Zähler zurücksetzen um Überläufe zu meiden    
}// # # # # # # # # # Read-RC-ISR-Routinen ENDE # # # # # # # # # # //


// # # # # # # # # # # TELEMETRIE BEGIN # # # # # # # # # # //
#ifdef Telemetrie_HOTT                    // HOTT-Telemetrie Start
volatile uint8_t  HOTT[46];
   
void TELEMETRIE_send(){    
    HOTT[0]   = 0x7C;                     // Start Byte
    HOTT[1]   = 0x8C;                     // 8C = ESC
    HOTT[2]   = 0x00;                     //
    HOTT[3]   = 0xC0;                     // <<4
    HOTT[4]   = 0x00;                     // ALARM 
    HOTT[5]   = 0x00;                     // ALARM
    HOTT[6]   = (uint8_t)(Solarvolt&255); // L-Byte Spannung in cV
    HOTT[7]   = (uint8_t)(Solarvolt>>8);  // H-Byte Spannung in cV
    HOTT[8]   = (uint8_t)(MPP&255);       // L-Byte Spannung_min in cV     
    HOTT[9]   = (uint8_t)(MPP >>8);       // H-Byte Spannung_min in cV   
  //HOTT[10]  = (uint8_t)(looptime&255);  // L-Byte Kapazität in cAh
  //HOTT[11]  = (uint8_t)(looptime >>8);  // H-Byte Kapazität in cAh                                          
    HOTT[12]  = Temp_20;                  // Temp 1a Offset-20
  //HOTT[13]  = Temp1B;                   // Temp 1b Offset-20
    HOTT[14]  = (uint8_t)(MPP&255);       // L-Byte Strom in dA
    HOTT[15]  = (uint8_t)(MPP >>8);       // H-Byte Strom in dA
  //HOTT[16]  = (uint8_t)(AmpMax);        // L-Byte Strom_max in dA
  //HOTT[17]  = (uint8_t)(Amp_Max);       // H-Byte Strom_max in dA
    HOTT[18]  = (uint8_t)(OCR3AL);        // L-Byte RPM/10
    HOTT[19]  = (uint8_t)(OCR3AH);        // H-Byte RPM/10
    HOTT[20]  = (uint8_t)(0x6c);          // L-Byte RPM_max/10    
    HOTT[21]  = (uint8_t)(0x07);          // H-Byte RPM_max/10   
    HOTT[22]  = OCR3A/8-117;              // Temp2a Offset-20
  //HOTT[23]  = Temp2A;                   // Temp2b Offset-20
    HOTT[43]  = 0x7D;
}

void TELEMETRIE_init(){
    UBRR1L    = 0b00011001;      // Hott-UART 19200 Baud         
    UCSR1B    = 0b10011000;      // Hott-RX Interrupt aktiviert
    TCCR4A    = 0b00000000;      // Hott-Delay-Timer läuft alle 2048uS über, wird erst in der Hott-ISR gestartet
    TCCR4B    = 0b00000000;      // Hott-Delay-Timer STOP, damit ohne Hott steht, aktiviert sich in der Hott-ISR
    TIMSK4    = 0b00000100;      // Hott-Delay-Timer Overflow ISR aktiviert 
}

ISR(USART1_RX_vect){
if  (UDR1    == HOTT[1])         // Hott hat nach Daten gerufen, Senderoutine wird gestartet:
{   UCSR1B    = 0b00001000;      // Hott-RX-Interrupt wird während der Senderoutine gesperrt,
    HOTT[44]  = 0b00000000;      // Hott-Checksum auf Null stellen,
    HOTT[45]  = 0b11111110;      // Hott-Counter-Byte zurücksetzen 3 OVFs Vorlauf für 6mS
    TCNT4     = 0b10000000;      // Hott-Delay-Timer zurücksetzen 1/2 Cycle abkürzen für 5mS
    TCCR4B    = 0b00000110;      // Hott-Delay-Timer starten, 2048uS pro Überlauf, Prescale 1/8
}}

ISR(TIMER4_OVF_vect){            // Hott-Delay-Timer läuft im Sendebetrieb alle 2048uS über
if  (HOTT[45] < 0b00101101)      //  Solange noch nicht 45 alle Bytes gesendet sind, Sendung mit der Maus:
{                                         //while (!(UCSR1A & (1<<UDRE1))){} <---WIRKLICH NÖTIG ??? 
    UDR1      = HOTT[HOTT[45]];  //  aktuelles Hott-Byte schreiben
    HOTT[44]  = HOTT[44]         //  Hott-Checksum HOTT[44] bauen, es wird nur das L-Byte gesammelt,
              + HOTT[HOTT[45]];  //  und mit dem aktuellem Hott-Byte addiert.      
}else{  
if  (HOTT[45]== 0b00101101)      // Wenn alle 45 Bytes gesendet wurden, ist Sendeschluss: 
{   TCCR4B    = 0b00000000;      //  Hott-Delay-Timer stoppen, keine OVFs mehr.
    UCSR1B    = 0b10011000;}     //  Hott-RX-Interrupt wieder aktivieren (Empfangsbereit -ohne GEZ).            
}   HOTT[45] ++ ;                //  Nach jedem Durchlauf wird das Hott-Counter-Byte um 1 erhöht. 
}
#endif // HOTT TELEMETRIE ENDE 

#ifdef Telemetrie_SERIAL      // Serialdebug, 
void TELEMETRIE_send(){       // Wird einmal pro loop ausgeführt, sync mit 500Hz
static uint8_t loopcount; 
loopcount++;                  // 2x pro Sekunde
if (loopcount == 0 ){
Serial.print("mV  ");   Serial.println(Solarvolt);
Serial.print("MPP ");   Serial.print(MPP);   
Serial.print(" / ");    Serial.println(2400-RC);
Serial.print("PWM ");   Serial.println(OCR3A);
Serial.print("°C: ");   Serial.println(Temp_20-20);
Serial.println();
}}
void TELEMETRIE_init(){}
#endif

#ifdef Telemetrie_JETI //Platzhalter für JETI Telemetrie
void TELEMETRIE_send(){}
void TELEMETRIE_init(){TCCR4B=0b00000000;}
#endif

#ifdef Telemetrie_OFF  //Platzhalter für mit-ohne Telemetrie
void TELEMETRIE_send(){}
void TELEMETRIE_init(){TCCR4B=0b00000000;}
#endif

// # # # # # # # # # # TELEMETRIE ENDE # # # # # # # # # # //
 
Und wenn man auf den VCC -Pin mit 3.3V als externe Betriebsspannung draufgeht ( .. aus dem Pololu ) ?
geht das nicht auch, wenn ich das Pinout richtig verstanden habe ?


Soweit ich das sehe, haben meine Regler alle kein BEC, somit kein 5V vorhanden.
Habe nur Solarspannung und dann eben runter auf 3.3V mit dem Low-drop 3.3V Polulu,
das schien bisher ein guter Ansatz zu sein.


Soviele unterschiedliche Potentiale finde ich nicht gerade toll, aber wenns für den Zweck sein muss.
Muss ich halt grübeln:
a) Stepup von 3.3 => 5 oder 6V,
b) Solarspannung direkt auf RX + Raw des ProMicro
c) Solarspannung Stepdowned auf 5v für RX und Raw
 
Moin Rudi

Wenn du 3,3V BEC hast, kannst Du entweder mit den 3,3V direkt auf VCC, oder mit der Solarspannung auf RAW, so wie es mit Deiner Verkabelung besser zusammenpasst.

Praktischer ist vermutlich den Widerstand 27K direkt von RAW nach A1 auf der Unterseite zu löten, und Solarspannung dann auf RAW. (Vielleicht generell auch per Anleitung so machen?)

An RX kommt keine Spannung, da kommt Telemetrie dran.


EDIT - Version 2 -auch vorläufig und andere Schreibweise (ist die Besser?)

D234 Brücke habe ich rausgeworfen nur noch D4

Widerstand 10K von GND zu A1
Widerstand 27K von RAW zu A1
Widerstand 1k2 von RX zu TX (Nur bei Telemetrie)

RAW = Solarspannung
GND = Minus
D4 = Impuls Gaskanal
D5 = Impuls Regler
RX = Telemetrie (nur bei Telemetrie)
 
Nun auch online:

http://solarflug.lambertus.info/MPPC_T.html



MPPC_T6.jpg
 
Der neue Volks-MPP

Der neue Volks-MPP

Moin
Schonmal eine Vorschau auf die nächste Version.

Neu ist:
Es rennt jetzt auf den meisten Arduinoboards, und sogar auf der Attiny x4 Serie.
Code:
BOARD         CPU  Freq   RC  ESC  Solar  Resistors  AREF
ARDUINO NANO  328p 16MHz  D8  D10   A4    10K + 82K  1,10V
ARDUINO MINI  328p  8MHz  D8  D10   A4    10K + 82K  1,10V
ARDUINO MINI  328p 16MHz  D8  D10   A4    10K + 82K  1,10V 
ARDUINO MICRO 32u4  8MHz  D4  D10   A1    10K + 27K  2,56V
ARDUINO MICRO 32u4 16MHz  D4  D10   A1    10K + 27K  2,56V
ATTINY44/84         8MHz  D7  D5    A0    10K + 82K  1,10V

Die ArduinoBoards mit USB bekommt man ab 2-3€, und sollte für Jeden ohne Programmierkenntnisse nach Anleitung nutzbar sein.

Die Sachen mit-ohne USB sind dann eher was für die Bastlerfraktion, ---ein Attiny DIP14 Chip wiegt 0,8g und kostet 80Cent, so geht es dann auch ohne SMD :) Nächster Schritt ist der Attiny 441/841, das Winzding wiegt 0,2g inkl 2xUART, ist grad so noch Handverlötbar, bzw es gibt ihn als Micro-USB Board als "Wattuino Nanite 841".

Hott rennt vorerst nur auf den 3,3V Boards, ich bin noch auf der Suche nach der richtigen Einfachst-Schaltung, das Hott auch an den 5V Boards funzt. (ToDo)


Der Code erkennt automatisch über die Arduino-IDE das Board, es muss nichts eingestellt werden.
Ja, Arduino-IDE ! Ich bin kein Arduino-IDE Fan, aber warum nicht die Vorteile der höheren Hardwareunabhängigkeit und die Einfachheit in Bedienung für solch ein Projekt nutzen ?

Erreicht wurde das, indem nun alles auf dem einem 16Bit Timer1 läuft, Alles inkl der Telemetrie ohne blocking. :)

-Der PWM Timer taktet wie bisher im 2mS 500Hz um die PPM an den Regler auszugeben, ein tik pro uS.

Zum einlesen braucht man deshalb nichtmal den overflow, da die Signale auch 1-2mS lang sind.
Ist der Wert von steigender Flanke kleiner als der von der fallenden Flanke, gab es keinen Overflow, ist er größer, gab es einen und man addiert 2000 dazu. Extrem simpel, muss man nur mal drauf kommen :cool:

Die Schleife taktet, wie gesagt in 500Hz 2mS, Hott will die Bytes in 2mS haben .....*klingeling* also einfach mit einschleifen.
Habe eteas rummprobiert, vor des erstem Sendbyte soll ja lt- Protokoll 5mS gewartet werden, verkürzt man das, kommt es schnell aus dem Lot, darüber habe ich bis 10mS getestet, rennt problemlos. Wenn der Sender nach DAten fragt, wird nun drei runden ausgesetzt (Byte 0-2) und ab Byte drei die 45Bytes gesendet. Startsignal ist wenn der Bytecounter unter 48 gerät. So stelle man den Counter auf Null, der Sendebetrieb geht automatisch los.

Die Hott-Bytes werden nicht mehr im Array gespeichert, spart etwas Sram, für sehr kleinere Attinys,

Einige Boards nutzen Uart1 für Telemetrie, einige andere Uart0, ist auch berücksichtigt.

Hier nur mal eine grobe Vorschau, so einige Ecken und Kanten, Pinzuordnungen u.s.w. will ich noch bei. Im "trockentest" rannte es schon auf unterschiedlichen Boards.





Code:
uint8_t MPP_delay = 5;    // 1-10 higher is slower, Only use when you know what you doing (RTFM) !! 
float   Voltcal   = 10.9;  // Calibration for Telemtrie, Only use when you know what you doing (RTFM) !! 

uint16_t RC, MPP, SVolt,  ICR1a;
uint8_t  SolarP, count=47, csum;

void setup() { 

#if   defined   (__AVR_ATmega32U4__)
      SolarP  = A1;             // Select Solarvoltage Pin
      DDRB   |= 0b01000100;     // ESC-PPM-OUT OC1B 32u4 = PB6(D10)
      PORTD  |= 0b00010000;     // READ-RC-IN  ICP1 32u4 = PD4(D4) 
      #define   UART_1
      HOTTSTART(); 
      
#elif defined   (__AVR_ATmega328P__) 
      SolarP  = A4;             // Select Solarvoltage Pin
      DDRB   |= 0b01000100;     // ESC-PPM-OUT OC1B 328p = PB2(D10) 
      PORTB  |= 0b00000001;     // READ-RC-IN  ICP1 328p = PB0(D8) 
      #define   UART_0 
      HOTTSTART();
      
#elif defined   (__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
      SolarP  = A0;             // Select Solarvoltage Pin
      DDRA   |= 0b00100000;     // ESC-PPM-OUT OC1B Attinyx4 = PA5(D5) 
      PORTA  |= 0b10000000;     // READ-RC-IN  ICP1 Attinyx4 = PA7(D7)        
#endif   

#if   F_CPU  == 8000000     
      TCCR1A  = 0b00100011;     // Fast PWM,   OC1A as Top, OC1B is PWM
      TCCR1B  = 0b01011010;     // ICP-rising, Prescale 1/8
#elif F_CPU  == 16000000     
      TCCR1A  = 0b00100011;     // Normal PWM, OC1A as Top, OC1B is PWM
      TCCR1B  = 0b01010010;     // ICP-rising, Prescale 1/8
#endif 

      TIMSK1  = 0b00100000;     // ICP-ISR activ
      OCR1A   = 2000;           // PPM-OUT Timer Top for 2mS 500Hz
      OCR1B   = 1100;           // Start PPM ESC
      sei();
      analogReference(INTERNAL);
      delay(2500);              //wait init ESC
}

void loop(){
while(TIFR1   & (1<<TOV1))          // OVF -Flag abfragen, taucht alle 2mS auf.
{     TIFR1  |= (1<<TOV1);          // wenn gesetzt dann OVF1 Flag löschen.            
      Telemtrie_send();             // Telemetrie, wenn aktiv, siehe Unterprogramm           
      MPP     = 2200 - RC;          // RC wird in die ADC range gewandelt                       
      SVolt   = 0;                  // SVolt zurücksetzen
      for(int i=1; i<=10; i++)      // Schleife zum ADC runden
{     SVolt  += analogRead(SolarP); // alle ADC Werte addieren  
}     SVolt  /= Voltcal;            // teilen und zugleich Kalibrieren

  if (SVolt > MPP) {if (OCR1B < 1900) {OCR1B += +1 + ((SVolt - MPP) / 5); }} //Voltage to high -inc PWM
  else             {if (OCR1B > 1100) {OCR1B += -1 - ((MPP - SVolt) / 5); }} //Voltage to high -dec PWM
}}


ISR (TIMER1_CAPT_vect) {          // RC READ ISR  
if(TCCR1B   &  (1<<ICES1))        // we have rising edge -
{   TCCR1B &= ~(1<<ICES1);        // switch ICP to falling edge                                             
    ICR1a   =  ICR1;              // store ICP1 IN ICP1a
} else                            // we have falling edge
{   TCCR1B |=  (1<<ICES1);        // switch ICP @ rising edge                                               
 if (ICR1   <  ICR1a)             // if Overflow ? 
       {RC  =  ICR1+2000-ICR1a;}  // Yes > Calc RC with OVF
 else  {RC  =  ICR1     -ICR1a;}  // No  > Calc RC without OVF
}}



// AB HIER NUR NOCH TELEMETRIE-ZEUG, KEIN MPP-ZEUG MEHR !!!! 

#if defined UART_1  ||  defined UART_0

void Telemtrie_send(){
  if (count<48){  
  switch(count){ 
    default:  HOTTSEND(0x00);           break;
    case  3:  HOTTSEND(0x7C);           break;  // Start Byte
    case  4:  HOTTSEND(0x8C);           break;  // 8C = ESC
    case  6:  HOTTSEND(0xC0);           break;  // Start Byte<<4 
    case  9:  HOTTSEND(SVolt&255);      break;  // L-Byte Spannung        >>> Solarvolt--IST
    case 10:  HOTTSEND(SVolt>>8);       break;  // H-Byte Spannung
  //case 11:  HOTTSEND(0xff);           break;  // L-Byte Spannung_min  
  //case 12:  HOTTSEND(0xff);           break;  // H-Byte Spannung_mi
  //case 13:  HOTTSEND(0xff);           break;  // L-Byte Kapazität
  //case 14:  HOTTSEND(0xff);           break;  // H-Byte Kapazität
    case 15:  HOTTSEND(35);             break;  // Temp 1A Offset-20 
    case 16:  HOTTSEND(36);             break;  // Temp 1B Offset-20
    case 17:  HOTTSEND(MPP&255);        break;  // L-Byte Strom in cA 
    case 18:  HOTTSEND(MPP>>8);         break;  // H-Byte Strom in cA
  //case 19:  HOTTSEND(0xff);           break;  // ??
  //case 20:  HOTTSEND(0xff);           break;  // ??
    case 21:  HOTTSEND(OCR1BL);         break;  // L-Byte RPM
    case 22:  HOTTSEND(OCR1BH);         break;  // H-Byte RPM
  //case 23:  HOTTSEND(0xff);           break;  // L-Byte RPM_max
  //case 24:  HOTTSEND(0xff);           break;  // H-Byte RPM_max
    case 25:  HOTTSEND(45);             break;  // Temp2A Offset-20 
    case 26:  HOTTSEND(46);             break;  // Temp2B Offset-20
    case 46:  HOTTSEND(0x7D);           break;  // End Byte 
    case 47:  HOTTSEND(csum); csum = 0; HOTT_RxON();  break;  // CheckSum alle Bytes durch, RX starten
} }}
#else                                           // Dummy für Boards mit-ohne Telemtrie
void Telemtrie_send(){}
#endif

#if defined UART_1                  
    void  HOTTSTART() { UBRR1L  = F_CPU/307200-1; }
    void  HOTT_RxON() { UCSR1B  = 0b10011000;     }
    void  HOTTSEND    (uint8_t Byte)   
    { if (count   > 2)  
       {  UDR1    = Byte;           // send actual Hott-Byte
          csum   += Byte;           // build Hott-Checksum   
       }  count  ++ ;             
    }
    ISR  (USART1_RX_vect)         
    { if (UDR1   == 0x8C)           // Hott hat nach Daten gerufen, Senderoutine wird gestartet:
       {  UCSR1B  = 0b00001000;     // Hott-RX-Interrupt wird während der Senderoutine gesperrt,
          count   = 0b00000000;     // Hott-Counter-Byte zurücksetzen 3 OVFs Vorlauf für 6mS
    }  }

 
#elif defined UART_0
    void  HOTTSTART() { UBRR0L  = F_CPU/307200-1; }
    void  HOTT_RxON() { UCSR0B  = 0b10011000;     }
    void  HOTTSEND    (uint8_t Byte)   
    { if (count   > 2)  
       {  UDR0    = Byte;           // send actual Hott-Byte
          csum   += Byte;           // build Hott-Checksum   
       }  count  ++ ;             
    }
    ISR  (USART0_RX_vect)         
    { if (UDR0   == 0x8C)           // Hott hat nach Daten gerufen, Senderoutine wird gestartet:
       {  UCSR0B  = 0b00001000;     // Hott-RX-Interrupt wird während der Senderoutine gesperrt,
          count   = 0b00000000;     // Hott-Counter-Byte auf Null setzen startet die Senderoutine
    }  } 
 

#endif
 

bendh

User
Hallo Holger,

Frage zur Telemetrie, wird der "VolksMPP" eines Tages auch mit FrSky reden können?

Ich habe den langen Solarflug Beitrag versucht zu lesen, aber da herrscht so ein Durcheinander. Gibt es eine einfache Anleitung um sich so ein Solarmodell zu bauen?
 
@Bernd
Genau das frage ich mich auch schon die ganze Zeit. Eine Shopping Liste wäre schon hilfreich. Flieger hab ich schon konzipiert, aber bei den Solarkomponenten und deren Beschaffung hapert es und die beiden Threads über Solarflieger bringen einen Dummie wie mich nicht weiter.

Gruß Frank
 
Was genau soll auf dieser Shoppingliste stehen bzw was fehlt- was hast du bereits ?

Ich habe auch die Regelung noch nicht in trocken Tüchern.
 
Moin
Ich könnte mal eine Liste auf meiner Seite zusammenschreiben, was man wo bekommt, und welche Sachen sich so bewährt haben.

Guter Standard der sich für das 12Zellen Setup bewährt hat:
AXI 2212/34 oder was selber gewickeltes.
Aeronaut 11x12 (Tuning: Hälse auf 6mm runterschleifen und kürzen, das Blatt állg. dünner schleifen, halbes Gewicht ist machbar)
28-30mm Mittelstück, entweder selber was fräsen, oder HM-Leichtspinner stark runterfeilen.

Solarzellen habe ich noch E60 Bin-H (werksselektiere), da kann ich noch welche von abgeben. Ansonsten Ebay-Lotterie.
http://solarflug.lambertus.info/index.php?id=sunpower-bincode

Steuerung, für die "erste Hilfe" werden wir in Michas Shop nächste Woche ein paar fertig bespielte Arduinos und attiny-DIP Chips zum Selbstkostenpreis reinpacken, damit das logistisch automatisch "rund" läuft. (321meins).
Den Attiny44 12Pin-DIP-Chip 0,8g. Software und Firmware Updater gleich mit drauf, Widerstände liegen dann passend auch bei, teilverlötet als "Bausatz".
Und irgendeinen Arduino, wahrscheinlich den Mini für mit-Telemetrie.

zwei weitere Firmen sind auch drann, bis zur Saison wird es wohl einiges geben.



Mit der Software bin ich am Wochende auch wieder ein grosses Stück weiter:
FrSky und Jeti müsste jemand anderes drann, da ich selber ausschlieslich Hott fliege, und mir nicht nut fürs Proggen solche Anlagen kaufe .

-Für die Telemetrie habe ich TX und RX gegeneinander kmpl gesperrt, und so den Widerstand dazwischen eingespaart. Wichtiger war mir dabei, nun sind auch die 5V Versionen mit der bekannten Z-Diode-Widerstand Kombi nutzbar auch mit Telemetrie nutzbar. (Besser ist trotzdem die 3,3V Version).

-Ich habe angefangen "Internet - Unterseiten" für die einzelnen verschiedenen Boards zu erstellen, damit die vielen Möglichkeiten der Software nachher nicht unübersichtliche werden. Damit ich nun noch jede Boardvariante für ien Foto kaufen und löten muss, mache ich die Bilder mit "Fritzing" -funzt super dafür-

-Attiny 841 ist nun auch mit drinn und gestestet. Telemetrie rennt auf beiden Serialports. Boards z.B: das winzige Wattunino nanite 841
20150131_1.jpg
https://www.watterott.com/de/Wattuino-Nanite841

oder man lötet sich was mit SMD (als Platine so eine billige Soic-DIP Adapter Platine, auch lasse ich für den Eigenbedarf bald Platinen mit dem Chip machen, aus soner Eurokarte kommen ja ewig viele Platinen bei raus, das wird dann die Version mit den Tantal-Elkos auf der Rückseite). Da kann ich dann auch gerne "Rohplatinen" von abgeben, ist dann aber def. nicht Anfängertauglich !

doch unfertige Spielerei mit dem 841, so das es noch Handverlötbar bleibt , das funzt dann auch mit Telemtrie. (übe noch etwas mit dem Proggi, hätte nicht gedacht das es derart simpel ist, Platinen zu machen, erinnert etwas an Lego spielen, ein Klötzchen hier, und eins da :) ): Mal schauen wohin sich das in den nächsten Monate noch entwickelt ;) :D

8412.jpg8411.jpg

Also quasi der Nachfolger von:
mppc_mini1.jpeg


Bisher sind in der Soft drinn:
Arduino Nano
Arduino Uno (alsUn fug :D)
Arduino Mini / Pro-Mini
Arduino Micro / Pro Micro (Leonardo Polulu A-Start u.s.w.)
Attiny 24 44 84 (auch als DIP-Chip)
Attiny 441 / 841
Attiny 1634 (unfertig könnte auch als DIP Telemtrie)

Gibt es da noch Wünsche ? Vorraussetzung ist der klassische AVR mit dem 16Bit Timer1 und für die Telemetrie Hardware -Uart.
 
Sau geil, danke Holger. Sowas für jeder Mann das finde ich Extraklasse ! Wurde der Code mit dem 32U4 schon getestet (der von deiner Website)?
 
Moin
Ja es gab ein paar Rückmeldungen, trotz Winter.
2 Kollegen im auf der Südhalbkugel sind damit geflogen, alles bestens.
Einige haben es schon auch hier gebaut, es gab oft Probleme mit dem Treiber von dem 32u4 Leonardo Arduinoboard unter Windows, leider kann ich hier kaum helfen, da ich kein Windows habe. Am Ende hats dann aber geklappt. Probleme gab es auch mit anderen Boards, so das ich es nun auf das 32u4 Board eingegrenzt habe.
Es sind ein paar "kosmetische" Änderungen eingeflossen, aber die alte Version macht ihre Arbeit gut.
Die Tempsteuerung ist wieder rausgeflogen, der interne Sensor macht manchmal völligen Unsinn, ist aber weniger tragisch.
Am Telemetriesystem konnte ich noch einiges abspecken.
Kalibrierung vereinfacht.
Sobald ich selber wieder testen kann, sprich wenn Sonne ohne Saukälte ist, stell ich die Version2 online.


Das nächste Projekt sieht anders aus, Basis wieder Attiny44, den wird man dann auch billig für die Nichtprogrammierer als DIP-Chip (0,8g) fertig geproggt mitsammt den Widerständen im Shop beim Micha bekommen. Wer es kann, kann sich auch natürlich selber einen bespielen, er ist baugleich mit der SMD Version in meinem oberem Beitrag, oder gar die Platine selber fräsen.
Hott kann der attiny jetzt auch, ich nutze einfach den USI (i2c) für das einlesen, und clone mit einem Timer das clock-signal, das funzt super. Gesendet wird einfach Bitweise mit zeitlichem Abstand, einmal in den 2mS Zeitfenstern in der Loop gleich am Anfang, ein 19200er Byte dauert so knapp 0,5mS, dann ist noch 1,5mS Zeit MPP-zu reglen. So kommt sich nichts ins Gehege, und die Steuerung läuft sauber und differnziert. Kommt kein Hott Signal (bei den armen Wichten die eine falsche Fernsteuerung gekauft haben ;);)) dann passiert einfach nichts, und alles ist auch gut.
 
Arduino Abgespeckt ..

Arduino Abgespeckt ..

Hallo Solarflugwillige ohne Telemetrie,
die doch selber den Arsch hochkriegen muessen.
Ich habe Holgers Arduino von (wann auch immer) etwas entschlackt.
Die Temperaturerfassung und Anpassung war echt irgendwie für garnix nuetzlich.

Was noch gefixt werden soll: PWM out nimmt immer noch Werte ausserhalb (des Fensters 1100-1900) ms an. (typischerweise 1907, 1080).....
Gibt der Pilot mehr Gas, bleibt PWM out ??? seehr lange auf 1100 ms, um dann sprunghaft auf Vollgas zu gehen. Der Stick-gesteuerten Mittelbereich ist mir noch schleierhaft..
Eher nur digitale Endausschläge :D





Code:
// Arduino IDe 1.8.8
// Boardlayout  Lilypad Arduino USB
// Programmer: USBtinyISP (AtTinyCore)
// Hardware: Arduino ProMicro 3.3V, z.B. Sparkfun.com
// Pinout: 
// RAW: +Vsolar
// GND: -Vsolar, -Rx, -ESC
// D4: <= RX Signal Motor
// D5: => ESC Signal
//
// v29 19-02-2019
// can touch this
uint8_t   SERIALMONITOR = 1;             // default: 0 0=schaltet die serielle Debugausgabe ab,  1=schaltet sie ein. Durch Debug wird der Schleifendurchlauf stark verlangsamt. Niemals im Debug Mode Fliegen gehen ! 
float     VOLTCAL = 5.44;                // default: 5.45 ein Anpassungsfaktor für Messergebniskalibrierung der Solarspannung Mit Multimeter und Debugausgabe einleveln
uint8_t   MPPGAIN = 5;                   // default: 5  Sprungwert zur Anpassung des Regelverhaltens bis zum MPP   1: langsames Anregeln zum StellPunkt, 10: sprunghaftes Anregeln zum Stellpunkt    
uint16_t  Abbruchspannung = 520;         // default: 520 bei Erreichen von 5.20V oder weniger wird der Antriebsmotor ohne weiteren Regelzyklus ausgemacht um rc-blackout zu verhindern
uint16_t  UntereKnueppelgrenze = 1100 ;  // default: 1100 feste untere Grenze im ms des Gaswertes festlegen um Fehlmessungen im Bereich darunter zu egalisieren
uint16_t  ObereKnueppelgrenze  = 1900 ;  // default: 1900 feste obere Grenze im ms des Gaswertes festlegen um Fehlmessungen im Bereich darueber zu egalisieren
// touch no further



volatile uint16_t RC=0, Solarvolt;
uint16_t MPP;

void setup() {    
           
    PORTD |= 0b00010000;                  // Read RC Pullup aktiviert
    TCCR1A = 0b00000000;                  // Read RC Normal PWM-Mode 
    TCCR1B = 0b01000010;                  // Read RC ICP aktivieren, Prescale 1/8
    TIMSK1 = 0b00100000;
    DDRC  |= 0b01000000;                  // PPM_OUT
    TCCR3A = 0b10000010;                  // PPM_OUT
    TCCR3B = 0b00011010;                  // PPM_OUT
    ICR3   = 2000;                        // PPM_OUT}    
    OCR3A  = 1100;                        // 1100uS zum Init an den Regler ausgeben

    
    Serial.begin(500000);
    delay(2500);                         // warten bis Regler initialisiert ist 
}

void loop() {
  
while(TIFR3  & (1<<TOV3)){              // OVF -Flag abfragen, wenn gesetzt dann OVF1 Flag löschen,
      TIFR3 |= (1<<TOV3);               // Schleife rennt nun mit 500HZ sync zu PPM-OUT 
 

      
  if (SERIALMONITOR == 1)               // Serial Debug siehe Unterprogramm
     {serialdebug();}   
           
      MPP  = 2400-RC;                   // MPP aus RC uebertragen
      ADMUX  = 0b11000110;              // ADC1 fuer Solarspannung waehlen
      ADCSRB = 0b00000000;
      uint16_t Utemp = 0;  

for  (int i=1; i <= 5; i++)             // zum Runden mehrfach lesen und addieren
     {            
      ADCSRA |= (1<<ADSC);  
      while (ADCSRA & (1<<ADSC)) ;
      Utemp = Utemp + ADC; 
     }    
Solarvolt = Utemp / VOLTCAL;      // bei 5 Durchläufen passt der Teiler von Variable VOLTCAL sehr genau
    
// Not aus  ob das gut geht ?
if (Solarvolt <= Abbruchspannung)
{
  OCR3A = UntereKnueppelgrenze;
}


if (Solarvolt > MPP) {if (OCR3A < ObereKnueppelgrenze) {OCR3A += +1 + ((Solarvolt - MPP) / MPPGAIN); }} //Voltage to high -inc PWM
else                 {if (OCR3A > UntereKnueppelgrenze) {OCR3A += -1 - ((MPP - Solarvolt) / MPPGAIN); }} //Voltage to high -dec PWM
  
                      //Serial.println(TCNT3); //check Looptime -only for debug
}}  // # # # # # # # # # # LOOP ENDE # # # # # # # # # # //


// # # # # # # # # # # Read-RC-ISR-Routine START # # # # # # # # # # //
ISR (TIMER1_CAPT_vect){
if  (PIND &(1<<PD4)){         // rising edge
    OCR1A  = ICR1;            // ICP-Timestamp in OCR1A zwischenspeichern
    TCCR1B = 0b00000010;      // ICP auf falling edge stellen
}else{                        // falling edge
    RC     = ICR1-OCR1A;      // RC berrechnen
    if (RC < UntereKnueppelgrenze) {RC = UntereKnueppelgrenze;};  //bei gemessenen Ausreissern nach unten feste Grenze setzen vom VariablenGrenzwert
    if (RC > ObereKnueppelgrenze) {RC = ObereKnueppelgrenze;};  //bei gemessenen Ausreissern nach oben feste Grenze setzen vom VariablenGrenzwert
    TCCR1B = 0b01000010;      // ICP auf rising edge stellen
    TCNT1  = 0b00000000;      // Zähler zurücksetzen um Überläufe zu meiden   
}}


// # # # # # # # # # # SERIALDEBUG # # # # # # # # # # //
void serialdebug(){       // Wird mit ca. 2Hz ausgeführt
static uint8_t loopcount; loopcount++;           
if (loopcount == 0 ){         // 2x pro Sekunde 
Serial.print("gemessene Spannung in V ");   Serial.println(Solarvolt);
Serial.print("MPP ");   Serial.println(MPP);   
Serial.print("Gasknüppelwert in ms ");    Serial.println(RC);
Serial.print("PWM in ms zu ESC ");   Serial.println(OCR3A);
Serial.println();
}}
 
So, wieder etwas weiter im Thema...

Die Spannungsmessung mit dem ProMicro ist ja erfreulicherweise extremst genau, sie scheint gegenüber ordentlichen Messgeräten eine maximale Abweichung von 0,01 V über den gesamten Messbereich von 4,8 bis 8V zu haben.
Zumindest was ich so mit meinen Apparaturen herausfinden konnte.

Der Regelkreis erscheint mir mit den ZehntelVolt allerdings etwas nervös, und macht mir in der Auswertung noch etwas Kopfzerbrechen.

Ich habe noch 2 Vorab Bedingungen eingebaut, einmal Motor-Notaus bei gemessener Solarspannung kleiner (anpassbar, momentan 5.2V), ohne hier noch mal durch weitere Schleifen zu laufen,
(Falls mal ne Monster-SpringWolke kommen sollte, oder sonst irgend ne unvorhergesehene Sache ...
und Dauerhaft Motor auf 0 bei Gasknüppel Stellung kleiner 1105 uS.


Frage: zeigt mir eine Jetibox zur PWM Messung angeschlossen an D5 sinnvolle Werte an, oder wird die aufgrund der Frequenz nen Blackout kriegen, oder Gedankenfehler meinerseits ?
Hab wie immer sehr wenig Zeit um´s selber auszutesten.
 
Hallo Rudi

In der ISR fehlt was; Orginal (letzte Version), der schaut nach dem Overflow, indem er schaut ob der erste Wert größer ist als der zweite, oder umgekehrt.
Code:
ISR (TIMER1_CAPT_vect) {              // RC READ ISR  
if(     TCCR1B  &  (1<<ICES1))        // we have rising edge -
{       TCCR1B &= ~(1<<ICES1);        // switch ICP to falling edge                                             
        ICR1a   =  ICR1;              // store ICP1 IN ICP1a
}else{  TCCR1B |=  (1<<ICES1);        // switch ICP @ rising edge                                               
   if(  ICR1    <  ICR1a)             // if Overflow ? 
          { RC  =  ICR1+2000-ICR1a;}  // Yes > Calc RC with OVF
   else   { RC  =  ICR1     -ICR1a;}  // No  > Calc RC without OVF
}}

Wenn Du einen Not-Aus willst, ein anderer Vorschlag, in der loop

if RC < 1200
dann RC Signal direkt 1zu1 zum Regler,
ansonsten... ab zur Solarregelung

Weil, dann könntest zugleich beim Landen im unterem Knüppelbereich die Bremse lösen und anziehen.




Ich habs mal auf nötigste ebgespeckt, ohne Serialzeug, mit Rudi Spezial-Notaus ;) (aber alles ungetestet)

Code:
uint16_t RC, MPP, SVolt,  ICR1a;

void setup() { 
      DDRB   |= 0b01010100;     // ESC-PPM-OUT OC1B 32u4 = PB6(D10)
      PORTD  |= 0b00010000;     // READ-RC-IN  ICP1 32u4 = PD4(D4) 
      TCCR1A  = 0b00100011;     // Fast PWM,   OC1A as Top, OC1B is PWM
      TCCR1B  = 0b01011010;     // ICP-rising, Prescale 1/8
      TIMSK1  = 0b00100000;     // ICP-ISR activ
      OCR1A   = 2000;           // PPM-OUT Timer Top for 2mS 500Hz
      OCR1B   = 1100;           // Start PPM ESC      
      sei();    
      analogReference(INTERNAL);
      delay(2500);              //wait init ESC
}
 
void loop(){
while ( TIFR1   & (1<<TOV1))          // OVF -Flag abfragen, taucht alle 2mS auf.
{       TIFR1  |= (1<<TOV1);          // wenn gesetzt dann OVF1 Flag löschen. 
  
       //serialdebug();();             //Darf maximal 0,5mS dauern

      if (RC < 1200) {OCR1B = RC;} else {   //spezial Rudi Notaus
        
      MPP     = 2200- RC;            // RC wird in die ADC range gewandelt                       
      SVolt   = 0;                  // SVolt zurücksetzen
      for(int i=1; i<=8; i++)       // Schleife zum ADC runden
{     SVolt  += analogRead(A0);     // alle ADC Werte addieren  
}     SVolt  = SVolt * 6 / 67;      // teilen und zugleich Kalibrieren

  if (SVolt > MPP) {if (OCR1B < 1900) {OCR1B += +1 + ((SVolt - MPP) / 5); }} //Voltage to high -inc PWM
  else             {if (OCR1B > 1100) {OCR1B += -1 - ((MPP - SVolt) / 5); }} //Voltage to high -dec PWM
}}}


ISR (TIMER1_CAPT_vect) {          // RC READ ISR  
if(TCCR1B   &  (1<<ICES1))        // we have rising edge -
{   TCCR1B &= ~(1<<ICES1);        // switch ICP to falling edge                                             
    ICR1a   =  ICR1;              // store ICP1 IN ICP1a
} else                            // we have falling edge
{   TCCR1B |=  (1<<ICES1);        // switch ICP @ rising edge                                               
 if (ICR1   <  ICR1a)             // if Overflow ? 
       {RC  =  ICR1+2000-ICR1a;}  // Yes > Calc RC with OVF
 else  {RC  =  ICR1     -ICR1a;}  // No  > Calc RC without OVF
}}


Serialdebug sollte unter 0,5mS dauern (ca. ein 19k2 Byte), in der debugschleife evtl einen Zähler, und nach und nach immer nur ein Byte raushauen (ein Zeichen).
 
Hallo Holger

Ich bin nun auch soweit, dass ich am Pro Micro rum experimentieren kann.


Noch eine kurze Frage:


Als Ausgangslage habe ich den Code von deiner Website genommen, den 2018-11-23 ist dieser noch auf dem neusten Stand?

Und da ich 14 Zellen habe, muss ich logischerweise die Spannung anpassen müsste demzufolge ca 6.33V sein ist das korrekt?
 
Hi Robin
>Es überschlägt sich grad :D

Wenn du ohne Hott telemetrie willst: http://www.rc-network.de/forum/showthread.php/505097-Solarflieger?p=4742413&viewfull=1#post4742413
>Im <Beitrag dadrunter der Serialdebug

Ich hatte nur kein Bock mehr mit dem 32u4, wegen der ewigen Bootloader Probleme :(:cry:

Nun hab ich alles wieder auf dem Nano gezwängt, und da weitergemacht, aktueller Stand ist, das ich an einem Program für den Schleppi dazu bastel, das über USB dann alles bei laufendem Motor einstellt. Ist alles irgendwie einfach von der Bedienung her, und man hat alle Daten schick im Blick. Brauche da aber so ungefähr noch ne Woche, bis die "Beta" fertig ist.
attachment.php



Spannung ist etwa 0,52 x Solarzellen, sollte bei Dir dann 7,28v Sein. Die Spannung stellst Du ja über den Sender ein.
Zweiwegeschalter, ein Ende -100% ist Motor-aus, das andere Ende sollte dann von -100% langsam hochfahren, dabei sinkt die Spannung, dort wo die 7,28V erreicht sind, erstmal "festmachen" - Feintuning dann mit Wattmeter in der Sonne.
 
Hallo Holger

Danke für deine Nachricht. Wie genau meinst du "die Spannung stellst du mit dem Sender ein?" Ich blicke bei eurem Programm noch nicht ganz durch.

Ich nehme an mit dem Sender steuert man die Spannung (mit dem Gaskanal) von den Zellen. Dabei liegt der Wert bei Vollgas im optimalen Bereich der Spannung damit die Zellen ihre volle Leistung abrufen können. Und somit der Flieger maximal Vortrieb hat.

Die Einstellung dieses Wertes (da nicht alle 12 oder 14 zeller die gleichen Werte liefern, muss man den Wert einmal individuell bestimmen) und diesen danach im Programm hinterlegen, ist das korrekt?

Dein kleine Software sieht aber vielversprechend aus :)
 
Ansicht hell / dunkel umschalten
Oben Unten