boucle for avec servo moteur

bonsoir à tous ,

pour les besoins d'un projet je voudrais creer une sorte de ''vague '' avec 6 servo moteur
type chaser ...
pour l'instant je les controle en même temps avec une boucle FOR pour faire un cycle aller retour , ça c'est OK
mais pour creer un ''décalage " régulier je seiche ...
si vous quelqu'un pouvait m'aiguiller
merci à vous :slight_smile:

et si tu commençait par nous montrer ton code ? peut-être que ça aiderait pour te proposer une amélioration :smiley:

effectivement , ce sera plus simple :

       if (_radioData.ValeurB >=200){   
          
          
          
          
          for(int pos = 5; pos <= 110; pos += 1) 
  {                                 
    myservoA.write(pos);
    myservoB.write(pos);
    myservoC.write(pos);
    myservoD.write(pos);
    myservoE.write(pos);
    myservoF.write(pos);     
    delay(30);                       
  } 
 
       for(int pos = 110; pos>=5; pos-=1)    
  {                                
    myservoA.write(pos);
    myservoB.write(pos);
    myservoC.write(pos);
    myservoD.write(pos);
    myservoE.write(pos);
    myservoF.write(pos);              
    delay(15);                       
  } 
 
    _radioData.ValeurB = 0 ;  
   
          
    }

le code complet ce serait mieux…

pour arriver à faire un truc efficace il me semble qu’il faudrait organiser les servos en tableau, donc pour modifier cela il faut avoir le code complet avec les déclarations

un truc du genre :

for (uint8_t pos = 0; pos <116; pos++)
{
  for (uint8_t i = 0; i<6; i++)
  {
    uint8_t position = pos+i;
    if(position<5) position = 5;
    else if (position>110) position = 110;
    myservo[i].write(position);
  }
  delay(30);
}


for (int pos = 116; pos >-1; pos--)
{
  for (int i = 5; i>-1; i--)
  {
    int position = pos-i;
    if(posistion>110) position = 110;
    else if (position<5) position =5;
    myservo[i].write(position);
  }
  delay(15);
}

voici le code complet , un grand merci pour ton aide :

#include<Servo.h>
#include <SPI.h>
#include <NRFLite.h>



Servo myservoA;
Servo myservoB;
Servo myservoC;
Servo myservoD;
Servo myservoE;
Servo myservoF;


const static uint8_t RADIO_ID = 0;       
const static uint8_t PIN_RADIO_CE = 9; 
const static uint8_t PIN_RADIO_CSN = 10;

struct RadioPacket // Packet de données envoyé,

{
    uint32_t Valeur;
    uint32_t ValeurB;
    uint32_t ValeurC;
   
};

NRFLite _radio; //Déclaration du module NRF
RadioPacket _radioData;//Déclaration du packet de données


int tir = 3;


void setup()
{
    
   pinMode( tir , OUTPUT );
   digitalWrite(tir, HIGH);
  
  myservoA.attach(A0);      
  myservoA.write(10); 
  
  myservoB.attach(A1);
  myservoB.write(10);
  
   myservoC.attach(A2);
  myservoC.write(10);
  
  
   myservoD.attach(A3);
  myservoD.write(10);
  
  
   myservoE.attach(A4);
  myservoE.write(10);
  
  
   myservoF.attach(A5);
  myservoF.write(10);
  
  
   
     Serial.begin(9600);
    
    
    if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN))//si l'initialisation du module n'est pas finie
    {
        Serial.println("L'arduino ne peut pas communiquer avec le module ");
        while (1); // Attend
    }
    Serial.println("Setup fini");
    
   
    
    
    
    
    
    
}

