Servo-Steuerung

OP #3660150
Lesenswert?

Hallo Zusammen

ich habe folgende Problem bei der Servo-Steuerung (mittels ATMega644):
Ein Servo soll 300 Positionen (Zahlen) darstellen und fährt über eine 
Strecke von 350 Positionen (200 bis 550).
Sobald der erste Wert s aus der zweiten Gleichung berechnet wird, 
springt der Servo. Danach nicht mehr.
Dabei ist es egal, ob ich für die ersten Positionen (z.b. bis 280) eine 
vereinfachte Rechnung nehme oder nicht.

Woran liegt dies???

Zusammengesetzter Programmausschnitt:
1
uint16_t a; 
2
uint16_t s;
3

4
a = 300; 
5

6
while(1) {
7

8
a--;  // bis a=0
9

10
if(a >= 280)
11
s = - a + 500 ;
12

13
else
14
s = - ((1167 / 1000) * a ) + 550;
15

16
    
17
OCR1A = ICR1 - s;
18

19
_delay_ms(100);
20

21
}
Gast #3660159
Lesenswert?

warum compilierst du diesen code nicht einfach auf deinem rechner, und 
fügst ein printf ein, mit dem du dir die werte am schirm angucken 
kannst?

der kommentar "a--;  // bis a=0"
verhindert nicht, dass a irgendwann mal kleiner als null werden will, 
und da es ein unsigned ist, läuft a in einen sehr großen wert über.
evtl. ist das ja der fehler.
Gast #3660179
Lesenswert?

Axel L. schrieb:
> s = - ((1167 / 1000) * a ) + 550;

Das ist eine Integer Division, d.h. 1167/1000 ergibt 1, weil die 
kommastellen abgeschnitten werden. also vom prinzip steht da:
s = - (1*a) + 550;

Wenn sich die werte in der Klammer eh nicht ändern ( 1167/1000 ), warum 
schreibst du dann nicht einfach direkt: s = - (1.167 * a) + 550; ?
OP #3660241
Lesenswert?

Kaj schrieb:
> Axel L. schrieb:
>> s = - ((1167 / 1000) * a ) + 550;
>
> Das ist eine Integer Division, d.h. 1167/1000 ergibt 1, weil die
> kommastellen abgeschnitten werden. also vom prinzip steht da:
> s = - (1*a) + 550;
>
> Wenn sich die werte in der Klammer eh nicht ändern ( 1167/1000 ), warum
> schreibst du dann nicht einfach direkt: s = - (1.167 * a) + 550; ?+

Yo, das wars. Danke Kai.

Man, ich glaub es nicht. Ich dachte erst, mein µC kann nicht mit 
Kommazahlen umgehen, daher die Division.

Nun läuft der Servo so wie er soll. :-))
Gast #3660335
Lesenswert?

Ja, funktioniert, Akte kann geschlossen werden.

Der Code ist Mist.

a) was soll das
if(a >= 280) s = - a + 500 ;
gibt es einen Grund diese Unlinearität zu machen?

b) der uC "kann" natürlich keine Fließkommazahlen, sondern das macht 
eine C-Bibliothek für dich, die Fließkomma mit Integer macht -> 
furchtbar langsam.


Du willst doch eigentlich nur einen Eingangswert a, der von 300 bis 0 
läuft auf einen Ausgangswert s, der von 200 bis 550 läuft linear 
skalieren.

Wie du richtig erkannt hast, ist der Faktor dieser Funktion 350/300, was 
man gleich mal auf 7/6 kürzen kann.
Damit ergibt sich die Funktion, die deine Umrechnung komplett in Integer 
und auch komplett linear macht:

s = 550 - ((a * 7) / 6);

Ohne if's und but's.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren