Problem mit Servoansteuerung

Hallo zusammen,

ich habe ein spezifisches Problem bei einer Servoansteuerung.

Sas Servo ist eines seiner RC-Analge, wird also mit 1000 bis 2000µs angesprochen, mitte in 1500µs.

Es geht um einen Anwendungsfall, wo dieses Servo mittels eines Schalters am Sender von einer Stellung in die nächste fährt, un eben beim zurückschalten wieder zurück.

Eigentlich also ganz trivial, könnte man jedenfalls vermuten.

dazu kommt nach, dass das Servo sich mit einer über ein Poti einstellbaren Geschwindigkeit bewegen soll.
Auch nicht so schwer. Differenz neue Pulslänge/alte Pulslänge in abs() addieren oder subtrahieren in 1µs Schritten.

Das Servo bewegt ein größeres langes Teil hin und her, es soll "Scale" aussehen, daher sehr langsam.

Das alles läuft auch schon bestens, wenn da nicht, ja , wenn da nicht diese Einschaltphase wäre, wo nach servo attach mit voll Speed in die Mitte gedonnert würde, oder gar an den Anschlag, so dass das dünne lange Teil zu brechen droht, hat man den Eindruck.

Nun ist es so, das im normalen Betrieb folgender Endzustand erreicht wird:
Das Servo wurde mittel Schalter am Sender in die eine, oder die andere Endstellung gefahren.
diese Stellungen sind sendeitig genau justiert, also z.B. 1210µs und 1847µs, Damit das Gestänge das zu bewegende Teil in genau die richtigen Stellungen fährt.

Dann wird der Empänger ausgeschaltet. Dann der Sender.

Jetzt wird der Sender eingeschaltet ( Er strahlt also schon mal z. B die Pulslänge von 1847ms wieder ab, da der Schalter ja noch so steht, wie beim Einschalten.

Jetzt wird der Empfänger unter Saft gesetzt, damit auch der Adrduino ( übrigens eine Nanao ).

Jetzt soll das Servo aber nicht mit voll Stoff losrennen. Es soll einfach stehenbleiben wo es steht. Da der Empfänger und der Arduino erst mal hochfahren müssen, und erst mal servo attach gemacht wird. Tut das Servo dies aber nicht.

Erst nach Durchlauf dess Sketches bis an die Stelle, wo der eingehende Impuls wiederum als Servosignal anliegt, fährt das Servo in die Mitte, und zwar mit Vollgas.

Ich würde gerne eine Situation herstellen, das der Servo zunächst mal keinen Impuls bekommt.
Das kleine einschaltzucken ist Servoabhängig, ein guter macht danicht viel und benimmt sich einigermassen.

Jetzt soll der Sketch erst mal schauen, ob denn am Eingang bereits halbwegs konstante Impulse gelesen werden. Also in diesem Fall hier die oben zufällig erdachten 1847µs.

Dann erst soll der mit Servo attach beschriebene Augang beginnen, diese Impulslänge auszugeben, und beim Schalten halt zu wechseln.

Ich habe auch schon probiert, Sender und Empänger einzuschalten, und zu warten bis der Empänger sauber ausspuckt, und dann erst den Arduino zu starten( z.B. mittesl Reset.
Aber auch da fährt der Servo in Millsekunden zur Mitte um dann wieder die Endstellung anzufahren.
Da die Modell notwendige Endstellung noch nicht bekannt ist, und sich ggf. auch leicht anpassbar sein muss, der befreundete Anwender aber nicht irgendwelche Werte in irgendeiner lib ändern kann/soll, suche ich nach einer Möglickeit, das ganze ohne das Anfahren der Mittelstellung zu programmieren.

Was funktioniert, aber antiquiert ist, das der Arduino eine weiter Funktion ausführt, indem er 10 Sek. nach den Einschalten ein Ralais dauerhaft betätigt, das dann erst den Servo bestromt.
Hab ich probiert, funktioniert, aber eigentlich, lächel, programmiert man nicht einen contrller und bedient sich modernster Mittel, um dann mittel Relais einen Servo zu bestromen.

Schöner fände ich, die Ausgabe der Servoimpulse einfach zu unterdücken, also nichts auszugeben, bis sauber die Impulse gelesen werden.

Und genau da komme ich nicht weiter.

Wie kann ich nach "servo.attach" verhindern, das Ausgang schon aktiv Impulse rausschmeißt, und nicht erst wartet, was denn für eine Imulslänge gerade am Eingangspunkt anstehen, und dann diese ausgibt.

Hat da jemand eine zündende Idee?

Das Problem ist daß ein normaler Servo keine Rückmeldung gibt, in welcher Position es gerade ist. Ich weiß nicht ob digitale Servos (mit bidirektionaler Ansteuerung) seine Position rückmeldet damit die Steuerung seine Schritte von dieser Anfangsposition startet.

Ich sähe hier einen Schrittmotor zb einen 28 byj-48 als geeigneter.

Grüße Uwe

Speichere die letzte Position des Servos im EEPROM ab.
Beim nächsten Einschalten diese Position aus dem EEPROM einlesen und entsprechend anfahren.
Je nach Last am Servo kann man das PWM-Signal mit detach() nach einer Bewegung ausschalten. Das beugt Brummen vor.

Woher soll er die letzte Position kennen?

Gruß Tommy

Nach jeder Bewegung des Servos zu einer best. Position, einfach diese Position im EEPROM wegschreiben.

Du kennst die Anzahl der garantierten Schreibzyklen des EEPROM?

Gruß Tommy

Natürlich.

Er soll ja auch nicht jede kleinste Bewegung speichern, sondern nur die Endposition.

So mach ich das bei Servodekodern für die Modellbahn.

Die 100000 Zyklen werde ich nicht erleben.

Das machen die MobaTools sehr schön im Hintergrund, mein Tipp nicht nur für den Modellbauer :slightly_smiling_face:

Grundsätzlich hast Du zwei Probleme:

  1. Beim Einschalten ist die Ist-Position des Servos unbekannt. Dies habe ich durch eine Mittelanzapfung des Potis im Servo gelöst. Der Arduino kann aus der Spannung die Ist-Position berechnen, was kalibriert werden muß. Ich habe gelötet, solche Servos gibt es aber auch fertig als Analog Feedback Servo. Dies ist nicht das Problem, nach dem Du fragst, würde aber das "größere lange Teil" schonen, wenn die Ausschaltprozedur nicht eingehalten werden konnte.
    Die vorigen Beiträge scheinen sich mit dieser Problematik zu befassen, wie ich meine aber fälschlicherweise. Das solltest Du klären!
    Meine arg angestaubte Anleitung: RC-Servo mit Istpositionsmeldung - Anfangszucken unterdrücken. Den 3,9 kΩ Pullup-Widerstand in der Signalleitung habe ich eingebaut.
  2. "wenn da nicht diese Einschaltphase wäre, wo nach servo attach mit voll Speed in die Mitte gedonnert würde, ..." kann ich im Zusammenhang mit den MobaTools nicht reproduzieren. Da ich keine Fernbedienung habe, mein Testprogramm mit Tastern:
#include <MobaTools.h>
// Die Taster müssen so angeschlossen sein, dass der Eingang bei gedrücktem
// Taster auf LOW (=0) geht. 
const int tasterPin1 = 2;    // Taster1 Pin 2
const int tasterPin2 = 3;    // Taster2  Pin 3
const int servoPin =  8;     // Anschluß für den Servo 

bool tasterStatus1, tasterStatus2;
MoToServo meinServo;

void setup() {
    pinMode(tasterPin1, INPUT_PULLUP); // so ist kein externer pullup Widerstand am 
    pinMode(tasterPin2, INPUT_PULLUP); // Taster erforderlich
    
    meinServo.attach( servoPin, true ); // Servo an Pin 9; autoOff
    meinServo.setSpeed( 50, HIGHRES );  // Verfahrgeschwindigkeit einstellen
}

void loop() {
    tasterStatus1 = digitalRead(tasterPin1);
    tasterStatus2 = digitalRead(tasterPin2);

    if (tasterStatus1 == LOW) {
        meinServo.write(1000); //wird langsam  drehen
    }

    if (tasterStatus2 == LOW) {
        meinServo.write(2000); //wird langsam drehen
    }
}

Test mit UNO:

  1. Taster2 ► Servo dreht in Position "2000"
  2. UNO Reset
  3. Taster2 ► Servo bleibt in Position "2000"
  4. Taster1 ► Servo dreht langsam in Position "1000"
  5. Taster2 ► Servo dreht langsam in Position "2000"

Wie sieht das bei Dir aus?

Danke für den Tip mit dem detach().

Im Setup direkt nach Servo.attach(Ausgang, min , max );
detach() gesetzt.

Servo zuckt nicht, bleibt stehen.

Im Loop dann erst
x= pulsein(y,HIGH,30000)
dann mit vorheriger Pulslänge vergleichen.
in der
if
else anschliessßend wieder das sero.attach(Ausgang) einführen.

Dann hat er den Puls bereits gelsen, und schreibt ihn auch direkt hinein.
das "attach wird dadurch zwar ständig widerholt, aber das ist nicht schlimm, da ja die Servobewegung eh sehr langsam von statten geht.

Es geht am Ende darum, einen Mast auf einem Schiff, der zum Zwecke der Brückenunterfahrung gekippt werden muss. Ist natürlich ein ferngesteuertes Schiff, und das Kippen soll lediglich die Funktionsvielfalt erhöhen. Das Ding passt auch im Mast aufwärtsmodus unter jede Brücke:-).

Wie dem auch sei, das detach kannte ich nicht, herzlichen Dank für den Tip.
Der beste Sketch ist der, der bug-frei läuft.

Und meiner läuft jetzt hier gerade seit einer Stunde ohne Mucken, und der Servo steht nach Reset, oder nach dem Ein und ausschalten da, wo er vorher stehen gelassen wurde.

Das liegt daran, dass in den MobaTools - in Kenntnis dieses Problems - beim attach noch keine Impulse ausgegeben werden ( Im Gegensatz zur Standard - Servo Lib ). Erst mit dem ersten write() nach dem attach wird die Ausgabe der Impulse gestartet - und diesem write() muss man dann eben den richtigen Wert mitgeben.

Wenn man im setup direkt nach attach gleich detach macht, kann man sich das attach da aber auch gleich sparen, und macht es nur da wo man das Servo auch bewegen will. Kennt man den richtigen Wert bereits, kann man auch ein write() vor dem attach machen. Dann fährt das Servo nicht in die Mitte, sondern zu dem vorgegebenen Wert.

1 Like

Da hat eben ein Praktiker die Bibliothek geschrieben :clap:

Ja, das hab ich probiert, hab das attach oben rausgenommen und unten wieder eingesetzt. Komischerweise hatte ich aber damit keinen Erfolg.

Jetzt klappt das.

Beim nächsten mal werde ich mich wieder an MoBa-tools halten. Die Lib ist echt besser als diie Servo .h.

Muss mich nur wieder einarbeiten. Hatte damit schon ganz nette Dinge hinbekommen. Z.B. Fade-LED, für die Beleuchtungssteuerung. Klappt hervorragend.

Vielleicht schreibe ich das Programm noch mal um dafür.

Ist in den MobaTools auch enthalten :slightly_smiling_face:

Ich kann es Dir nicht versprechen, aber möglicherweise ist die Bewegung sogar besser.

Speziell was die Umstellung von der Servo.h angeht, gibt es da bei den Aufrufen/Methoden kaum Unterschiede - außer das man eben die Bewegungsgeschwindigkeit einstellen kann und den oben geschilderten Unterschied beim attach.
Die größte Umstellung im Sketchablauf dürfte sein, dass sich der Servo nach dem write() noch (langsam) bewegt, während der Sketch schon weiterläuft. Da man aber abfragen kann, ob sich der Servo noch bewegt, kann man den Sketch auch entsprechend anhalten.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.