Forum: Mikrocontroller und Digitale Elektronik D1 Mini: Servo.write(0) stellt den Servo nicht auf 0


von Thomas B. (blinki)


Angehängte Dateien:

Lesenswert?

Hallo,

Problem:
mein Servo an zwei D1 Mini stellt sich nicht auf 0 - circa 90°.
servo.write(0); stellt sich auf etwa 90 'echte' Grad.

Infos:
1. Ich habe den Aufbau aus den Bildern mit einem zweiten D1 Mini an 
einer Steckplatine nachgebaut und den Fehler reproduziert (Bild anbei). 
An der Verlötung liegt es nicht.

2. Ich habe den Servo mal von dem Holz runtergeholt und von 
servo.write(0) - servo.write(180); durchlaufen lassen: dann bewegt er 
sich von etwa 90 bis 180°.

3. Wenn der D1 Mini von der IDE neu beschrieben wird und der Servo am 
Controller hängt, fährt der Servo für einen Moment auf echte 0° 
(vermutlich reseten sich da die Pins oder so...).

4. Ein Offset würde ich ausschließen. Dazu unten mein Testcode. 180° und 
160° werden super unterschieden.


5. Frage: was zur Hölle? :D Was soll ich messen? Ich hab ein Multimeter.


1
#import <Servo.h>
2
Servo servo;
3
4
void setup() {
5
  servo.attach(D4);
6
}
7
8
void loop() {
9
  
10
  servo.write(180); // = echte 180°
11
12
  delay(1000);
13
14
  servo.write(160); // = echte 160°
15
16
  delay(1000);
17
18
  servo.write(0); // = echte 90° (geschätzt)
19
20
  delay(1000);
21
}

: Bearbeitet durch Moderator
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas B. schrieb:
> Was soll ich messen?
Die Pulsdauer des High-Impulses des PWM-Signals musst du messen.
Dort drin steckt die für die Position nötig Information.

> Ich hab ein Multimeter.
Tja, nur ein Hammer, wo ein Schraubendreher nötig wäre.
Ohne Oszilloskop kannst du nichts sinnvolles messen...

BTW: mit den [c] Tokens gibts Syntax Highlighting gratis dazu.

: Bearbeitet durch Moderator
von Wolfgang (Gast)


Lesenswert?

Thomas B. schrieb:
> 5. Frage: was zur Hölle? :D Was soll ich messen? Ich hab ein Multimeter.

Das Signal, was du zum Servo schickst. Alleine mit einem Multimeter ist 
das schwierig.

Lothar M. schrieb:
> Ohne Oszilloskop kannst du nichts sinnvolles messen...

Unfug, ein Logikanalysator für den Gegenwert von zwei Kantinenessen 
würde schon sehr viel weiter helfen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> ein Logikanalysator für den Gegenwert von zwei Kantinenessen würde schon
> sehr viel weiter helfen.
Klar, geht auch.
Und im Gegenwert eines Adaptersteckers plus Spannungsteiler gibt es das 
Soundkartenoszilloskop: https://www.zeitnitz.eu/scope_de

Allerdings bringt so ein richtiges Oszi noch die Möglichkeit mit sich, 
die Signalqualität reproduzierbar und auf mehr als 1 Bit genau 
beurteilen zu können.

: Bearbeitet durch Moderator
von EAF (Gast)


Lesenswert?

Wenn ich mich richtig erinnere, dann ist die Arduino Servo Lib nicht für 
ESP8266  vorbereitet/geeignet.
Beim ESP verwendet man analogWrite().

Eine kurze Suche brachte dieses Beispiel:
Siehe: 
https://github.com/sarincr/ESP8266-Arduino-IDE/blob/master/12.Servomotor/12.Servomotor.ino

**ohne Gewähr**

von Thomas B. (blinki)


Lesenswert?

Schonmal vielen Dank für eure Zeit und Antworten. Die [c] Tokens habe 
ich angesehen und verstanden. Danke für den Tipp!

Danke auch für beide Hardwareempfehlungen. Unabhängig von dem aktuellen 
Problem sind das wahrscheinlich praktische Tools für die Zukunft.

---------------------------------------------
Unabhängig vom Messen denke ich aber, dass EAF wohl Recht hat.
Habe eben mit einem dritten D1 getestet und sowohl den, als auch den 
zweiten an 3.3V gehängt. Immer das selbe Ergebnis.

Ich recherchiere dem nach. Das klingt nämlich verdammt schlüssig.

Vielen Dank! Ich melde mich.

von Philipp G. (geiserp01)


Lesenswert?

0-180, deine ‘echte 90 grad’ liegen bei 90.

von Thomas B. (blinki)


Lesenswert?

Offensichtlich Philipp. Und was ist daraus die praktische 
Schlussfolgerung? Wo liegen denn die 'echten 0°'? ^^

Ich verstehe nicht, was du sagen möchtest, danke dir aber für deinen 
Beitrag.

von Wolfgang (Gast)


Lesenswert?

Thomas B. schrieb:
> Danke auch für beide Hardwareempfehlungen. Unabhängig von dem aktuellen
> Problem sind das wahrscheinlich praktische Tools für die Zukunft.

Die Zukunft ist JETZT - ist die Bestellung schon raus? ;-)

Mikrocontroller mit externen digitaler Peripherie ohne LA ist tappen im 
Dunkeln.

von Mario P. (Gast)


Lesenswert?

funktioniert "servo.writeMicroseconds(Wert)" bei Dir?

writeMicroseconds(Wert)
    Sendet den angegebenen Wert an den Servo. Meistens wird dadurch der 
Schaft des Servos an eine bestimmte Position bewegt. Bei Standard-Servos 
mit Hebel bedeutet ein Wert von 1000 das eine Ende, 2000 das andere und 
ein Wert dazwischen ein entsprechender Winkel (1500 sind dann ungefähr 
die Mitte). Beispiel: servo.writeMicroseconds(1200)

Mario P.

von Mario P. (Gast)


Lesenswert?

um welches Servo geht es konkret? (genaue Servobezeichnung oder noch 
besser dessen Datenblatt)

Mario P.

von Thomas B. (blinki)


Angehängte Dateien:

Lesenswert?

Hi Mario,
writeMicroseconds() bringt das identische Ergebnis zu write(). Da deckt 
er nur die 90 - 180° ab.

Der Servo ist ein Reely S-7361, den ich mal bei Conrad im Laden gekauft 
habe. Ein Datenblatt hat mir das Internet nicht ausgespuckt.

Bishr bestes Ergebnis:
Ein bisschen abgewandelt von EAFs Tipp 
(https://github.com/sarincr/ESP8266-Arduino-IDE/blob/master/12.Servomotor/12.Servomotor.ino)
bringt mir das hier aktuell die ganze Range. Allerdings rastet der Servo 
bei 0 - 3 nicht ein.
(vergleiche Bild im Anhang)

1
int from = 0;
2
int to = 32;
3
int i = from;
4
5
void setup() {
6
  pinMode(D4, OUTPUT);
7
  analogWriteFreq(50); 
8
}
9
10
void loop() {
11
  if(i < to){
12
    analogWrite(D4, i);
13
    i = i + 1;
14
  }else{
15
    i = from;
16
  }
17
  delay(500);
18
}

von Thomas B. (blinki)


Lesenswert?

Mit
1
analogWriteFreq

kann man schön rumspielen.
Je größer hier die Zahl, desto größer wird die Range einstellbarer 
Punkte.

Mit analogWrite(360) kann ich Werte von analogWrite(45) bis 
analogWrite(225) fahren und habe die oben gezeichneten Anschläge.

Allerdings 'bounced' der Servo noch zurück. Wenn ich z.B. 
analogWrite(170) mache, dann fährt er dorthin, schlägt an und fährt dann 
ein kleines Stück zurück, so, als würde er dort abprallen.

Es ist verrückt. Ich verstehe aber halt auch gar nichts von Servos und 
Elektrotechnik, wie ihr vermutlich ja schon bemerkt habt :)

Ich muss mir das mal detaillierter zu Gemüte führen.

Ein Logikanalysator ist jedenfalls ganz schön teuer und braucht viel 
Platz. Weiß nicht, ob ich sowas will.

von EAF (Gast)


Lesenswert?

Thomas B. schrieb:
>> analogWriteFreq
> Je größer hier die Zahl, desto größer wird die Range einstellbarer
> Punkte.
Im Prinzip eine gute Idee.....
Nur dass der Servo es gerne im 20ms Raster haben möchte.
Aus der Ecke machen die 50Hz durchaus Sinn.

von EAF (Gast)


Lesenswert?

Thomas B. schrieb:
> Ein Logikanalysator ist jedenfalls ganz schön teuer und braucht viel
> Platz. Weiß nicht, ob ich sowas will.

10 Euronen für deinen Zwecke, ca so groß wie eine Streichholzschachtel.

von Mario P. (Gast)


Lesenswert?

Was meinst Du mit "einrasten" des Servos?
Wenn das Servo dort zappelt oder nicht zur Ruhe kommt, bist Du am 
mechanischen Anschlag des Servos. Ein Betrieb des Servos dort beschädigt 
das Servo.

Mario P.

von Mario P. (Gast)


Lesenswert?

Kann Dein Multimeter Frequenzmessung, Messung der Impulsdauer? Welches 
Multimeter hast Du?

Mario P.

von Thomas B. (blinki)


Lesenswert?

Also erstmal muss ich sagen, dass ihr ne ziemlich tolle Community seid.

Danke für den Support und die Ideen.
Nach dem Logikanalysator schau ich nochmal genauer. Mein Multimeter ist 
ein MT-52 Voltcraft. Hab's erst seit gestern.

Die Standard Servo Lib hab ich zum Laufen gebracht. Jetzt kann ich die 
vollen 180° ausnutzen.
1
#import <Servo.h>
2
Servo servo;
3
int i = 0;
4
5
void setup() {
6
  servo.attach(D4, 500, 2400);
7
}
8
void loop() {
9
   servo.writeMicroseconds(500);    // identisch: write(0);
10
   delay(2000);
11
   servo.writeMicroseconds(1450);   // identisch: write(90);
12
   delay(2000);
13
   servo.writeMicroseconds(2400);   // identisch: write(180);
14
   delay(2000);
15
}

Einzig und allein 'bounced' der Servo noch. D.h. im Detail, dass er über 
das Ziel hinausschießt und dann langsam zurückfedert auf die korrekte 
Stellung.


(Mit dem Einrasten meinte ich, dass der Servo, wenn er einen validen 
Befehl bekommen hat, sich feststellt - sich also nicht mehr von Hand 
durch sanftes Drehen bewegen lässt. Ich denke, das ist, wie es sein 
soll. Oben in der Paintzeichung ist aufgeführt, dass er eben bei 0 - 3 
nicht 'einrastete', also scheinbar keine Befehle bekommt. Ist 
mittlerweile ja aber nicht mehr relevant).


Ich muss mich jetzt mal dringend ins Bett legen. Ich hab Kopfschmerzen 
des Zorns. Ich schau morgen wieder in den Thread.

Vielen Dank euch allen.

von Thomas B. (blinki)


Lesenswert?

Update:

ich konnt's nicht verheben und hab's einen anderen Servo rausgekramt. 
Ein SM-2309S
1
servo.attach(D4, 540, 2400);
erledigt den Zaubertrick, wenn man mit der Standard <Servo.h> Lib 
arbeiten will. Ohne die Min/Max Parameter für die attach() bewegt sich 
auch der SM-2309S nur um 90°.


Das "Bouncen" mach der zweite Servo nicht. Da ist alles gut.

Ich halte das Thema für erledigt.

Tausend Dank euch allen, hab ne Menge gelernt.

: Bearbeitet durch User
von Mario P. (Gast)


Lesenswert?

Es ist schön, wenn Du es so zum Laufen bekommen hast.
Die weiteren Parameter zu servo.attach() für die maximale und minimale 
Impulslänge und den zugehörigen Winkelstellungen wären jetzt auch meine 
nächsten Empfehlungen gewesen;

MT-52 Voltcraft:
Meine Frage nach dem MM hatte den Hintergedanken, ob Du damit die 
Widerholfrequenz des Signals und dann die Pulslänge als den relevanten 
Wert für die Winkelvorgabe hättest ermitteln können:

- Frequenzmessung ist möglich - die Wiederholrate des Pulses für das 
Servo (standard: 20ms, bei Digitalservos auch weniger; genauer Wert aber 
unkritisch)
- Pulslängenmessung ist leider nicht möglich - die Winkelinformation 
steckt in der Pulslänge

Die Mittelstellung des Servos ist standardmäßig wie in 
Beitrag "Re: D1 Mini: Servo.write(0) stellt den Servo nicht auf 0" 
anegeben bei 1500µs.
Im Modellbau werden mit den Servos meist Gestänge bewegt. Daher werden 
dort nur Winkel im Bereich von -45°...0°...+45° genutzt. Bei größeren 
Winkeln werden die entstehenden Hebelverhältnisse deutlich ungünstiger 
bis unbenutzbar.
Die -45° werden standardmäßig bei einer Pulslänge von 1000µs erreicht, 
die +45° bei einer Pulslänge von 2000µs (soweit die Theorie, wenn 
Bauteiltoleranzen und andere Einflüsse außer Acht gelassen werden). 
Diese Werte passen recht gut zu Deinen letzten Werten in 
Beitrag "Re: D1 Mini: Servo.write(0) stellt den Servo nicht auf 0".

Thomas B. schrieb
> sich also nicht mehr von Hand  durch sanftes Drehen bewegen lässt
In diesem Fall registriert der Sensor für die Winkelstellung im Servo 
deren Änderung durch das von außen am Servo angreifende Drehmoment. Über 
die Servoelektronik wird dadurch der Motor aktiviert, um diesen 
Winkelfehler wieder zu beheben. Das äußert sich dann im Drehmoment, das 
von außen zum Bewegen des Servos benötigt wird. Du arbeitest also gegen 
das Drehmomemt des Servomotors. Das fühlt sich dann für Dich wie ein 
"Einrasten" an.

Thomas B. schrieb
> Oben in der Paintzeichung ist aufgeführt, dass er eben bei 0 - 3
> nicht 'einrastete', also scheinbar keine Befehle bekommt.
Deine Impulslängen und damit die Soll-Winkelstellung kommen nach wie vor 
an. Der Erfassungsbereich des Winkelsensors ist dort aber überschritten 
und er liefert in diesem Winkelbereich keine gültigen Daten mehr. 
Winkeländerungen durch äußere Drehmomente können also nicht erkannt 
werden. Entsprechend wird auch nicht der Servomotor zu deren 
Rückstellung aktiviert.

Mario P.

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
Noch kein Account? Hier anmelden.