void loop()
{
    while (_radio.hasData())
    {
        _radio.readData(&_radioData); // lecture des nouvelles données 
        
     
        
        _radioData.Valeur = map( _radioData.Valeur, 0, 255, 5, 110);

        _radioData.ValeurB = _radioData.ValeurB ; 
        
        _radioData.ValeurC = _radioData.ValeurC ; 
       
        
         
       } 
       
       
          myservoA.write(_radioData.Valeur);
          myservoB.write(_radioData.Valeur);
           myservoC.write(_radioData.Valeur);
          myservoD.write(_radioData.Valeur);
           myservoE.write(_radioData.Valeur);
          myservoF.write(_radioData.Valeur);
          
             
        
          
          
       if (_radioData.ValeurB >=200){   
          
          
          
          
          for(int pos = 5; pos <= 110; pos += 1) 
  {                                 
    myservoA.write(pos);
    myservoB.write(pos);
    myservoC.write(pos);
    myservoD.write(pos);
    myservoE.write(pos);
    myservoF.write(pos);     
    delay(30);                       
  } 
 
       for(int pos = 110; pos>=5; pos-=1)    
  {                                
    myservoA.write(pos);
    myservoB.write(pos);
    myservoC.write(pos);
    myservoD.write(pos);
    myservoE.write(pos);
    myservoF.write(pos);              
    delay(15);                       
  } 
 
    _radioData.ValeurB = 0 ;  
   
          
    }       
          
    
   Serial.println(_radioData.ValeurB); 
 
   
   
    if (_radioData.ValeurC >=200){ 
        digitalWrite(tir, LOW);
        
      }    
      
      else {
    
       digitalWrite(tir, HIGH);
     
      } 
     
     
        
  }

ok bah alors tu vas remplacer tes déclarations multiples de servos par :

Servo myservo[6];

et déclarer un autre tableau pour les pins :

const int servopins[6] = {A0, A1, A2, A3, A4, A5};

et donc dans ton setup tu vas faire :

for(uint8_t i =0; i<6; i++)
{
  myservo[i].attach(pinservo[i]);
  myservo[i].write(10);
}

les autres endroits à modifier, je te laisse les trouver :wink: (remplacer tes ABCDEF par un index entre 0 et 5)

encore merci pour ta précieuse aide
mais pour l'instant c'est un peu du " charabia" je suis débutant
mais je vais essayer de comprendre et d'adapter ton code en fonction de mon besoin

y'a pas grand chose de plus à modifier, juste remplacer tes deux boucles for de la vague par celles que je t'ai donné (à tester avec le matos, je en suis pas sur d'avoir fait les additions/soustractions dans le bon sens), et à un autre endroit dans ton code, tu as :

          myservoA.write(_radioData.Valeur);
          myservoB.write(_radioData.Valeur);
           myservoC.write(_radioData.Valeur);
          myservoD.write(_radioData.Valeur);
           myservoE.write(_radioData.Valeur);
          myservoF.write(_radioData.Valeur);

qu'il te faut aussi remplacer par une boucle for pour écrire la valeur dans tous les servos

tu peux aussi remplacer à la main tous tes myservoX.write par myservo[indexDuServo].write, mais c'est plus simple de le faire avec une boucle for

bon , je viens de passer une partie de l’apres midi à tester et reprendre le code avec tes conseils :

j’ai pas encore tt compris le principe des ''tableaux ‘’ , même si je comprends bien que cela permet de ne pas recopier diff variables , mais du coup c’est moins clair pour moi …

en essayant ta boucle dans ta boucle , si je comprends bien on demande de faire une boucle de valeur pour l’ecriture d’un servo puis on se décalle vers un autre servo
cependant j’ai l’impression que du coup avec cette méthode on fait d’abord le mvt sur le premier servo puis sur le 2 ème …
alors que je voudrais moins de décalage entre chaque servo et du coup en testant d’autre méthode j’arrive plus à un meilleur resultat en faisant :

              for(int pos = 5; pos <= 110; pos += 1) 
  {                                 
    myservoA.write(pos);
    myservoB.write(pos-10);
    myservoC.write(pos-20);
    myservoD.write(pos-30);
    myservoE.write(pos-40);
    myservoF.write(pos-50);
       
    delay(40);                       
  } 
 
  
 
       for(int pos = 110; pos>=5; pos-=1)    
  {                                
    myservoA.write(pos);
    myservoB.write(pos+10);
    myservoC.write(pos+20);
    myservoD.write(pos+30);
    myservoE.write(pos+40);
    myservoF.write(pos+50);
             
    delay(40);                       
  }

j’ai pas encore fait la modif avec ton principe de tableau :slight_smile: mais le problème avec le principe de décaler les départs des autres servo , c’est que à la fin de la 1 er boucle 1 quand pos = 110 seul le servo A y arrive
et donc le B C D E F à la fin accélèrent pour ce mettre à la valeur 110 avant de commencer la 2 eme boucle !
alors que je voudrait que tt les servo arrivent à leur valeur 110 chacun leur tour
et les autres attendent et quand tt le monde est à 110 on passe à la deuxieme boucle ds le même principe

ça doit bien être possible
merci encore pour tes conseils
cordialement

bon je viens d’essayer d’adapter une partie de mon code avec tes conseils ( tableau pr les pins et les servos )

mais je n’arrive pas à compiler ?

Servo myservo[6];


const int servopins[6] = {A0, A1, A2, A3, A4, A5};



void setup() {
  
for(uint8_t i =0; i<6; i++)
{
  myservo[i].attach(servopins[i]);
  myservo.write(10);
}



}

void loop() {
  

  
 for (uint8_t pos = 0; pos <116; pos++)
{
  for (uint8_t i = 0; i<6; i++)
  {
    uint8_t position = pos+i;
    if(position<5) position = 5;
    else if (position>110) position = 110;
    myservo[i].write(position);
  }
  delay(30);
}


for (int pos = 116; pos >-1; pos--)
{
  for (int i = 5; i>-1; i--)
  {
    int position = pos-i;
    if(position>110) position = 110;
    else if (position<5) position =5;
    myservo[i].write(position);
  }
  delay(15);
}



}

myservo.write(10);

????

nicopyro:
j'ai pas encore fait la modif avec ton principe de tableau :slight_smile: mais le problème avec le principe de décaler les départs des autres servo , c'est que à la fin de la 1 er boucle 1 quand pos = 110 seul le servo A y arrive
et donc le B C D E F à la fin accélèrent pour ce mettre à la valeur 110 avant de commencer la 2 eme boucle !
alors que je voudrait que tt les servo arrivent à leur valeur 110 chacun leur tour
et les autres attendent et quand tt le monde est à 110 on passe à la deuxieme boucle ds le même principe

ça doit bien être possible

j'espere bien que c'est possible, puisque normalement c'est exactement ce que fait le code que je t"ai donné :stuck_out_tongue: c'est pour ça que l'index de la boucle principale va de 0 à 116, et non plus de 5 à 110 :wink:

pour ton erreur de compilation, bidouillelec t'as donné la solution. Enfin pas donné, mais mis le doigt là où ça cloche : myservo est un tableau de servos, il faut donc absolument en donner l'index entre pour dire dans lequel il faut écrire la valeur 10... exactement ce qui est fait à la ligne au dessus

sinon quand tu rencontre une erreur de compilation, il faut aussi donner le message d'erreur, pas juste dire "j'ai une erreur"... cette fois elle était évidente, mais sinon c'est le boulot du devin...

...et je viens de me rendre compte, toutes mes excuses, que c'est moi qui ai oublié de mettre l'index dans le code que je t'avais donné en #5... voila voila... désolé. :stuck_out_tongue:

le post #5 est corrigé :wink:

merci Bricofoy ,

effectivement je viens enfin de comprendre le principe d’un tableau avec les indices
du coup je trouve que le "décalage " de mvt entre les servos n’est pas assez marqué
pous avoir plus de delay entre chaque départ , je dois jouer sur la valeur (uint8_t pos = 0; pos <116; )pos++) ?

c’est bien ça ?

oui, sur ces valeurs extrèmes, et sur le décalage qui va avec dans la seconde boucle qui balaye les 6 servos. Mais si tu dois décaler plus, tu va devoir avoir le minimum <0 donc il ne faut plus utiliser un uint8_t (unsigned int 8 bits, qui comme son nom l’indique , unsigned, n’est pas signé donc ne peut contenir de valeurs négatives), mais un int.

tu peux peut-être commencer juste augmenter le décalage entre les servos dans la seconde boucle. moi j’avais juste ajouté “i” (qui varie entre 0 et 5), ce qui fait un décalage de 1° entre les positions de chaque servo, mais tu peux par exemple ajouter i4 pour avoir un décalage de 4° à chaque fois
Logiquement pour bien continuer à comencer à partir de 5 et arriver à 110, il faut augmenter les extrêmes de la boucle principale d’autant, soit donc si on prends i
4, il faudra augmenter de 5*4=20, donc entre -15 et 130.

autant ajouter des variables pour modifier ça facilement :

const int nbrservos=6;
const int decalage = 4;
const int posmini=5;
const int posmaxi=110;


for (uint8_t pos = posmini-decalage*(nbrservos-1); pos <posmaxi+decalage*(nbrservos-1); pos++)
{
  for (uint8_t i = 0; i<nbrservos; i++)
  {
    uint8_t position = pos+i*decalage;
    if(position<posmini) position = posmini;
    else if (position>posmaxi) position = posmaxi;
    myservo[i].write(position);
  }
  delay(30);
}

de la sorte tu peux modifer la valeur de “decalage” pour modifier… le décalage :smiley:

je te laisse faire la modif de la redescente de la vague, en t’inspirant de ça ça devrait aller :wink:

nicopyro:
bonjour Bricofoy ,

je me permet de vous contacter suite à votre aide , sur la réalisation d’une '‘VAGUE’ avec 6 servos moteur ( courant février )
vous m’aviez conseillé d’utiliser un tableau de valeur pour la déclaration des 6 servos et leur ‘‘Attached’’ à la broche , également ce principe de tableau était utilisé également pour créer la boucle four For avec l’effet de vague
Cependant je voudrais rajouter 2 autres servos , ( donc 8 au total ) je voulais les mettre à suivre sur le sortie A6 A7 de ma carte nano , et je viens d’apprendre que les pin A6 et A7 de pouvais pas etre des sortie !
donc j’ai déplacé en D7 D8 , mais du coup comment faire pour garder le principe du tableau avec :

Servo myservo[8];

const int servopins[8] = {A0, A1, A2, A3, A4, A5 , D7 , D8};   ?

for(uint8_t i =0; i<8; i++)
{
 myservo[i].attach(servopins[i]);
 myservo[i].write(10);
}




et justement dans la boucle setup , je voudrais que les servos ce positionnent tous à 10° 
comme ici "myservo_.attach(servopins*);*_
<em>_ myservo*.write(10);*_</em>

<em>_*cependant , le positionnement est tres brutale je trouve , il y a t'il un moyen pour réaliser un déplacement lent à chaque position*_</em> 
<em>_*la fonction ''MYSRVo .write ( ) peu être modifier pour un déplacement plus soft ?*_</em>
<em>_*merci à toi*_</em>
<em>_*[/quote]*_</em>
<em>_*Salut*_</em>
<em>_*As-tu essayé ta modification avant de poser la question ? car c'est exactement ce qu'il faut faire :D*_</em> 
<em>_*A ceci près qu'il faut utiliser 7 et 8 directement comme numéros de broches et non pas D7 D8*_</em>
<em>_*Sinon la fonction write ne fait que dire au servo de se positionner à 10°, si le mouvement est trop rapide alors il faut soit changer de servo par un plus lent, soit faire le mouvement en plusieurs fois (mais ceci implique de connaître la position actuelle du servo avant de demander le mouvement)*_</em>

effectivement ça fonctionne comme cela , si j'ai bien compris c'est un des avantages des tableaux de valeurs :slight_smile:

une dernière chose , j'aimerais également un mouvement sur mes 8 servos , inversés:
je m'explique , j'ai 8 servos sur un support en cercle , je voudrais créer 2 groupes de 4 servos , 4 qui descendent et 4 qui montent en inversé 1/2 quoi :

l'idée je les mets tous à 50 ° , puis le servos 1 3 5 7 effectue une boucle For de 50° à 100 °
les servos 2 4 6 8 effectue une boucle for de 50° à 0 °
et inversement au retour
peux tu m'aiguiller :slight_smile:
bonne soirée

avec de la même manière une boucle, mais une condition sur l'index pour commander dans un sens si le numéro du servo est pair, dans l'autre si il est impair ?