Servo.h Frequenz ändern

Wo sind denn hier die Experten?

Ketchup:
Wo sind denn hier die Experten?

Keine Ahnung! Mir sind die Informationen zu dünn, um eine hinreichend gute Hilfestellung geben zu können. Du redest zwar von einem "Bl regler", ich denke aber, dass den wenigsten klar ist, dass ein Brushless-Regler gemeint ist. Welches Fabrikat/Hersteller, dass man mal in ein Datenblatt schauen kann?

Es geht um das "wie" und nicht "wieso".

Die Frage ist doch Präzise genug, oder hab ich was übersehen?

Durch die Bibliothek Servo.h erzeugt man ein PWM Signal um Servo's oder ähnliches anzusteuern.
Gibt es eine Möglichkeit bei dieser Bibliothek die Periodendauer von Standard 20ms (50Hz) auf 10ms (100Hz) zu ändern?

Gruss Kay

Sicher gehts für Dich um das <<Es geht um das "wie" und nicht "wieso".>>
Aber eine gewisse Neugierde und den Wunsch unsererseits nicht "eine Antwort" zu geben sondern "eine möglichst gute Antwort" zu geben mußt Du aber schon akzeptieren.
Un die Frequenz zu ändern braucht man nur den "richtigen" Wert in der Bibiothek zu verändern. Ich habe aber ehrlich gesagt keine Lust, Zeit zu investieren, die richtige Stelle zu finden, weil Du gerne die Bibothek mit 100 Hz anstatt 50 Hz am laufen haben möchtst.
Ich habe oft erlebt, daß man in einer Lösung festgefahren ist diese umbedingt haben will, obwohl andere Lösungswege zielführender und einfacher sind.
Viele Grüße Uwe

Ich selber habe noch zu wenig Ahnung über Bibliotheken um das selber zu finden.

Das warum ist eigentlich einfach:

Ich habe eine PID Lageregelung Programmiert für einen Quatrokopter, die Brushless-Regler steuere ich mit 200Hz an, diese Regler Funktionieren sehr gut mit diesem Signal, die Regelung ist viel ruhiger als mit 50Hz.

Nur generiere ich das Servosignal durch einen eigenen Code ohne Bibliothek, und finde dies nicht so schön.
Eventuell weiss ja jemand wo und was ich in dieser Bibliothek ändern muss.

Gruss Kay

Vermutlich gehts um diesen Wert:

#define REFRESH_INTERVAL    20000     // minumim time to refresh servos in microseconds

Steht ungefähr am Ende der Definitionen.

Hallo MaFu

Vielen Dank für deine Antwort.
Reicht es wenn ich in der Datei Servo.h diesen Wert ändere und dann speichere?
Oder braucht es da mehr dazu?

Gruss Kay

Keine Ahnung, sollte aber reichen. Probiers aus.

Werde ich Morgen machen, vielen Dank.

Gruss Kay

So

Habe es versucht, leider ohne Erfolg.
Scheinbar reicht es nicht wenn man diese Zahl ändert, die Bibliothek neu einliesst und Uploadet.
Das Oszi hat keine Änderung des Signales angezeigt, ich habe diverse Werte versucht.

Jetzt sind wieder die Experten gefragt, ich hoffe jemand weiss eine Lösung wie ich diese Bibliothek ändern kann.

Gruss Kay

Jungs, hier mal ein Beispiel wie ich ein Servosignal mit 100Hz erzeuge:

// von Kay
// 14 April 2012

// Erzeugen von einem Servosignal von 100Hz
// Ohne Bibliothek und ohne Delay


int Winkel=1500;          // Servo Winkel 90°
int Periodendauer=10000;  // Periodendauer 10 millisekunden = 100Hz
int x=1;
int Servo=9;              // Servo an Pin 9
unsigned long Zeit;

void setup()
{
  Zeit = micros();
  pinMode(Servo,OUTPUT);
}

void loop()
{
if (x == 1)
digitalWrite(Servo,HIGH);
if (x==1&&(micros() - Zeit) >Winkel)  // Erzeugen von einem Impuls von 1,5ms = 90° Servo Winkel
{
  Zeit=micros();
  digitalWrite(Servo,LOW);
  x=0;
  }
  if (x==0&(micros() - Zeit) >Periodendauer) // Erzeugen von 100Hz Periodendauer
  {
    Zeit=micros();
    x=1;
  }
}

Schön währe wirklich wenn ich die Bibliothek Servo.h so ändern kann das ich Servosignale von z.B. 100Hz erzeugen kann.

Gruss Kay

REFRESH_INTERVAL ist der entsprechende Wert, der das Intervall zwischen den Impulsen angibt. Ich vermute hier hast du einen Fehler an anderer Stelle gemacht. Dein Beispiel arbeitet auch eher bei 80Hz als bei den von dir angegebenen 100Hz - das sollte dein Oszi dir aufgezeigt haben. Versuch doch mal, die Wiederholrate in der Servo.h geringer einzustellen und das Ergebnis auf dem Oszi zu messen.

Und in deinem Beispiel hast du & mit && verwechselt - was bei deinem Code glücklicher Weise trotzdem zum richtigen Ergebnis führt.

