c'est quoi la fonction « _GLOBAL__sub_D_xxx »: ?

Bonjour à tous,

mon souci est le suivant :

dans le cadre d'un projet de validation de mon bts je dois programmer une partie d'une maquette qui fonctionnera à base de carte arduino mega 2560 (le projet doit être en langage objet c'est imposé, donc avec des classes ).

J'ai un message d'erreur que je ne comprend pas même après quelques recherches et je commence à être court en délai donc je m'adresse à vous en espérant que je serai débloqué.

Je réalise le code qui me permettra de contrôler les rotations d'un plateau qui sera fixé sur un moteur pas à pas. Donc je contrôle effectivement le plateau quand je code avec les standards d'arduino? Par contre en passant en langage objet j'obtiens quelques erreurs :

MoteurDuPlateau.cpp.o: dans la fonction « _GLOBAL__sub_D_stepDelay »:
/usr/share/arduino/MoteurPlateau.ino:14: définitions multiples de « retourPlateau »
MoteurPlateau.cpp.o:MoteurPlateau.cpp:34: défini pour la première fois ici
/usr/lib/gcc/avr/4.8.2/../../../avr/bin/ld: désactivation de la relâche: il ne pourra pas travailler avec des définitions multiples
MoteurDuPlateau.cpp.o: dans la fonction « _GLOBAL__sub_D_stepDelay »:
/usr/share/arduino/MoteurPlateau.ino:14: définitions multiples de « nbPas »
MoteurPlateau.cpp.o:MoteurPlateau.cpp:34: défini pour la première fois ici
MoteurDuPlateau.cpp.o: dans la fonction « _GLOBAL__sub_D_stepDelay »:
/usr/share/arduino/MoteurPlateau.ino:14: définitions multiples de « stepDelay »
MoteurPlateau.cpp.o:MoteurPlateau.cpp:34: défini pour la première fois ici
collect2: error: ld returned 1 exit status

voici le code de mon .cpp :

#include "MoteurPlateau.h"


// constructeur de la classe
MoteurPlateau::MoteurPlateau()
{
  retourPlateau = 24;
}

//destructeur
MoteurPlateau::~MoteurPlateau()
{

}

//methode privées

//initialisation des broches en mode sortie
void MoteurPlateau::initialiserMoteurPlateau(){ 
  pinMode(dir_A,OUTPUT);
  pinMode(dir_B,OUTPUT);
  pinMode(pwm_A,OUTPUT);
  pinMode(pwm_B,OUTPUT);
}

// méthodes publiques

void MoteurPlateau::retournerPlateau(){
  setNbPas(24);
  // consiste à appeller la méthode actionnerPlateau() avec un pas de 24
  
  actionnerPlateau(nbPas_);
}


void MoteurPlateau::stopperPlateau(){
  digitalWrite(pwm_A,LOW);
  digitalWrite(pwm_B,LOW);
  digitalWrite(dir_A,LOW);
  digitalWrite(dir_B,LOW);
}

void MoteurPlateau::actionnerPlateau(int nbPas) // ACTIONNE LE PLATEAU DANS LE SENS ANTI-HORAIRE
{

  nbPas = 200;
  //setNbPlateau(nbPas_);

  // The function will run for the amount of times called in the method.
  // This is accomplished by a while loop, where it will subtract 1 from the amount, after every run.

  while(nbPas_!=0){

    // Starting position (if repeated, ful step (4))
    // EXPLINATION: in this case, both our power are high.
    // Therefore both coils are activated, with their standard polarities for their magnetic fields.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,HIGH);

    delayMicroseconds(stepDelay);

    //Half step (½)
    // EXPLINATION: In this case, only out b-coil is active, still with it's stand polarity.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,LOW);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay);

    //Full step (1)
    // EXPLINATION: In this case, the b-coil is activated as in previous cases.
    // But the a-coil now has it's direction turned on. So now it's active, but with the reversered polarity.
    // By continuing this pattern (for reference: http://www.8051projects.net/stepper-motor-interfacing/full-step.gif) , you'll get the axis to turn.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay);

    // Half step (1½)
    digitalWrite(pwm_A,LOW);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay);

    // Full step (2)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay);

    // Half step (2½)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,LOW);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay);

    // Full step (3)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,HIGH);

    delayMicroseconds(stepDelay);

    // Half step (3½)
    digitalWrite(pwm_A,LOW);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,HIGH);

    nbPas--; 


  }

}

Comme je l'ai précisé si je m'abstiens de créer des classes et que je code de façon classique donc juste un void setup() et un void loop() ça fonctionne au poil. Donc pour moi même si le code de ma méthode actionnerPlateau n'est pas optimisé il est correct. mais je ne vois pas d'où peuvent venir les messages d'erreur que j'obtiens.

Est-ce que quelqu'un peut m’éclaircir un peu les idées surtout sur la signification du : « _GLOBAL__sub_D_xxx » ?

Merci d'avance pour votre aide.

Le .h c'est bien aussi :slight_smile:

salut,

oui désolé j'ai oublié de l'inclure mais du coup j'ai résolu mon souci. Je poste quand même mes .h et .cpp
le .h :

#ifndef _MOTEURPLATEAU_H
#define _MOTEURPLATEAU_H


#include <Arduino.h> // bibliotheque Arduino
// **** declaration des fonctions et constantes nécéssaires ****


// initialisation des broches
const int dir_A = 2;
const int pwm_A = 3;

const int dir_B = 8;
const int pwm_B = 9;

// initialisation des variables

//  déclaration de ma classe objet MoteurPlateau
class MoteurPlateau
{
public:
  MoteurPlateau();  // constructeur

  ~MoteurPlateau();  //destructeur

  // getter et setter du moteur pour changer et acceder au nombre de pas

  int getNbPas(void) const { 
    return nbPas_; 
  }
  void setNbPas(int nbPas) { 
    nbPas_ = nbPas; 
  }

  //getter et setter pour modifier le temps de pause entre les pas
  int getStepDelay(void) const { 
    return stepDelay_; 
  }
  int setStepDelay(int stepDelay) {
    stepDelay_ = stepDelay; 
  }
  //déclaration des méthodes utilisées pour faire fonctionner le moteur

  void actionnerPlateau(int nbPas_);
  void stopperPlateau();
  void retournerPlateau();


  // Attributs et methodes privées

private:

  // Attributs : 
  int nbPas_; // nombre de pas à effectuer pour la rotation du moteur
  int stepDelay_; // temps de pause entre chaque pas.

  //methodes :
  void initialiserMoteurPlateau();

};


#endif //  # define _PLATEAU_H

et le .cpp :

#include "MoteurPlateau.h"


// constructeur de la classe
MoteurPlateau::MoteurPlateau()
{
  setNbPas(200);
  setStepDelay(500);
  //retourPlateau = 24;
}

//destructeur
MoteurPlateau::~MoteurPlateau()
{

}

//methode privées

//initialisation des broches en mode sortie
void MoteurPlateau::initialiserMoteurPlateau(){ 
  pinMode(dir_A,OUTPUT);
  pinMode(dir_B,OUTPUT);
  pinMode(pwm_A,OUTPUT);
  pinMode(pwm_B,OUTPUT);
}

// méthodes publiques

void MoteurPlateau::retournerPlateau(){
  // On modifie le nombre de pas pour obtenir une rotation de 180°.
  setNbPas(24);
  
  // consiste à appeller la méthode actionnerPlateau() avec un pas de 24  
  actionnerPlateau(nbPas_);
  
  /* On remet le nombre de pas initial pour la rotation normale.
  On pourra par la suite créer une méthode pour controler le nombre
  de pas du moteur à tout instant.
  */
  setNbPas(200);
}


void MoteurPlateau::stopperPlateau(){
  digitalWrite(pwm_A,LOW);
  digitalWrite(pwm_B,LOW);
  digitalWrite(dir_A,LOW);
  digitalWrite(dir_B,LOW);
}

void MoteurPlateau::actionnerPlateau(int nbPas_) // ACTIONNE LE PLATEAU DANS LE SENS ANTI-HORAIRE
{
  
  // The function will run for the amount of times called in the method.
  // This is accomplished by a while loop, where it will subtract 1 from the amount, after every run.

  while(nbPas_!=0){

    // Starting position (if repeated, ful step (4))
    // EXPLINATION: in this case, both our power are high.
    // Therefore both coils are activated, with their standard polarities for their magnetic fields.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,HIGH);

    delayMicroseconds(stepDelay_);

    //Half step (½)
    // EXPLINATION: In this case, only out b-coil is active, still with it's stand polarity.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,LOW);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    //Full step (1)
    // EXPLINATION: In this case, the b-coil is activated as in previous cases.
    // But the a-coil now has it's direction turned on. So now it's active, but with the reversered polarity.
    // By continuing this pattern (for reference: http://www.8051projects.net/stepper-motor-interfacing/full-step.gif) , you'll get the axis to turn.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    // Half step (1½)
    digitalWrite(pwm_A,LOW);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    // Full step (2)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    // Half step (2½)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,LOW);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    // Full step (3)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,HIGH);

    delayMicroseconds(stepDelay_);

    // Half step (3½)
    digitalWrite(pwm_A,LOW);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,HIGH);

    nbPas_--; 


  }

}

J'ai contourné le problème en créant un autre attribut pour ma classe qui le nombre de pas du moteur, et j'ai viré ma variable retourPlateau qui ne sert a rien.

salut,

j'ai un autre problème maintenant, j’essaie de faire un test unitaire de mon code . Il compile et semble s’exécuter mais mon moteur ne tourne pas. Par contre il émet un son qui laisse penser qu'il tourne mais il n'en est rien. Je ne vois pas ce qui cloche.

je poste juste mon test.ino vu que les .h et .cpp sont au dessus

// Includes
#include "MoteurPlateau.h"
#include <Arduino.h>
#include <ArduinoUnit.h>

using namespace std;
//#include <iostream>


//const int nbPas_;
//const int nbPas;

MoteurPlateau moteurPlateau; // instancier l'objet moteurPlateau lié à la classe MoteurPlateau

//test(initialiserMoteurPlateau)
//{
//  moteurPlateau.initialiserMoteurPlateau();
//}

test(actionnerPlateau)
{
  for (int i=0;i<10;i++)
  {
    int pas = moteurPlateau.getNbPas();
    Serial.println(pas);
  moteurPlateau.actionnerPlateau(pas); 
  }
}

//// test du stop
//test(stopperPlateau)
//{
//  moteurPlateau.stopperPlateau();
//  delay(10000);
//}

//}



void setup()
{
  Serial.begin(9600); // Initialise la communication à 9600 bit/s
}

void loop()
{
  Test::run();
  //moteurPlateau.actionnerPlateau();
}

je n'ai pas de messages d'erreur et voici ce qu'affiche le moniteur serie de l'ide :

Test actionnerPlateau passed.
Test summary: 1 passed, 0 failed, and 0 skipped, out of 1 test(s).

quelqu'un a une idée ?

C'est bon j'ai résolu mon souci!
Cela venait du fait que je n'initialisais pas mes broches lors de mes tests. J'ai donc passé ma méthode initialiserMoteurPlateau() de privée à public pour pouvoir l’appeler lors des test.

// test de l'initialisation
test(1initialiserPlateau)
{
  moteurPlateau.initialiserMoteurPlateau(); 
}

// test de la rotation du plateau
test(2actionnerPlateau)
{
  moteurPlateau.setNbPas(200);
  int pas = moteurPlateau.getNbPas();

  for (int i=0;i<200;i++)
  {

    moteurPlateau.actionnerPlateau(pas);
    Serial.println(i);
    delayMicroseconds(1000);
  }

}

Mon moteur tourne.

Par contre j'ai des ratés, c'est-à-dire que parfois au lieu d’effectuer mes 200 pas il n'en effectue qu'un ou deux, difficile à voir, et ça arrive de façon complètement aléatoire.

Est-ce que quelqu'un peut m'expliquer ce qui cause ce phénomène.

Bonjour,
Souvent une des causes de pertes de pas vient d'une vitesse moteur trop importante.
Tu devrais faire un test en réduisant la vitesse.
@+

icare:
Bonjour,
Souvent une des causes de pertes de pas vient d'une vitesse moteur trop importante.
Tu devrais faire un test en réduisant la vitesse.
@+

salut Icare , merci pour ta réponse je vais faire quelques recherches, pour savoir comment gérer la vitesse de mon moteur car je n'y ai pas encore touché.

Par contre le processeur de la carte chauffe énormément, apparemment ça provient de mon code donc je cherche une solution à ce premier problème avant de continuer.

Merci pour ton conseil Icare.

J'ai modifié ma méthode retournerPlateau() et ma vitesse de rotation (stepDelay_), ça à résolu mes problèmes de température. Ma classe plateau est finie, les tests fonctionnent comme je veux.
.h :

#ifndef _MOTEURPLATEAU_H
#define _MOTEURPLATEAU_H


#include <Arduino.h> // bibliotheque Arduino
// **** declaration des fonctions et constantes nécéssaires ****


// initialisation des broches
const int dir_A = 2;
const int pwm_A = 3;

const int dir_B = 8;
const int pwm_B = 9;

// initialisation des variables

//  déclaration de ma classe objet MoteurPlateau
class MoteurPlateau
{
public:
  MoteurPlateau();  // constructeur

  ~MoteurPlateau();  //destructeur

  // getter et setter du moteur pour changer et acceder au nombre de pas

  int getNbPas(void) const { 
    return nbPas_; 
  }
  void setNbPas(int nbPas) { 
    nbPas_ = nbPas; 
  }
 
  
  //getter et setter pour modifier la vitesse de rotation du moteur
  int getStepDelay(void) const { 
    return stepDelay_; 
  }
  int setStepDelay(int stepDelay) {
    stepDelay_ = stepDelay; 
  }
  //déclaration des méthodes utilisées pour faire fonctionner le moteur

  void actionnerPlateau(int nbPas_);
  void stopperPlateau();
  void retournerPlateau(int nbPas_);
  void initialiserMoteurPlateau();

  // Attributs et methodes privées

private:

  // Attributs : 
  int nbPas_; // nombre de pas à effectuer pour la rotation du moteur
  int stepDelay_; // permet de gérer la vitesse du plateau.

  //methodes :

};


#endif //  # define _PLATEAU_H

.cpp :

#include "MoteurPlateau.h"


// constructeur de la classe
MoteurPlateau::MoteurPlateau()
{
  setNbPas(50);
  setStepDelay(5000);
}

//destructeur
MoteurPlateau::~MoteurPlateau()
{

}

//methode privées

//initialisation des broches en mode sortie


// méthodes publiques

//void MoteurPlateau::initialiserMoteurPlateau(){ 
//  pinMode(dir_A,OUTPUT);
//  pinMode(dir_B,OUTPUT);
//  pinMode(pwm_A,OUTPUT);
//  pinMode(pwm_B,OUTPUT);
//}

void MoteurPlateau::actionnerPlateau(int nbPas_) // ACTIONNE LE PLATEAU DANS LE SENS ANTI-HORAIRE
{
  // The function will run for the amount of times called in the method.
  // This is accomplished by a while loop, where it will subtract 1 from the amount, after every run.

  while(nbPas_!=0){

    // Starting position (if repeated, ful step (4))
    // EXPLINATION: in this case, both our power are high.
    // Therefore both coils are activated, with their standard polarities for their magnetic fields.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,HIGH);

    delayMicroseconds(stepDelay_);

    //Half step (½)
    // EXPLINATION: In this case, only out b-coil is active, still with it's stand polarity.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,LOW);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    //Full step (1)
    // EXPLINATION: In this case, the b-coil is activated as in previous cases.
    // But the a-coil now has it's direction turned on. So now it's active, but with the reversered polarity.
    // By continuing this pattern (for reference: http://www.8051projects.net/stepper-motor-interfacing/full-step.gif) , you'll get the axis to turn.
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,HIGH);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    // Half step (1½)
    digitalWrite(pwm_A,LOW);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    // Full step (2)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    // Half step (2½)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,LOW);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,LOW);

    delayMicroseconds(stepDelay_);

    // Full step (3)
    digitalWrite(pwm_A,HIGH);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,HIGH);

    delayMicroseconds(stepDelay_);

    // Half step (3½)
    digitalWrite(pwm_A,LOW);
    digitalWrite(pwm_B,HIGH);
    digitalWrite(dir_A,LOW);
    digitalWrite(dir_B,HIGH);

    nbPas_--; 

//stopperPlateau();
  }

}


void MoteurPlateau::retournerPlateau(int nbPas_)  // PERMET DE RETOURNER LE PLATEAU POUR LA RECUPÉRATION DU VERRE
{
 while(nbPas_!=0){
 
 // Starting position (if repeated, ful step (4))
 digitalWrite(pwm_A,HIGH);
 digitalWrite(pwm_B,HIGH);
 digitalWrite(dir_A,LOW);
 digitalWrite(dir_B,LOW);
 
 delayMicroseconds(stepDelay_);
 
 // Half step (½)
 digitalWrite(pwm_A,LOW);
 digitalWrite(pwm_B,HIGH);
 digitalWrite(dir_A,LOW);
 digitalWrite(dir_B,LOW);
 
 delayMicroseconds(stepDelay_);
 
 // Full step (1)
 digitalWrite(pwm_A,HIGH);
 digitalWrite(pwm_B,HIGH);
 digitalWrite(dir_A,HIGH);
 digitalWrite(dir_B,LOW);
 
 delayMicroseconds(stepDelay_);
 
 // Half step (1½)
 digitalWrite(pwm_A,HIGH);
 digitalWrite(pwm_B,LOW);
 digitalWrite(dir_A,HIGH);
 digitalWrite(dir_B,LOW);
 
 delayMicroseconds(stepDelay_);
 
 // Full step (2)
 digitalWrite(pwm_A,HIGH);
 digitalWrite(pwm_B,HIGH);
 digitalWrite(dir_A,HIGH);
 digitalWrite(dir_B,HIGH);
 
 delayMicroseconds(stepDelay_);
 
 // Half step (2½)
 digitalWrite(pwm_A,LOW);
 digitalWrite(pwm_B,HIGH);
 digitalWrite(dir_A,LOW);
 digitalWrite(dir_B,HIGH);
 
 delayMicroseconds(stepDelay_);
 
 // Full step (3)
 digitalWrite(pwm_A,HIGH);
 digitalWrite(pwm_B,HIGH);
 digitalWrite(dir_A,LOW);
 digitalWrite(dir_B,HIGH);
 
 delayMicroseconds(stepDelay_);
 
 // Half step (3½)
 digitalWrite(pwm_A,HIGH);
 digitalWrite(pwm_B,LOW);
 digitalWrite(dir_A,LOW);
 digitalWrite(dir_B,LOW); 
 
 nbPas_--;
 }
 
 //stopperPlateau();
}


void MoteurPlateau::stopperPlateau(){  // Arreter le plateau
  digitalWrite(pwm_A,LOW);
  digitalWrite(pwm_B,LOW);
  digitalWrite(dir_A,LOW);
  digitalWrite(dir_B,LOW);
}

test.ino :

// Includes
#include "MoteurPlateau.h"
#include <Arduino.h>
#include <ArduinoUnit.h>


MoteurPlateau moteurPlateau; // instancier l'objet moteurPlateau lié à la classe MoteurPlateau


// test de la rotation du plateau
test(1actionnerPlateau)
{
  moteurPlateau.setNbPas(49);
  int pas = moteurPlateau.getNbPas();
  
  for (int i=0;i<1;i++)
  {

    moteurPlateau.actionnerPlateau(pas);
    
    delayMicroseconds(500);
  }

}

// test du stop
test(2stopperPlateau)
{
  moteurPlateau.stopperPlateau();
  
  delay(1000);
}

test(3retournerPlateau)
{
    moteurPlateau.setNbPas(25);
  int retour = moteurPlateau.getNbPas();

  for (int j=0;j<1;j++)
  {

    moteurPlateau.retournerPlateau(retour);

    delayMicroseconds(500);
 
  }
}


// test du stop
test(4stopperPlateau)
{
  moteurPlateau.stopperPlateau();
  delay(2000);
}



void setup()
{
  Serial.begin(9600); // Initialise la communication à 9600 bit/s

  pinMode(dir_A,OUTPUT);
  pinMode(dir_B,OUTPUT);
  pinMode(pwm_A,OUTPUT);
  pinMode(pwm_B,OUTPUT);
}

void loop()
{
  Test::run();
  //moteurPlateau.actionnerPlateau();
}

Maintenant je dois coupler le moteur à un capteur infrarouge de sorte que quand le capteur détecte un objet le plateau arrête de tourner. Mais je vais ouvrir un autre sujet au besoin.

Sujet résolu !!