Animation pilote maquette - code servos simultanés

Bonjour tout le monde

Je me présente, Vincent 48 ans, habitant Béziers, passionné de maquettes de planeurs anciens et webmaster du site et forum retroplane.

J'ai découvert il y a peu de temps Arduino, mais je n'ai aucune connaissance en programmation. j'ai eu l'aide du forum robot-maker, mais je suis actuellement encore bloqué par un problème, et j'ai l'impression que je leur ai fait perdre patience. Donc si vous le voulez bien, ce serait sympa de m'aider a finir un code d'animation, sur lequel je bloque

ce code est destiné à animer le pilote de ma dernière maquette

vous pouvez voir une petite vidéo de l'animation ici
http://www.retroplane.net/mira3/animation_pilote2.wmv

et le détail de la construction est ici
http://www.retroplane.net/mira3/page2.htm

je vous explique ce que je souhaterais faire
actuellement j'ai 3 servos dans mon pilote, tete, bras, machoire

toutes mes actions se font les unes derrière les autres
mais je voudrais pouvoir faire de petits mouvements de tête pendant que le pilote parle ou bouge le bras. il faut donc modifier le code pour que 2 servos "tete et machoire" marchent simultanément.

C'est surement tout simple et pourtant je n'y arrive pas, je vous met un bout de mon code avec les servos les uns derriere les autres, je vous serais tres reconnaissant si vous pouviez m'aider

#include <Servo.h>  


Servo bras;   
Servo tete; 
Servo machoire;  
int bra = 0; 
int tet = 0;  
int mache = 0;
int bouton = 2;

void setup() 
{ 
  bras.attach(3); 
  tete.attach(5); 
  machoire.attach(6); 

  Serial.begin(9600); 
  pinMode(bouton, INPUT);


} 

void loop() { 

  if (digitalRead(bouton) == HIGH)

  { 
    delay(2000); //pause 2s avant commencer animation

    for(bra = 90; bra>=50; bra-=1) //leve le bras    
    {                                 
      bras.write(bra);                
      delay(30);

    }  
    delay(300);
    int compteur = 0; 
    while (compteur < 14) //bras va et vient de 7° sur la trompette
    { 

      for(bra = 50; bra < 57; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(15);  

      }

      for(bra = 57; bra>=50; bra-=1) //leve le bras    
      {                                 
        bras.write(bra);                
        delay(15);

      }

      compteur++;
    } 
    { 
      delay(300);

      for(bra = 50; bra < 90; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(20);  

      } 

      delay(100); 

      for(tet = 90; tet < 130; tet += 1)  //bouge la tete
      {                                
        tete.write(tet);              
        delay(15);                        

      }

      for(tet = 130; tet>=50; tet-=1)     
      {                                 
        tete.write(tet);                
        delay(15);

      }  

      delay(100);  

      for(tet = 50; tet < 110; tet += 1)  
      {                                
        tete.write(tet);              
        delay(20);                        

      }

      delay(500);    //commence à parler

      int compteur = 0; 
      while (compteur < 20) //dis son nom
      { 

        for(mache = 90; mache < 120; mache += 1)


        {                                   
          machoire.write(mache);              
          delay(4); 

        }  
        for(mache = 120; mache>=90; mache-=1) 

        {                                 
          machoire.write(mache);               
          delay(4);

        } 
        compteur++;

      }
    }
  }
}

et le bout de ce code modifié, mais qui ne marche pas sans que je comprenne pourquoi, (j'ai commenté les problemes sur le code)

#include <Servo.h>  


Servo bras;   
Servo tete; 
Servo machoire;  
int bra = 0; 
int tet = 0;  
int mache = 0;
int bouton = 2;

void setup() 
{ 
  bras.attach(3); 
  tete.attach(5); 
  machoire.attach(6); 

  Serial.begin(9600); 
  pinMode(bouton, INPUT);


} 

void loop() { 

  if (digitalRead(bouton) == HIGH)

  { 
    delay(2000); //pause 2s avant commencer animation

    for(bra = 90; bra>=50; bra-=1) //leve le bras    
    {                                 
      bras.write(bra);                
      delay(30);

    }  
    delay(300);
    int compteur = 0; 
    while (compteur < 14) //bras va et vient de 7° sur la trompette
    { 

      for(bra = 50; bra < 57; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(15);  

      }

      for(bra = 57; bra>=50; bra-=1) //leve le bras    
      {                                 
        bras.write(bra);                
        delay(15);

      }

      compteur++;
    } 
    { 
      delay(300);

      for(bra = 50; bra < 90; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(20);  

      } 

      delay(100); 

      for(tet = 90; tet < 130; tet += 1)  //bouge la tete
      {                                
        tete.write(tet);              
        delay(15);                        

      }

      for(tet = 130; tet>=50; tet-=1)     
      {                                 
        tete.write(tet);                
        delay(15);

      }  

      delay(100);  

      for(tet = 50; tet < 110; tet += 1)  
      {                                
        tete.write(tet);              
        delay(20);                        

      }

      delay(500);    //commence à parler

      int compteur = 0; 
      while (compteur < 3) //dis son nom
      { 

        for(mache = 90; mache < 120; mache += 1)
              { 
        for(tet = 110; tet>=90; tet-=1) //je voudrais que la tête bouge en même temps que la machoire marche, mais avec ce code la tete bouge en boucle rapidement et la machoire marche hyper lentement, en fait les delay ne sont pas pris en compte et gènent et seulement apres le reste de l'animation se joue

        {                                   
          machoire.write(mache);              
          delay(4); //ce sont ces delay qui genent l'anim, si je les enlève ça marcherait mais les servo s'actionnent trop rapidement
          
        tete.write(tet);                
        delay(15); //ce sont ces delay qui genent l'anim, si je les enlève ça marcherait mais les servo s'actionnent trop rapidement
        } 
        }  
        for(mache = 120; mache>=90; mache-=1) 

        {                                 
          machoire.write(mache);               
          delay(4);

        } 
        compteur++;

      }
    }
  }
}

Salut,

Pour commencer, je me permets de te féliciter pour ton boulot, c'est du grand art (j'en serais incapable!). Il te faut donc une animation qui va avec!

Je comprends bien ton programme, bien écrit et facile à lire, tu m'as l'air d'être quelqu'un de minutieux, encore bravo!

Actuellement, tu fais des mouvements les uns après les autres, et tu ne peux pas faire des mouvements simultanés, ce que tu voudrais faire si j'ai bien compris.

je vois deux possibilités, la seconde étant une extension de la première.

Solution 1 : une séquence d'animation à 3 listes...

On imagine trois tableaux de la même taille :

const Bra = 3    // numéro du servo Bras
const Tet = 5    // numéro du servo Tête
const Mac = 6    // numéro du servo Mâchoire

const MAX_ANIM = 256;
// tab_servo[n] contient le numéro du servo pour l'action n
volatile byte tab_servo[MAX_ANIM] = {Tet, Tet, Tet, Tet,  Bra, Bra, Tet, Mac, Tet, Mac, Tet};
// tab_valeur[n] contient la valeur à envoyer au servo N° tab_servo[n] pour l'action n
volatile byte tab_valeur[MAX_ANIM] = { 90,  85,  80,  75,  50,  57,  60,  90,  75, 120,  90};
// tab_tempo[n] contient le nombre de pas avant le passage à l'action suivante (n+1)
volatile byte tab_tempo[MAX_ANIM] = { 25,  25,  25,  25,  150, 150,  15,  60,  60,  60,  60};
volatile word tab_index;  // index de l'action en cours

Bien sûr, tu seras limité avec la taille de la ram de ton nano (je ne sais pas quel proc est monté dessus...) à MAX_ANIM actions, ici 256.

volatile boolean animation = false;

volatile word compteur;

ISR(TIMER1){
  compteur++;  // on incrémente le compteur de pas.
  if (compteur >= tab_tempo[tab_index]) { // le compteur a atteint le nombre de pas désiré, on passe à l'action suivante
    compteur = 0;
    tab_index++;
    if (tab_index > MAX_ANIM) tab_index = 0; // dans le cas où l'animation tourne en boucle.
    servo.Write(tab_servo[tab_index], tab_valeur[tab_index]);  //envoie l'action suivante
  }
}

setup(){
//  Préparer le timer1 de façon à ce qu'il appelle l'ISR ci-dessus toutes les x milliseconde quand on l'y autorisera.
}

loop{
  lecture_télécommande();
//  si lancement ou reprise après pause de la séquence, alors autoriser l'interruption du timer1
//  si pause de la séquence, interdire l'interruption du timer1
//  si stop, interdire l'interruption du timer1, faire servo.Write() sur les trois servos pour les remettre en position 0 et mettre tab_index à 0;
}

Explication :
La fonction loop() tourne en continu, donc on va l'utiliser pour détecter les commandes IR par exemple.
Ensuite, on définit le timer à 10ms, cela veut dire que toutes les 10ms, l'ISR sera appelée sans qu'on ait rien à programmer, ça se fait vraiment tout seul (le principe des timers)! ta séquence programmée dans les tableaux aura donc un pas de 10ms. Dans mon exemple, pour les 4 premières actions (la tête tourne), il faudra que l'ISR soit appelée 25 fois pour passer à l'action suivante, soit 250ms entre deux actions, la tête tournera de 90 à 75 en 750 millisecondes, puis le bras commencera à bouger vers 50° une seconde après le lancement de la séquence.
1500ms plus tard (150 appels de l'ISR), le bras ira à 57°,
1500ms plus tard, la tête va à 60,
150 ms après, la mâchoire va sur 90,
600 ms après, la tête va sur 75,
600 ms après, la mâchoire va sur 120,
600 ms après, la tête va sur 90,
600 ms après, c'est la fin de ma séquence, mais on peut en rajouter...

Bref, en 11 instructions, j'ai fait une séquence de 6,55 secondes... En plus, on n'a juste à changer les 10ms du timer en 5ms par exemple pour que la séquence se déroule 2 fois plus vite...

la solution 2 reprend celle-là, mais en utilisant le tableau tab_servo[] qui contient des octets (dont seuls les 4 premiers bits servent) pour rajouter des codes sr les 4 derniers bits de chaque octet qui permettraient par exemple de répéter 3 fois de la séquence 124 à 197... mais là, ça commence à faire compliquer (mais dans le cas de séquences répétitives, ça fait gagner de la mémoire...)

Le seul inconvénient de ma (mes) méthode(s), c'est que c'est incompatible avec la librairie servo (car cette librairie coupe les interruptions dans tous les sens, et rendrait la lecture de séquence très peu précise). J'ai une solution pour palier à ça en utilisant en direct les sorties PWM, et tu vas finir par me dire que c'est beaucoup trop compliqué... Mais je te garantis que c'est faisable (d'autant plus faisable avec un mega2560, car on peut contrôler jusqu'à 12 servos sans que ça se voit), je l'ai fait plusieurs fois! Voir aussi avec la mémoire dispo, peut-être passer par ProgMem...

sinon, désolé d'avoir dit des gros mots :grin: :smiley:

Merci de t'interresser à mon problème, mais je rapelle que je n'ai aucune connaissance en programmation, et ton code je ne sais pas l'intégrer et est-ce que ça maitrise la vitesse de rotation des servos, j'ai l'impression que non?
C'est pas possible de modifier/compléter le code que je donne au départ? car celui là je commençais a le maitriser pour l'adapter a mon anim. d'autant que toute ma synchro avec la bande son est faite et j'aurais aimé ne pas avoir à la refaire, c'est pour ça je pensais pouvoir intégrer du code au mien pour que des actions de servo marchent simultanément sans que ça dérègle ma base de synchronisation

VincentB:
Bonjour tout le monde

Je me présente, Vincent 48 ans, habitant Béziers, passionné de maquettes de planeurs anciens et webmaster du site et forum retroplane.

J'ai découvert il y a peu de temps Arduino, mais je n'ai aucune connaissance en programmation. j'ai eu l'aide du forum robot-maker, mais je suis actuellement encore bloqué par un problème, et j'ai l'impression que je leur ai fait perdre patience. Donc si vous le voulez bien, ce serait sympa de m'aider a finir un code d'animation, sur lequel je bloque

ce code est destiné à animer le pilote de ma dernière maquette

vous pouvez voir une petite vidéo de l'animation ici
http://www.retroplane.net/mira3/animation_pilote2.wmv

et le détail de la construction est ici
MIRA 3

je vous explique ce que je souhaterais faire
actuellement j'ai 3 servos dans mon pilote, tete, bras, machoire

toutes mes actions se font les unes derrière les autres
mais je voudrais pouvoir faire de petits mouvements de tête pendant que le pilote parle ou bouge le bras. il faut donc modifier le code pour que 2 servos "tete et machoire" marchent simultanément.

Bonjour
déjà, clap clap ! c'est très sympa et bien fait comme réalisation :grin:
et puis tout ce qui vole ou a volé , j'aime bien ! 8)

Si j'ai bien compris, vous avez scénarisé l'animation ? (durée et actions ? )
en theorie votre "probleme" revient donc à connaitre/envoyer l'ordre de positionnement des (3) servos à chaque étape ?
le taux de rafraichissement est donc au mini equivalent au taux d'actualisation du servo le plus rapidement sollicité en changement de position.

Il semblerait que là ce soit la mâchoire ?

C'est aussi dépendant du temps de transfert mécanique entre les positions extrêmes des servos.

personnellement à ce stade réflexion et si je devais faire , je me dirigerais vers une solution lecture table d’événements :
1 - détermination de la durée du pas (fréquence de réactualisation Fr)
2 - remplissage de la table fonction de Fr et du scenario.

en "production"
lire et appliquer fonction de Fr le positionnement lu des x servos.

défauts : masse d'info de position "relativement" importante à coder/engranger (mais voir calcul d'occupation en fonction de la durée).

avantages : les positionnements ne sont plus "code dépendant", en dehors de ce que peut absorber un arduino en EE, je vois bien un shield SD embarquant plusieurs scénarios.

mais .. ce n'est là que ma réflexion :cold_sweat:

personnellement à ce stade réflexion et si je devais faire , je me dirigerais vers une solution lecture table d’événements :
1 - détermination de la durée du pas (fréquence de réactualisation Fr)
2 - remplissage de la table fonction de Fr et du scenario.

en "production"
lire et appliquer fonction de Fr le positionnement lu des x servos.

défauts : masse d'info de position "relativement" importante à coder/engranger (mais voir calcul d'occupation en fonction de la durée).

avantages : les positionnements ne sont plus "code dépendant", en dehors de ce que peut absorber un arduino en EE, je vois bien un shield SD embarquant plusieurs scénarios.

c'est ce que fait le code que j'ai proposé... mais voilà, je sais bien que pour Vincent, c'est que des gros mots (ISR, timer...) et donc soit on lui colle un truc tout fait, mais s'il veut le modifier, y arrivera-t-il? ou sinon on trouve un intermédiaire... et là, pas facile.

sinon, une autre idée :

il garde son code tel qu'il est, mais vire tout ce qui touche au servo de la mâchoire. les valeurs envoyées au servo mâchoire pourraient être gérées par (oui, je sais, c'est inévitable) un timer :

On fait passer la bande son par un détecteur de crête moyenne (circuit passe-bas diode + RC) puis sur l'entrée analogique 0.
Toutes les x millisecondes (250 par exemple), on fait un analogRead (A0), et si ça dépasse un seuil (par exemple un potar via analogRead(A1), plus facile à régler), on ouvre la bouche, sinon, on la ferme.

