Problème double boucle For

Bonjour,

Mon problème est que mes 2 boucles, séparément fonctionnent, mais ne fonctionnent plus quand que je les mets à la suite.

for(unsigned int PosUs10 = MiddlePos*10 ; PosUs10 <= UpperPos*10 ; PosUs10 += increment10){

Me donne bien : 1505.00, 1515.30, 1525.60, ainsi de suite.

for(unsigned int PosDeg = MiddlePosDeg*10 ; PosDeg <= UpperPosDeg*10 ; PosDeg += 1){

Me donne bien : 90, 91, 92, ainsi de suite.

Merci pour votre aide.

Le code :

/*************************************
Simple Arduino sweep sketch in microseconds

Note: The code is written in a simple blocking way and not optimized. It's a terrible
startingpoint to use in your own code!

PREREQUISITES:
- Know the lower ans upper value of a servo

INSTRUCTIONS
- Fill in 'LowerPos', 'UpperPos' and 'MiddlePos'
- Upload sketch
- Set Serial Monitor to 115200 baud
- Set Serial Monitor to "Both NL & CR"
- Connect a servo to 'ServoPin' (default: pin 9)
- Press "Send" when the servo is positioned at Middle when you are asked
*************************************/

#include <Servo.h>

const byte ServoPin = 10;
//Enter the minimum limit pulse width (in ms)
const unsigned int LowerPos = 520;
//Enter the lower maximum pulse width (ms)
const unsigned int UpperPos = 2480;
//Middle Calculate Formula
const unsigned int MiddlePos = ((UpperPos - LowerPos) / 2) + LowerPos;
// 10,3 Microseconds = 1°
const unsigned int increment10 = 103; //10.3 * 10
//boolean SerialDisplay;
const unsigned int MiddlePosDeg = ((UpperPos - LowerPos) / 2) / increment10; 
const unsigned int UpperPosDeg = (((UpperPos - LowerPos) / 2) / increment10) * 2; 

Servo testServo;

// variable to store the servo position
int PosUs = MiddlePos;
int PosDeg = MiddlePosDeg;

void setup() {
  Serial.begin(115200);
//  Serial.display=true
//  testServo.writeMicroseconds(MiddlePos);
  testServo.attach(ServoPin, LowerPos, UpperPos);
 
  Serial.print("Lower value set to ");
  Serial.println(LowerPos);
 
  Serial.print("Upper value set to ");
  Serial.print(UpperPos);
  Serial.print(" = ");
  Serial.print(UpperPosDeg*10);
  Serial.println("° ");
 
  Serial.print("Middle value set to ");
  Serial.print(MiddlePos);
  Serial.print(" = ");
  Serial.print(MiddlePosDeg*10);
  Serial.println("° ");
  Serial.println();
  Serial.println("Servo on central location");
  Serial.println("Press \"Send\" to continue");
  Serial.println();

  while(!Serial.available());
  clearSerialBuffer();
}

void loop() {
  // if (SerialDisplay)
  //  Serial.println("");
  // goes from MiddlePos to UpperPos. 
  /*Incrementing floating values of a non-integer increment, 
   * do not add true, because rounding errors accumulate.
   * Use the "fixed point" integer value multiplied by 10:*/

  for(unsigned int PosUs10 = MiddlePos*10 ; PosUs10 <= UpperPos*10 ; PosUs10 += increment10){
    for(unsigned int PosDeg = MiddlePosDeg*10 ; PosDeg <= UpperPosDeg*10 ; PosDeg += 1){
    double PosUs = PosUs10 / 10.0;
    delay(650);
    Serial.print(PosUs);
    Serial.print(" = ");
    Serial.print(PosDeg);
    Serial.print("°, "); 
    }
   }
    Serial.println();    
    Serial.println(); 
    
  //for(unsigned int PosUs10 = MiddlePos*10 ; PosUs10 >= LowerPos*10 ; PosUs10 -= increment10)
  for(unsigned int pos = MiddlePos ; pos >= LowerPos ; pos -= 10)
  {
  //double PosUs = PosUs10 / 10.0;
    delay(650);
    Serial.print(pos);
    Serial.print(" "); 
   }
    Serial.println();
    delay(15000);
    Serial.println();
 //   SerialDisplay=false;
  }
  
 void clearSerialBuffer()
{
  //clear serial buffer (but do nothing with it)
  while(Serial.available())
  {
    Serial.read();
  }
}

Et qu'est ce qui s'affiche sur la console ?

Sur la 1ère boucle la valeur resta a 1505.
Je devrais avoir un incrément de 10.3 :

1505.00 = 90°, 1515.30 = 91°, 1525.60 = 92° ainsi de suite.

Mais, j’ai

1505 = 90°, 1505 = 91°, 1505 = 92° ainsi de suite

C'est normal, tes boucles sont imbriquées. Celle de l'intérieur doit se faire en entier pour chaque valeur de celle de l'extérieur.

Si tu veux obtenir une valeur différente pour chaque valeur d'une variable, il ne te faut qu'une seule boucle. La seconde valeur doit être déduite de la première.

Merci lesept,
Cela devient compliqué, pour l’expérience que j’ai en C !
Un petit coup de main ou un exemple simple est possible ?

Le petit test ci-dessous, fonctionne.
Je ne parviens pas à comprendre ou je foire !

void setup() {
    Serial.begin(115200);

}

void loop() {
for (int x = 0; x < 8; x++) {
  for (int y = 0; y < 8; y++) {
    Serial.print ("x = ");
    Serial.println(x);
    Serial.print ("y = ");
    Serial.println(y);
    delay(1000);
    Serial.println();
  }
 }
}

Bonjour,

Il te faut une seule boucle. Tes deux variables doivent évoluer en même temps

  unsigned int PosUs10;
  unsigned int PosDeg;
  for (PosUs10 = MiddlePos * 10, PosDeg = MiddlePosDeg * 10 ; PosUs10 <= UpperPos * 10 && PosDeg <= UpperPosDeg * 10 ; PosUs10 += increment10, PosDeg += 1)
  {
    double PosUs = PosUs10 / 10.0;
    delay(650);
    Serial.print(PosUs);
    Serial.print(" = ");
    Serial.print(PosDeg);
    Serial.println("°");
  }

Merci pour cette belle modification.
Je ne sais pas pourquoi, mais l’incrémentation ne va pas jusqu’au bout
Les valeurs sont bien prises en compte, soit :
LowerPos = 520
UpperPos=2480
MiddlePos = ((UpperPos - LowerPos) / 2) + LowerPos; = 1500
Donc l’incrémentation commence bien a 1500 (MiddlePos), et devrait aller au plus proche de 2480 (UpperPos).
Soit aller jusqu’à 2478.50, mais elle s’arrête a 2427 soit 5 incrément trop tôt.
Une idée de ce qui en être la cause ?

Peut-être que posdeg arrive à son maximum avant posus

C'est ce qui peut arriver quand on a deux limites. Soit on arrête quand une des deux limites est atteinte (c'est ce qui est fait dans le programme) soit on arrête quand les deux limites sont atteintes ou dépassées dans ce cas il faut remplacer le && par un || dans le if.

Bien vu ! c’était bien le cas.
Encore merci à vous deux.
L’affichage PosUs sur la console se fait sur deux chiffres après la virgule (enfin le point) est-il possible de n’afficher qu’un chiffre ?

Serial.print(PosUs, 1);

Merci, que pensez-vous de ce code dans son ensemble ?
Je suis ouvert à tous conseils \ remarques.

Pour calculer la moyenne de deux variables a et b, je fais (a+b) /2 et pas (a-b) /2+b, ce qui est équivalent mais plus compliqué

Merci lesept,
Quelle formule de calcul utiliseriez-vous pour trouver l'équivalence en degrés de " UpperPosUs", " LowerPosUs" et " MiddlePosUs"?

Pour résumer:

10,3 Microseconds = 1°
Increment10 = 103 soit (10.3 * 10)

UpperPosUs = 2480

LowerPosUs = 520

MiddlePosUs = (UpperPos + LowerPos) / 2 = 1500

nerixs:
Quelle formule de calcul utiliseriez-vous pour trouver l'équivalence en degrés de " UpperPosUs", " LowerPosUs" et " MiddlePosUs"?

    float PosDeg = 90+(PosUs-MiddlePos) / (increment10/10.0);

Heu !!! je ne suis pas sûr d'avoir tous compris.
D’où vient le 90?
Un servo qui ne couvrirait que 150° n'aura pas son milieu a 90°.

Si le milieu est à 75, tu mets 75

nerixs:
Un servo qui ne couvrirait que 150° n'aura pas son milieu a 90°.

Pourquoi? C'est une pure convention. Ton servo peut très bien varier de 15 à 165 degrés ou de -75 à +75 degrés.

Si le milieu est à 75, tu mets 75

Si on dit que la valeur la plus basse de la durée correspond au zéro du servo, c'est encore plus simple:

   float PosDeg = (PosUs-LowerPos) / (increment10/10.0);

kamill:
Pourquoi? C'est une pure convention. Ton servo peut très bien varier de 15 à 165 degrés ou de -75 à +75 degrés.

Si le milieu est à 75, tu mets 75

Très bonne remarque!
Mais, le 90 ou le 75 que tu utilises dans ton calcule on n'est pas sensé le connaitre n'ayant au départ que des valeurs en microsecondes.
Si mon calcule est bon pour trouver le milieu en degrés:
MiddlePosDeg = ((UpperPos - LowerPos) / 2) / (increment10/10.0);
MiddlePosDeg = (2300 - 710) / 2) / 10,3
MiddlePosDeg = (1590 / 2) /10,3
MiddlePosDeg = 795 /10,3 = 77, 185 (77°)
De là, calculer UpperPosDeg et LowerPosDeg, mais je ne suis déjà pas sûr de ma logique pour MiddlePosDeg.