Ironman Helm Servo dreht falsch herum

Servus zusammen.

Ich habe ein Problem mit der Drehrichtung mehrerer Servomotoren. Diese sollen verschieden Teile des Helmes bewegen. Ich kenne mich mit Arduino null aus, und bin auf den Code angewiesen.

Dummerweise drehen mehrere Servos in die falsche Richtung. Darunter Brow Center und Nose Center.

Die Werte um die Grad einzustellen habe ich schon vertauscht und auch den open und close Befehl. Das führte nur zum Stillstand oder ein kurzes "Wippen".

Ich weiß jetzt aber schon mal wie man einen Motor umlötet und ihn 360 Grad drehen lassen kann ;)(habe den Poti Anschlag am Zahnrad abgetrennt). Ich habe zum Glück zwei Servos mehr im Set.

Da ich nicht noch einen zerstören will und nicht sicher bin wie ich den Poti auch umlöten kann, hoffe ich auf eure Hilfe.

Dummerweise gehen auch die LED Augen an, wenn die Maske sich öffnet . Die sollen aber an sein im geschlossenen Zusatnd

`#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

// Adjust for global change in small sg90 servo movement //
#define SERVOMIN 150
#define SERVOMAX 450
/////////////////////////////////////////////////////
#define SERVO_FREQ 50

uint8_t servonum = 0;
int buttonPin = 2;
int ledPin = 6;
int buttonState = 0;
int globalPos = 1;
unsigned long previousMillis = 0;
unsigned long interval = 5000;
int a = 60;

int animDelay = 1;
int mainServoL = 0;
int mainServoR = 1;
int servoBrowCenter = 4;

// Adjust below numbers for individual servos
int mainServoClosed = 750;
int mainServoOpen = 1950;
int servoBrowCenterOpen = 40;
int servoBrowCenterClosed = 120;
int servoCheeksOpen = 20;
int servoCheeksClosed = 90;
int servoNoseSideOpen = 86;
int servoNoseSideClosed = 10;
int servoBrowSideOpen = 30;
int servoBrowSideClosed = 90;
int servoNoseCenterOpen = 1;
int servoNoseCenterClosed = 110;


void setup() {
  Serial.begin(9600);
  Serial.println("Boot Up");
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);
  pinMode(buttonPin, INPUT_PULLUP);
  delay(50);
  pwm.sleep();
}

int getAngleToPulse(int angle) {
  return map(angle, 0, 180, SERVOMIN, SERVOMAX);
}

void loop() {

  buttonState = digitalRead(buttonPin);
  if (buttonState == 0) {
    Serial.println("Wake up");
    pwm.wakeup();

    if (globalPos > 0) {
      Serial.println("Opening");
      // CHEEKS
      for (uint16_t pulselen = servoCheeksClosed; pulselen >= servoCheeksOpen; pulselen--) {
        pwm.setPWM(9, 0, getAngleToPulse(servoCheeksClosed + servoCheeksOpen - pulselen));
        pwm.setPWM(8, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      Serial.println("1. Cheeks Open");
      // NOSE Side
      for (uint16_t pulselen = servoNoseSideClosed; pulselen >= servoNoseSideOpen; pulselen--) {
        pwm.setPWM(6, 0, getAngleToPulse(servoNoseSideClosed + servoNoseSideOpen - pulselen));
        pwm.setPWM(7, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      Serial.println("2. Nose Side Open");
      //BROW Center 
      for (uint16_t pulselen = servoBrowCenterClosed; pulselen >= servoBrowCenterOpen; pulselen--) {
        pwm.setPWM(servoBrowCenter, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      Serial.println("3. Brow Center Open");
      // BROW Side
      for (uint16_t pulselen = servoBrowSideOpen; pulselen <= servoBrowSideClosed; pulselen++) {
        pwm.setPWM(2, 0, getAngleToPulse(pulselen));
        pwm.setPWM(3, 0, getAngleToPulse(servoBrowSideOpen + servoBrowSideClosed - pulselen));
      }
      delay(animDelay);
      Serial.println("4. Brow Side Open");
      // NOSE Center
      for (uint16_t pulselen = servoNoseCenterClosed; pulselen >= servoNoseCenterOpen; pulselen--) {
        pwm.setPWM(5, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      Serial.println("5. Nose Center Open");
      // EYES
      analogWrite(ledPin, 0); 
      // MAIN SERVOS
      for (uint16_t microsec = mainServoClosed; microsec < mainServoOpen; microsec +=5) {
        pwm.writeMicroseconds(mainServoL, microsec);
        pwm.writeMicroseconds(mainServoR, (mainServoOpen+mainServoClosed-microsec));
      }
      globalPos = 0;
      delay(animDelay);
      Serial.println("6. Main Open");
    } else {
      Serial.println("Closing");
      //MAIN SERVOS
      for (uint16_t microsec = mainServoOpen; microsec > mainServoClosed; microsec-=5) {
        pwm.writeMicroseconds(mainServoL, microsec);
        pwm.writeMicroseconds(mainServoR, (mainServoOpen+mainServoClosed-microsec));
      }
      delay(animDelay);
      //NOSE Center :exploding_head:
      for (uint16_t pulselen = servoNoseCenterOpen; pulselen <= servoNoseCenterClosed; pulselen++) {
        pwm.setPWM(5, 0, getAngleToPulse(pulselen));
      }
      
      delay(animDelay);
      
      // BROW Side
      for (uint16_t pulselen = servoBrowSideClosed; pulselen >= servoBrowSideOpen; pulselen--) {
        pwm.setPWM(2, 0, getAngleToPulse(pulselen));
        pwm.setPWM(3, 0, getAngleToPulse(servoBrowSideOpen + servoBrowSideClosed - pulselen));
      }
      delay(animDelay);
      // BROW Center :exploding_head:
      for (uint16_t pulselen = servoBrowCenterOpen; pulselen <= servoBrowCenterClosed; pulselen++) {
        pwm.setPWM(servoBrowCenter, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      // NOSE Side
      for (uint16_t pulselen = servoNoseSideOpen; pulselen <= servoNoseSideClosed; pulselen++) {
        pwm.setPWM(6, 0, getAngleToPulse(servoNoseSideClosed + servoNoseSideOpen - pulselen));
        pwm.setPWM(7, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      //CHEEKS
      for (uint16_t pulselen = servoCheeksOpen; pulselen <= servoCheeksClosed; pulselen++) {
        pwm.setPWM(9, 0, getAngleToPulse(servoCheeksClosed + servoCheeksOpen - pulselen));
        pwm.setPWM(8, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      //EYES :exploding_head:
      analogWrite(ledPin, 255);
      globalPos = 1;
      delay(100);
      Serial.println("Sleep");
      pwm.sleep();
    }
    delay(500);
  }
  delay(10);
}

Das wäre der Code. Vielleicht hat jemand eine Idee.`

Ich bedanke mich schon jetzt für eure Mühe :smiling_face_with_three_hearts:

Hallo,

ausgehend vom originalen Code brauchst du eigentlich nur die Endwerte vertauschen.

Entweder

#define SERVOMIN 450
#define SERVOMAX 150

oder
return map (angle, 180, 0, SERVOMIN, SERVOMAX);

oder
return map (angle, 0, 180, SERVOMAX, SERVOMIN);

Hallo Doc_Arduino. Danke ersteinmal für die schnelle Antwort.

Ich habe deine Werte getestet und diese Wirken sich auf alle Servos aus.

Da verschiedene Bewegungen aber auf der rechten und linken Seite ausgeführt werden, habe ich das gleiche Problem dann für sie andere Seite.

Ich hoffe man kann es verstehen, wenn ich es so beschreibe.

Ich habe bei
int servoBrowCenterOpen = 40;
int servoBrowCenterClosed = 120;

auch schon versucht
int servoBrowCenterOpen = 120;
int servoBrowCenterClosed = 40;
.
Das führte aber nur dazu, dass der Servo gar nicht mehr ansprach. sobald der erste Wert größer als der Zweite Wert ist geht er nicht mehr.

uint16_t pulselen = servoBrowCenterClosed; pulselen >= servoBrowCenterOpen; pulselen--) {

Hier wäre ein größer als drin . Vielleicht ist es das?
Es ist fast als als ob irgendeine Logik die Bewegung verhindert.

Also das ändern auf
int servoBrowCenterOpen = 120;
int servoBrowCenterClosed = 40;

uint16_t pulselen = servoBrowCenterClosed; pulselen <= servoBrowCenterOpen; pulselen--) {
führt dazu, dass der Servo nur kurz nach links und rechts wackelt und dann wieder in der Ausgangststellung verweilt.

Ich blicke es einfach nicht :exploding_head:

Hallo @mmaarrcceell81

beim Lesen deines User-namens kommt mir der Gedanke
ist vermutlich jemand der schnell fertig werden will.

sinngemäßes Zitat:
"Wer den schnellen Erfolg sucht sollte Holzhacken aber nicht programmieren"

Wenn das so ist, dann müssen für verschiedene Servos auch verschiedene Konstanten verwendet werden.

Besonders schnell sein wollen führt beim Programmieren dazu das alles noch viiiel langsamer wird.

Du wirst schneller ans Ziel kommen wenn du nur eine einzige Kleinigkeit änderst und dann austestest wie sich diese eine Änderung auswirkt.

Oder du kauft dir elektronische Servosignal-invertierer

vgs

Mein Username den ich sonst benutze war schon vergeben.
Arduino ist halt von denjenigen genutzt worden, der den Code geschrieben hat.
Ich habe keine Ahnung von der Programmierung und habe es halt ausprobiert. Doch die Logik des Codes verstehe ich nicht.
Eigentlich soll es sich nur richtig Bewegen und gut ist. :sweat_smile:

Hallo,

ich sehe aktuell nur 2 Möglichkeiten.

a) du schreibst dir noch eine zweite getAngleToPulse() Funktion für vertauschte Servos.

