Go Down

Topic: "Previoius definition of 'class TimerOne'" and creating PWM with Timer1 (Read 670 times) previous topic - next topic

gamd

Hello,

I am currently trying to experiment with TimerOne a bit: https://playground.arduino.cc/code/timer1

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:
Code: [Select]

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:
Code: [Select]

#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:
Code: [Select]

#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


Power_Broker

Welcome to the forum!

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.
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

gamd

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:

Code: [Select]

#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.

blh64

You never initialize the serial port
Code: [Select]

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().


gamd

Oh, yes! Thank you.

My updated code is:
Code: [Select]

//#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?

Deva_Rishi

#5
Dec 26, 2018, 09:24 pm Last Edit: Dec 26, 2018, 09:31 pm by Deva_Rishi
Code: [Select]
pinMode(9, OUTPUT);
 you want to read your output ? and digitally ? (i never considered doing that)
Code: [Select]
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
Code: [Select]
digitalWrite(10, digitalRead(10)^1);
what does this do ?
To 'Correct' you have to be Correct. (and not be condescending..)

blh64

flag needs to be declared as volatile since it is used both inside and outside the ISR
Code: [Select]

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

blh64

Code: [Select]
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
Code: [Select]
digitalWrite(10, !digitalRead(10));

Deva_Rishi

isn't the period for the pwm the same as it's initialized value,
Code: [Select]
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.
To 'Correct' you have to be Correct. (and not be condescending..)

gamd

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?

Deva_Rishi

#10
Dec 27, 2018, 01:04 pm Last Edit: Dec 27, 2018, 01:05 pm by Deva_Rishi
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.
To 'Correct' you have to be Correct. (and not be condescending..)

blh64

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()
Code: [Select]

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

gamd

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:
Code: [Select]


#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:
Code: [Select]

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



Deva_Rishi

How about you use the timer1 just for the pwm of pin 9
Code: [Select]
uint32_t moment=0;
Code: [Select]

//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
Code: [Select]
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;
}
To 'Correct' you have to be Correct. (and not be condescending..)

rakon234

#14
Dec 27, 2018, 10:55 pm Last Edit: Dec 29, 2018, 12:38 pm by rakon234
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.

Go Up