Le corps du pilote continuera à bouger sur le scénario actuel, la bouche suivra le volume sonore de la parole...

Bon, ben je crois que mon animation va rester comme elle est, ce que vous me proposez est trop compliqué pour moi

Je reexplique simplement ce que je veux obtenir:
-actuellement mon pilote bouge la machoire synchro avec une bande son qui est externe à la programation puisque joué par un lecteur mp3
mais pendant qu'il parle, sa tête ne bouge pas, donc je trouve que ça fait un peu figé

je voulais donc juste faire des petits mouvements de tête de quelques degrés (servo tete) pendant qu'il parle (servo machoire) rien de plus

je pensais que ça aurait été tout simple avec un code facile de même type que celui que j'ai dejà, et que ça s'intègrerait dans mon code existant sans que ça modifie toute ma synchro, puisque le servo tête serait censé bouger en même temps que le servo machoire

j'imaginais que mon 2eme code, (que je montre dans mon 1er message) était très proche du but, juste quelques parentheses a modifier pour que ça marche

VincentB:
Bon, ben je crois que mon animation va rester comme elle est, ce que vous me proposez est trop compliqué pour moi

Je reexplique simplement ce que je veux obtenir:
-actuellement mon pilote bouge la machoire synchro avec une bande son qui est externe à la programation puisque joué par un lecteur mp3
mais pendant qu'il parle, sa tête ne bouge pas, donc je trouve que ça fait un peu figé

je voulais donc juste faire des petits mouvements de tête de quelques degrés (servo tete) pendant qu'il parle (servo machoire) rien de plus

je pensais que ça aurait été tout simple avec un code facile de même type que celui que j'ai dejà, et que ça s'intègrerait dans mon code existant sans que ça modifie toute ma synchro, puisque le servo tête serait censé bouger en même temps que le servo machoire

j'imaginais que mon 2eme code, (que je montre dans mon 1er message) était très proche du but, juste quelques parentheses a modifier pour que ça marche

ok
alors j'essaierai : à chaque modif de machoire, d'appliquer un random de qq° à la position tête :
dans le 1er code
machoire.write(mache);
randNumber = random(-5,5); //exemple attention au type et aux bornes
tet=tet+randnumber
tete.write(tet);

Bonjour, en ajoutant ton code, j'ai une erreur

randNumber = random(-5,5);

 In function 'void loop()':
error: 'randNumber' was not declared in this scope

il ne faut pas en remettre un morceau ailleurs? si oui où et quoi? j'ai essayé plusieurs trucs a taton dans le void setup mais ça me met d'autres erreurs
et que veux dire ton commentaire //exemple attention au type et aux bornes

VincentB:
Bonjour, en ajoutant ton code, j'ai une erreur

randNumber = random(-5,5);

In function 'void loop()':
error: 'randNumber' was not declared in this scope




il ne faut pas en remettre un morceau ailleurs? si oui où et quoi? j'ai essayé plusieurs trucs a taton dans le void setup mais ça me met d'autres erreurs
et que veux dire ton commentaire //exemple attention au type et aux bornes

bonjour
c'etait juste un exemple d'insertion
il faut declarer la variable randNumber
essaie ce code testé compilé ok

#include <Servo.h>  


Servo bras;   
Servo tete; 
Servo machoire;  
int bra = 0; 
int tet = 0;  
int mache = 0;
int bouton = 2;
long randNumber;
void setup() 
{ 
  bras.attach(3); 
  tete.attach(5); 
  machoire.attach(6); 

  Serial.begin(9600); 
  pinMode(bouton, INPUT);


} 

void loop() { 

  if (digitalRead(bouton) == HIGH)

  { 
    delay(2000); //pause 2s avant commencer animation

    for(bra = 90; bra>=50; bra-=1) //leve le bras    
    {                                 
      bras.write(bra);                
      delay(30);

    }  
    delay(300);
    int compteur = 0; 
    while (compteur < 14) //bras va et vient de 7° sur la trompette
    { 

      for(bra = 50; bra < 57; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(15);  

      }

      for(bra = 57; bra>=50; bra-=1) //leve le bras    
      {                                 
        bras.write(bra);                
        delay(15);

      }

      compteur++;
    } 
    { 
      delay(300);

      for(bra = 50; bra < 90; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(20);  

      } 

      delay(100); 

      for(tet = 90; tet < 130; tet += 1)  //bouge la tete
      {                                
        tete.write(tet);              
        delay(15);                        

      }

      for(tet = 130; tet>=50; tet-=1)     
      {                                 
        tete.write(tet);                
        delay(15);

      }  

      delay(100);  

      for(tet = 50; tet < 110; tet += 1)  
      {                                
        tete.write(tet);              
        delay(20);                        

      }

      delay(500);    //commence à parler

      int compteur = 0; 
      while (compteur < 20) //dis son nom
      { 

        for(mache = 90; mache < 120; mache += 1)


        {                                   
          machoire.write(mache); 
          randNumber = random(-5,5);
          tet=tet+randNumber;
          tete.write(tet);          
          delay(4); 

        }  
        for(mache = 120; mache>=90; mache-=1) 

        {                                 
          machoire.write(mache);  
          randNumber = random(-5,5); 
          tet=tet+randNumber;
          tete.write(tet);         
          delay(4);

        } 
        compteur++;

      }
    }
  }
}

re

j'ai testé ce code en réel avec 2 servos (machoire, tete)
ça fonctionne
maintenant à voir si cela est un rendu réaliste :
j'ai mis -15 +15 en debattement et retour en position origine entrée tête

#include <Servo.h>  


Servo bras;   
Servo tete; 
Servo machoire;  
int bra = 0; 
int tet = 0;  
int tets=0;
int mache = 0;
int bouton = 2;
long randNumber;
void setup() 
{ 
  bras.attach(3); 
  tete.attach(5); 
  machoire.attach(6); 

  Serial.begin(9600); 
  pinMode(bouton, INPUT);


} 

void loop() { 

  if (digitalRead(bouton) == HIGH)

  { 
    delay(2000); //pause 2s avant commencer animation

    for(bra = 90; bra>=50; bra-=1) //leve le bras    
    {                                 
      bras.write(bra);                
      delay(30);

    }  
    delay(300);
    int compteur = 0; 
    while (compteur < 14) //bras va et vient de 7° sur la trompette
    { 

      for(bra = 50; bra < 57; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(15);  

      }

      for(bra = 57; bra>=50; bra-=1) //leve le bras    
      {                                 
        bras.write(bra);                
        delay(15);

      }

      compteur++;
    } 
    { 
      delay(300);

      for(bra = 50; bra < 90; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(20);  

      } 

      delay(100); 

      for(tet = 90; tet < 130; tet += 1)  //bouge la tete
      {                                
        tete.write(tet);              
        delay(15);                        

      }

      for(tet = 130; tet>=50; tet-=1)     
      {                                 
        tete.write(tet);                
        delay(15);

      }  

      delay(100);  

      for(tet = 50; tet < 110; tet += 1)  
      {                                
        tete.write(tet);              
        delay(20);                        

      }

      delay(500);    //commence à parler

      int compteur = 0; 
      while (compteur < 20) //dis son nom
      { 

        for(mache = 90; mache < 120; mache += 1)


        {                                   
          machoire.write(mache); 
          randNumber = random(-15,15);
          tets=tet;
          tet=tet+randNumber;
          tete.write(tet); 
          tet=tets;         
          delay(4); 

        }  
        for(mache = 120; mache>=90; mache-=1) 

        {                                 
          machoire.write(mache);  
          randNumber = random(-15,15);
          tets=tet;
          tet=tet+randNumber;
          tete.write(tet); 
          tet=tets;       
          delay(4);

        } 
        compteur++;

      }
    }
  }
}

Ton 1er code m'envoyait le servo tete en butée à 180° après l'avoir fait gigoter
mais ton second pourrait convenir, ce qui est dommage c'est que le servo tete gigote trés vite tout le temps de durée de la machoire, j'ai mis 2° sinon ça bouge trop, mais bon le compteur machoire n'est pas de 20 comme dans mon exemple, je peux mettre ton code juste sur les scènes où le compteur de machoire est de 4 ou 5, et je suis pas obligé d'appliquer le mouvement de tete a chaque fois que la machoire bouge

le delay(4) de machoire correspond a sa vitesse de mouvement, ça il ne me faut pas y toucher, mais avec ton code ce serait pas possible d'appliquer une modif pour que le servo tete gigote moins vite?

en tout cas je te remercie déjà pour ce que t'as fait

Bonjour,

Voici un exemple d'utilisation de l'excellente librairie qui permet la gestion quasi simultanée des servos.

Je pense que cet exemple une fois adapté à vos besoins, pourra vous aider à résoudre votre problème.

Il faudra bien sur modifier celui-ci en fonction des séquences souhaitées.

//
 Test de la Lib ServoTimer2 IDE 0023
// Library by Mems ( Thank you mems )

#include <ServoTimer2.h>  // the servo library

// define the pins for the servos
#define tetePin 2
#define brasPin 3
#define machoirePin 4

ServoTimer2 servoTete;    // Jusqu'à 8 servos
ServoTimer2 servoBras;
ServoTimer2 servoMachoire;

void setup() {
  servoTete.attach(tetePin);     
  servoBras.attach(brasPin);
  servoMachoire.attach(machoirePin);
}

int incPulse(int val, int inc){
  if( val + inc  > 2000 )    // 2000
      return 1000 ;          // 1000
  else
    return val + inc;
}

void loop()
{
  int val;

  val = incPulse( servoTete.read(), 1);
  servoTete.write(val);

  val =  incPulse( servoBras.read(), 2);
  servoBras.write(val);

  val = incPulse(servoMachoire.read(), 8);
  servoMachoire.write(val);

  delay(10);
}

En espérant que cela vous soit utile.

Salutations

"Artouste" finalement ton code est impec, en mettant des tous petits mouvements de 1° tout le long de l'anim, ça lui donne un air plus vivant, ça me va bien comme ça
"Bernarduino" j'essayerais par curiosité, mais je ne pense pas tout refaire, par contre je suppose qu'il faut télécharger cette librairie?

VincentB:
"Artouste" finalement ton code est impec, en mettant des tous petits mouvements de 1° tout le long de l'anim, ça lui donne un air plus vivant, ça me va bien comme ça
"Bernarduino" j'essayerais par curiosité, mais je ne pense pas tout refaire, par contre je suppose qu'il faut télécharger cette librairie?

bien tant mieux si cela te conviens
je finissais de tester un code avec un peu de modulo :grin:
en jouant là,
int fm = 20; // facteur modulo pour tete/machoire 20 juste pour voir
à l’œil cela semble encore plus doux

#include <Servo.h>  


Servo bras;   
Servo tete; 
Servo machoire;  
int bra = 0; 
int tet = 0;  
int tets=0;
int mache = 0;
int bouton = 2;
long randNumber=0;
int fm = 20; // facteur modulo pour tete/machoire 20 juste pour voir 
void setup() 
{ 
  bras.attach(3); 
  tete.attach(5); 
  machoire.attach(6); 

  Serial.begin(9600); 
  pinMode(bouton, INPUT);


} 

void loop() { 

  if (digitalRead(bouton) == HIGH)

  { 
    delay(2000); //pause 2s avant commencer animation

    for(bra = 90; bra>=50; bra-=1) //leve le bras    
    {                                 
      bras.write(bra);                
      delay(30);

    }  
    delay(300);
    int compteur = 0; 
    while (compteur < 14) //bras va et vient de 7° sur la trompette
    { 

      for(bra = 50; bra < 57; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(15);  

      }

      for(bra = 57; bra>=50; bra-=1) //leve le bras    
      {                                 
        bras.write(bra);                
        delay(15);

      }

      compteur++;
    } 
    { 
      delay(300);

      for(bra = 50; bra < 90; bra += 1)  //baisse le bras
      {                                
        bras.write(bra);              
        delay(20);  

      } 

      delay(100); 

      for(tet = 90; tet < 130; tet += 1)  //bouge la tete
      {                                
        tete.write(tet);              
        delay(15);                        

      }

      for(tet = 130; tet>=50; tet-=1)     
      {                                 
        tete.write(tet);                
        delay(15);

      }  

      delay(100);  

      for(tet = 50; tet < 110; tet += 1)  
      {                                
        tete.write(tet);              
        delay(20);                        

      }

      delay(500);    //commence à parler

      int compteur = 0; 
      while (compteur < 20) //dis son nom
      { 

        for(mache = 90; mache < 120; mache += 1)


        {                                   
          machoire.write(mache); 
          
         if (mache % fm ==0) {
          randNumber = random(-2,2);
          tets=tet;
          tet=tet+randNumber;
          tete.write(tet); 
          tet=tets;   }      
          delay(4); 

        }  
        for(mache = 120; mache>=90; mache-=1) 

        {                                 
          machoire.write(mache);  
           if (mache % fm ==0) {
          randNumber = random(-2,2);
          tets=tet;
          tet=tet+randNumber;
          tete.write(tet); 
          tet=tets;   }      
          delay(4);

        } 
        compteur++;

      }
    }
  }
}

VincentB:
"Artouste" finalement ton code est impec, en mettant des tous petits mouvements de 1° tout le long de l'anim, ça lui donne un air plus vivant, ça me va bien comme ça
"Bernarduino" j'essayerais par curiosité, mais je ne pense pas tout refaire, par contre je suppose qu'il faut télécharger cette librairie?

Des photos... ou mieux, une petit vidéo ? XD

Ha oui, là c'est encore mieux, je l'ai mis sur toute mon anim, c'est nickel

Jean-François, photos, video il y a les liens dans mon 1er message du sujet
mais demain je ferais une nouvelle vidéo du pilote avec ce petit mouvement de tête
je vous remercie beaucoup de votre aide, c'est passionnant ces cartes, quand on maitrise ça doit être génial

Voilà j'ai refait une petite vidéo de l'animation, même url que la précédente
http://www.retroplane.net/mira3/animation_pilote2.wmv
les mouvements de tête sont petits, mais suffisants pour lui donner un air moins figé qu'auparavant
Encore merci Artouste et à ceux qui m'ont aidé

VincentB:
Ha oui, là c'est encore mieux, je l'ai mis sur toute mon anim, c'est nickel

Alors tant mieux, ce n'est pas vraiment beau ni optimisé comme code, mais ça à au moins le mérite d’être efficace et facilement integrable.

Jean-François, photos, video il y a les liens dans mon 1er message du sujet
mais demain je ferais une nouvelle vidéo du pilote avec ce petit mouvement de tête
je vous remercie beaucoup de votre aide, c'est passionnant ces cartes, quand on maitrise ça doit être génial

effectivement c'est bien sympathique comme cartes, avec un peu de pratique la maitrise du "général" vient assez vite.
En tout cas même sans la tête qui bouge ! :grin: votre réalisation est bien sympa, vous faites des présentations dans le cadre des rencontres de modélisme ?

Artouste:
votre réalisation est bien sympa, vous faites des présentations dans le cadre des rencontres de modélisme ?

Oui chaque été on organise la rencontre Retroplane dédiée uniquement aux maquettes de planeurs anciens, c'est l'aboutissement du travail qu'on a effectué toute l'année et détaillé sur notre forum, l'an dernier près de Cherbourg RETROPLANE 2011 aux Pierres Pouquelées et cet été ce sera en Autriche RETROPLANE 2012 au Spitzerberg - Autriche

Très beau travail en tout cas. :astonished: