Hallo zusammen Ausgangslage - Arduino Nano - Zwei digitale Servos - Zwei Schaltregler Der eine Schaltregler stellt die +5V für den Nano bereit, der andere dient als Versorgungsspannung für die Servos. Wenn Pin2 auf HIGH gelegt wird, bewegen sich beide Servos simultan auf Position (a). Bei LOW gehen diese wieder in die Ausgangsstellung, die Position (b). In beiden Positionen, sowohl (a) als auch (b), soll die Position nicht von den Servos gehalten werden. Um das zu erreichen, arbeite ich mich den Befehlen Servo.attach und Servo.deatach. Das funktioniert. Versuchsaufbau Um die Anwendung zu testen, habe ich einen Versuchsaufbau mit einem Labornetzgerät und einer elektronischen Last aufgebaut. Die elektronische Last lässt sich programmieren. In meinem Aufbau tut diese nichts anderes, als alle 10 Sekunden Pin2 zu invertieren. Problembeschreibung Von 20-30 Bewegungen fällt eine aus. Die nächste erfolgt dann natürlich wieder 10 Sekunden später. Hierbei ist kein Muster erkennbar, es kann fünf Mal funktionieren, dann eine Bewegung ausfallen, oder 30 Mal hintereinander funktionieren. Im Schnitt komme ich auf die erwähnten 20-30 Bewegungen. Das betrifft immer beide Servos, also beide Ausgänge. Vorgehensweise zur Lösung @ Die Servos ziehen unter Last zusammen max. 800mA. Das Labornetzgerät liefert 3A. Mit DSO kein Spannungsabfall zu beobachten. Auch Versuche mit C's am Ein- und Ausgang der Schaltregler haben keine Besserung gebracht. @ Das PWM Signal sieht auf dem DSO so aus, wie es sein soll. Keine Auffälligkeiten zu erkennen. -> Ich denke hier liegt eher ein Problem im Coding vor. Wenn der Befehl Servo.detach ausgeführt wird, wird der Pin der PWM geführt hat freigegeben. Meine Vermutung, bei Servo.attach ein paar Millisekunden warten, bis sich der PWM Timer reinitialisiert hat, oder den Timer direkt initialisieren. Hat jemand eine Idee? Ich freue mich auf sachliche Antworten. Gruss, Philipp
:
Bearbeitet durch User
Auf das Programm an sich habe ich hier leider grad keinen Zugriff. Es lässt sich leicht auf das folgende reduzieren: Loop { if (Pin2 == high) { Servo.attach; Servo.write(90); Servo.detach; } else { Servo.attach; Servo.write(0); Servo.detach; } }
Du musst vor dem detach ausreichend lange warten, damit die Servos sich zur Zielposition hin bewegen können.
Philipp G. schrieb: > Hat jemand eine Idee? Ich würde da einfach die PWM weiter laufen lassen und den Pin über DDRx abschalten. Ggf. dazu noch einen Pulldown.
Stefan U. schrieb: > Du musst vor dem detach ausreichend lange warten, damit die Servos > sich zur Zielposition hin bewegen können. Das Programm wartet, bis Servo.read >= iEndPos. @vka: Was meinst du mit DDRx?
Philipp G. schrieb: > @vka: Was meinst du mit DDRx? Das Richtungsregister des PWM Ports. Ohne in die Konfiguration der PWM einzugreifen, kann man durch Umschalten des Signalpins auf Eingang die PWM abschalten.
> Das Programm wartet, bis Servo.read >= iEndPos.
Wo denn? Ich sehe dazu keinen Hinweis im Quelltext.
Es geht doch um RC Modellbau Servos und die dazugehörige Arduino Klasse,
oder etwa nicht?
Diese RC Modellbau Servos haben keinen Rückkanal, deren aktuelle
Positionen kann man nicht auslesen. Dir bleibt daher nur die
Möglichkeit, zu schätzen, wie lange die Servos bis zum Erreichen der
Soll-Position brauchen, bevor du das Signal abschaltest.
Wenn du meinst, dass ich hier auf einem Irrweg bin, dann zeige deinen
Schaltplan, das Programm, einen Link auf die verwendete Library und
einen Link auf die Produktbeschreibung der Servos.
Stefan U. schrieb: > Wo denn? Ich sehe dazu keinen Hinweis im Quelltext. > > Es geht doch um RC Modellbau Servos und die dazugehörige Arduino Klasse, > oder etwa nicht? Das ist korrekt. Stefan U. schrieb: > Diese RC Modellbau Servos haben keinen Rückkanal, deren aktuelle > Positionen kann man nicht auslesen. Dir bleibt daher nur die > Möglichkeit, zu schätzen, wie lange die Servos bis zum Erreichen der > Soll-Position brauchen, bevor du das Signal abschaltest. Nun ja, Ich gehe davon aus, die Servo.read Funktion wertet das PWM Signal aus, nicht die tatsächliche Position der Servos. Aber mechanisch ist ja alles in Ordnung. Das Problem ist nach wie vor, dass manchmal nach dem Detach Befehl es zu Ausfällen kommt. Stefan U. schrieb: > Wenn du meinst, dass ich hier auf einem Irrweg bin, dann zeige deinen > Schaltplan, das Programm, einen Link auf die verwendete Library und > einen Link auf die Produktbeschreibung der Servos. Ich verwende die folgenden Libs: #include <Servo.h> #include "ServoEaser.h" https://github.com/todbot/ServoEaser/blob/master/ServoEaser.h Ich habe nun die Funktion reinit() eingefügt, leider hat dies nicht den gewünschten Erfolg gebracht: head
1 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
2 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
3 | #include <Servo.h> |
4 | #include "ServoEaser.h" |
Loop
1 | void loop() |
2 | {
|
3 | if (digitalRead(iIGNPlusPin) == HIGH) |
4 | {
|
5 | if (bIsOpen == false) |
6 | {
|
7 | unsigned long currentMillis = millis(); |
8 | if (bAttached == false) |
9 | {
|
10 | reinit; |
11 | SrvRight.attach(10); |
12 | SrvLeft.attach(9); |
13 | bAttached = true; |
14 | previousMillis = millis(); |
15 | }
|
16 | if( servoEaserL.hasArrived()) |
17 | {
|
18 | lastMillis = millis(); |
19 | servoEaserL.easeTo(180 - iEndPos, 1700); |
20 | servoEaserR.easeTo(iEndPos, 1700); |
21 | }
|
22 | //Serial.println(SrvRight.read());
|
23 | //if ((unsigned long)(currentMillis - previousMillis) >= interval)
|
24 | if (SrvRight.read() >= iEndPos) |
25 | {
|
26 | SrvRight.detach(); |
27 | SrvLeft.detach(); |
28 | previousMillis = millis(); |
29 | bIsOpen = true; |
30 | bAttached = false; |
31 | }
|
32 | }
|
33 | }
|
34 | else
|
reinit:
1 | void reinit() |
2 | {
|
3 | TCCR1B = 0; |
4 | // set timer 1 prescale factor to 64
|
5 | sbi(TCCR1B, CS11); |
6 | sbi(TCCR1B, CS10); |
7 | // put timer 1 in 8-bit phase correct pwm mode
|
8 | sbi(TCCR1A, WGM10); |
9 | }
|
Matthias S. schrieb: > Das Richtungsregister des PWM Ports. Ohne in die Konfiguration der PWM > einzugreifen, kann man durch Umschalten des Signalpins auf Eingang die > PWM abschalten. Steh immer noch auf dem Schlauch. Kannst Du mir bitte ein Beispiel machen?
:
Bearbeitet durch User
Philipp G. schrieb: > Steh immer noch auf dem Schlauch. Kannst Du mir bitte ein Beispiel > machen? Gibts in meinem Frequenzumrichter: https://www.mikrocontroller.net/articles/3-Phasen_Frequenzumrichter_mit_AVR Ich zitiere:
1 | // from vfd.h
|
2 | //! Bit pattern of PWM pins placed on PORTB.
|
3 | #define PWM_PATTERN_PORTB ((1 << PB1) | (1 << PB2) | (1 << PB3))
|
4 | |
5 | //! Bit pattern of PWM pins placed on PORTD.
|
6 | #define PWM_PATTERN_PORTD ((1 << PD3) | (1 << PD5) | (1 << PD6))
|
7 | // in main.c
|
8 | /*! \brief Enables PWM output pins
|
9 | *
|
10 | * This function enables PWM outputs by setting the port direction for
|
11 | * all PWM pins as output. The PWM configuration itself is not altered
|
12 | * in any way by running this function.
|
13 | */
|
14 | static void EnablePWMOutputs(void) |
15 | {
|
16 | DDRB |= PWM_PATTERN_PORTB; |
17 | DDRD |= PWM_PATTERN_PORTD; |
18 | }
|
19 | /*! \brief Disables PWM output pins
|
20 | *
|
21 | * This function disables PWM outputs by setting the port direction for
|
22 | * all PWM pins as inputs, thus overriding the PWM. The PWM configuration
|
23 | * itself is not altered in any way by running this function.
|
24 | */
|
25 | static void DisablePWMOutputs(void) |
26 | {
|
27 | DDRB &= ~PWM_PATTERN_PORTB; |
28 | DDRD &= ~PWM_PATTERN_PORTD; |
29 | }
|
Hier werden alle 6 PWM Ausgänge ein- bzw. ausgeschaltet, die im Projekt benutzt werden. Bei dir ist das nur ein Bit pro Servo.
Super, danke Dir. Also, anstatt Servo.attach oder Servo.deattach zu benutzen, wechsle ich diese einfach durch Deine Funktionen aus und teste. Muss ich nach dem enablen warten, oder wartet der uC bis das PWM enabled ist, also synchrone Abfolge? Nochmal danke @Matthias.
:
Bearbeitet durch User
Philipp G. schrieb: > Ausgangslage > > - Arduino Nano > - Zwei digitale Servos > - Zwei Schaltregler Was für eine Schnittstelle haben denn die Servos? Ist es wirklich RC-Like mit der PWM oder ist es was mit Rückkanal. Das würde die Confusion mit Servo.read erklären... Das Verhalten von Servos ist IMHO nicht definiert wenn die PWM nicht mehr anliegt. Vor allem wenn der Schaltkreis im Servo digital ist wie du beschreiben hast. Servotyp wäre hier hilfreich ...
soundso schrieb: > Was für eine Schnittstelle haben denn die Servos? Ist es wirklich > RC-Like mit der PWM. Das würde die Nö, wirklich RC Servos ganz normal. > Confusion mit Servo.read erklären... Ich hatte Servo.read als Ausgabe mit Serial.read drin, das funktioniert wirklich. Das ist aber wirklich nur die Positionsvorgabe vom uC nicht den Rückwert vom Servo. Das Servo hat ja gar keinen, das macht nur was das PWM Signal ihm sagt. soundso schrieb: > Das Verhalten von Servos ist IMHO nicht definiert wenn die PWM nicht > mehr anliegt. Vor allem wenn der Schaltkreis im Servo digital ist wie du > beschreiben hast. Servotyp wäre hier hilfreich ... Ich weiss, deswegen sind es digitale Servos. Die haben die wunderschöne Eigenschaft, dass wenn kein verwertbares PWM Signal am Eingang anliegt deren Controller den Brushless Motor einfach abschalten. Das mache ich mir zunutze. Das sind diese hier: http://www.savoxusa.com/Savox_SA1283SG_Digital_Servo_p/savsa1283sg.htm Natürlich ist das Verhalten nicht standardisiert, ein anderes könnte die letzte Position halten, ein analoges könnte wild ausschlagen. Könnte auch eine Herstellerüberlegung sein, wenn das Signal fehlt geben wir das Servo frei, um Beschädigungen beim Flugzeug Absturz auf ein Minimum zu reduzieren. Sowohl hitec, Futaba als auch Savöx machen das so. Aber wir weichen vom Thema ab.
:
Bearbeitet durch User
Ich hatte bisher mit 6 unterschiedlichen analogen Servos von 5 unterschiedlichen marken zu tun. Alle lassen den Motor frei (stromlos) drehen, wenn sie kein Signal bekommen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.