Hallo miteinander
Ich stehe irgendwie auf dem Schlauch, den bei meinem kleinen Regler
funktioniert das Ganze nicht so, wie es sollte: Entweder erreicht er die
Position nicht, oder fängt an zu schwingen oder regelt zu schwach nach.
Ich habe mitlerweile schon alles ausprobiert, aber nichts hat
funktioniert:
- Kp hinzugefügt
- Integralanteile hinzugefügt (bewirkte, dass dieser erst soweit
vermindert wurde, als der Motor überschwungen hat).
- Drehmomentkompensation über Strom-Feedback
Die Regelfunktion wird alle 2ms aufgerufen, aber wenn der Motor mit dem
Getriebe und der Welle ins schwingen kommt, so macht der zu bewegende
Schlitten etwa 2-6mm Hin- und Herbewegungen.
1 | unsigned char goto_pos(int seek_position, int max_speed){ // Motor: go to this position
|
2 | unsigned char acceleration = 0;
|
3 | char at_position = 0;
|
4 | int y = 0;
|
5 | int error = 0;
|
6 | int current = 0;
|
7 |
|
8 | if(! do_PI){ // No PI action
|
9 | if(abs(seek_position - read_a2d(motor_position)) > deadband){ // Check actual position
|
10 | return 0; // Not at seek position
|
11 | }
|
12 | else{ // At seek position
|
13 | return 1;
|
14 | }
|
15 | }
|
16 |
|
17 | do_PI = 0;
|
18 | error = seek_position - read_a2d_12bit(motor_position);
|
19 | if(max_speed < min_duty_cycle) max_speed = min_duty_cycle; // Minimum required speed to move
|
20 | current = read_a2d(current_fb);
|
21 | current >>= 3; // Sacle current
|
22 | if(current > 50) current = 50;
|
23 |
|
24 | if(abs(error) > deadband){ // Error to big -> adjust
|
25 | y = error / 3; // Scale error
|
26 | if(error > 0){ // Positive error
|
27 | P1M1 = 1; // Motor should go forward
|
28 | }
|
29 | if(error < 0){ // Negative error
|
30 | P1M1 = 0; // Motor should go backwards
|
31 | }
|
32 |
|
33 | y = abs(y);
|
34 | if(y > max_speed){ // Limit maximum
|
35 | acceleration = accel_timer; // ->After 500ms 100%
|
36 | if(acceleration < max_speed){ // Acceleration (soft start)
|
37 | accel_timer_on = 1;
|
38 | y = acceleration;
|
39 | }
|
40 | else{ // Top speed
|
41 | y = max_speed;
|
42 | accel_timer_on = 0; // Stop timer
|
43 | }
|
44 | }
|
45 | else{ // Deceleration
|
46 | accel_timer = 0;
|
47 | accel_timer_on = 0;
|
48 | }
|
49 | at_position = 0; // Error to big -> not at position
|
50 | }
|
51 | else{ // Error small enough -> at position
|
52 | y = 0; // Clear PWM
|
53 | at_position = 1;
|
54 | }
|
55 | if(y > max_speed) y = max_speed;
|
56 |
|
57 | if(y > 100) y = 100; // Adjust to duty-cycle values
|
58 | if(y < 0) y = 0;
|
59 | set_speed = y;
|
60 | return at_position; // True if is in threshold
|
61 | }
|
Die Position entspricht der Schlittenposition, da dieser den Schleifer
mitbewegt.
Ich könnte wirklich einen neuen Ansatz vertragen... habt ihr eine Idee?
Besten Dank
MFG
Patrick