IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Déclaration et prise en charge ?


Sujet :

C++

  1. #1
    Invité
    Invité(e)
    Par défaut Déclaration et prise en charge ?
    Bonjour,

    J’ai un problème sur une esquisse Arduino (langage C++)
    Dans cette déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const unsigned int StepSizeUs = 10;
    J’aimerais utiliser 10,3 est-ce possible ? si oui pouvez-vous me dire comment ?

    Idem dans ma boucle For :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (pos =  MiddlePos; pos >= LowerPos; pos -= 10)
    J’aimerais aussi utiliser 10,3.

    Merci pour votre aide
    Bien cordialement
    Eric

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    C'est écrit unsigned int, donc non tu peux pas utiliser un nombre à virgule..
    Ça signifie quoi 10.3 de toute façon ? Ce truc semble être en microsecondes, donc 10.3 microsecondes euh... ça supporte des nanosecondes ton système ?
    Utiliser un nombre a virgule pour faire un pas et une boucle est une mauvaise idée.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Oui c’est bien 10,3 microsecondes = 1° donnée du constructeur.
    Pouvez-vous me dire comment gérer le nombre a virgule ?
    Pourquoi la boucle ne le gère pas ?

  4. #4
    Invité
    Invité(e)
    Par défaut
    Je pensais que "float" ???.
    Je ne comprends et maîtrise pas tout, j'essaie de remplacer les servomoteurs du petit robot de mon fils qui sont HS et qui ne se fabrique plus.
    Le programme du petit robot étaient fournis et n'étaient pas censé être modifié.
    Je pensais pouvoir m'en sortir avec le web, n'étant par programmeur! Je me trompais.
    J'espère que vous pourrez m'aider.
    Bien cordialement.
    Dernière modification par Invité ; 25/10/2019 à 12h46.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Voici le code soyez indulgent.
    Pour résumer, mon code fonctionne, mais ne gère pas une incrémentation avec un nombre a virgule.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    /*************************************
    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, higher, and middle values 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 = 9;
    //Enter the minimum limit pulse width (in ms)
    const unsigned int LowerPos = 710;
    //Enter the lower maximum pulse width (ms)
    const unsigned int UpperPos = 2300;
    //Middle Calculate Formula
    const unsigned int MiddlePos = ((UpperPos - LowerPos) / 2) + LowerPos;
    // 10,3 Microseconds = 1°
    //####
    // How to declare 10.3?
    // const float StepSizeUs = 10,3;
    // in void loop()=> for => pos += 10,3 and pos -= 10 don't work
    //####
     
    Servo testServo;
     
    // variable to store the servo position
    int pos = MiddlePos;
     
    void setup() {
      Serial.begin(115200);
      testServo.writeMicroseconds(MiddlePos);
      testServo.attach(ServoPin, LowerPos, UpperPos);
     
      Serial.print("Lower value set to ");
      Serial.println(LowerPos);
     
      Serial.print("Upper value set to ");
      Serial.println(UpperPos);
     
      Serial.print("Middle value set to ");
      Serial.println(MiddlePos);
      Serial.println();
      Serial.println("Servo on central location");
      Serial.println("Press \"Send\" to continue");
     
      while(!Serial.available());
      clearSerialBuffer();
    }
     
    void loop() {
        Serial.println("");
      // goes from MiddlePos to UpperPos. 
      //#### (10,3 don't work result like 10) I would like to use StepSizeUs ####
      //for (pos = MiddlePos; pos <= UpperPos; pos = (float)pos + 10.3) {
      for (pos = MiddlePos; pos <= UpperPos; pos += 10) { 
        // in steps of 10 µS
        testServo.writeMicroseconds(pos); // tell servo to go to position in variable 'pos'
        delay(550);
        Serial.print(pos);
        //Serial.print(pos,2); //number after the decimal point
        Serial.print(" "); 
      }
        Serial.println("");
      // goes from MiddlePos to LowerPos. 
      //#### (10,3 don't work result like 10) I would like to use StepSizeUs ####
      //for (pos = MiddlePos; pos <= LowerPos; pos = (float)pos - 10.3) {
      for (pos =  MiddlePos; pos >= LowerPos; pos -= 10) { 
        testServo.writeMicroseconds(pos); // tell servo to go to position in variable 'pos'
        delay(550);
        Serial.print(pos);
        //Serial.print(pos,2); //number after the decimal point
        Serial.print(" ");
       }
        delay(6000);
      }
     
     void clearSerialBuffer(){
      //clear serial buffer (but do nothing with it)
      while(Serial.available()){
        Serial.read();
      }
     }

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Si tu veux un incrémenter des valeurs flottantes d'un incrément non-entier, tu ne dois pas utiliser de vraie addition, car les erreurs d'arrondi se cumulent.

    Par contre tu peux bosser avec ce qu'on appelle de la "virgule fixe": Ici vu que tu as juste un chiffre décimal après la virgule, tu peux travailler avec des valeurs entières multipliées par 10:

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    unsigned int increment10 = 103; //10.3 * 10
    for(unsigned int pos10 = MiddlePos*10 ; pos10 <= UpperPos*10 ; pos10 += increment10)
    {
    	double pos = pos10 / 10.0;
    	//...
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Est-ce que la doc indique que Servo supporte une telle valeur ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Invité
    Invité(e)
    Par défaut
    @ Bousk
    Dans la doc, il est écrit:
    10.3 µS matches 1°
    Arduino lib "Servo.h" (2400-544)/180.
    Ce qui donne exactement: 10,31111111111111

    @Médinoc
    Merci pour cet exemple.
    J'ai compris le principe, mais suis moins à l'aise avec la mise en pratique.
    Pouvez-vous m'explique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    double pos = pos10 / 10.0;
    Bien cordialement

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je ne vois pas ce qui est à expliquer là-dedans, en fait.
    Cette ligne récupère jute la vraie valeur à virgule flottante depuis celle à "virgule fixe", vu qu'on est "après" l'incrémentation.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Ce que j’essaie de comprendre, c’est qu’on incrémente pos de 103 soit 10.3 * 10 et après traitement on le divise par 10.0
    Pourquoi le .0 ?
    Quoi qu’il en soit le résultat voulu est là, merci beaucoup.
    Dernière modification par Invité ; 26/10/2019 à 13h20.

  11. #11
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 768
    Par défaut
    Citation Envoyé par NeriXs Voir le message
    Pourquoi le .0 ?
    En C/ C++, avec les opérations (+, /, *, -) le type "le plus large" est pris pour réaliser l'opération. Le type du résultat n’influence pas le résultat.
    Et c'est d'ailleurs un piège pour les débutants "Mais pourquoi mon résultat est 0 lorsque je fais 1 / 3 ?" (<- parce ce que c'est une division entière)

    Donc, pour résumer, si tu ne mets pas ".0", 10 est de type int et donc int / int donne un int (opération entière)
    Par contre, 10.0 est de type float et donc XXX / float ou float/ XXX donne un float (opération flottante)

    Tu peux caster comme un goret également result = (float) (((float) pos)/ ((float) 10)); (<- exemple avec tous les casts)

  12. #12
    Invité
    Invité(e)
    Par défaut
    Merci fœtus ma question n’était pas si anodine que ça !
    Je suis débutant, ça c’est sûr .
    Dernière modification par Invité ; 26/10/2019 à 13h34.

  13. #13
    Invité
    Invité(e)
    Par défaut
    J’aimerais récupérer l’équivalence de mes valeurs µS en dégrées, pour chacune de mes boucles.
    Pourriez-vous me donner un petit exemple concret ?
    Je ne vois pas comment l’aborder

    Voici le code modifié comme proposé par Médinoc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    /*************************************
    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 = 9;
    //Enter the minimum limit pulse width (in ms)
    const unsigned int LowerPos = 710;
    //Enter the lower maximum pulse width (ms)
    const unsigned int UpperPos = 2300;
    //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;
     
    Servo testServo;
     
    // variable to store the servo position
    int pos = MiddlePos;
     
    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.println(UpperPos);
     
      Serial.print("Middle value set to ");
      Serial.println(MiddlePos);
      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 pos10 = MiddlePos*10 ; pos10 <= UpperPos*10 ; pos10 += increment10)
      {
      double pos = pos10 / 10.0;
        delay(650);
        Serial.print(pos);
        Serial.print(" "); 
       }
        Serial.println();    
        Serial.println(); 
      for(unsigned int pos10 = MiddlePos*10 ; pos10 >= LowerPos*10 ; pos10 -= increment10)
      {
      double pos = pos10 / 10.0;
        delay(650);
        Serial.print(pos);
        Serial.print(" "); 
       }
        Serial.println();
        delay(3000);
        Serial.println();
     //   SerialDisplay=false;
      }
     
     void clearSerialBuffer()
    {
      //clear serial buffer (but do nothing with it)
      while(Serial.available())
      {
        Serial.read();
      }
    }
    Dernière modification par Invité ; 27/10/2019 à 10h54.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Je pense avoir trouvé la solution.
    Je triche un peu, dites-moi si c’est acceptable ?
    J’utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MiddlePosDeg = ((UpperPos - LowerPos) / 2) / increment10;
    Qui normalement devrait donner :
    MiddlePosDeg = ((2480 -520) / 2) / 103
    MiddlePosDeg = 9,5145
    Vu que le résultat est automatiquement arrondi me donne 9
    9 * 10 j’ai mes 90°

    Même calcule pour "UpperPosDeg" que je multiplie par 2 et j’ai mes 180°

    Mon problème est que mes 2 boucles, séparément fonctionnent, mais ne fonctionnent plus quand que je les mets à la suite.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(unsigned int PosUs10 = MiddlePos*10 ; PosUs10 <= UpperPos*10 ; PosUs10 += increment10){
    Me donne bien : 1505.00, 1515.30, 1525.60, ainsi de suite.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(unsigned int PosDeg = MiddlePosDeg*10 ; PosDeg <= UpperPosDeg*10 ; PosDeg += 1){
    Me donne bien : 90, 91, 92, ainsi de suite.

    Le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    /*************************************
    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();
      }
    }

  15. #15
    Invité
    Invité(e)
    Par défaut
    Le petit test ci-dessous, fonctionne.
    Je ne parviens pas à comprendre ou je foire !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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();
      }
     }
    }

  16. #16
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 768
    Par défaut
    Je vois à peu près ce que tu veux faire, et j'ai fait des traces : (compilation en C)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #include <stdio.h>
    #include <stdlib.h>
     
    int main (int argc, char** argv)
    {
        unsigned int PosUs10, PosDeg;
     
        unsigned int LowerPos, UpperPos, MiddlePos, increment10, MiddlePosDeg, UpperPosDeg;
        char ServoPin;
     
        ServoPin = 10;
        //Enter the minimum limit pulse width (in ms)
        LowerPos = 520;
        //Enter the lower maximum pulse width (ms)
        UpperPos = 2480;
        //Middle Calculate Formula
        MiddlePos = ((UpperPos - LowerPos) / 2) + LowerPos;
        // 10,3 Microseconds = 1°
        increment10 = 103; //10.3 * 10
        //boolean SerialDisplay;
        MiddlePosDeg = ((UpperPos - LowerPos) / 2) / increment10; 
        UpperPosDeg = (((UpperPos - LowerPos) / 2) / increment10) * 2; 
     
        for(PosUs10 = MiddlePos*10 ; PosUs10 <= UpperPos*10 ; PosUs10 += increment10){
            for(PosDeg = MiddlePosDeg*10 ; PosDeg <= UpperPosDeg*10 ; PosDeg += 1){
                double PosUs = PosUs10 / 10.0;
     
                printf("%f = %u° (%u < %u < %u, %u < %u < %u)\n", PosUs, PosUs10, MiddlePos*10, PosUs10, UpperPos*10, MiddlePosDeg*10, PosDeg, UpperPosDeg*10);
            }
        }
     
        return EXIT_SUCCESS;
    }
    Dans ta deuxième boucle, tu calcules avec une variable qui ne varie pas
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 165 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 166 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 167 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 168 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 169 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 170 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 171 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 172 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 173 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 174 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 175 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 176 < 180)
    2478.500000 = 24785° (15000 < 24785 < 24800, 90 < 177 < 180)
    J'espère que je ne me suis pas troué dans mon post et qu'il est utile/ pas hors-sujet.
    D'ailleurs je ne comprends pas pourquoi tu t'acharnes avec 2 boucles tu fait 1 boucle qui fait varier la variable PosUs10 de 103 en 103 et avec un calcul, tu les converti en degrés.

  17. #17
    Invité
    Invité(e)
    Par défaut
    Merci foetus,
    Comme conseillé avec une seule boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (PosUs10 = MiddlePos * 10, PosDeg = MiddlePosDeg * 10 ; PosUs10 <= UpperPos * 10 || PosDeg <= UpperPosDeg * 10 ; PosUs10 += increment10, PosDeg += 1)
    Ça semble déjà mieux, que disent les traces, je code sous Arduino alors pour compiler !!!

  18. #18
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Je comprends parfaitement ton souhait de faire plaisir à ton fils, et il est d'ailleurs tout à ton honneur. Il faut cependant arriver à se mettre en tête que ce que tu veux faire a peut-être l'air très facile, quand on voit les autres le faire, mais que cela implique pas mal de connaissances et de "coup de mains" qui ne sont pas vraiment innés.

    C'est un peu comme si tu voulais réparer le moteur de ta tondeuse : si tu ne connais rien en mécanique, tu as sans doute largement intérêt à aller jusqu'au garage et à le faire réparer par un professionnel . La grosse différence, c'est que tout le monde est susceptible d'apprendre les bases de la programmation. Il faut juste que les gens acceptent l'idée que, s'ils ne comprennent pas ce qu'il font, il n'arriveront jamais à rien de "correct".

    Je crois donc que la première chose à faire est de comprendre un tout petit peu le principe de la boucle "pour" (for, en anglais):

    La première chose, c'est que c'est une boucle. C'est à dire que c'est "quelques lignes de code" qui seront répétées "un certain nombre de fois". La boucle "pour" en outre pour particularité d'utiliser un "compteur" de manière à déterminer si ces "quelques lignes de codes" doivent effectivement être exécutée "une fois de plus".

    Pour créer cette boucle, nous devons fournir trois parties distinctes, qui seront séparées par des point-virgule (';'):
    la première donne la valeur de départ que devra utiliser le compteur : quand tu écris PosUs10 = MiddlePos * 10 tu dis que PosUs10 prend la valeur calculée de MiddlePos multipliée par 10 comme valeur de départ
    1. La deuxième donne la condition qui permettra de rentrer "une fois de plus" dans la boucle : quand tu écris PosUs10 <= UpperPos * 10, tu dis que "les quelques lignes de code qui suivent" devront être répétée aussi "longtemps que PosUs10 (qui a, au début, la valeur correspondant à MiddlePos * 10) n'est pas plus petit ou égale à la valeur de UpperPos * 10"
    2. la troisième indiquera le "pas" qu'il faudra utiliser, la manière dont la valeur du compteur devra évoluer après chaque exécution de la boucle, de manière à déterminer si il faut entrer "une fois de plus" dans la boucle

    Tu n'as -- a priori -- absolument pas besoin de jouer avec PosUs10 et MiddlePosDeg vu que tu peux très facilement calculer l'un à partir de l'autre. Et pour cause : si l'une des broche de ton servomoteur est soumise pendant "un certain temps" à tension donnée, il va forcément tourner d'un angle bien précis qui est déterminé par le temps qui lui est nécessaire pour parcourir 1°.

    Nous sommes donc face à une simple règle de trois : Vu que le servomoteur tourne d'un degré en 10.3111 microsecondes, combien de temps va devoir tourner le servomoteur pour passer de sa position actuelle à un angle décalé de X° Et bien la réponse est simple : il faudra X le temps nécessaire à parcourir un degré.

    Et comme l'une des règles essentielles en programmation est de ne pas rendre les choses plus complexes que nécessaires, si tu peux, avec la seule valeur correspondant à l'angle, calculer "tout le reste" (ce qui comprend le temps que la broche devra être soumise au courant adéquat), tu peux envisager de faire les différents calculs uniquement... quand tu en as besoin.

    Et tout le reste va partir de là : si tu connais la position d'origine de ton servomoteur (comprend: la position à laquelle il se trouve au moment où tu envisages de le faire bouger), et que tu sais à quelle position il devra se trouver lorsqu'il aura fini de bouger, tu es capable de déterminer l'angle qu'il doit parcourir, et donc le temps dont il aura besoin pour y arriver. Le reste, c'est du simple calcul de base : des additions, des multiplications, et soustractions et des divisions.

    Par exemple, Nous pourrions tout à fait se dire que nous avons 180° entre les deux butées du servomoteur (la butée "position minimale" et la butée "position maximale"), et nous pourrions donc dresser la liste des des temps pendant lesquels la borne adéquate du servomoteur doit être soumise à un courant pour atteindre les différents angles à partir de la butée minimale avec un code qui pourrait être aussi simple que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for(int angle = 0; // on commmance avec l'angle 0°
        angle<180;  // on entre dans la boucle tant que l'ange est plus petit que 180°
        ++angle){ // à chaque fin de boucle, on incrémente l'angle de 1
        std::cout<<"pour parcourir un angle de "<<angle<<"°, il faut du courant pendant "<<angle * 10.3111<<"\n";
    }
    Et si tu veux pouvoir réutiliser le temps après l'avoir calculé, tu peux le faire sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for(int angle = 0; // on commmance avec l'angle 0°
        angle<180;  // on entre dans la boucle tant que l'ange est plus petit que 180°
        ++angle){ // à chaque fin de boucle, on incrémente l'angle de 1
        float enlapsedTime = angle * 10.31111: // l'idéal aurait sans doute d'avoir une constante correspondant 
                                               // à cette valeur 10.3111 
        std::cout<<"pour parcourir un angle de "<<angle<<"°, il faut du courant pendant "<<enlapsedTime<<"\n";
    }
    ce qui donnera exactement le même résultat
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  19. #19
    Invité
    Invité(e)
    Par défaut
    Merci pour ces explications
    Les valeurs en degrés entre les deux butées du servomoteur sont inconnues, le servomoteur peut très bien avoir une course de 15 à 165 degrés, soit 150 degrés de débattement.
    Votre code ne devrait-il pas plutôt utiliser les valeurs mini et maxi connues en millisecondes et l'incrément 10.3 pour définir les valeurs en degrés?

  20. #20
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Justement, les butées sont connues, vu qu'elles représentent respectivement les valeurs 2400 et 520. C'est toi même qui a donné ces valeurs . Et mieux encore, je peux te dire que cet écart représente un angle de 180°.

    Car les deux bornes que tu cherches, elles sont exactement là, devant ton nez Ou du moins, ce sont les valeurs que tu nous as données. J'espère donc que tu as respecté le conseil
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /* 
    PREREQUISITES:
    - Know the lower ans upper value of a servo
    /*
    Si ce ne sont pas ces valeurs, d'où viennent elles

    Parce que tu as dit toi-même qu'en divisant la 2400-520 par 180, on obtenait 10.3111 microseconde, qui correspond au temps nécessaire pour que le servomoteur fasse parcoure 1°. Et, a partir de là, tu calcule comme tu veux selon la formule: angle_parcouru = vitesse * temps_de_courant.
    En sachant que vitesse est constante (on parcoure systématiquement 1° en fournissant du courant pendant 10.3111 microseconde) le temps pendant lequel tu dois fournir le courant est strictement proportionnel à l'ange que tu veux parcourir.

    Alors, bien sur, tu peux toujours envisager de tout calculer à chaque fois, et te dire que tu veux te déplacer pendant XXX microsecondes au lieu de te dire que tu veux te déplacer de XXX degrés. Mais ce n'est pas efficace, ne serait-ce que à cause des arrondis et autres imprécisions dont souffrent les nombres à virgules flottantes.

    Par contre, si tu part du principe que tu calcule l'angle qui doit séparer le "point d'arrivée" du "point de départ" de ton servomoteur, les choses sont tout de suite beaucoup plus simple : si, en soustrayant l'angle de départ de l'angle d'arrivée, tu obtiens une valeur positive, c'est que ton servomoteur doit tourner vers sa borne maximale. Sinon, c'est qu'il tourne vers sa borne minimale. Combien de temps doit-il tourner hé bien la valeur absolue de l'angle indiqué * 10.31111 microseconde.
    Et une fois que tu as pu calculer le temps de mobilisation de ton servomoteur, tu peux appliquer le courant à la borne adéquate pendant la durée impartie

    Voilà qui te fait deux calculs tous simples, non
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Erreur 3251 : mise à jour non prise en charge
    Par gletare dans le forum Access
    Réponses: 2
    Dernier message: 10/02/2006, 10h17
  2. [VB.Net] Prise en charge de <summary> sous VS2003
    Par tomnie dans le forum Windows Forms
    Réponses: 4
    Dernier message: 16/12/2005, 12h01
  3. Réponses: 2
    Dernier message: 12/05/2005, 10h10
  4. Prise en charge multilingue sur le portal
    Par nic211 dans le forum Oracle
    Réponses: 4
    Dernier message: 07/07/2004, 14h43
  5. [SQL Serveur] prise en charge de l'arabe
    Par lamiae18 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 26/03/2004, 12h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo