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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.