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– Anonymous Penguin2014年08月21日 00:50:35 +00:00Commented Aug 21, 2014 at 0:50
1 Answer 1
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.
-
Shouldn't
TimerTwo tmb2;
beTmb2 tmb2;
?Gerben– Gerben2014年08月21日 09:43:33 +00:00Commented Aug 21, 2014 at 9:43 -
Yeah, you're right Gerben. I've just edited itKingsley– Kingsley2014年08月22日 20:23:29 +00:00Commented Aug 22, 2014 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– CharlieHanson2015年06月05日 01:32:10 +00:00Commented Jun 5, 2015 at 1:32