Aller au contenu


Photo
* * * * * 1 note(s)

Guide linéaire motorisé


  • Veuillez vous connecter pour répondre
172 réponses à ce sujet

#101 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 09 mai 2020 - 10:11

Bonjour, j'ai beaucoup de mal à comprendre le codage du loop . J'ai repris le code du post #94 , j'ai besoin de revoir quelque chose. Pour les petit soucis d'affichage je verrai après. 

 

Ce qui m’interroge vraiment c'est le passage des variables.  Pour m'aider j'ai modifier la fonction float ReglageAffichageDistance   .

 Certe plus compliqué ou plus long à écrire (tant pis si il faut pas le faire, je nettoierai après , c'est juste pour comprendre ) . Au fonctionnement c'est identique .

 

Ma question est es ce que la modif  à du sens parce que je la comprends mieux comme cela ou c'est le hasard qui fait que ça marche encore ?

#include <AccelStepper.h>
AccelStepper stepper (1, 9, 8);
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int PinBoutonInit = A0; //Bouton qui déplacera le chariot vers la buté à 30 cm
const int PinContactButé = A1;// Contact qui stope le chariot à 30 cm
const int PinBoutonReglageDistanceCm = A2;//Bouton de reglage distance en Cm
const int PinBoutonReglageDistanceMm = A3;//Bouton de reglage distance en Mm


float ReglageAffichageDistance (float maDistance) {
 float startValue=maDistance;
  float NouvelleDistance = startValue;

  while (digitalRead(PinBoutonReglageDistanceCm ) == 0) { // J'appuis sur réglage des cm

    NouvelleDistance = NouvelleDistance + 1 ;   // Le compteur s'incrémente de 1 cm
    if (NouvelleDistance > 290) {
  NouvelleDistance = 30;
} 
    attendreMs(500);                            // on attend 500 ms sans utiliser la fonction delay()
    Serial.println(NouvelleDistance);
  }
  
  return NouvelleDistance;       // quand on a fini d'incrémenter on retourne la valeur au reste du programme
}


void attendreMs (unsigned int attente) {
  unsigned long InstantouJappuis = millis();           // Variable qui enregistre le déroulement du temps qui passe depuis l'appuis
  while (millis() - InstantouJappuis <  attente ) { // décompte de 500ms en cours
  }
}



void  AfficherLaDistance  (float Distance) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (  " Butée " );
  lcd.setCursor(7, 0);
  lcd.print (  Distance  );
  lcd.setCursor(13, 0);
  lcd.print (  " cm "   );
}



void  AfficherInitTermine () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" terminée "  );
  Serial.println ("Initialisation terminée " );
}

void  AfficherInitEnCours () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" en cours "  );
  Serial.println (" Initialisation en cours "  );

}
void initMoteur () {
  if (digitalRead(PinBoutonInit) == 0) {
    AfficherInitEnCours ();
    stepper.setSpeed(3900);

    while (digitalRead(PinContactBute) == 1) {
      stepper.runSpeed();
      // on attends la buté
    }
    stepper.stop(); // On remet à 0 les consignes de vitesse ...
    float Distance = 30.0;

    AfficherInitTermine ();
    delay(3000);
    AfficherLaDistance(Distance) ;

  }
}
void setup() {

  Serial.begin(9600);
  pinMode(A0, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A1, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A2, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  stepper.setMaxSpeed(4000);
  
}
void loop() {
 
 static float maDistance = 30; // Variable qui va stocker la distance de consigne
  initMoteur ();  // Repositionne le moteur si jamais on appuis sur le bouton
  maDistance = ReglageAffichageDistance (maDistance); // Stock le résultat de la distance modifiée
  AfficherLaDistance(maDistance);  // on met à jour l'affichage
  
 }


#102 Sandro

Sandro

    Membre chevronné

  • Modérateur
  • PipPipPipPip
  • 1 321 messages
  • Gender:Male

Posté 09 mai 2020 - 10:57

Ce qui m’interroge vraiment c'est le passage des variables.  Pour m'aider j'ai modifier la fonction float ReglageAffichageDistance   .
 Certe plus compliqué ou plus long à écrire (tant pis si il faut pas le faire, je nettoierai après , c'est juste pour comprendre ) . Au fonctionnement c'est identique .
 
Ma question est es ce que la modif  à du sens parce que je la comprends mieux comme cela ou c'est le hasard qui fait que ça marche encore ?

float ReglageAffichageDistance (float maDistance) {
 float startValue=maDistance;
  float NouvelleDistance = startValue;

  while (digitalRead(PinBoutonReglageDistanceCm ) == 0) { // J'appuis sur réglage des cm

    NouvelleDistance = NouvelleDistance + 1 ;   // Le compteur s'incrémente de 1 cm
    if (NouvelleDistance > 290) {
  NouvelleDistance = 30;
} 
    attendreMs(500);                            // on attend 500 ms sans utiliser la fonction delay()
    Serial.println(NouvelleDistance);
  }
  
  return NouvelleDistance;       // quand on a fini d'incrémenter on retourne la valeur au reste du programme
}

void loop() {
  static float maDistance = 30; // Variable qui va stocker la distance de consigne
  initMoteur ();  // Repositionne le moteur si jamais on appuis sur le bouton
  maDistance = ReglageAffichageDistance (maDistance); // Stock le résultat de la distance modifiée
  AfficherLaDistance(maDistance);  // on met à jour l'affichage
}

Ce que tu as fait n'est pas faux, et c'est pas un hasard que ça fonctionne. Par contre, je pense que ça t'induit en erreur, et c'est "dangereux" tant que tu n'as pas un niveau de programmation suffisant pour comprendre exactement ce que tu fais.

En effet, maintenant tu te retrouve avec DEUX variables DISTINCTES qui portent le MÊME NOM (maDistance) mais qui ne sont pas une seule variable (ie chacune a son propre emplacement dans la mémoire, et à priori rien ne force quelles aient la même valeur).

 

 

Je te propose donc un autre code "illustré", qui reflète mieux ce qui se passe (et t'évitera donc des erreurs dans le futur):

Le code de base:

float fois_deux(float a)
{
  float b=2*a;
  return b;
}

void loop()
{
  float mon_nombre=5.0;
  float le_double_de_mon_nombre=fois_deux(mon_nombre);
}

et le code "équivalent" :

float fois_deux(float a)
{
  float a=5.0;  //on ne récupère que la VALEUR passé en argument : la fonction "fois_deux" n'a aucune information sur d'où vient la valeur
  float b=2*a;
  return 10.0;  //on renvoit la VALEUR de b : le return ne se soucie pas d'où vient la valeur, et ne transmet donc aucune information à propos d'où elle venait
}

void loop()
{
  float mon_nombre=5.0;
  fois_deux(5.0); //prends en entrée la valeur 5.0 contenu dans mon_nombre, mais la fonction fois_deux ne sait pas d'où vient cette valeur //renvois 10.0
  float le_double_de_mon_nombre=10.0;  //on reprends la valeur 10.0 renvoyée
}

 

 

Donc pour résumer, dans les fonctions, on ne transmet JAMAIS* de variables, seulement des valeurs (ie des nombres) : à l'intérieur d'une fonction, on ne sait pas de quelle variable venait une valeur, et à l'extérieur d'une fonction on ne sait pas dans quelle variable la valeur était stockée dans le fonction.
 

* : il existe des moyens de partager vraiment une variable, mais c'est une mauvaise pratique dans 95% des cas, donc on n'abordera pas ça tant que tu n'aura pas bien progressé en programation.

 


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#103 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 10 165 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 09 mai 2020 - 04:42

Je dirais même plus : 

Le nom d'un paramètre dans une fonction n'a pas d'impacte tant que tu utilises le même partout là où tu veux l'utiliser. 



ça aussi ça marche : 


 

float ReglageAffichageDistance (float x) {
  
  float NouvelleDistance = x;

  while (digitalRead(PinBoutonReglageDistanceCm ) == 0) { // J'appuis sur réglage des cm

    NouvelleDistance = NouvelleDistance + 1 ;   // Le compteur s'incrémente de 1 cm
    if (NouvelleDistance > 290) {
      NouvelleDistance = 30;
    } 
    attendreMs(500);                            // on attend 500 ms sans utiliser la fonction delay()
    Serial.println(NouvelleDistance);
  }
  
  return NouvelleDistance;       // quand on a fini d'incrémenter on retourne la valeur au reste du programme
}

// et mettre ça dans le loop
//float ReglageAffichageDistance (maDistance);

en réalité tu peux même faire : 

 

float ReglageAffichageDistance (float x) {  
  while (!digitalRead(PinBoutonReglageDistanceCm )) { // J'appuis sur réglage des cm
    x++;   // Le compteur s'incrémente de 1 
    if (x > 290) 
     x = 30;
    attendreMs(500);                            // on attend 500 ms sans utiliser la fonction delay()
    Serial.println(x);
  }  
  return x;       // quand on a fini d'incrémenter on retourne la valeur au reste du programme
}

à toi de voir ce qui est le plus pratique / lisible pour toi =)  ( il y a même des notions plus " courte " pour les if quand tu veux que ça tienne sur une ligne mais c'est pas forcément plus lisible : 
(x > 290 ) ? x = 30; 

mais au moins c'est bien de savoir que ça existe =)


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#104 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 09 mai 2020 - 05:39

Merci à tous les deux pour ces réponses .

 

Rien ne m’empêche de directement l'écrire comme cela la fonction ? ...

 

float ReglageAffichageDistance (float NouvelleDistance) {

#include <AccelStepper.h>
AccelStepper stepper (1, 9, 8);
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
const int PinBoutonInit = A0; //Bouton qui déplacera le chariot vers la buté à 30 cm
const int PinContactBute = A1;// Contact qui stope le chariot à 30 cm
const int PinBoutonReglageDistanceCm = A2;//Bouton de reglage distance en Cm
const int PinBoutonReglageDistanceMm = A3;//Bouton de reglage distance en Mm
 
 
float ReglageAffichageDistance (float NouvelleDistance) {
 
  
 while (digitalRead(PinBoutonReglageDistanceCm ) == 0) { // J'appuis sur réglage des cm
 
    NouvelleDistance = NouvelleDistance + 1 ;   // Le compteur s'incrémente de 1 cm
    if (NouvelleDistance > 290) {
  NouvelleDistance = 30;
} 
    attendreMs(500);                            // on attend 500 ms sans utiliser la fonction delay()
    Serial.println(NouvelleDistance);
  }
  return NouvelleDistance;       // quand on a fini d'incrémenter on retourne la valeur au reste du programme
}
 
 
void attendreMs (unsigned int attente) {
  unsigned long InstantouJappuis = millis();           // Variable qui enregistre le déroulement du temps qui passe depuis l'appuis
  while (millis() - InstantouJappuis <  attente ) { // décompte de 500ms en cours
  }
}
 
 
 
void  AfficherLaDistance  (float Distance) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (  " Butée " );
  lcd.setCursor(7, 0);
  lcd.print (  Distance  );
  lcd.setCursor(13, 0);
  lcd.print (  " cm "   );
}
 
 
 
void  AfficherInitTermine () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" terminée "  );
  Serial.println ("Initialisation terminée " );
}
 
void  AfficherInitEnCours () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" en cours "  );
  Serial.println (" Initialisation en cours "  );
 
}
void initMoteur () {
  if (digitalRead(PinBoutonInit) == 0) {
    AfficherInitEnCours ();
    stepper.setSpeed(3900);
 
    while (digitalRead(PinContactBute) == 1) {
      stepper.runSpeed();
      // on attends la buté
    }
    stepper.stop(); // On remet à 0 les consignes de vitesse ...
    float Distance = 30.0;
 
    AfficherInitTermine ();
    delay(3000);
    AfficherLaDistance(Distance) ;
 
  }
}
void setup() {
 
  Serial.begin(9600);
  pinMode(A0, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A1, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A2, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  stepper.setMaxSpeed(4000);
  lcd.begin(16, 2);
  lcd.print("START PRESS INIT");
}
 
void loop() {
  static float maDistance = 33; // Variable qui va stocker la distance de consigne
  initMoteur ();  // Repositionne le moteur si jamais on appuis sur le bouton
  maDistance = ReglageAffichageDistance (maDistance); // Stock le résultat de la distance modifiée
  AfficherLaDistance(maDistance);  // on met à jour l'affichage
 }


#105 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 09 mai 2020 - 06:05

Si la question juste avant est ok , j'en ai une autre mais en sens inverse .

Toujours avec le code si dessus , On envoi donc la valeur "ma distance" créer dans le loop , dans la fonction

 float ReglageAffichageDistance (float NouvelleDistance)  pour faire mon réglage de distance . Jusque la j'ai compris .

 

Mais ensuite pour afficher la distance , je lis dans le loop  cette écriture : AfficherLaDistance(maDistance);

Cela voudrai dire que la variable maDistance est tous le temps mis à jour dans le loop !! 

Par quel moyen la mise à jour de la variable "maDistance" se fait ???



#106 Sandro

Sandro

    Membre chevronné

  • Modérateur
  • PipPipPipPip
  • 1 321 messages
  • Gender:Male

Posté 09 mai 2020 - 06:44

Message #104 : si j'ai rien raté, pas de problème

 

Message #105 :

la mise à jour de la variable maDistance dans loop est faite par :

maDistance = 

ce que tu mets à droite du égal sera la nouvelle valeur : ça peut être :

- un nombre :

maDistance = 42.1;

- le résultat d'une opération :

maDistance = 2 * maDistance + 3.14;

- le résultat renvoyé par une fonction :

maDistance = ReglageAffichageDistance (30.0);

- le résultat renvoyé par une fonction qui prend l'ancienne valeur en entrée :

maDistance = ReglageAffichageDistance (maDistance);

 


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#107 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 09 mai 2020 - 07:09

Sur le code du message #104 ,  cela voudrai dire que par le biais du loop et de cette ligne:

maDistance = ReglageAffichageDistance (maDistance);" que j'envoie dans ma fonction float ReglageAffichageDistance (float NouvelleDistance) {  , la mise à jour de la variable maDistance entre les deux se fait en permanence dans un sens comme dans un autre ?



#108 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 10 165 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 09 mai 2020 - 07:55

Sur le code du message #104 ,  cela voudrai dire que par le biais du loop et de cette ligne:

" maDistance = ReglageAffichageDistance (maDistance);" que j'envoie dans ma fonction float ReglageAffichageDistance (float NouvelleDistance) {  , la mise à jour de la variable maDistance entre les deux se fait en permanence dans un sens comme dans un autre ?

 

 

Hum ...  non un "= "ça ne se fait que dans un sens. 

Là tu mets dans " maDistance " le résultat de  " ReglageAffichageDistance (maDistance);" 

 

 

Alors certes tu mets en paramètre la variable dans la fonction mais tu aurai pu faire  : 

x = 0 ; 
maDistance = ReglageAffichageDistance (x);

 

En faisant ça tu repartirais toujours de 0 ... 

mais en remplaçant x par madistance, tu remet tout le temps à jour ce qui te sert de point de départ.
Ce qui te permet de repartir avec la bonne première valeur =)


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#109 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 09 mai 2020 - 08:13

Ya un truc que je pige pas dans le loop . Je l'ai recopié si dessous .

 

Ma variable static float maDistance = 33; 

Ensuite par le biais de maDistance = ReglageAffichageDistance (maDistance); j'envoie 33 dans ma fonction float ReglageAffichageDistance (float NouvelleDistance) { qui modifie ma distance en appuyant sur le bouton .

Disons que je la règle à 40 . C'est marqué dans le port série par exemple .

Apres dans se meme loops je demande avec la fonction AfficherLaDistance(maDistance); de m'afficher la distance sur l'écran .

Comment se fait t'il que cela n'affiche pas 33 !? puisque la fonction n'a pas le moyen de savoir que j'ai appuyé !

void loop() {
  static float maDistance = 33; // Variable qui va stocker la distance de consigne
  initMoteur ();  // Repositionne le moteur si jamais on appuis sur le bouton
  maDistance = ReglageAffichageDistance (maDistance); // Stock le résultat de la distance modifiée
  AfficherLaDistance(maDistance);  // on met à jour l'affichage
 }


#110 Sandro

Sandro

    Membre chevronné

  • Modérateur
  • PipPipPipPip
  • 1 321 messages
  • Gender:Male

Posté 09 mai 2020 - 09:07

Tout d'abord, une petite explication sur le signe "=" : il s'agit de l'affectation, c'est-à-dire qu'on prend la valeur de ce qu'il y a a gauche pour le stocker dans la variable à droite.

Il y a quelques langages où le "=" est remplacé par une flèche "<-" de la droite vers la gauche.

Ce qui est important à comprendre, c'est qu'on ÉVALUE la partie de droite, c'est-à-dire qu'on calcule sa valeur (donc l'arduino vas remplacer un calcul ou une fonction par son résultat). On s'en fiche donc de savoir quel était le résultat ou la fonction, seul compte le résultat.

Pour la partie de gauche, c'est nécessairement une variable, dont on vas modifier la valeur.

 

 

Je vais essayer de décomposer la fonction loop en étapes :

le loop de base en numérotant les lignes :

void loop() {
1)  static float maDistance = 33; // Variable qui va stocker la distance de consigne
2)  initMoteur ();  // Repositionne le moteur si jamais on appuis sur le bouton
3)  maDistance = ReglageAffichageDistance (maDistance); // Stock le résultat de la distance modifiée
4)  AfficherLaDistance(maDistance);  // on met à jour l'affichage
}

La version décomposée :

Etape 1:

float maDistance = 33;

signifie qu'on crée une variable appellée maDistance et on lui affecte la valeur 33 (ie on lui donne la valeur 33).

Le fait d'ajouter le mot clef "static" devant la déclaration de la variable signifie qu'on ne la crée que la première fois, qu'ensuite on garde la valeur quelle avait à la fin de la fonction (ici le loop)

Cette étape permet donc de ne pas perdre la valeur en arrivant à la fin du loop

 

Étape 2:

rien à dire, on place le moteur, mais on ne modifie pas maDistance

 

Étape 3:

Par ordre des nécessités :

3a)

maDistance = ...

On veut donner à maDistance (celui de gauche) une nouvelle valeur : pour ça, il faut calculer le résultat du "calcul" de droite.

3b) le calcul de droite est

ReglageAffichageDistance (maDistance)

Il faut donc appeler la fonction ReglageAffichageDistance, avec son argument (ie son entrée), pour obtenir le résultat.

3c) Pour connaitre la VALEUR de son argument, il vaut calculer la VALEUR de maDistance : ça, on sait faire, c'est la VALEUR qui est stoquée dans la variable.

 

Bon, l'arduino (plus précisément le compilateur) est malin, et il sait qu'est-ce qui nécessite quoi pour arriver au résultat, du coup, il fait les choses dans l'ordre qu'il sait faire :

3.1) il ÉVALUE le "calcul" maDistance, pour obtenir sa valeur (33 au premier tour du loop)

3.2) il appelle la fonction ReglageAffichageDistance(33) : il donne a la fonction la VALEUR de l'argument (à ce stade, il a complètement oublié d'où vient cette valeur)

3.3) il récupère le RÉSULTAT de la fonction ReglageAffichageDistance, qui est un NOMBRE (ie une VALEUR), et non une variable. Disons que l'utilisateur a choisi 40, le résultat sera donc 40

3.4) il  MODIFIE la variable maDistance en copiant le RÉSULTAT (ie le nombre 40) dans la variable maDistance. maDistance vaut donc maintenant 40, et plus 33 (nb : pendant qu'on était encore en train d'exécuter la fonction, la valeur de maDistance n'avait pas encore changé)

 

4)

4.1) on évalue l'argument maDistance, qui vaut maintenant 40

4.2) on appelle la fonction AfficherLaDistance avec l'argument 40 :

AfficherLaDistance(40)

donc on affiche Butée : 40 cm

 

 

 

Est-ce que c'est plus clair comme ça?
 

 

 


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#111 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 10 mai 2020 - 08:55

Merci , j'abuse de votre patience à tous les deux et cela m’embête .

Je vais aller au bout du sujet que je pense avoir compris avec cette citation : 

 

 

 

3.4) il  MODIFIE la variable maDistance en copiant le RÉSULTAT (ie le nombre 40) dans la variable maDistance. 

Je pense que le lien se fait avec le return qui'il y a dans la fonction float ReglageAffichageDistance (float NouvelleDistance) { .



#112 Sandro

Sandro

    Membre chevronné

  • Modérateur
  • PipPipPipPip
  • 1 321 messages
  • Gender:Male

Posté 10 mai 2020 - 09:19

Oui et non.

Le return permet de générer le RÉSULTAT à l'étape 3.3 (si tu n'as pas de return dans ta fonction, alors elle ne renvoi rien (void)).

A l'étape 3.4, c'est ensuite le RÉSULTAT (ie une valeur, c'est à dire un simple nombre), qui est placé dans ta variable maDistance pour la modifier.

 

Pour reprendre 3.3 et 3.4 :

3.3) ReglageAffichageDistance(33)   donne 40
3.4) maDistance est modifiée et prend la valeur 40

On aurait pu remplacer le code par

maDistance=2*20;

et on aurait eut les mêmes étapes :

3.3) 2*20 donne 40
3.4) maDistance est modifiée et prend la valeur 40

Une fonction, c'est rien d'autre qu'un gros calcul! (d'ailleurs un certain de nombre de calculs plus complexes, comme le cosinus, le sinus, la valeur absolue, ... sont des fonctions)

 

 


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#113 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 10 mai 2020 - 12:35

Merci Sandro pour cette nouvelle explication . J'ai enfin compris .

Je vais reprendre le code ci dessous et le modifier pour que quand je tienne appuyé sur le bouton des réglages des centimètres , je vois le défilement sur l'écran . Ce qui n' est pas le cas avec se code . Vu avec Mike au post # 100 .

D'ailleurs je viens de m'apercevoir qu' avec ce code l'initialisation ne marche pas  .

30 devrai s'afficher et ce n'est plus le cas . 

Ouille  sa complique .

#include <AccelStepper.h>
AccelStepper stepper (1, 9, 8);
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
const int PinBoutonInit = A0; //Bouton qui déplacera le chariot vers la buté à 30 cm
const int PinContactBute = A1;// Contact qui stope le chariot à 30 cm
const int PinBoutonReglageDistanceCm = A2;//Bouton de reglage distance en Cm
const int PinBoutonReglageDistanceMm = A3;//Bouton de reglage distance en Mm
 
 
float ReglageAffichageDistance (float NouvelleDistance) {
 
  
 while (digitalRead(PinBoutonReglageDistanceCm ) == 0) { // J'appuis sur réglage des cm
 
    NouvelleDistance = NouvelleDistance + 1 ;   // Le compteur s'incrémente de 1 cm
    if (NouvelleDistance > 290) {
  NouvelleDistance = 30;
} 
    attendreMs(500);                            // on attend 500 ms sans utiliser la fonction delay()
    Serial.println(NouvelleDistance);
  }
  return NouvelleDistance;       // quand on a fini d'incrémenter on retourne la valeur au reste du programme
}
 
 
void attendreMs (unsigned int attente) {
  unsigned long InstantouJappuis = millis();           // Variable qui enregistre le déroulement du temps qui passe depuis l'appuis
  while (millis() - InstantouJappuis <  attente ) { // décompte de 500ms en cours
  }
}
 
 
 
void  AfficherLaDistance  (float Distance) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (  " Butée " );
  lcd.setCursor(7, 0);
  lcd.print (  Distance  );
  lcd.setCursor(13, 0);
  lcd.print (  " cm "   );
}
 
 
 
void  AfficherInitTermine () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" terminée "  );
  Serial.println ("Initialisation terminée " );
}
 
void  AfficherInitEnCours () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" en cours "  );
  Serial.println (" Initialisation en cours "  );
 
}
void initMoteur () {
  if (digitalRead(PinBoutonInit) == 0) {
    AfficherInitEnCours ();
    stepper.setSpeed(3900);
 
    while (digitalRead(PinContactBute) == 1) {
      stepper.runSpeed();
      // on attends la buté
    }
    stepper.stop(); // On remet à 0 les consignes de vitesse ...
    float Distance = 30.0;
 
    AfficherInitTermine ();
    delay(3000);
    AfficherLaDistance(Distance) ;
 
  }
}
void setup() {
 
  Serial.begin(9600);
  pinMode(A0, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A1, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A2, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  stepper.setMaxSpeed(4000);
  lcd.begin(16, 2);
  lcd.print("START PRESS INIT");
}
 
void loop() {
  static float maDistance = 33; // Variable qui va stocker la distance de consigne
  initMoteur ();  // Repositionne le moteur si jamais on appuis sur le bouton
  maDistance = ReglageAffichageDistance (maDistance); // Stock le résultat de la distance modifiée
  AfficherLaDistance(maDistance);  // on met à jour l'affichage
 }


#114 Sandro

Sandro

    Membre chevronné

  • Modérateur
  • PipPipPipPip
  • 1 321 messages
  • Gender:Male

Posté 10 mai 2020 - 12:47

Est-ce que ça affiche 33 à la place?


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#115 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 10 mai 2020 - 01:28

Oui 33 ou une autre valeur si je l'ai modifié par la fonction réglage 



#116 Sandro

Sandro

    Membre chevronné

  • Modérateur
  • PipPipPipPip
  • 1 321 messages
  • Gender:Male

Posté 10 mai 2020 - 02:59

La raison est que pour l'instant, initMoteur ne modifie pas maDistance.

Du coup, tu appelles ReglageAffichageDistance avec maDistance qui n'a pas bougé, même si tu as appuyé sur le bouton d'initialisation.

Hors, si tu ne fais rien dans la fonction ReglageAffichageDistance (ie pas de bouton appuyé), alors la fonction termine presque instantanément, et dessuite après on affiche maDistance. Du coup, tu n'as pas le temps de voir apparaitre la valeur 30 de l'initialisation.

 

 

Je vois plusieurs solutions, selon le déroulement du loop que tu souhaites avoir :

A) Déroulement A :

1) tu fais l'initialisation en forçant d'attendre que tu ais appuyé sur le bouton d'initialisation

2) tu fais le réglage

3) tu valide le réglage

4) le moteur bouge

 

dans ce cas, il y a 2 modifications:

- la fonction initMoteur est bloquante (ie elle ne termine pas avant que tu ais vraiment fait une initialisation)

- la fonction ReglageAffichageDistance ne termine pas tant que tu n'as pas appuyé sur le bouton de validation (et qu'elle n'affiche rien avant que tu n'ai appuyé sur un bouton de réglage)

 

B) Déroulement B:

1) tu fais l'initialisation si tu veux

2) tu fais le réglage si tu veux

3) tu le valide si tu veux

4) le moteur bouge (si la position souhaitée a changée)

 

dans ce cas, il faut modifier la fonction initMoteur, de manière à ce qu'elle prenne en entrée l'ancienne valeur de maDistance et renvoie soit l'ancienne valeur si tu n'as pas appuyé sur le bouton d'initialisation, soit la nouvelle valeur si tu as appuyé sur le bouton d'initialisation.

 

 

NB : dans le cas du déroulement B, tu peux tout faire dans le désordre : tu peux par exemple initialiser 2 fois, puis régler une fois (sans valider), puis initialiser à nouveau, puis régler et valider. Dans le cas A, tu fais tout dans l'ordre : tu commence par initialiser, ensuite tu es obliger de régler (tu ne peux pas initialiser une seconde fois), puis tu valide et le moteur bouge. Ce n'est qu'après avoir bougé que tu pourra (et devra) initialiser à nouveau

 

NB : si tu souhaites un autre fonctionnement, c'est possible, il faut juste expliquer précisément lequel


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#117 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 10 165 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 10 mai 2020 - 06:18

Sandro répond plus vite que moi :P 

Je souhaitais que tu modifie déjà ce premier point et que tu te rende compte du problème discuter un peu de la chose ^^ 
Et comme l'a expliqué sandro il y a plusieurs façon de faire =) 

 

Je recommande la façon qui prend modèle sur ce qui a été fait avec la fonction  " ReglageAffichageDistance"

C'est une structure de fonction qui va pouvoir te servir pour pas mal de chose =) surtout si tu veux pouvoir ajuster les chiffres après la virgule après ;) 

Un autre façon de faire c'est de transformer la fonction initMoteur() pour qu'elle retourne 0 ou 1 en fonction de si elle a initialisé le moteur ou pas =) . Et dans ton loop tu remet ta distance à 30 si la fonction initMoteur te retourne 1 =) 

Mais justement c'est en testant et en te posant les bonnes questions que tu vas progresser ;)

 

Et il est important de bien tout tester au fur et à mesure =)


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#118 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 11 mai 2020 - 07:33

Bonsoir , 

J'ai vraiment besoin d'initialiser entre chaque prise de mesure . J'ai lu et relu et rerelu pour chercher une solution . Alors , pour faire simple j'ai pris vos conseils à tous les deux et j'ai modifier le code avec un peu de chacun  . 

Comme il est ci dessous , ce code marche bien . Je peux initialiser et régler mes distances à tout moment . J'ai modifié un peu  le loop ,   l'initialisation et la fonction réglage distance () .

J'arrive à tous lire sur l'écran et dans le Serial.println  . Bien sur il me faut votre avis parce que je me perd trop souvent à force de  relire  vos explications .

Si tout est ok on feras les millimètres .

// essais reglage  maDistance tout ok
#include <AccelStepper.h>
AccelStepper stepper (1, 9, 8);
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int PinBoutonInit = A0; //Bouton qui déplacera le chariot vers la buté à 30 cm
const int PinContactBute = A1;// Contact qui stope le chariot à 30 cm
const int PinBoutonReglageDistanceCm = A2;//Bouton de reglage distance en Cm
const int PinBoutonReglageDistanceMm = A3;//Bouton de reglage distance en Mm


float  ReglageAffichageDistance ( float  NouvelleDistance  ) {


  while (digitalRead(PinBoutonReglageDistanceCm ) == 0) { // J'appuis sur réglage des cm

    NouvelleDistance = NouvelleDistance + 1 ;   // Le compteur s'incrémente de 1 cm
    if (NouvelleDistance > 290) {
      NouvelleDistance = 30;
    }
    attendreMs(500);                            // on attend 500 ms sans utiliser la fonction delay()
    Serial.println(NouvelleDistance);
    AfficherLaDistance(NouvelleDistance);
  }
  return NouvelleDistance;       // quand on a fini d'incrémenter on retourne la valeur au reste du programme
}


void attendreMs (unsigned int attente) {
  unsigned long InstantouJappuis = millis();           // Variable qui enregistre le déroulement du temps qui passe depuis l'appuis
  while (millis() - InstantouJappuis <  attente ) { // décompte de 500ms en cours
  }
}



void  AfficherLaDistance  (float Distance) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (  " Butée " );
  lcd.setCursor(7, 0);
  lcd.print (  Distance  );
  lcd.setCursor(13, 0);
  lcd.print (  " cm "   );
}



void  AfficherInitTermine () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" terminée "  );
  Serial.println ("Initialisation terminée " );
}

void  AfficherInitEnCours () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" en cours "  );
  Serial.println (" Initialisation en cours "  );

}
float initMoteur (float InitDistance ) {


  if (digitalRead(PinBoutonInit) == 0) {
    AfficherInitEnCours ();
    stepper.setSpeed(3900);

    while (digitalRead(PinContactBute) == 1) {
      stepper.runSpeed();
      // on attends la buté
    }
    stepper.stop(); // On remet à 0 les consignes de vitesse ...


    InitDistance  = 30.0;

    Serial.println (" D "  );
    Serial.println (InitDistance);

    AfficherInitTermine ();
    delay(3000);
    AfficherLaDistance(InitDistance) ;
  }
  return InitDistance;   // quand on a fini d'initialisé on retourne la valeur au reste du programme
}

void setup() {

  Serial.begin(9600);
  pinMode(A0, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A1, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A2, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  stepper.setMaxSpeed(4000);
  lcd.begin(16, 2);
  lcd.print("START PRESS INIT");
}

void loop() {

  static float maDistance = 29; // Variable qui va stocker la distance de consigne
  maDistance = initMoteur (maDistance);  // Permet d'initialisé ma distance sur 30 cm
  maDistance = ReglageAffichageDistance ( maDistance); // réglage de la distance de 30 à 290 cm
}


#119 Sandro

Sandro

    Membre chevronné

  • Modérateur
  • PipPipPipPip
  • 1 321 messages
  • Gender:Male

Posté 11 mai 2020 - 07:52

A première lecture, j'ai pas vu de problème.

Donc si tu dis que tu as testé et que ça marche, alors je pense que tu peux passer à la suite.

 

Pour les mm, je pense que le plus simple est de faire une seconde fonction assez semblable à ReglageAffichageDistance. Si tu pars sur cette piste, tu peux par exemple renommer ReglageAffichageDistance en ReglageAffichageDistanceCm et créer une fonction ReglageAffichageDistanceMm.


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#120 cook

cook

    Membre

  • Membres
  • 120 messages

Posté 11 mai 2020 - 09:45

A un moment donné dans un des messages , il y a un début de solution pour faire les Mm en rapport avec le travail que vous m'avez fait faire . On en a parlé il me semble , mais je sais plus ou  . Je vais recherché  Bonne soirée 






0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users