mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Werte für Servo skalieren


Autor: Jeff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich möchte einen Servomotor von einem anderen Device steuern. Das Device 
gibt über einen Regler einen 8-Bit Wert von 0-255 vor. Den kann ich 
leider nicht ändern.

Die Steuerung des Servos klappt einwandfrei. Nur ist der +/-90 Grad 
Bereich den der Servo von der Mittelstellung aus schafft viel zu groß. 
Das sollten
höchstens +/-15 Grad sein.

Dazu hab ich den Servowert mit folgender Formel begrenzt:

servowert = ((servowert / 4) + 97);

Funktioniert soweit auch, nur leider hab ich da jetzt ganz schöne 
Stopper drin und der Servo braucht eine gewisse Zeit bis er auch die 
Änderung des Reglers reagiert, weil wahrscheinlich nicht jede Position 
des Reglers angefahren werden kann..

Hat jemand ne Idee wie ich das verbessern kann?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servowert ist der Wert den du vom Device bekommst?

Du wirst ja mit diesem Wert irgendetwas machen, bevor du
ihm ans Servo legst. Zb. Umrechnen in eine Zeit oder einen
Timerwert.

Verlagere deine Skalierung an eine Stelle nach dieser
Umrechnung (oder bau sie in diese Umrechnung ein),
aber Limitiere nicht davor. Dadurch das du im Ganzzahl
Bereich rechnest, verlierst du sont ne Menge. Konkret
verringerst du den Wertebereich, den du vo Device bekommst
von 0 bis 255 auf den Bereich 0 bis 63. Anstelle von 256
verschiedenen Servopositionen, hast du nur noch 64.

Autor: Jeff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Verlagere deine Skalierung an eine Stelle nach dieser
>Umrechnung (oder bau sie in diese Umrechnung ein),
>aber Limitiere nicht davor.

Ich überlege nur gerade wie. Da ich den Motor selber ansteuere ist das 
nicht so einfach. Hab halt nur diese Werte für die Abfrage.

>Konkret verringerst du den Wertebereich, den du vo Device bekommst
>von 0 bis 255 auf den Bereich 0 bis 63. Anstelle von 256
>verschiedenen Servopositionen, hast du nur noch 64.

Hab schon überlegt in den Float Bereich zu gehen. Meinst du das macht 
Sinn? Braucht halt nur ziemlich viel Speicherplatz.

Autor: Jeff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ich aber machen könte wäre statt der 8-Bit Auflösung des AD-Wandlers 
16-Bit zu nutzen und den 8-Bit Vorgabewert des Devices auf 16 Bit 
hochzurechnen.

Autor: TOM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Regler hast du selbst implementiert?
Dann könntest du doch einfach den Ist-Wert nach oben skalieren, anstatt 
den Sollwert nach unten, dann bleibt die Auflösung erhalten.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jeff wrote:
>>Verlagere deine Skalierung an eine Stelle nach dieser
>>Umrechnung (oder bau sie in diese Umrechnung ein),
>>aber Limitiere nicht davor.
>
> Ich überlege nur gerade wie. Da ich den Motor selber ansteuere ist das
> nicht so einfach. Hab halt nur diese Werte für die Abfrage.

Aber du musst ja doch irgendwas mit diesem Wert machen.
Was machst du denn damit?
Oder geht der Servowert direkt in deine Regelung ein?

>
> Hab schon überlegt in den Float Bereich zu gehen. Meinst du das macht
> Sinn? Braucht halt nur ziemlich viel Speicherplatz.

Im Moment sehe ich keinen Grund für float.
Aber ohne die Kenntnis dessen, wie dieser Servowert weiterverarbeitet
wird, kann man schlecht einen Rat geben.

Denkbar wäre ja eventuell auch eine rein mechanische Lösung
des Problems. Das Abtriebsgestänge am Servohebel einfach
weiter innen einhängen. Das Servo dreht nach wie vor 90°,
aber der linearisierte Weg wird kleiner.

Autor: Jeff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Oder geht der Servowert direkt in deine Regelung ein?

Im Prinzip schon. Und da wird dann eine Art Zweipunktregelung gemacht.

Ungefähr so:

void motor_regelung()
{

if((lenkung_ist <= (lenkung_soll + 3)) && (lenkung_ist >= (lenkung_soll 
- 3)))
{
  PORTB &= ~(1 << PB1);
  PORTB &= ~(1 << PB0);
        //Anhalten

}

if((lenkung_ist +3) < (lenkung_soll))
{
  PORTB |= (1 << PB1);
  PORTB &= ~(1 << PB0);
        //Rechts drehen
}


if((lenkung_ist -3) > (lenkung_soll))
{
  PORTB |= (1 << PB0);
  PORTB &= ~(1 << PB1);
        //Links drehen
}

}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar.

Dann würde sich aber tatsächlich das von TOM Vorgeschlagene anbieten.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann muß man aber darauf achten, daß es nie (z.B. durch mechanisches 
Verdrehen) sein kann, daß der skalierte ist-Wert den Wertebereich der 
Variablen verläßt. lenkung_ist muß also mindestens mit 16 Bit definiert 
sein.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.