Ab Zeile 74 sind vier Return untereinander, was macht das Programm beim ersten Return, kommt es irgend wann zu den folgenden.
Zeile 103 ist Unsinn, der Compiler sollte da eine Warnung ausgeben.
Moin,
Ich habe mir für meinen Bot ein Programm zusammen geschnitten. Es soll ADC7-4 auslesen, und demendsprechend die Motoren per L293D H-Brücke ansteuernl.
Jedoch wird immer nur ein ADC-Kanal ausgelesen. Ich habe echt keine Ahnung, woran das liegen kann.
Könnte mir mal bitte jmd. über das Programm schauen?
http://rafb.net/p/LbsHLK81.html
Code:#include <avr/io.h> #include <stdlib.h> #include <inttypes.h> #include <avr/interrupt.h> #include <util/delay.h> volatile unsigned char servopos0; #define SERVO_0_PIN 7 #define SERVOPORT PORTC #define DDRSERVO DDRC #ifndef F_CPU #define F_CPU 8000000UL #endif void servo_init() { TIMSK|=(1<<OCIE2); TCCR2 |= (1<<WGM21) | (1<<CS20); OCR2 = F_CPU/100000; DDRSERVO |= (1<<SERVO_0_PIN); } ISR(TIMER2_COMP_vect) { char cSREG; cSREG = SREG; static int scount; if(scount>servopos0)SERVOPORT&=~(1<<SERVO_0_PIN); else SERVOPORT|=(1<<SERVO_0_PIN); if(scount<2000)scount++; else scount=0; SREG = cSREG; } uint16_t readADC(uint8_t channel) { uint8_t i; uint16_t result0 = 0; uint16_t result1 = 0; uint16_t result2 = 0; uint16_t result3 = 0; ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); ADMUX = channel; ADMUX |= (1<<REFS1) | (1<<REFS0); ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); for(i=0; i<3; i++) { ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); result0+= ADCW; result1+= ADCW; result2+= ADCW; result3+= ADCW; } ADCSRA &= ~(1<<ADEN); result0/= 3; result1/= 3; result2/= 3; result3/= 3; return result0; return result1; return result2; return result3; } /***************************Hauptprogramm***************************/ int main (void) { DDRD = 0xFF; PORTA = 0b00001111; uint16_t result0 = 0; uint16_t result1 = 0; uint16_t result2 = 0; uint16_t result3 = 0; servo_init(); sei(); while (1) { servopos0 = 100; result0= readADC(4); result1= readADC(5); result2= readADC(6); result3= readADC(7); if(result0 >=300, result1 >= 300, result2 >= 300) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } } }
Mfg JeyBee
Ab Zeile 74 sind vier Return untereinander, was macht das Programm beim ersten Return, kommt es irgend wann zu den folgenden.
Zeile 103 ist Unsinn, der Compiler sollte da eine Warnung ausgeben.
Hallo JeyBee,
hab mir den Code nur oberflächlich angeguckt, aber da fallen einige Fehler auf:
1. Das Speichern des SREGs in der ISR wird vom Compiler automatisch gemacht und ist unnötig.
2. warum werden in readADC vier verschiedene Result-Variablen angelegt? Einer reicht doch, zudem jede der vier Variablen zu jeder Zeit den gleichen Wert hat!
3. if(result0 >=300, result1 >= 300, result2 >= 300) :
Die Kommas machen nicht das, was Du denkst. Es wird nur geprüft, ob result2 >= 300 ist. Was Du willst ist eine logische Und-Verknüpfung, also
if((result0 >=300) && (result1 >= 300) && (result2 >= 300))
Noch ein kleiner Tipp: Lass die Schleife in readAdc bis 4 laufen. Dadurch muss der summierte Wert später durch 4 geteilt werden, was einfach nur ein rechtsshift um 2 ist. Das ist viel schneller als das Teilen durch 3.
MfG Mark
Hallo
So vielleicht:
GrußCode:#include <avr/io.h> #include <stdlib.h> #include <inttypes.h> #include <avr/interrupt.h> #include <util/delay.h> volatile unsigned char servopos0; #define SERVO_0_PIN 7 #define SERVOPORT PORTC #define DDRSERVO DDRC #ifndef F_CPU #define F_CPU 8000000UL #endif void servo_init(void) { TIMSK|=(1<<OCIE2); // Interrupt gestatten TCCR2 |= (1<<WGM21) | (1<<CS20); // CTC-Mode, no prescaling (= anstelle von |= wäre sicherer) OCR2 = F_CPU/100000; // 100000kHz DDRSERVO |= (1<<SERVO_0_PIN); } ISR(TIMER2_COMP_vect) { char cSREG; cSREG = SREG; static int scount; if(scount>servopos0)SERVOPORT&=~(1<<SERVO_0_PIN); else SERVOPORT|=(1<<SERVO_0_PIN); if(scount<2000)scount++; else scount=0; SREG = cSREG; } uint16_t readADC(uint8_t channel) { uint16_t result; ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); // ADC einschalten, prescal /64 ADMUX = channel; // Kanal wählen ADMUX |= (1<<REFS1) | (1<<REFS0); // + interne 2,56V-Referenz ADCSRA |= (1<<ADSC); // Konvertierung starten while(ADCSRA & (1<<ADSC)); // warten bis Wandlung abgeschlossen result= ADC; // Ergebnis zwischspeichern ADCSRA &= ~(1<<ADEN); // ADC ausschalten return(result); // Ergebnis abliefern } /***************************Hauptprogramm***************************/ int main (void) { DDRD = 0xFF; PORTA = 0b00001111; uint16_t result0 = 0; uint16_t result1 = 0; uint16_t result2 = 0; uint16_t result3 = 0; servo_init(); sei(); while (1) { servopos0 = 100; result0= readADC(4)/3; // /3 ???? result1= readADC(5)/3; result2= readADC(6)/3; result3= readADC(7)/3; if((result0 >=300) && (result1 >= 300) && (result2 >= 300)) // ????????????????? { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } } }
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Hi,
Erstmal vielen dank, für die vielen Antworten.
Aber auch das Programm von radbruch, spricht nur einen Sensor an.
Ich habe eben nochmal alles vermessen, die Pins stimmen, an der Hardware kann es also nicht liegen.
Im AVRstudio habe ich auch die korrekte MCU etc. eingestellt, daran dürfte es also auch nicht liegen.
Ich bin echt ratlos.
Gruss JeyBee
Bei mir (8MHz Mega32) scheint das zu funktionieren:
Die Ausgabe:Code:#include <avr/io.h> #include <stdlib.h> #include <inttypes.h> #include <avr/interrupt.h> #include <util/delay.h> volatile unsigned char servopos0, p=0; #define SERVO_0_PIN 7 #define SERVOPORT PORTC #define DDRSERVO DDRC #ifndef F_CPU #define F_CPU 8000000UL #endif void servo_init(void) { TIMSK|=(1<<OCIE2); // Interrupt gestatten TCCR2 |= (1<<WGM21) | (1<<CS20); // CTC-Mode, no prescaling (= wäre sicherer) OCR2 = F_CPU/100000; // 100000kHz DDRSERVO |= (1<<SERVO_0_PIN); } ISR(TIMER2_COMP_vect) { char cSREG; cSREG = SREG; static int scount; if(scount>servopos0)SERVOPORT&=~(1<<SERVO_0_PIN); else SERVOPORT|=(1<<SERVO_0_PIN); if(scount<2000)scount++; else {scount=0; if(p) p--;} SREG = cSREG; } uint16_t readADC(uint8_t channel) { uint16_t result; ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); // ADC einschalten, prescal /64 ADMUX = channel; // Kanal wählen //ADMUX |= (1<<REFS1) | (1<<REFS0); // + interne 2,56V-Referenz ADMUX |= (0<<REFS1) | (1<<REFS0); // + 5V-Referenz ADCSRA |= (1<<ADSC); // Konvertierung starten while(ADCSRA & (1<<ADSC)); // warten bis Wandlung abgeschlossen result= ADC; // Ergebnis zwischspeichern ADCSRA &= ~(1<<ADEN); // ADC ausschalten return(result); // Ergebnis abliefern } /*************** Ausgabe an Terminal *******************************/ #define BAUD_LOW 38400 //Low speed - 38.4 kBaud #define UBRR_BAUD_LOW ((F_CPU/(16*BAUD_LOW))-1) void writeChar(char ch) { while (!(UCSRA & (1<<UDRE))); UDR = (uint8_t)ch; } void writeString(char *string) { while(*string) writeChar(*string++); } void writeInteger(int16_t number, uint8_t base) { char buffer[17]; itoa(number, &buffer[0], base); writeString(&buffer[0]); } /***************************Hauptprogramm***************************/ int main (void) { DDRD = 0xFF; //PORTA = 0b00001111; uint16_t result0 = 0; uint16_t result1 = 0; uint16_t result2 = 0; uint16_t result3 = 0; servo_init(); // Setup für RP6 (8MHz Mega32) // UART: UBRRH = UBRR_BAUD_LOW >> 8; // Setup UART: Baudrate is Low Speed UBRRL = (uint8_t) UBRR_BAUD_LOW; UCSRA = 0x00; UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); UCSRB = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE); sei(); while (1) { servopos0 = 100; result0= readADC(0); result1= readADC(1); //result2= readADC(6); result3= readADC(7); writeString("ADC0:"); writeInteger(result0, 10); writeString(" ADC1:"); writeInteger(result1, 10); writeString(" ADC7:"); writeInteger(result3, 10); writeChar('\n'); p=10; while(p); } }
GrußCode:[READY] ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:947 ADC7:1023 ADC0:765 ADC1:838 ADC7:1023 ADC0:765 ADC1:727 ADC7:1023 ADC0:765 ADC1:616 ADC7:1023 ADC0:765 ADC1:518 ADC7:1023 ADC0:765 ADC1:443 ADC7:1023 ADC0:765 ADC1:388 ADC7:1023 ADC0:765 ADC1:345 ADC7:1023 ADC0:765 ADC1:340 ADC7:1023 ADC0:765 ADC1:323 ADC7:1023 ADC0:765 ADC1:313 ADC7:1023 ADC0:765 ADC1:292 ADC7:1023 ADC0:765 ADC1:279 ADC7:1023 ADC0:765 ADC1:279 ADC7:1023 ADC0:765 ADC1:276 ADC7:1023 ADC0:765 ADC1:279 ADC7:1023 ADC0:765 ADC1:373 ADC7:1023 ADC0:765 ADC1:551 ADC7:1023 ADC0:765 ADC1:722 ADC7:1023 ADC0:765 ADC1:874 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:744 ADC0:765 ADC1:1023 ADC7:547 ADC0:765 ADC1:1023 ADC7:392 ADC0:765 ADC1:1023 ADC7:273 ADC0:765 ADC1:1023 ADC7:190 ADC0:765 ADC1:1023 ADC7:162 ADC0:766 ADC1:1023 ADC7:154 ADC0:766 ADC1:1023 ADC7:173 ADC0:765 ADC1:1023 ADC7:327 ADC0:765 ADC1:1023 ADC7:500 ADC0:765 ADC1:1023 ADC7:668 ADC0:765 ADC1:1023 ADC7:823 ADC0:766 ADC1:1023 ADC7:1023 ADC0:766 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:765 ADC1:1023 ADC7:1023 ADC0:657 ADC1:1023 ADC7:1023 ADC0:506 ADC1:1023 ADC7:1023 ADC0:386 ADC1:1023 ADC7:1023 ADC0:276 ADC1:1023 ADC7:1023 ADC0:124 ADC1:1023 ADC7:1023 ADC0:15 ADC1:1023 ADC7:1023 ADC0:0 ADC1:1023 ADC7:1023 ADC0:0 ADC1:1023 ADC7:1023 ADC0:0 ADC1:1023 ADC7:1023 ADC0:0 ADC1:1023 ADC7:1023 ADC0:0 ADC1:1023 ADC7:1023 ADC0:148 ADC1:1023 ADC7:1023 ADC0:299 ADC1:1023 ADC7:1023 ADC0:432 ADC1:1023 ADC7:1023 ADC0:555 ADC1:1023 ADC7:1023 ADC0:666 ADC1:1023 ADC7:1023 ADC0:759 ADC1:1023 ADC7:1023 ADC0:771 ADC1:1023 ADC7:1023 ADC0:771 ADC1:1023 ADC7:1023 ADC0:771 ADC1:1023 ADC7:1023 ADC0:771 ADC1:1023 ADC7:1023 ADC0:771 ADC1:1023 ADC7:1023 ADC0:770 ADC1:1023 ADC7:1023 ADC0:770 ADC1:1023 ADC7:1023
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Nabend,
Wenn ich aber diese &&'s bei dem IF drinne habe, reagieren die Mottoren erst, wenn ALLE drei Sensoren ein Hinderniss melden.... Das ist ja auch nicht der Sinn.
Ich möchte, dass wenn einer der Sensoren etwas erkennt, die Motoren reagierten, denn jeder Sensor ist in einem anderen Winkel angeordnet...
Darum habe ich jetzt wieder drei einzelne If-Anweisungen.
Ich hoffe, ich dass ich noch ein paar Fragen stellen darf
Mfg JeyBee
if((result0 >=300) || (result1 >= 300) || (result2 >= 300))
Wenn ein Ergebniss größergleich 300 ist....
Dann solltest du deine Wünsche besser erklären...Das ist ja auch nicht der Sinn.
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Neues Problem:
Ich möchte, dass der Sensor in der Mitte auf dem Servo sich wärend des fahrens dreht, und in 3 Stellungen eine Messung macht. Jedoch kann die MCU ja immer nur eine Sache pro Takt machen, desshalb wärden die anderen 3 Sensoren einfach ignoriert -> der Bot fährt überall rein.
Ich habe den Code mal gepastet:
http://rafb.net/p/pHGMMB69.html
Code:#include <avr/io.h> #include <stdlib.h> #include <inttypes.h> #include <avr/interrupt.h> #include <util/delay.h> volatile unsigned char servopos0, p=0; #define SERVO_0_PIN 7 #define SERVOPORT PORTC #define DDRSERVO DDRC #ifndef F_CPU #define F_CPU 8000000UL #endif void servo_init(void) { TIMSK|=(1<<OCIE2); // Interrupt gestatten TCCR2 |= (1<<WGM21) | (1<<CS20); // CTC-Mode, no prescaling (= wäre sicherer) OCR2 = F_CPU/100000; // 100000kHz DDRSERVO |= (1<<SERVO_0_PIN); } ISR(TIMER2_COMP_vect) { char cSREG; cSREG = SREG; static int scount; if(scount>servopos0)SERVOPORT&=~(1<<SERVO_0_PIN); else SERVOPORT|=(1<<SERVO_0_PIN); if(scount<2000)scount++; else {scount=0; if(p) p--;} SREG = cSREG; } uint16_t readADC(uint8_t channel) { uint16_t result; ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); // ADC einschalten, prescal /64 ADMUX = channel; // Kanal wählen //ADMUX |= (1<<REFS1) | (1<<REFS0); // + interne 2,56V-Referenz ADMUX |= (0<<REFS1) | (1<<REFS0); // + 5V-Referenz ADCSRA |= (1<<ADSC); // Konvertierung starten while(ADCSRA & (1<<ADSC)); // warten bis Wandlung abgeschlossen result= ADC; // Ergebnis zwischspeichern ADCSRA &= ~(1<<ADEN); // ADC ausschalten return(result); // Ergebnis abliefern } /***************************Hauptprogramm***************************/ int main (void) { DDRD = 0xFF; PORTA = 0b00001111; uint16_t result0 = 0; uint16_t result1 = 0; uint16_t result2 = 0; uint16_t result3 = 0; servo_init(); sei(); while (1) { servopos0 = 90; result0= readADC(4); result1= readADC(5); result2= readADC(6); result3= readADC(7); _delay_ms(200); if(result0 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } if(result1 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } if(result2 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } servopos0 = 60; result0= readADC(4); result1= readADC(5); result2= readADC(6); result3= readADC(7); _delay_ms(200); if(result0 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } if(result1 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } if(result2 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } servopos0 = 150; result0= readADC(4); result1= readADC(5); result2= readADC(6); result3= readADC(7); _delay_ms(200); if(result0 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } if(result1 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } if(result2 >=200) { PORTD |= (1<<PD5); PORTA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA2)); PORTA &=~ ((1<<PA1) | (1<<PA3)); _delay_ms (100); PORTA |= ((1<<PA0) | (1<<PA1)); _delay_ms(100); } else { PORTD |= (1<<PD5); PORTA |= ((1<<PA1) | (1<<PA3)); PORTA &=~ ((1<<PA0) | (1<<PA2)); } } } ////////// /* Servopos: Mitte = 90 Links = 150 Rechts = 60 */ //////////
Hat jmd. eine bessere Idee?
Mfg JeyBee
Hast du dir schon mal ausgerechnet wie lange deine while-Schleife dauert wenn dein Bot so in eine Ecke fährt das bei allen drei Sensoren der Wert >200 ist. Soll der Kontroller sonst nichts machen?
Lesezeichen