Multiple definition error

Hi everyone. Lately I started working on a library to make multiple servos work using the known PCA9685 pwm driver. My sketch includes 2 .cpp/ino.cpp files and a .h file. It looks like this:

servos.h

#ifndef _SERVOS_
#define _SERVOS_


#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();        <-- I think the error lies in this line


//rest of the code



#endif

EXAMPLE.ino.cpp:

#include "servos.h"


void setup() {  //my setup code    }
   


void loop() {  //my loop code   }

EXAMPLE.cpp:

#include "servos.h"


     //code and functions here as usual

I did not include the code itself since it does not mention the pwm function at all. The error seems to only be related to writing #include “servos.h” in both of my .cpp files (Meaning that the error doesn’t show up if I only include the header in one .cpp file). After experimenting and reading other posts I I’m pretty sure the error is in the header file and lies in the line:
“Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();”. Here is the error:

Arduino:1.8.9 (Windows 10), board:"Arduino/Genuino Uno"

sketch\EXAMPLE.cpp.o (symbol from plugin): In function `pwm':

(.text+0x0): multiple definition of `pwm'

sketch\EXAMPLE.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

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

Hopefully someone can help me :smiley:

Your "EXAMPLE.cpp" and "EXAMPLE.ino.cpp" are both including 'servos.h' and in 'servos.h' you create an instance of the Adafruit_PWMServoDriver named 'pwm'. That means that 'pwm' is created twice.

You should move the creation to ONE of the .cpp files in your library and put this in your 'servos.h':

extern Adafruit_PWMServoDriver pwm;

The .cpp files that include 'servos.h' will all have access to 'pwm' but it will be declared in only one place.

Isn't

#ifndef _SERVOS_
#define _SERVOS_

Supposed to prevent this problem ?

guix:
Isn't

#ifndef _SERVOS_

#define SERVOS




Supposed to prevent this problem ?

No. That only works on a per-compilation unit basis.

Variable DEFINITIONS belong in a .cpp file.

extern DECLARATIONS go in the .h file.

johnwasser:
Your "EXAMPLE.cpp" and "EXAMPLE.ino.cpp" are both including 'servos.h' and in 'servos.h' you create an instance of the Adafruit_PWMServoDriver named 'pwm'. That means that 'pwm' is created twice.

You should move the creation to ONE of the .cpp files in your library and put this in your 'servos.h':

extern Adafruit_PWMServoDriver pwm;

The .cpp files that include 'servos.h' will all have access to 'pwm' but it will be declared in only one place.

A bit lost here. Moving the entire creation in one file would just be impossible (each .cpp controls a servo and since I can have a huge amount of servos acting at once it would just make it too complex and long). Then it wouldn't solve my problem of multiple "include" actions in different files.
For now I put 'extern Adafruit_PWMServoDriver pwm;' in the .h file, but then the other files don't know what I'm talking about when I use the pwm function. What can I do to make the library avaiable in all tabs without having a 'multiple definition' error?

IcoJeBeje:
Moving the entire creation in one file would just be impossible

Go back and read @johnwasser’s recommendation, it says nothing of the kind.

Put the extern declaration in servos.h and remove the definition from there. Put the definition in one (and only one) of the .cpp files.

If you don’t know the difference, see: Difference between Definition and Declaration - GeeksforGeeks

gfvalvo:
Go back and read @johnwasser's recommendation, it says nothing of the kind.

Put the extern declaration in servos.h and remove the definition from there. Put the definition in one (and only one) of the .cpp files.

If you don't know the difference, see: Difference between Definition and Declaration - GeeksforGeeks

I got it now. It works. Thank you! :smiley: