"Previoius definition of 'class TimerOne'" and creating PWM with Timer1

Hello,

I am currently trying to experiment with TimerOne a bit: Arduino Playground - HomePage

I am using the Eleego UNO R3 for it and sloeber Eclipse IDE. I've downloaded the timer1.zip and stored the TimerOne.h and TimerOne.cpp in E:\ard-eclipse\sloeber\arduinoPlugin\libraries\timer_one\version1. Then I've created a new sketch and did "add a library to the selected project". I chose "timer_one".

After I clicked "Upload Sketch" I got following errors:

Description: 
make: *** [sloeber.ino.cpp.o] Error 1
previous definition of 'class TimerOne'
recipe for target 'sloeber.ino.cpp.o' failed
redefinition of 'class TimerOne'

Resource Qualified Name:
/pwm_timer1
/pwm_timer1/libraries/timer_one/TimerOne.h
/pwm_timer1/Release/subdir.mk
/pwm_timer1/libraries/timer_one/TimerOne.h

What have I done wrong here? I do not have anything doubled or so. Why would that be a redefine?

My code pwm_timer1.ino:

#include "Arduino.h"

#include "TimerOne.h"

unsigned long pwm_high = 0;
unsigned long current_t = 0;

void setup()
{
  pinMode(10, OUTPUT);
  Timer1.initialize(500000);         // initialize timer1, and set a 1/2 second period
  Timer1.pwm(9, 512);                // setup pwm on pin 9, 50% duty cycle
  Timer1.attachInterrupt(callback);
}


void loop()
{
//Add your repeated code here
}

void callback()
{
  digitalWrite(10, digitalRead(10)^1);
  Serial.println(millis());
}

And sloeber.ino.cpp:

#ifdef __IN_ECLIPSE__
//This is a automatic generated file
//Please do not modify this file
//If you touch this file your change will be overwritten during the next build
//This file has been generated on 2018-12-25 19:13:08


void setup() ;
void loop() ;
void callback() ;

#include "pwm_timer1.ino"


#endif

Welcome to the forum!

gamd:
sloeber Eclipse IDE

Why wouldn't you use the Arduino IDE? Try it in the Arduino IDE and run it without the file/piece of code within the #ifdef. If it still gives an error, post the entire printout here.

Thanks for your answer!

I use it, because I am used to the Eclipse IDE and it is has a good file overview on the left side. Luckily I've found the error. I've edited sloeber.ino.cpp to:

#ifdef __IN_ECLIPSE__
//This is a automatic generated file
//Please do not modify this file
//If you touch this file your change will be overwritten during the next build
//This file has been generated on 2018-12-25 19:13:08



void callback() ;

#include "pwm_timer1.ino"


#endif

Now I have no error anymore. But I do not get any Serial output. It seems the Timer1 would never go into overflow. But I set it to 1/2 second so it should really call the ISR callback(), which should print me the millis() in an unsigned long.

You never initialize the serial port

void setup()
{
  Serial.begin(9600);
  while( !Serial );
  ...
}

Also, you should not use Serial.print() within a ISR. It is not guaranteed to work. It will probably work some of the time, but not always.. Better to just set a flag and deal with the flag inside loop().

Oh, yes! Thank you.

My updated code is:

//#include "Arduino.h"

#include "TimerOne.h"

unsigned long pwm_high = 0;
unsigned long current_t = 0;

byte flag = LOW;

void setup()
{
  Serial.begin(9600);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  Timer1.initialize(500000);         // initialize timer1, and set a 1/2 second period
  Timer1.pwm(9, 512);                // setup pwm on pin 9, 50% duty cycle
  Timer1.attachInterrupt(callback);
}


void loop()
{
  if(flag == HIGH)
  {
	 //Serial.print(millis());
	 //Serial.println(digitalRead(9));
	 flag = LOW;
  }
  Serial.println(digitalRead(9));
}

void callback()
{
  digitalWrite(10, digitalRead(10)^1);
  flag = HIGH;
}

For this I tried to see the actual PWM signal, which I created on digital pwm pin 9. But somehow I only get zeros at my Serial monitor. What is my mistake here?

pinMode(9, OUTPUT);

you want to read your output ? and digitally ? (i never considered doing that)

Serial.println(digitalRead(9));

so you read when the pin is low every time.. the ISR gets called after every cycle, at the same moment

digitalWrite(10, digitalRead(10)^1);

what does this do ?

flag needs to be declared as volatile since it is used both inside and outside the ISR

volatile byte flag = LOW;

Also, you should sample the value of pin 9 more often to see if it is changing, not just every 500 msec

Deva_Rishi:

digitalWrite(10, digitalRead(10)^1);

what does this do ?

It reads pin 10 and performs an exclusive OR with 1 which is the same as the more common version of toggling a pin

digitalWrite(10, !digitalRead(10));

isn't the period for the pwm the same as it's initialized value,

Timer1.initialize(500000);         // initialize timer1, and set a 1/2 second period
  Timer1.pwm(9, 512);

so then calling the ISR to read the pin at the moment the cycle is complete.

Thank you. I do not really understand. I want to print a 0001100011000 pattern read from pwm pin 9 so I can see the pwm the timer1 producing is actually there. But if I declare pin 9 as output, input or nothing it always gives me following pattern on the serial monitor:
0
0
0
0

0
0
0
0

0
0
0
0

0

0
0
0
0

0
0
0
0

0
0
0
0

0
0
0
0

0
0
0
0

What am I missing here?

what you are missing is that you set the interval for calling the ISR reading the pin to the same as the time for a pwm cycle of the pin. Hence the pin will always have the same state (though it is either just about to change or has just changed (i think the latter but .. ah well) connect a LED to pin 9 as well and see.

If you print the results of reading pin 9 every time through loop(), you will get thousands of readings before you toggle the pin with your 500msec cycle time. Since your frequency is 500msec, I'd suggest putting a delay inside loop()

void loop()
{
  delay(50);  // should get enough readings to see pin
  Serial.print(millis());
  Serial.print(": " );
  Serial.println(digitalRead(9));
}

Thank you for the answers! Unfortunately, I couldn't change anything to the better here. I did add a delay and changed the ISR time and pwm duty cycle.

Updated Code:

#include "TimerOne.h"

unsigned long pwm_high = 0;
unsigned long current_t = 0;

volatile byte flag = LOW;

void setup()
{
  Serial.begin(9600);
  pinMode(10, OUTPUT);
	pinMode(9, OUTPUT);
	Timer1.initialize(50000); // initialize timer1, and set a 1/2 second period
	Timer1.pwm(9, 128);                // setup pwm on pin 9, 50% duty cycle
  Timer1.attachInterrupt(callback);
}


void loop()
{
  if(flag == HIGH)
  {
	 //Serial.print(millis());
		//Serial.print(digitalRead(10));
	 flag = LOW;
  }
	delay(50);
	Serial.print(millis());
	Serial.print(": ");
	Serial.println(digitalRead(9));
}

void callback()
{
  digitalWrite(10, digitalRead(10)^1);
  flag = HIGH;
}

The result on the serial monitor is just:

49: 0

99: 0
149: 0
199: 0

250: 0
301: 0
351: 0

401: 0
451: 0
501: 0
551: 0

602: 0
652: 0
702: 0
752: 0

802: 0
852: 0
903: 0
953: 0

1004: 0
1054: 0

1104: 0
1155: 0
1205: 0
1255: 0

1305: 0
1355: 0
1405: 0
1457: 0
1507: 0
1557: 0
1607: 0

1657: 0
1708: 0
1758: 0
1808: 0

1858: 0
1909: 0
1959: 0

2010: 0
2060: 0
2110: 0
2160: 0

2210: 0
2260: 0
2311: 0

2362: 0
2412: 0
2462: 0
2512: 0

2563: 0
2613: 0
2663: 0
2713: 0

2763: 0
2814: 0
2865: 0

2915: 0
2965: 0
3015: 0
3065: 0

3116: 0
3166: 0
3216: 0

3266: 0
3317: 0
3367: 0
3418: 0

3468: 0
3518: 0
3568: 0
3618: 0

3668: 0
3719: 0
3770: 0

3820: 0
3870: 0
3920: 0
3971: 0

4021: 0
4071: 0
4121: 0

4171: 0
4222: 0
4273: 0
4323: 0

4373: 0
4423: 0
4473: 0
4524: 0
4574: 0
4624: 0
4675: 0

4725: 0
4775: 0
4826: 0
4876: 0

4926: 0
4976: 0
5026: 0

5076: 0
5128: 0
5178: 0
5228: 0

5278: 0
5328: 0
5379: 0
5429: 0
5479: 0
5529: 0
5580: 0

5630: 0
5681: 0
5731: 0
5781: 0

5831: 0
5881: 0
5932: 0

5982: 0
6033: 0
6083: 0
6133: 0

6183: 0
6234: 0
6284: 0

6334: 0
6384: 0
6434: 0
6486: 0

6536: 0
6586: 0
6636: 0
6686: 0

6736: 0
6787: 0
6837: 0

6887: 0
6938: 0
6988: 0
7038: 0

7089: 0
7139: 0
7189: 0

7239: 0
7289: 0
7340: 0
7391: 0

7441: 0
7491: 0
7541: 0
7591: 0
7642: 0
7692: 0
7742: 0

7792: 0
7843: 0
7894: 0
7944: 0

7994: 0
8044: 0
8094: 0

8144: 0
8195: 0
8245: 0
8296: 0

8346: 0
8396: 0
8446: 0
8497: 0
8547: 0
8597: 0
8647: 0

8697: 0
8749: 0
8799: 0
8849: 0

8899: 0
8949: 0
8999: 0

9050: 0
9100: 0
9150: 0
9201: 0

9251: 0
9302: 0
9352: 0

9402: 0
9452: 0
9502: 0
9552: 0

9603: 0
9654: 0
9704: 0
9754: 0

9804: 0
9854: 0
9905: 0

How about you use the timer1 just for the pwm of pin 9uint32_t moment=0;

//Timer1.initialize(500000);         // initialize timer1, and set a 1/2 second period
  Timer1.pwm(9, 512,30000);   // 30 ms 
  //Timer1.attachInterrupt(callback);

and use millis() to do a poll every half second

void loop()
{
  if (moment<millis()-500) 
  {
     callback();
     moment=millis();
  }
  if(flag == HIGH)
  {
	 //Serial.print(millis());
         Serial.print(digitalRead(9));
	 flag = LOW;
  }
	delay(50);
	//Serial.print(millis());
	//Serial.print(": ");
	//Serial.println(digitalRead(9));
}

void callback()
{
  digitalWrite(10, digitalRead(10)^1);
  flag = HIGH;
}

hi Chaturbate Xnxx Tubegalore
hope you good mt friends here

A class can be defined only once per translation unit, and has to have the same definition across translation units.

This error is typically caused by including the header that defines the class multiple times (directly or indirectly) and should be fixed by using include guards.

yeah i think the title of this thread is not really corresponding to it's issue anymore.

@Deva_Rishi

Unfortunately that doesn't work either. The output on the Serial Monitor ist just "00000000000000000000000000000000000000000000".

And setting the pwm pin as output and reading it's state on another pin ?

Try this code

#include "TimerOne.h"

unsigned long pwm_high = 0;
unsigned long current_t = 0;

volatile byte flag = LOW;

void setup()
{
  Serial.begin(9600);
  pinMode(10, OUTPUT);
	pinMode(9, OUTPUT);
	Timer1.initialize(50000); // initialize timer1, and set a 1/2 second period
	Timer1.pwm(9, 128);                // setup pwm on pin 9, 50% duty cycle
  Timer1.attachInterrupt(callback);
  sei();
}


void loop()
{
  if(flag == HIGH)
  {
	 Serial.print(millis());
	 flag = LOW;
  }
}

void callback()
{
  flag = HIGH;
}

At no point does the author of the TimerOne library enable the global interrupt flag. Thus the callback is never called and you only print out the pin state. Adding it in the setup function should enable the interrupts.

Modified Oct 2011 by Andrew Richards to avoid certain problems:
[...]

  • Remove global enable of interrupts (sei())- could be running within an interrupt routine)

LightuC:
At no point does the author of the TimerOne library enable the global interrupt flag. Thus the callback is never called and you only print out the pin state. Adding it in the setup function should enable the interrupts.

interrupts are on by default.

If you change pin 9 to pin 13 and toggle it in the ISR callback, the onboard LED will blink quite nicely