Marek080:
REFRESH_INTERVAL ist der entsprechende Wert, der das Intervall zwischen den Impulsen angibt. Ich vermute hier hast du einen Fehler an anderer Stelle gemacht. Dein Beispiel arbeitet auch eher bei 80Hz als bei den von dir angegebenen 100Hz - das sollte dein Oszi dir aufgezeigt haben. Versuch doch mal, die Wiederholrate in der Servo.h geringer einzustellen und das Ergebnis auf dem Oszi zu messen.

Und in deinem Beispiel hast du & mit && verwechselt - was bei deinem Code glücklicher Weise trotzdem zum richtigen Ergebnis führt.

Vielen Dank für deine Antwort.
Du hast recht, das Oszi sagt ca. 87Hz.
Den Fehler && stimmt auch, hab das gar nicht bemerkt.

Zu dem REFRESH_INTERVAL in der Datei Servo.h, diesen Parameter hab ich geändert, von 20000 (ca.50Hz) auf z.B. 10000 (ca.100Hz), das Signal am Pin hat sich jedoch nicht verändert.

Weisst du was ich da falsch mache?

Hast du mal versucht, die Frequenz auf 40Hz oder 30Hz zu senken? Es geht erstmal darum festzustellen, ob der Parameter seinen Zweck erfüllt. Langsamer sollte kein Problem sein, schneller könnte an die Grenzen der gewählten Timereinstellungen stoßen.

Hab ich nun versucht (30000, 40000 und 60000), der Spuckt immer 100Hz aus.
Dabei dachte ich Standard sind es 50Hz.

Aber wieso ändert sich nichts am Signal?

Es geht :slight_smile:

Ich bin sehr Dumm.
Ich hatte den Arduino Ordner 2X, und ich hatte die Servo.h Datei im falschen Ordner bearbeitet.
Das ist sehr Peinlich.

Vielen Dank für eure Hilfe und Geduld.

Gruss Kay

Noch ein Hinweis, was hier passiert. Folgendes macht die Servo-Lib: für jeden Servo wird der Ausgangspin auf HIGH gesetzt, dann das Auslösen des Interrupts neu gesetzt, so daß er nach der Länge des HIGH-Signals wieder zuschlägt, um dann LOW zu setzen. Danach wird das gleiche mit dem nächsten Servo durchgeführt bis alle abgearbeitet sind. Jetzt wird das Auslösen des Interrupts auf REFRESH_INTERVAL gesetzt und beim nächsten Interrupt neu gestartet.

Daraus ergibt sich folgendes: hat man vier Servos und alle sind bei 1500µs, dann vergehen von den 20000µs REFRESH_INTERVAL schon 6000µs für das Erzeugen der Signale (+ die Verabeitungszeit). Sind alle vier bei den maximal erlaubten 2400µs, dann braucht man bereits den halben REFRESH_INTERVAL. Daraus ergibt sich ein Limit für die maximale Wiederholrate in Abhängigkeit der Anzahl der Servos. Andersum gibt der 16-Bit-Counter ein oberes Limit für REFRESH_INTERVAL vor. Beim 16MHz ATmega wird der Wert von REFRESH_INTERVAL mit 2 multipliziert in das Counter-Register geschrieben, welches meiner Meinung nach ja nur 16 Bit groß ist und damit nur Werte bis 65535 aufnehmen kann. Also wird bei etwas mehr als 32000 der REFRESH_INTERVAL nicht mehr das tun, was man erwarten würde.

Hallo Marek080

Also ich muss das jetzt erst mal verdauen, was du da geschrieben hast. :slight_smile:

Werde Morgen 4 Signale Proggen, und dann messen wo da die Grenzen liegen um deine Ausführung zu verstehen.

Gruss Kay

Hab nun mal ein paar Messungen gemacht, und gleich an dich gedacht, Marek080.

Um Logischer Messen zu können habe ich die Parameter so verändert:

#define MIN_PULSE_WIDTH       1000     // the shortest pulse sent to a servo  
#define MAX_PULSE_WIDTH      2000     // the longest pulse sent to a servo 
#define DEFAULT_PULSE_WIDTH  1500     // default pulse width when servo is attached
#define REFRESH_INTERVAL    3000     // minumim time to refresh servos in microseconds

Sehr Interessant wahren dann auch die Messungen:

Bei 1 Servo alleine:

Servo Winkel 0° = Impuls 1,0ms, Frequenz 333Hz
Servo Winkel 90° =Impuls 1,5ms, Frequenz 333Hz
Servo Winkel 180°=Impuls 2,0ms, Frequenz 333Hz

Bei 4 Servosignalen gleichzeitig:

Alle Servo Winkel 0° =Impuls 1,0ms, Frequenz 250Hz
Alle Servo Winkel 90° =Impuls 1,5ms, Frequenz 166Hz
Alle Servowinkel 180°=Impuls 2,0ms, Frequenz 125Hz

Je nach der menge Servos und definierten Winkel variiert die Periodendauer, der Impuls dagegen stimmt immer genau.

Deine Erklärung habe ich noch nicht ganz verstanden, aber ich bleibe dran. :slight_smile:

Gruss Kay