0

I have an Arduino sketch with a timer interrupt class and would like to place the TIMER2Services() function in the TimerTwoTest.ino file for easy access. On compile I get a multiple definition of tmb2 error in the .ino TIMER2Services() function. I have tried all the variations I can think of but no luck. Is there a way to do this?

TimerTwoTest.cpp.o: In function `TIMER2Services()':
D:\Arduino157/TimerTwoTest.ino:41: multiple definition of `tmb2'
TimerTwo.cpp.o:C:\Users\...\build8577138580185682113.tmp/TimerTwo.cpp:10: first defined here

collect2.exe:

TimerTwo.h:

class Tmb2
{
  public:
  void initTIMER2(unsigned int Hz, unsigned int ulPeriod);
  void resetTIMER2(unsigned int Hz, unsigned int ulPeriod);
  TIMER2_TYPE getPeriodTIMER2(void);
  void activeTIMER2 (void);
  private:
}tmb2;

TimerTwo.cpp:

extern void TIMER2Services(void);

[this function is line 10 for the error]
void Tmb2::initTIMER2(unsigned int Hz, unsigned int ulPeriod){  //setperiod and enable interrupt
  if (Hz){
    ulPeriod = 1000/Hz;    //if Hz > 0 use frequency microseconds
  }
  Timer2.attachInterrupt(TIMER2Services).setPeriod(ulPeriod).start();
}

TimerTwoTest.ino:

volatile unsigned long burpCount = 0;

//This routine services the interrupt
void TIMER2Services(void){
  burpCount++;
}
  • Which file(s) are you including, and where? Also: it looks like you're using an external library: is this correct? – Anonymous Penguin Aug 21 '14 at 0:50
2

The problem is your definition of tmb2. You're declaring the variable in the header file, and not the C(++) file.

Please try this:

TimerTwo.h

#ifndef __TIMER_TWO_H__
#define __TIMER_TWO_H__

extern void TIMER2Services(void);

class Tmb2
{
    public:
        void initTIMER2(unsigned int Hz, unsigned int ulPeriod);
        void resetTIMER2(unsigned int Hz, unsigned int ulPeriod);
        TIMER2_TYPE getPeriodTIMER2(void);
        void activeTIMER2 (void);
    private:
};

#endif // #ifndef __TIMER_TWO_H__

The #ifndef TIMER stuff saves you getting multiple definitions from header files if they're included more than once. There's other ways to do this, but this is simple and well-known.

TimerTwo.cpp

#include "TimerTwo.h"

void Tmb2::initTIMER2(unsigned int Hz, unsigned int ulPeriod)
{  
    //setperiod and enable interrupt
    if (Hz)
    {
        ulPeriod = 1000/Hz;    //if Hz > 0 use frequency microseconds
    }
    Timer2.attachInterrupt(TIMER2Services).setPeriod(ulPeriod).start();
}

TimerTwoTest.ino

#include "TimerTwo.h"

Tmb2 tmb2;
volatile unsigned long burpCount = 0;

// This routine services the interrupt
void TIMER2Services(void)
{
    burpCount++;
}

void setup()
{
    tmb2.initTIMER2(blah1,blah2);
}

For the sake of neatness, I'd move TIMER2Services into class Tmb2 as a static function... if possible.

| improve this answer | |
  • Shouldn't TimerTwo tmb2; be Tmb2 tmb2;? – Gerben Aug 21 '14 at 9:43
  • Yeah, you're right Gerben. I've just edited it – Kingsley Aug 22 '14 at 20:23
  • I would also re-think the closeness of the class name and instantiation name: Tmb2 looks very much like tmb2, and could lead to errors of mistaken identity. It's certainly a personal 'good practice' for me, but there are no rules for either opinions. – CharlieHanson Jun 5 '15 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.