INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Servo.h und Digitalservos
10.03.2015, 21:25 (Dieser Beitrag wurde zuletzt bearbeitet: 10.03.2015 21:27 von fs82.)
Beitrag #1
Servo.h und Digitalservos
Hallo,

ich bastel seit einigen Tagen an einem Arduino Uno herum und möchte gerne zwei Servos ansteuern. Das sind zwei handelsübliche RC-Digital-Servos von Spektrum (A3020) und angesteuert über die standardmäßig vorhandene Servo-Bibliothek. Die Servos bekommen zunächst ihren Strom über den Arduino. Leider ist es nun so, dass die Servos anfangen zu zittern, ganz minimal, aber für die Anwendung als Kamerastabilisierung zu viel.

Ich hab dann die vergangene Tage herumgespielt und folgendes ausprobiert:

(1) eigene Stromversorgung via Lipo und BEC (6V) -> keine Verbesserung
(2) zusätzliche ELKOs bis 470 µF -> keine Verbesserung
(3) statt einem Digitalservo ein Analogservo -> Zittern verschwunden

Der letzte Versuch hat mich dann auf die Idee gebracht, das die Servos vielleicht defekt sind (liest man ja öfters in Foren das Zittern von der Charge abhängen kann). Also hab ich sie an meine Graupner Funke angeschlossen und siehe da kein Zittern, kein Zucken, sondern funktionieren einwandfrei.

Jetzt war guter Rat teuer, aber nach einigem Grübeln ging mir durch den Kopf, dass eventuell das Steuersignal (PWM) nicht ganz sauber/störungsfrei ist und, da die Digital-Servos angeblich wesentlich feiner auslösen, könnte sich das ja in einem Zittern bemerkbar machen. Also hab ich zunächst via delay() und digitalWrite() versucht ein eigenes PWM-Signal zu erzeugen, was aber zu ähnlich schlechten bzw. schlechteren Ergebnissen führte als mit der Servo-Bibliothek.

Aber nach kurzen Suchen im Netz bin ich auf die Bibliothek TimerOne gestoßen. Dort wird u.a. mittels des 16bit Timers des Arduino auf PIN 9 und 10 ein PWM-Signal erzeugt, dessen Periodenlänge man einstellen kann. Wenn ich das verwende um einen Steuerimpuls für meine Digital-Servos zu generieren funktioniert das einwandfrei. Kein Zucken, kein Zittern nichts, der Servo fährt die Position an und bleibt dort.

Jetzt ist die Frage, ich muss zugegeben ich bin kein Programmierer und neu in der Mikrokontrollerwelt, woher könnte in der Servo-Bibliothek die Ungenauigkeit kommen. Der Digital-Servo reagiert auf 1µs Differenz im Duty-Cycle des PWM Signals (getestet mit der TimerOne Bibliothek). Beide Bibliotheken arbeiten, wenn ich alles richtig versteh mit dem 16bit Timer des Arduino, aber irgendwo muss in der Servo-Bibliothek eine zusätzliche Rechenoperation (Rundungsfehler?) oder ein extra Sicherheitsfaktor sein, welcher das PWM-Signal beeinflusst. Leider muss ich gestehen, dass die Servo.cpp zu hoch für mich ist. Aber hat das vielleicht auch jemand anders das festgestellt, oder versteht den Quellcode besser und kann mir auf die Sprünge helfen?

Hardware: Arduino Uno R3, Spektrum A3020
Software: Arduino Software (Version 1.0.5) aus Repository für Ubuntu 14.04 LTS

Viele Grüße
Fabian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
11.03.2015, 05:52
Beitrag #2
RE: Servo.h und Digitalservos
Hallo Fabian,

da ich bisher keine Digitalservos nutze, kann ich das Problem nicht nachvollziehn, es interessiert mich aber.

Gib mal bitte die Werte per servo.h mit writeMicroseconds statt nur mit write aus, ob es da auch zittert. Die Werte müssen halt angepasst werden.

http://arduino.cc/en/pmwiki.php?n=Refere...croseconds

Gruß Rainer
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
11.03.2015, 09:14
Beitrag #3
RE: Servo.h und Digitalservos
Hallo Rainer,

ich verwende in der Servo.h schon die Funktion writeMicroseconds(). Das macht aber keinen Unterschied im Verhalten der Servos. Soweit ich den Quellcode überblicke ruft write() letztendlich auch writeMicroseconds() auf, daher müsste das unerheblich sein, denn ich denke die Ungenauigkeit entsteht bei der Generierung des PWM-Signals über mehrere Periodenlängen. In der TimerOne Bibliothek muss ich die Mikrosekunden auch in einen Duty-Cycle (Wert zwischen 0 und 1023) umrechnen, was ich über die map() Funktion gelöst habe. Damit generiert er offenbar ein sauberes, konstantes PWM-Signal für den Servo.

Vielleicht sollte ich noch erwähnen, obwohl das meines Erachtens keinen Einfluss haben durfte, dass der Spektrum Servo nur von 900 bis 2100 µs verfährt und offensichtlich keine 180 Grad Verfahrbereich hat, sondern weniger. Wieviel Grad genau muss ich bei Gelegenheit mal ausmessen (vermute 120°), da die bereitgestellten Spezifikationen von Spektrum echt dürftig sind.

Gruß Fabian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
11.03.2015, 21:04 (Dieser Beitrag wurde zuletzt bearbeitet: 11.03.2015 21:06 von fs82.)
Beitrag #4
RE: Servo.h und Digitalservos
Ok, zunächst mal ziehe ich meine Aussage zurück, dass der Servo auf 1µs Unterschied reagiert. Das kann nicht sein, denn wenn ich den Duty-Cycle bei 20000µs Periodenlänge (50Hz) über 1024 Werte einstellen muss, kann ich ja höchstens in 20µs Schritten (rund) auslösen. Ergo reagiert der Servo doch nicht ganz so feinfühlig wie behauptet. Asche auf mein Haupt, aber man lernt halt nie aus.

Jedenfalls hab ich die Servosteuerung mal mit der TimerOne-Bibliothek umgesetzt. Google behauptet ja, dass man Digitalservos auch mit 300Hz befeuern kann, was ich dementsprechend getan habe. Das funktioniert ausnehmend gut und hat den Vorteil, dass meine Auflösung für den Duty-Cycle jetzt rund 3µs beträgt. Das wichtigste ist, dass meine beiden Servos jetzt beide absolut zitterfrei laufen und perfekt die Position halten. Einziger Nachteil ist, der aber bei einem Zwei-Achsen-Gyro nicht so ins Gewicht fällt, dass man lediglich an Pin 9 und 10 beim Uno den Timer1 bzw. die PWM Steuerung aus der TimerOne-Bibliothek verwenden kann.

Bin aber immer noch für Ideen und Anregungen offen, wie man das Ganze mit der Servo-Bibliothek lösen kann.

Gruß
Fabian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
11.03.2015, 21:34
Beitrag #5
RE: Servo.h und Digitalservos
Hi,
versuch's mal mit der RCArduinoFastLib.
Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.03.2015, 18:03 (Dieser Beitrag wurde zuletzt bearbeitet: 12.03.2015 18:14 von fs82.)
Beitrag #6
RE: Servo.h und Digitalservos
Hallo Thorsten,

danke für den Hinweis. Ich hab mir die Bibliothek mal heruntergeladen und versucht ein Minimalbeispiel zusammenzubauen.

Leider ist die Dokumentation der Bibliothek nicht so richtig gelungen, wie ich finde. Ich versteh z.B. nicht wozu ich die Variable SERVO_FRAME_SPACE in der Funktion setFrameSpaceA benötige, da diese ja gar keinen validen Servo Kanal beinhaltet, sondern nur die Anzahl der Servos. Sie müsste aber einen Servo Kanal beinhalten, wenn ich den Quelltext richtig verstehe. Stellt sich die Frage a) was setzt er denn, wenn ich SERVO_FRAME_SPACE verwende, und b) muss ich das eventuell für jeden Servo einzeln setzen. Jedenfalls ohne den Aufruf der setFrameSpaceA-Funktion gehts gar nicht Dodgy

Code:
#include "RCArduinoFastLib.h"

#define ROLL_OUT_PIN 9
#define PITCH_OUT_PIN 10

#define SERVO_ROLL 0
#define SERVO_PITCH 1

#define SERVO_FRAME_SPACE 2

void setup() {
    CRCArduinoFastServos::attach(SERVO_ROLL,ROLL_OUT_PIN);
    CRCArduinoFastServos::attach(SERVO_PITCH,PITCH_OUT_PIN);
    
    CRCArduinoFastServos::setFrameSpaceA(SERVO_FRAME_SPACE,8*2000);
    
    CRCArduinoFastServos::begin();
}

void loop() {
    CRCArduinoFastServos::writeMicroseconds(SERVO_ROLL,1000);
    CRCArduinoFastServos::writeMicroseconds(SERVO_PITCH,1000);
}

Aber egal, wichtig ist ja ob die Servos zittern oder nicht. Leider muss ich konstatieren: Ja, sie zittern. Allerdings wesentlich weniger als mit der Servo.h Bibliothek. Da bleib ich erstmal bei meiner Lösung über die TimerOne Bibliothek, solange ich mit zwei Servos auskomme.

Viele Grüße
Fabian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.03.2015, 18:27
Beitrag #7
RE: Servo.h und Digitalservos
Hi,
du kannst den Servoimpuls auch zu Fuß programmieren ganz ohne Library.
Schau dir dazu mal diesen Code an:
Code:
//###### ab hier Erzeugung des Servoimpulses
void servoausgabe(){
     servi = StellungInuS;    // Servostellung in uS
     currentMillisImp = millis();   // aktuelle Millisekunden abspeichern
     if(currentMillisImp - previousMillisImp > interval)  // wenn 21mS vorbei Servoimpuls generieren
           {
           previousMillisImp = currentMillisImp;   // neue Zeit setzen
          digitalWrite(serv, 1);  //
          delayMicroseconds(servi);
          digitalWrite(serv, 0);  //
          // hier könnten weitere Servoausgaben stehen
          }
}
interval ist mit 21 belegt was die Wiederholrate in mS von dem Servoimpuls angibt.
Die Servoimpulsbreite servi wird in uS berechnet und angegeben.
Auser in der Ausgabe sind im Rumpfprogramm keine weiteren delay() Aufrufe erlaubt sonst klappt das nicht.
lg
bk

1+1 = 10 Angel ...und ich bin hier nicht der Suchmaschinen-Ersatz Dodgy...nur mal so als genereller Tipp..
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.03.2015, 18:50
Beitrag #8
RE: Servo.h und Digitalservos
Hallo bk,

sowas ähnliches hab ich auch schon versucht und damit kein brauchbares Resultat erzielt. Ich gebe allerdings zu, dass ich die Periodenlänge von 20ms nicht via if-Abfrage sondern mit einem zusätzlichen delay() gelöst hatte. Allerdings soll die Periodenlänge nicht so relevant sein (laut google), da wären die Servos relativ kulant. Wichtig ist die Länge des Impulses und da liegt meines Erachtens der Hase im Pfeffer. Das klappt mit dem delay(), was ja über den Timer0 gesteurt wird, nicht 100% reproduzierbar und deswegen zittern die Digitalservos. Ich vermute dem Analogservo ist das einfach egal, weil er die Feinheiten eh nicht auflösen kann. Aber das Digitalservo zittert dann halt.

Gruß
Fabian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
Star ATtiny Servo SOS SOS hansanne1310 1 49 Heute 22:15
Letzter Beitrag: hotsystems
  Servo über Temperatur steuern querkopf71 3 38 Heute 19:21
Letzter Beitrag: hotsystems
  ATtiny und Servo Bibliothek malsehen 9 306 15.10.2016 18:09
Letzter Beitrag: malsehen
  Servo soll nur in Ruhelage stoppen Sven1996 1 239 19.08.2016 14:37
Letzter Beitrag: StephanBuerger
  Steuern von 4 Servo mittels eines Taster und eines Potis Jackie09 17 757 16.07.2016 11:43
Letzter Beitrag: Binatone
  Servo und PWM Ausgabe F2Ingo 4 493 17.06.2016 14:53
Letzter Beitrag: F2Ingo
  Hilfe bei Servo-steuerung Innocence 7 813 23.02.2016 11:00
Letzter Beitrag: hotsystems
  Servo.h lässt sich nicht einbinden ^^ EvilBen 5 705 08.02.2016 18:07
Letzter Beitrag: hotsystems
  Weichensteuerung mit Servo RCudino 21 3.022 05.01.2016 18:04
Letzter Beitrag: Markus0815
  Servo per Serieller Mointor ansteuern iggy 1 818 03.08.2015 03:08
Letzter Beitrag: yasi

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste