Vulpecula
Commander
- Registriert
- Nov. 2007
- Beiträge
- 2.245
Hallo zusammen!
Ich habe hier einen selbstbalancierenden Roboter, der auch gut funktioniert. Die Balance wird von einem PID-Regler gesteuert; den Teil habe ich soweit auch verstanden. Der PID Regler spuckt alle 4ms (250Hz) einen neuen Wert zur Ansteuerung der Motoren aus (
Mein eigentliches Problem liegt beim Verständnis der ISR, in der die eigentliche Ansteuerung der Motoren stattfindet. Die ISR wird alle 20µs (50kHz) aufgerufen. Hier mal der Code dazu (sorry für die miese Formatierung - ich hab es so aus dem Beispielcode übernommen um die originalen Kommentare zu erhalten):
Ich möchte die Funktion besser verstehen, komme aber durch reines Draufschauen nicht weiter. Das Ganze auf dem Papier nachzuvollziehen wird dazu schnell unübersichtlich. Daher frage ich mich, wie man derartige Funktonen am besten debuggen kann. Es würde mir für das Verständnis nämlich schon helfen, das Verhalten einzelner Variablen beobachten zu können. Vielleicht gibt es aber auch Tools zur Simulation, die einem helfen, solche Funktonen zu beobachten?
In der Regel würde ich Variablen einfach über UART ausgeben und könnte so deren Veränderungen nachvollziehen, aber das ist hier nicht praktikabel da serielle Ausgaben in einer ISR auf einem Mikrocontroller ein No-Go sind. Dazu kommt, dass die Frequenz, mit der die Funktion aufgerufen wird, kaum noch eine Auswertung via UART zulassen würde.
Vielleicht hat ja jemand einen Tipp für mich. Vielen Dank und Grüße - Vulpecula
P.S.: Falls jemand auf den ersten Blick erkennen kann, wie genau diese Funktion arbeitet, dann lasst es mich gerne wissen.
Ich habe hier einen selbstbalancierenden Roboter, der auch gut funktioniert. Die Balance wird von einem PID-Regler gesteuert; den Teil habe ich soweit auch verstanden. Der PID Regler spuckt alle 4ms (250Hz) einen neuen Wert zur Ansteuerung der Motoren aus (
throttle_left_motor
bzw. throttle_right_motor
).Mein eigentliches Problem liegt beim Verständnis der ISR, in der die eigentliche Ansteuerung der Motoren stattfindet. Die ISR wird alle 20µs (50kHz) aufgerufen. Hier mal der Code dazu (sorry für die miese Formatierung - ich hab es so aus dem Beispielcode übernommen um die originalen Kommentare zu erhalten):
C++:
ISR(TIMER2_COMPA_vect){
//Left motor pulse calculations
throttle_counter_left_motor ++; //Increase the throttle_counter_left_motor variable by 1 every time this routine is executed
if(throttle_counter_left_motor > throttle_left_motor_memory){ //If the number of loops is larger then the throttle_left_motor_memory variable
throttle_counter_left_motor = 0; //Reset the throttle_counter_left_motor variable
throttle_left_motor_memory = throttle_left_motor; //Load the next throttle_left_motor variable
if(throttle_left_motor_memory < 0){ //If the throttle_left_motor_memory is negative
PORTD &= 0b11110111; //Set output 3 low to reverse the direction of the stepper controller
throttle_left_motor_memory *= -1; //Invert the throttle_left_motor_memory variable
}
else PORTD |= 0b00001000; //Set output 3 high for a forward direction of the stepper motor
}
else if(throttle_counter_left_motor == 1)PORTD |= 0b00000100; //Set output 2 high to create a pulse for the stepper controller
else if(throttle_counter_left_motor == 2)PORTD &= 0b11111011; //Set output 2 low because the pulse only has to last for 20us
//right motor pulse calculations
throttle_counter_right_motor ++; //Increase the throttle_counter_right_motor variable by 1 every time the routine is executed
if(throttle_counter_right_motor > throttle_right_motor_memory){ //If the number of loops is larger then the throttle_right_motor_memory variable
throttle_counter_right_motor = 0; //Reset the throttle_counter_right_motor variable
throttle_right_motor_memory = throttle_right_motor; //Load the next throttle_right_motor variable
if(throttle_right_motor_memory < 0){ //If the throttle_right_motor_memory is negative
PORTD |= 0b00100000; //Set output 5 low to reverse the direction of the stepper controller
throttle_right_motor_memory *= -1; //Invert the throttle_right_motor_memory variable
}
else PORTD &= 0b11011111; //Set output 5 high for a forward direction of the stepper motor
}
else if(throttle_counter_right_motor == 1)PORTD |= 0b00010000; //Set output 4 high to create a pulse for the stepper controller
else if(throttle_counter_right_motor == 2)PORTD &= 0b11101111; //Set output 4 low because the pulse only has to last for 20us
}
Ich möchte die Funktion besser verstehen, komme aber durch reines Draufschauen nicht weiter. Das Ganze auf dem Papier nachzuvollziehen wird dazu schnell unübersichtlich. Daher frage ich mich, wie man derartige Funktonen am besten debuggen kann. Es würde mir für das Verständnis nämlich schon helfen, das Verhalten einzelner Variablen beobachten zu können. Vielleicht gibt es aber auch Tools zur Simulation, die einem helfen, solche Funktonen zu beobachten?
In der Regel würde ich Variablen einfach über UART ausgeben und könnte so deren Veränderungen nachvollziehen, aber das ist hier nicht praktikabel da serielle Ausgaben in einer ISR auf einem Mikrocontroller ein No-Go sind. Dazu kommt, dass die Frequenz, mit der die Funktion aufgerufen wird, kaum noch eine Auswertung via UART zulassen würde.
Vielleicht hat ja jemand einen Tipp für mich. Vielen Dank und Grüße - Vulpecula
P.S.: Falls jemand auf den ersten Blick erkennen kann, wie genau diese Funktion arbeitet, dann lasst es mich gerne wissen.