b) du lernst den Umgang mit Strukturen, Arrays und for Schleifen.

b) wird dich weiter bringen.
a) ist nur ein Shortfix.

Da bei pulselen vielleicht ++ statt -- ?

Ich habe befürchtet, dass es nicht so einfach ist. Ich würde erstmal den Shortfix nehmen. Ich befürchte, dass sonst mein bisher gebautes einfach kaputt geht. Sind alles super dünne Kabel und die gehen schon vom Ansehen kaputt. Also es wird ja wahrscheinlich nichts bringen die Zeile einfach zu kopieren. Der Servo muss sich ja uf Knopf druck entgegengesetzt zu den anderen Servos bewegen.

@ finn912 Ich habe es ohne die Minus versucht bin mir aber nicht sicher ob ich ++ getestet habe. Die Servos sind ja eigentlich einzeln angesteuert . Von meiner Logik wäre es ja einfach irgend etwas zu verdrehen. Aber offenbar ist meine Logik nicht dieselbe wie die des Nano :sweat_smile:

Keine guten Voraussetzungen für den Betrieb. Erst recht keine guten Voraussetzungen für Entwicklung.

Nochmal: wenn es besonders schnell gehen soll. Dann geht es in Wirklichkeit besonders laaaangsaaaam.
vgs

Bei ++ wird hoch gezählt und bei -- runder und wenn du schon > und < änderst...

Ok ich versuche das nochmal Finn. Ich habe den Helm halt nach Anleitung gedruckt und zusammengebaut. Eigentlich bin ich gar nicht davon ausgegangen, überhaupt etwas programmieren zu müssen :face_with_peeking_eye:.
Ich hatte auf ein Kochrezept zum Nachkochen gehofft.

uint16_t pulselen = servoBrowCenterClosed; pulselen <= servoBrowCenterOpen; pulselen++) {

führt nur dazu das der blöde Servo ein bissel zuckt. Sonst nichts. Warum weiß ich nicht.

Dieses blind wilde herumgedoktere auf Gut Glück ist wie Lotto-Spielen:
man gewinnt jahrzehntelang nix.

Kehre zurück zu dem Code bei dem sich alle Servos wenigstens "normal" bewegen.
Und dann benenne mal ein Servo das sich verkehrt herum bewegt.
Nenne die IO-pins an denen dieses eine Servo angeschlossen ist.

egal was du hier in Sketch schreibst - Problem bleibt, solange du die beide Seiten nicht trennst und Kode muss eine von zwei Servos invertiert behandeln

Was ein elendiges stochern im Nebel.

Tipp:
Es ist unglaublich hilfreich, wenn man die Sprache lernt, welche man verwendet.

int getAngleToPulse(int angle, bool reverse = false) {
  return map(angle, 0, 180,reverse?SERVOMAX:SERVOMIN, reverse?SERVOMIN:SERVOMAX);
}

Später dann:

 pwm.setPWM(7, 0, getAngleToPulse(pulselen));
// oder
 pwm.setPWM(7, 0, getAngleToPulse(pulselen,true)); // reverse = true

Je nach dem, was man möchte

1 Like

Danke für eure Antworten. Ich werde wahrscheinlich das Teil einfach spiegelverkehrt drucken, dass könnte mein Problem auch lösen.
Ich werde es mit dem Code trotzdem versuchen, aber bis ich das Ganze gelernt habe, bin ich wahrscheinlich grau auf dem Kopf . Mir fehlen halt alle Grundlagen.

Mir ist zum Beispiel nicht klar, warum bei

int getAngleToPulse(int angle, bool reverse = false) {
return map(angle, 0, 180,reverse?SERVOMAX:SERVOMIN, reverse?SERVOMIN:SERVOMAX);
}

ein bestimmter Servo weiß, das er gemeint ist. Bei

pwm.setPWM(7, 0, getAngleToPulse(pulselen));
// oder
pwm.setPWM(7, 0, getAngleToPulse(pulselen,true)); // reverse = true

ist es doch Steckplatz 7 bei Grad 0 oder? Beim ersten Befehl muss da ja noch irgendwie z.B. Servo 4 genannt sein?

wenn beide an einem Pin hängen - wissen sie es nicht, tun das gleiche.
wenn ein is am Pin 7 und andere am Pin z.B. 4 dann brauchst du nix neues drucken und schreibst

Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver();
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver();
pwm1.setPWM(7, 0, getAngleToPulse(pulselen));
pwm2.setPWM(4, 0, getAngleToPulse(pulselen,true)); // reverse = true

Bei pwm.setPWM(4, 0, getAngleToPulse(pulselen,true)); //reverse = true

gibt er folgenden fehler raus
er hat mich aber 4 statt Brow center open schreiben lassen.

\3d druck\ironman helmet\mk5_sketch_ADJUSTABLE\mk5_sketch_ADJUSTABLE.ino: In function 'void loop()':
C:\Users\Massi\Desktop\3d druck\ironman helmet\mk5_sketch_ADJUSTABLE\mk5_sketch_ADJUSTABLE.ino:81:55: error: too many arguments to function 'int getAngleToPulse(int)'
pwm.setPWM(4, 0, getAngleToPulse(pulselen,true)); //reverse = true
^
C:\Users\Massi\Desktop\3d druck\ironman helmet\mk5_sketch_ADJUSTABLE\mk5_sketch_ADJUSTABLE.ino:52:5: note: declared here
int getAngleToPulse(int angle) {
^~~~~~~~~~~~~~~

exit status 1

Compilation error: too many arguments to function 'int getAngleToPulse(int)'