Multiple definition of __vector11

Hello,

i have a little problem understanding when the compilier is loading which piece of code:

i have written a class, which shall controll some stepper motor drivers in the end. For one step the Pin has to be turned HIGH and LOW again and to set the right frequenzy my idea was to use an ISR witch changes the state of a toggle variable. Every instance takes the same global variable and just reads and compares it to something else. Everything works fine, if I put the constructor of the function into the *.h file, but if I do it in the *.cpp file I get the following error:

sketch\interruptToggle.cpp.o (symbol from plugin): In function __vector_11': (.text+0x0): multiple definition of __vector_11'

sketch\Test.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

exit status 1
Fehler beim Kompilieren für das Board Arduino Nano.

Here is the code of the .h file:

#ifndef INTERUPTTOGGLE_H
#define INTERUPTTOGGLE_H
#include <arduino.h>

static bool toggle;

class InterruptToggle{
  
  private:
    void init(){
      TCCR1A = 0;
      TCCR1B = 0;
      TCNT1 = 0;
      OCR1A = 200;
      TCCR1B |= (1<<CS11);
      TIMSK1 |= (1<<OCIE1A);
    }

  public:
    void foo();
    
};

ISR(TIMER1_COMPA_vect){
  TCNT1 = 0;
  toggle ^= 1;
}

#endif

and thats the *.cpp file:

#include "interruptToggle.h"

void InterruptToggle::foo(){
  //"DO Something";
}

the main scetch is empty exept the #include lib.
of course init() has to be called once :slight_smile:

Could someone be so kind to explain, why its working if foo() is fully defined in the .h file (without .cpp at all)

Greetings

move this part of the code

ISR(TIMER1_COMPA_vect){
  TCNT1 = 0;
  toggle ^= 1;
}

in the cpp and check again. The reason your compiler complains is that you have twice the include for the .h and so you defined the ISR twice

this should get rid of the warnings:

interruptToggle.h

#ifndef INTERUPTTOGGLE_H
#define INTERUPTTOGGLE_H
#include <arduino.h>

class InterruptToggle {

  private:
    void init() {
      TCCR1A = 0;
      TCCR1B = 0;
      TCNT1 = 0;
      OCR1A = 200;
      TCCR1B |= (1 << CS11);
      TIMSK1 |= (1 << OCIE1A);
    }

  public:
    void foo();
};
#endif

interruptToggle.cpp

#include "interruptToggle.h"
static bool toggle;

void InterruptToggle::foo(){
  //"DO Something";
}

ISR(TIMER1_COMPA_vect){
  TCNT1 = 0;
  toggle ^= 1;
}

sketch.ino

#include "interruptToggle.h"
void setup() {}
void loop() {}

PS: if init() is private, how are you going to call it ?

Thanks a lot, thats working. Its crazy I didn't think of that solution :crazy_face:

The rest is going to look like this:

#include "interruptToggle.h"

void InterruptToggle::foo(){
  //"DO Something";
}

void InterruptToggle::setTimer(){
  InterruptToggle::init();
}
void InterruptToggle::pinout(byte enPin, byte dirPin, byte stepPin){
  this->_EnPin = enPin;
  this->_DirPin = dirPin;
  this->_StepPin = stepPin;

  pinMode(_EnPin, OUTPUT);
  pinMode(_DirPin, OUTPUT);
  pinMode(_StepPin, OUTPUT);
    
}

ISR(TIMER1_COMPA_vect){
  TCNT1 = 0;
  toggle ^= 1;
}
#include "interruptToggle.h"

InterruptToggle myMotor1;
InterruptToggle myMotor2;

void setup() {
  // put your setup code here, to run once:
myMotor1.setTimer(); //called once and works for all motors after that
myMotor1.pinout(2,3,4);
myMotor2.pinout(5,6,7);
}

void loop() {
myMotor1.foo();

}

I'm still learning , how to implement different thinks correctly and I'm quite shure, that there are smarter solutions but one step after another.

given you have only 1 timer you setup, I'm not too sure what's the value added of creating a class...

your two instances

InterruptToggle myMotor1;
InterruptToggle myMotor2;

will share the ISR and foo()

So, for a deeper understanding, every time I include the headerfile it is executed? I thought that this would be avoided with the whole #ifndef stuff.

not 'executed' but inserted in place, and with your #ifndef stuff, will get compiled if it's not in that file yet. The #ifndef stuff is to prevent inserting something twice in the same file

You are right, the class will include some step calculations and maybe its going to check the endstops as well, but its only a small part of a bigger project and I didn't want to put all of the code in one file so it stays clearly arranged.

Maybe there is a different kind of structure the pros use, maybe I just wanted to use a class to get used to that concept :wink: Still learning a lot

May be best to keep the timer outside the class and when you get a call to your ISR, you go through the instance list and call a specific function

Ok, so if I #include my .h file in the main scope it includes itself via its .cpp file again. I really have to look up, how the compiler is working exactly, at the moment its a blackbox with some keyholes to look through throwing out cryptical information if somethings going wrong (ok, not that cryptical)

Tryed to avoid that, than I would have to call the method for turning with the toggle variable as an argument for each motor, thats how I did in before and I didn't like it, because outside of the class the ISR is not needed

each file is compiled separately. So each file needs to know what you use in there that might be defined elsewhere. That's where you usually use the .h for, to declare those elements so that the compiler knows what type they are. You basically tell the compiler for example "trust me, there is a class called InterruptToggle that will exist at some point, and here is what you need to know about it")

Once all the files are compiled, the linker puts everything together and resolves the missing links between the declaration and the definition before generating the final file.

So you can declare things as many times as you want but they need to be defined (see that as memory allocated if that helps) only once.

seems you'll be disappointed by your new idea... there will be only 1 ISR shared by all your instances and there is one timer... so as I said before, I don't know what good it does to you.

Thanks for that basic explanation of the compiler :+1:

And you are absolutly right, it does nothing good to me. I could make the init() function public, add some arguments and may try to change the frequenzy for different motors "on the fly" (none of them will run simultaniously).

I just wanted to keep the main scetch as short as possible and in my head the ISR belongs to the motors, so I put it there :upside_down_face:

the question you need to ask yourself, is "what is the timer used for" as there will be only ONE function (ISR) attached to the timer. You could embed the timer in your class (only configure it once though) and you could through constructor and destructor maintain a list of instances of your class in a class variable array (fixed length will be easier) and when the ISR is triggered, it can look at all the instances and do something with them.

This way you could "hide" in your class all the behavior

Ok, I have to think about that, at the moment the only thing I had in my mind was, that the timer is changing toggle and toggle is the thing the instances need to know about. Something like this:

    bool cutLength(unsigned int &step_count, bool Direction){ //Berechnung und Ausführen der benötigten Umdrehungen
      
      static bool lastToggle;  //Diese Variable wird mit dem aktuellen Zustand der Interrupt Service Routine verglichen und dient dem getakteten Ansteuern der Schritte
    
      digitalWrite(Enable, HIGH);                          
      digitalWrite(Dir, Direction);                         
      
      if(step_count && (lastToggle != toggle)){            
          
          lastToggle = toggle;
          step_count--;
          digitalWrite(Step, toggle);                                  
          return 1;                                          
      }
    
      if(!step_count){
        return 0;                                          
      }
    }

The Problem is, that I started coding that stuff but there had been a lot of sticks and stones combining different functionalites (each of them working by their own, but putting them together can be a pain in the ass). So now I learned a lot about classes and referenzing things and I think that now I'm at a point, where I have to rethink my whole concept, that I made up with less tools in my personal toolbox.

But for today I'm feeling saturated, so I think I will call it a day and continou tomorrow.

PS: Step is _StepPin, I copyed this part out of a different scetch

Thanks for your help! I really appreciate it :+1:

wise decision :wink: