D1 Mini: Servo.write(0) stellt den Servo nicht auf 0

#7013935
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
}
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #7013940
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.
Moderator (Firma: Titel) Persönliche Seite #7013959
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.
#7013983
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.
Gast #7014068
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.
Gast #7014079
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.
#7014167
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
}
Angehängte Dateien:
#7014201
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.
Gast #7014217
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.
#7014234
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.
#7014251
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.
Gast #7014286
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren