Che Guevara
08.12.2009, 14:37
Hallo Leute,
ich bins mal wieder :-)
ich habe jetzt einen Servo gehackt und habe ihm noch einen CNY70 eingebaut, welcher auf ein Zahnrad (schwarz und weiß angemalt) gerichtet ist. Ich steuere nur noch den Motor des Servos an, also ein ganz normaler Motor mit anschließender Übersetzung. Die impulse des CNY70 werden mit einem Schmitttrigger (74HC14N) "digitalisiert".
Hier mein Programm:
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$framesize = 80
$hwstack = 80
$swstack = 80
Config Int0 = Change
On Int0 Isr_von_int0
Enable Int0
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 8
Pwm1a = 0
Pwm1b = 0
Config Timer2 = Timer , Prescale = 1024
Timer2 = 178
On Timer2 Isr_von_timer2
Enable Timer2
Config Pind.2 = Input
Portd.2 = 0
Config Portb.0 = Output
Config Portb.1 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Portb.0 = 0
Portb.1 = 0
Const Kp = 0.9
Const Ki = 0.8
Const Kd = 0.86
Dim Cny_counter As Word
Dim Timer2_counter As Byte
Dim Print_flag As Bit
Dim Esum As Single
Dim E As Single
Dim Ta As Single
Dim Ealt As Single
Dim Soll As Single
Dim Ist As Single
Dim Kp_buffer As Single
Dim Ki_buffer As Single
Dim Kd_buffer As Single
Dim Kpid_buffer As Single
Ta = 0.05
Soll = 20
Print "PID-Regler mit CNY70"
Print
Waitms 500
Portb.0 = 1
Portb.1 = 0
Enable Interrupts
Do
If Print_flag = 1 Then
Reset Print_flag
Print "Counter = " ; Ist
Print
End If
Loop
End
Isr_von_int0:
Incr Cny_counter
Return
Isr_von_timer2:
Timer2 = 178
Incr Timer2_counter
If Timer2_counter = 10 Then
Set Print_flag
Timer2_counter = 0
Ist = Cny_counter
Cny_counter = 0
Gosub Regulator
Soll = Soll + Kpid_buffer
Pwm1a = Soll
End If
Return
Regulator:
E = Soll - Ist
Esum = Esum + E
Kp_buffer = Kp * E
Ki_buffer = Ki * Ta
Ki_buffer = Ki_buffer * Esum
Kd_buffer = E - Ealt
Kd_buffer = Kd_buffer / Ta
Kd_buffer = Kd_buffer * Kd
Kpid_buffer = Kp_buffer + Ki_buffer
Kpid_buffer = Kpid_buffer + Kd_buffer
Ealt = E
Return
Jetzt zu meinem Problem:
ich steuere die Geschwindigkeit über PWM, allerdings lese ich aber die Anzahl der Impulse in einer gewissen zeit (ta) ein. Das führt i-wie zu Problemen. Wie muss ich das Programm verändern, damit die Regelung vernünftig funktioniert?
Vielen Dank
Gruß
Chris
ich bins mal wieder :-)
ich habe jetzt einen Servo gehackt und habe ihm noch einen CNY70 eingebaut, welcher auf ein Zahnrad (schwarz und weiß angemalt) gerichtet ist. Ich steuere nur noch den Motor des Servos an, also ein ganz normaler Motor mit anschließender Übersetzung. Die impulse des CNY70 werden mit einem Schmitttrigger (74HC14N) "digitalisiert".
Hier mein Programm:
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$framesize = 80
$hwstack = 80
$swstack = 80
Config Int0 = Change
On Int0 Isr_von_int0
Enable Int0
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 8
Pwm1a = 0
Pwm1b = 0
Config Timer2 = Timer , Prescale = 1024
Timer2 = 178
On Timer2 Isr_von_timer2
Enable Timer2
Config Pind.2 = Input
Portd.2 = 0
Config Portb.0 = Output
Config Portb.1 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Portb.0 = 0
Portb.1 = 0
Const Kp = 0.9
Const Ki = 0.8
Const Kd = 0.86
Dim Cny_counter As Word
Dim Timer2_counter As Byte
Dim Print_flag As Bit
Dim Esum As Single
Dim E As Single
Dim Ta As Single
Dim Ealt As Single
Dim Soll As Single
Dim Ist As Single
Dim Kp_buffer As Single
Dim Ki_buffer As Single
Dim Kd_buffer As Single
Dim Kpid_buffer As Single
Ta = 0.05
Soll = 20
Print "PID-Regler mit CNY70"
Waitms 500
Portb.0 = 1
Portb.1 = 0
Enable Interrupts
Do
If Print_flag = 1 Then
Reset Print_flag
Print "Counter = " ; Ist
End If
Loop
End
Isr_von_int0:
Incr Cny_counter
Return
Isr_von_timer2:
Timer2 = 178
Incr Timer2_counter
If Timer2_counter = 10 Then
Set Print_flag
Timer2_counter = 0
Ist = Cny_counter
Cny_counter = 0
Gosub Regulator
Soll = Soll + Kpid_buffer
Pwm1a = Soll
End If
Return
Regulator:
E = Soll - Ist
Esum = Esum + E
Kp_buffer = Kp * E
Ki_buffer = Ki * Ta
Ki_buffer = Ki_buffer * Esum
Kd_buffer = E - Ealt
Kd_buffer = Kd_buffer / Ta
Kd_buffer = Kd_buffer * Kd
Kpid_buffer = Kp_buffer + Ki_buffer
Kpid_buffer = Kpid_buffer + Kd_buffer
Ealt = E
Return
Jetzt zu meinem Problem:
ich steuere die Geschwindigkeit über PWM, allerdings lese ich aber die Anzahl der Impulse in einer gewissen zeit (ta) ein. Das führt i-wie zu Problemen. Wie muss ich das Programm verändern, damit die Regelung vernünftig funktioniert?
Vielen Dank
Gruß
Chris