Hallo, Leute!
Endlich habe ich wieder Zeit für meinen Roboter...
Nun, auf dem Tisch habe ich das Problem mit der Reglung der
Rädermotoren.
Ich habe eine Schaltung gemacht, die mit PWM die Motoren steuert, und
mit einer optischen Encoder pro Motor eine Rückmeldung kriegt.
Nun soll das Programm geschrieben werden.
Schon vor X Monaten hatte ich das Programm für den "P" (Proportional)
geschrieben, ich wollte jetzt erweitern mit dem "I" (Integral).
Das ist mein Code:
1 | uint16_t pwm, nSpeed, err, p, l, r;
|
2 |
|
3 | l = getLeftPWM();
|
4 | r = getRightPWM();
|
5 | if(getLeftInterval() != 0 && getDirectionLeft() != DIR_STOP)
|
6 | {
|
7 | nSpeed = (1000 / getLeftInterval());
|
8 | if(nSpeed != getSpeed())
|
9 | {
|
10 | p = getLeftPWM() * getSpeed();
|
11 | pwm = p / nSpeed;
|
12 | err = p % nSpeed;
|
13 | if(err <= (nSpeed / 2))
|
14 | errL += err;
|
15 | else
|
16 | {
|
17 | pwm++;
|
18 | errL -= err;
|
19 | }
|
20 | if(errL < 0)
|
21 | {
|
22 | while(abs(errL) >= nSpeed)
|
23 | {
|
24 | pwm--;
|
25 | errL += nSpeed;
|
26 | }
|
27 | }
|
28 | else
|
29 | {
|
30 | while(errL >= nSpeed)
|
31 | {
|
32 | pwm++;
|
33 | errL -= nSpeed;
|
34 | }
|
35 | }
|
36 | if((pwm >= MINPWM) && (pwm <= MAXPWM))
|
37 | l = pwm;
|
38 | else if(pwm < MINPWM)
|
39 | l = MINPWM;
|
40 | else
|
41 | l = MAXPWM;
|
42 | setLeftCorrectionDone();
|
43 | turnOnLED(LED2);
|
44 | }
|
45 | else
|
46 | {
|
47 | turnOffLED(LED2);
|
48 | }
|
49 | }
|
50 | // das gleiche für den linken Motor...
|
51 | // dann:
|
52 | setLeftPWM(l);
|
53 | setRightPWM(r);
|
54 | TCCR1A |= _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);
|
55 | TCCR1B |= _BV(WGM13) | _BV(CS12) | _BV(CS10);
|
56 | ICR1 = ICR_LIMIT;
|
Die Funktionen getLeftPWM() und setLeftPWM() lesen, bzw. setzen den
neuen PWM-Wert. getLeftInterval() gibt zurück die Zeit, in
Millisekunden, zwischen zwei Pegel des Encoders. getSpeed() gibt zurück
den theoretische Geschwindigkeit, die ich erreichen will.
Also, das Programm funktioniert auch, aber ich habe immer eine
Abweichung zwischen den Motoren...
Manchmal ist es klein, manchmal größer.
Um eine Großordnung zu geben, wenn ich die Motoren 10 Mal drehen lassen,
habe ich eine Abweichung von 3-5 Schritte. Eine komplette Umdrehung des
Motors sind 100 Schritte, also ist eine Abweichung von 3-5°...
Es mag sein, daß es klein aussieht, aber ich möchte das beste kriegen,
was ich kriegen kann...
Eine komische Sache noch: auch wenn ich die Motoren länger drehen lasse,
ist die Abweichung nicht proportionell größer. Also, nach 30
Umdrehungen ist es nicht 9-15 Schritte, sondern vielleicht 4-7
Schritte...
Ideen?
Danke
Luca Bertoncello