Bibliothèque dans une bibliothèque...

Salut à tous !
Je dois utiliser la librairie MPU6050 dans mon programme, mais je trouve leur code long, avec plein d’option ne me servant pas, et un peu bordélique … Du coup, j’ai eu l’idée de refaire une bibliothèque en incluant wire.h, i2cdev.h, mpu6050.h, pour résumer tout le code à mpu.setup() dans void setup() et mpu.compute() dans void loop()… Sauf qu’une fois fais, au moment de compiler, toute les fonctions de la bibliothèque sont sujette à un message d’erreur : multiple definition of “la fonction”, ou, first defined here

.cpp

#include "Arduino.h"
#include <Wire.h>
#include <I2Cdev.h>
#include "GY88.h"



GY88 * GY88::pointeur = NULL;

GY88::GY88()
{
}

void GY88::ISR()
{
  GY88::pointeur->dmpDataReady();
}

void GY88::dmpDataReady() {
    mpuInterrupt = true;

}

void GY88::initialize()
{
    Wire.begin();
    Serial.begin(9600);

    GY88::pointeur = this;
    
    // initialize device
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();
    
    // verify connection
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

    Serial.println(F("\nSend any character to begin DMP programming and demo: "));
    while (Serial.available() && Serial.read()); // empty buffer
    while (!Serial.available());                 // wait for data
    while (Serial.available() && Serial.read()); // empty buffer again
    
    // load and configure the DMP
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

    // supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(166);
    mpu.setYGyroOffset(-79);
    mpu.setZGyroOffset(35);
    mpu.setZAccelOffset(1590);
    
    // make sure it worked (returns 0 if so)
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready

        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, ISR, RISING);
        mpuIntStatus = mpu.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }

    // configure LED for output
    pinMode(LED_PIN, OUTPUT);
  
}

void GY88::compute()
{
  if (!dmpReady) return;

    // wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize) 
    {
      
    }
    

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) 
    {
        // reset so we can continue cleanly
        mpu.resetFIFO();
         Serial.println(F("FIFO overflow!"));

    }

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    else if (mpuIntStatus & 0x02) 
    {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        
        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

        // display Euler angles in degrees
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
       
        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
    }

    
    
    x++;
}

.h

#ifndef GY88_h
#define GY88_h

#include "Arduino.h"
#include <Wire.h>
#include <I2Cdev.h>
#include "MPU6050_6Axis_MotionApps20.h"

class GY88
{
  public:

    GY88();
    void initialize();
    void compute();

    #define LED_PIN 6
    float euler[3];
    float ypr[3];
 

  private:

    MPU6050 mpu;
    bool blinkState = false;
    bool dmpReady = false;
    uint8_t mpuIntStatus;
    uint8_t devStatus;  
    uint16_t packetSize;
    uint16_t fifoCount;
    uint8_t fifoBuffer[64];

    Quaternion q;
    VectorInt16 aa;
    VectorInt16 aaReal;
    VectorInt16 aaWorld; 
    VectorFloat gravity; 

    int x = 0;

    volatile bool mpuInterrupt = false;
    static GY88 *pointeur;
    static void ISR();

    void dmpDataReady();
};

#endif

La copie compléte des messages d'erreurs aurait été utile.

Je ne sais pas pas si cela provient de ce que je vais évoquer mais il y a une habitude dans Wiring/Arduino de prédéclaration d'objet dans le fichier d'entête de bibliothèque qui peut semer le désordre --> a confirmer.

wire.h n'est pas une bibliothèque -> c'est un fichier d'entête. wire n'est pas une classe

La classe qui gère l'I2C est la classe TwoWire qui est enregistrée dans un fichier nommé wire.cpp

A la fin du fichier d'entête wire.h il y a une instanciation d'un objet wire.

extern TwoWire Wire;

Donc wire est un objet.

Je n'ai pas la réponse mais est-ce que cela peut poser problème si le fichier wire.h est inclus plusieurs fois ? Peut-il y avoir tentative de déclarer plusieurs objets wire ? Normalement il me semble que non à cause de la protection

#ifndef TwoWire_h
#define TwoWire_h
// code
#endif

mais je pose la question.

Nan pas de problème de ce côté là, je viens de tester ... Les erreurs :

Arduino : 1.6.8 (Windows 10), Carte : "Arduino/Genuino MKR1000"

sketch\GY88.cpp.o: In function `MPU6050::dmpInitialize()':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:325: multiple definition of `MPU6050::dmpInitialize()'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:325: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpPacketAvailable()':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:546: multiple definition of `MPU6050::dmpPacketAvailable()'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:546: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetAccel(long*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:575: multiple definition of `MPU6050::dmpGetAccel(long*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:575: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetAccel(short*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:583: multiple definition of `MPU6050::dmpGetAccel(short*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:583: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:591: multiple definition of `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:591: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetQuaternion(long*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:599: multiple definition of `MPU6050::dmpGetQuaternion(long*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:599: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetQuaternion(short*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:608: multiple definition of `MPU6050::dmpGetQuaternion(short*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:608: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:615: multiple definition of `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:615: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetGyro(long*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:632: multiple definition of `MPU6050::dmpGetGyro(long*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:632: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetGyro(short*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:640: multiple definition of `MPU6050::dmpGetGyro(short*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:640: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetGyro(VectorInt16*, unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:648: multiple definition of `MPU6050::dmpGetGyro(VectorInt16*, unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:648: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:656: multiple definition of `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:656: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:664: multiple definition of `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:664: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:676: multiple definition of `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:676: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetEuler(float*, Quaternion*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:687: multiple definition of `MPU6050::dmpGetEuler(float*, Quaternion*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:687: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:693: multiple definition of `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:693: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpProcessFIFOPacket(unsigned char const*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:715: multiple definition of `MPU6050::dmpProcessFIFOPacket(unsigned char const*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:715: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:716: multiple definition of `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:716: first defined here

sketch\GY88.cpp.o: In function `MPU6050::dmpGetFIFOPacketSize()':

C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:742: multiple definition of `MPU6050::dmpGetFIFOPacketSize()'

sketch\DroneV1.2.ino.cpp.o:C:\Users\quent\OneDrive\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:742: first defined here

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Arduino/Genuino MKR1000.

Ce rapport pourrait être plus détaillé avec
l'option "Afficher les résultats détaillés de la compilation"
activée dans Fichier -> Préférences.