Codice arduino Elmetto Iron Man MK5

Buongiorno a tutta la comunity,

Mi sono imbattuto sul progetto del casco iron man articolato con programmazione arduino. La persona che ha fornito il progetto ha anche rilasciato lo sketch per far si che tutte le parti del casco di muovano contemporaniamente ma in direzioni diverse. Ho iniziato tutto il cablaggio ma i servi 2 e 3 invece di muoversi verso l'alto, si muovono verso il basso (posizione sbagliata) . Qualcuno può aiutarmi a risolvere questo problema? grazie mille

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

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define SERVOMIN 150   // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 450   // This is the 'maximum' pulse length count (out of 4096)
#define USMIN 600      // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX 2400     // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
#define SERVO_FREQ 50  // Analog servos run at ~50 Hz updates

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 mainServoL = 0;
int mainServoR = 1;
int mainServoClosed = 5;
int mainServoOpen = 90;
int servoBrowCenter = 4;
int servoBrowCenterOpen = 40;
int servoBrowCenterClosed = 120;
int animDelay = 1;

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);
}
int getAngleToMilli(int angle) {
  return map(angle, 0, 180, USMIN, USMAX);
}

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 = 90; pulselen >= 20; pulselen--) {
        pwm.setPWM(9, 0, getAngleToPulse(90 + 20 - pulselen));
        pwm.setPWM(8, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      Serial.println("1. Cheeks Open");
      // NOSE Side
      for (uint16_t pulselen = 86; pulselen >= 10; pulselen--) {
        pwm.setPWM(6, 0, getAngleToPulse(86 + 10 - 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 = 30; pulselen <= 90; pulselen++) {
        pwm.setPWM(2, 0, getAngleToPulse(pulselen));
        pwm.setPWM(3, 0, getAngleToPulse(30 + 90 - pulselen));
      }
      delay(animDelay);
      Serial.println("4. Brow Side Open");
      // NOSE Center
      for (uint16_t pulselen = 110; pulselen >= 1; 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 = 750; microsec < 1950; microsec +=5) {
        pwm.writeMicroseconds(mainServoL, microsec);
        pwm.writeMicroseconds(mainServoR, (1950+750-microsec));
      }
      globalPos = 0;
      delay(animDelay);
      Serial.println("6. Main Open");
      //delay(100);
      //Serial.println("Sleep");
      //pwm.sleep();
    } else {
      Serial.println("Closing");
      //MAIN SERVOS
      for (uint16_t microsec = 1950; microsec > 750; microsec-=5) {
        pwm.writeMicroseconds(mainServoL, microsec);
        pwm.writeMicroseconds(mainServoR, (1950+750-microsec));
      }
      delay(animDelay);
      //NOSE Center
      for (uint16_t pulselen = 1; pulselen <= 110; pulselen++) {
        pwm.setPWM(5, 0, getAngleToPulse(pulselen));
      }
      
      delay(animDelay);
      
      // BROW Side
      for (uint16_t pulselen = 90; pulselen >= 30; pulselen--) {
        pwm.setPWM(2, 0, getAngleToPulse(pulselen));
        pwm.setPWM(3, 0, getAngleToPulse(30 + 90 - pulselen));
      }
      delay(animDelay);
      


      for (uint16_t pulselen = servoBrowCenterOpen; pulselen <= servoBrowCenterClosed; pulselen++) {
        pwm.setPWM(servoBrowCenter, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      // NOSE Side
      for (uint16_t pulselen = 10; pulselen <= 86; pulselen++) {
        pwm.setPWM(6, 0, getAngleToPulse(86 + 10 - pulselen));
        pwm.setPWM(7, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      //CHEEKS
      for (uint16_t pulselen = 20; pulselen <= 90; pulselen++) {
        pwm.setPWM(9, 0, getAngleToPulse(90 + 20 - pulselen));
        pwm.setPWM(8, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      //EYES
      analogWrite(ledPin, 255);
      globalPos = 1;
      delay(100);
      Serial.println("Sleep");
      pwm.sleep();
    }
    delay(500);
  }
  delay(10);
}

Buongiorno e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Presentazione effettuata. Scusi per l’errore commesso. Saluti

Avete montato il servo al contrario?

Se i servo sono collegati ai pin 2 e 3, allora è questo ciclo for() che gestisce il movimento.

Forse bisogna invertire il percorso?

      // BROW Side
      for (uint16_t pulselen = 90; pulselen >= 30; pulselen--) {
        pwm.setPWM(2, 0, getAngleToPulse(pulselen));
        pwm.setPWM(3, 0, getAngleToPulse(30 + 90 - pulselen));
      }

E naturalmente invertire anche la parte del codice che fa il movimento inverso.

Magari basta invertire i fili

Se e' un servo, no, serve invertire la variazione del PCM.

Oppure intendi invertire i due servo fra loro ? ... se sono montati in due sensi opposti, allora potrebbe funzionare (e potrebbe pure essere tutto li l'errore)

Grazie per la risposta, no il servo è montato in modo corretto. ho provato a fare la modifica che mi hai consigliato ma adesso i 2 servi non si muovo più.

Esatto
Due fili scambiati e via, andare!

i 2 fili quali intendi tu? i servi hanno 3 fili.

Non posso invertire i servi perchè se no toccano sulle parti circostanti e si blocca il meccanismo.

Credo che intenda invertire le connessioni fra servo 2 e 3 (i pin che li pilotano)

È un servo, non un motore che si alimenta con due fili (un + e un -) e invertendo i fili lo si fa girare nell'altro senso.

Un servo è comandato in PWM inviando una serie di impulsi elettrici di una durata specifica. La larghezza di questi impulsi determina la posizione dell'asse del servo. In generale, un impulso di circa 1 millisecondo corrisponde alla posizione minima (0°), mentre un impulso di circa 2 millisecondi corrisponde alla posizione massima (180°). Il segnale PWM viene ripetuto a una frequenza regolare, tipicamente 50 Hz, ovvero un periodo di 20 millisecondi. Il servo interpreta queste variazioni di durata dell'impulso per regolare con precisione la sua posizione.


Potete postare il codice modificato?

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

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define SERVOMIN 150   // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 450   // This is the 'maximum' pulse length count (out of 4096)
#define USMIN 600      // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX 2400     // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
#define SERVO_FREQ 50  // Analog servos run at ~50 Hz updates

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 mainServoL = 0;
int mainServoR = 1;
int mainServoClosed = 5;
int mainServoOpen = 90;
int servoBrowCenter = 4;
int servoBrowCenterOpen = 40;
int servoBrowCenterClosed = 120;
int animDelay = 1;

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);
}
int getAngleToMilli(int angle) {
  return map(angle, 0, 180, USMIN, USMAX);
}

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 = 90; pulselen >= 20; pulselen--) {
        pwm.setPWM(9, 0, getAngleToPulse(90 + 20 - pulselen));
        pwm.setPWM(8, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      Serial.println("1. Cheeks Open");
      // NOSE Side
      for (uint16_t pulselen = 86; pulselen >= 10; pulselen--) {
        pwm.setPWM(6, 0, getAngleToPulse(86 + 10 - 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 = 90; pulselen <= 30; pulselen++) {
        pwm.setPWM(2, 0, getAngleToPulse(pulselen));
        pwm.setPWM(3, 0, getAngleToPulse(30 + 90 - pulselen));
      }
      delay(animDelay);
      Serial.println("4. Brow Side Open");
      // NOSE Center
      for (uint16_t pulselen = 110; pulselen >= 1; 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 = 750; microsec < 1950; microsec +=5) {
        pwm.writeMicroseconds(mainServoL, microsec);
        pwm.writeMicroseconds(mainServoR, (1950+750-microsec));
      }
      globalPos = 0;
      delay(animDelay);
      Serial.println("6. Main Open");
      //delay(100);
      //Serial.println("Sleep");
      //pwm.sleep();
    } else {
      Serial.println("Closing");
      //MAIN SERVOS
      for (uint16_t microsec = 1950; microsec > 750; microsec-=5) {
        pwm.writeMicroseconds(mainServoL, microsec);
        pwm.writeMicroseconds(mainServoR, (1950+750-microsec));
      }
      delay(animDelay);
      //NOSE Center
      for (uint16_t pulselen = 1; pulselen <= 110; pulselen++) {
        pwm.setPWM(5, 0, getAngleToPulse(pulselen));
      }
      
      delay(animDelay);
      
      // BROW Side
      for (uint16_t pulselen = 30; pulselen >= 90; pulselen--) {
        pwm.setPWM(2, 0, getAngleToPulse(pulselen));
        pwm.setPWM(3, 0, getAngleToPulse(30 + 90 - pulselen));
      }
      delay(animDelay);
      


      for (uint16_t pulselen = servoBrowCenterOpen; pulselen <= servoBrowCenterClosed; pulselen++) {
        pwm.setPWM(servoBrowCenter, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      // NOSE Side
      for (uint16_t pulselen = 10; pulselen <= 86; pulselen++) {
        pwm.setPWM(6, 0, getAngleToPulse(86 + 10 - pulselen));
        pwm.setPWM(7, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      //CHEEKS
      for (uint16_t pulselen = 20; pulselen <= 90; pulselen++) {
        pwm.setPWM(9, 0, getAngleToPulse(90 + 20 - pulselen));
        pwm.setPWM(8, 0, getAngleToPulse(pulselen));
      }
      delay(animDelay);
      //EYES
      analogWrite(ledPin, 255);
      globalPos = 1;
      delay(100);
      Serial.println("Sleep");
      pwm.sleep();
    }
    delay(500);
  }
  delay(10);
}

Potresti semplicemente modificare da:

a:

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

Ho copiato il codice ma quando faccio la verifica mi da errore.

C:\Users\MGSmartech\OneDrive\Progetti 3D\Iron Man MK5 Helmet\files\mk5_sketch_11-28-2021\mk5_sketch_11-28-2021.ino:42:3: error: stray '`' in program
   `return map(angle, 0, 180, SERVOMAX, SERVOMIN;`
   ^
C:\Users\MGSmartech\OneDrive\Progetti 3D\Iron Man MK5 Helmet\files\mk5_sketch_11-28-2021\mk5_sketch_11-28-2021.ino:42:49: error: stray '`' in program
   `return map(angle, 0, 180, SERVOMAX, SERVOMIN;`
                                                 ^
C:\Users\MGSmartech\OneDrive\Progetti 3D\Iron Man MK5 Helmet\files\mk5_sketch_11-28-2021\mk5_sketch_11-28-2021.ino:45:3: error: stray '`' in program
   `return map(angle, 0, 180, SERVOMAX, SERVOMIN;`
   ^
C:\Users\MGSmartech\OneDrive\Progetti 3D\Iron Man MK5 Helmet\files\mk5_sketch_11-28-2021\mk5_sketch_11-28-2021.ino:45:49: error: stray '`' in program
   `return map(angle, 0, 180, SERVOMAX, SERVOMIN;`
                                                 ^
C:\Users\MGSmartech\OneDrive\Progetti 3D\Iron Man MK5 Helmet\files\mk5_sketch_11-28-2021\mk5_sketch_11-28-2021.ino: In function 'int getAngleToPulse(int)':
C:\Users\MGSmartech\OneDrive\Progetti 3D\Iron Man MK5 Helmet\files\mk5_sketch_11-28-2021\mk5_sketch_11-28-2021.ino:42:48: error: expected ')' before ';' token
   `return map(angle, 0, 180, SERVOMAX, SERVOMIN;`
                                                ^
C:\Users\MGSmartech\OneDrive\Progetti 3D\Iron Man MK5 Helmet\files\mk5_sketch_11-28-2021\mk5_sketch_11-28-2021.ino: In function 'int getAngleToMilli(int)':
C:\Users\MGSmartech\OneDrive\Progetti 3D\Iron Man MK5 Helmet\files\mk5_sketch_11-28-2021\mk5_sketch_11-28-2021.ino:45:48: error: expected ')' before ';' token
   `return map(angle, 0, 180, SERVOMAX, SERVOMIN;`
                                                ^

exit status 1

Compilation error: stray '`' in program

Ti dice che ci sono due apostrofi di troppo e manca una parentesi...
Ho corretto.

modifica fatta ma adesso i 2 servi sono completamente fermi...

Tu credi che io non lo sappia?

Quei due servo sono comandati in maniera speculare

È ovvio che se "girano" rovesci sono comandati erroneamente

Quindi essendo speculari e siccome ambedue girano rovesci...

La conclusione non è difficile da trarre.

Comunque staremo a vedere
Per il momento vedo una grande confusione!

1 Like

Guarda a me interessa risolvere la problematica e condividerla con chi ne avrà bisogno. :grinning: secondo te quale sarebbe la soluzione al problema?

Ciao, posta il link, per favore. Così vediamo cosa aveva previsto come hw l'autore.