Pages: [1] 2   Go Down
Author Topic: FrequencyTimer2 causing errors in 0015 at startup  (Read 5612 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm wanting to use interrupts, so I've read how to use, and downloaded the FrequencyTimer2 library.  I've unzipped it and put it in C:\Program Files\arduino-0015\hardware\libraries while the IDE is not running.

I then start the IDE and get this:

Code:
FrequencyTimer2.cpp:32: warning: 'SIG_OUTPUT_COMPARE2' appears to be a misspelled signal handler
FrequencyTimer2.cpp: In static member function 'static void FrequencyTimer2::setOnOverflow(void (*)())':
FrequencyTimer2.cpp:51: error: 'TIMSK' was not declared in this scope
FrequencyTimer2.cpp:51: error: 'OCIE2' was not declared in this scope
FrequencyTimer2.cpp:52: error: 'TIMSK' was not declared in this scope
FrequencyTimer2.cpp:52: error: 'OCIE2' was not declared in this scope
FrequencyTimer2.cpp: In static member function 'static void FrequencyTimer2::setPeriod(long unsigned int)':
FrequencyTimer2.cpp:99: error: 'TCCR2' was not declared in this scope
FrequencyTimer2.cpp:102: error: 'OCR2' was not declared in this scope
FrequencyTimer2.cpp:103: error: 'COM20' was not declared in this scope
FrequencyTimer2.cpp: In static member function 'static long unsigned int FrequencyTimer2::getPeriod()':
FrequencyTimer2.cpp:113: error: 'TCCR2' was not declared in this scope
FrequencyTimer2.cpp:114: error: 'OCR2' was not declared in this scope
FrequencyTimer2.cpp: In static member function 'static void FrequencyTimer2::enable()':
FrequencyTimer2.cpp:150: error: 'TCCR2' was not declared in this scope
FrequencyTimer2.cpp:150: error: 'COM20' was not declared in this scope
FrequencyTimer2.cpp: In static member function 'static void FrequencyTimer2::disable()':
FrequencyTimer2.cpp:160: error: 'TCCR2' was not declared in this scope
FrequencyTimer2.cpp:160: error: 'COM20' was not declared in this scope

etracer said (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236662893/3#4) the solution to the FrequencyTimer2 problem is in this post regarding Morse.h errors:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1237653105/3#3

but this solution does not apply to the FrequencyTimer2 library (I was, however, able to extrapolate that solution to the LedControl compile time errors I had by modifying LedControl.cpp and .h with the same mods).

However, etracer's answer cannot be applied to the FrequencyTimer2 library.  I can only assume that when the IDE start with 19 lines of red errors, the FrequencyTimer2 library will not function like it's supposed to.

Does anybody know the real answer to fixing this?

 :-/

For the record, I'm using an Arduino Duemilanove with the '328, and as stated in the subject, Arduino 0015.


Editorial comment, maybe I'm wrong here, but this is frustrating:

From looking around on the forums here for answers, it seems that when a new IDE is released, the author(s) break a lot of stuff, move things around, and its up to others to fix it, put the answer in a forum somewhere, and leave it up to us noobs to search down and find the errors that the authors made (which they MUST be aware of if they read the forums).  Why don't the authors check their work, admit their errors, and fix them?  Or at least state what needs to be done to make their code work?  I understand what open source means, but so far, in 2 out of 2 libraries I've downloaded which are supposed to work out of the box, none of them have.
« Last Edit: April 15, 2009, 04:02:54 pm by infinity6 » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After going back and re-reading the FrequencyTimer2 page (http://www.arduino.cc/playground/Code/FrequencyTimer2) the instructions say to "Unpack it in your lib/targets/libraries/ directory"

No such directory path exists on my Win box in the arduino-0015 directory.

So I put it where all the other libraries are, C:\Program Files\arduino-0015\hardware\libraries

Perhaps neither of those is the correct location to put the unpacked files when in 0015?

I've also stabbed at some possible solutions, and commenting out the #include <avr/interrupt.h> from the FrequencyTimer2.cpp file and adding #include <avr/io.h> to the FrequencyTimer2.h reduces the number of startup errors from 19 to just one:

Code:
FrequencyTimer2.cpp:33: error: expected constructor, destructor, or type conversion before '(' token


edited to add:
As it turns out, after a few more tries, adding the #include <avr/io.h> to FrequencyTimer2.h had no effect, simply commenting out #include <avr/interrupt.h> from FrequencyTimer2.cpp is the only change which reduced the startup errors from 19 to one.


Maybe I'm close?  I really have no idea what I'm doing, just kinda guessing based on things I've read in the forums, and tidbits of memory from my 2 or 3 C/C++ college classes 10 years ago.  I've dusted off the old textbooks, but they're not helping much either...

I'm not sure what else to guess at... :-/
« Last Edit: April 15, 2009, 05:56:33 pm by infinity6 » Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6651
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The problem is that the FrequencyTimer2 code assumes that any chip that is NOT an ATmega168 MUST BE an ATmega8, which has different symbol definitions.

You can go a long way toward getting it to compile by inserting the following "magic incantation" into FrequencyTimer2.cpp just after the "#include <avr/interrupt.h>" line:

Code:
#if defined(__AVR_ATmega328P__)
// A mega328 is mostly like an mega168, in terms of peripherals
#define __AVR_ATmega168__ 1
#endif

(I don't know if this produces a working library; it gets rid of the compiler errors, leaving a couple warnings.)
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, adding those lines reduced everything to a few warnings the first time after starting the IDE, and I never saw them again.

However, the code still won't compile.  And the odd thing is (at least to me) is that when the compiler errors come up, there's no highlighting of code when the following errors occur.  So I believe something's still not right in the header files or libraries or something.

Still kinda stumped...

Code:
In file included from C:\Program Files\arduino-0015\hardware\cores\arduino/WProgram.h:4,


                 from hardware\libraries\LedControl/LedControl.h:25,


c:/program files/arduino-0015/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'


c:/program files/arduino-0015/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


c:/program files/arduino-0015/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


In file included from C:\Program Files\arduino-0015\hardware\cores\arduino/WProgram.h:6,


                 from hardware\libraries\LedControl/LedControl.h:25,

Any other suggestions would be appreciated.  Thanks again.

Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The following changes to FrequencyTimer2 should get it to compile in 0015:

In FrequencyTimer2.h, replace the line
   #include  <wiring.h>
with
   #include <inttypes.h>
And put  the line
     #include  <wiring.h>
into  to FrequencyTimer2.cpp (just after the #include <FrequencyTimer2.h>

as suggested above, add the following to start of FrequencyTimer2.cpp :
    
#if defined(__AVR_ATmega328P__)
// Timer2 is the same on the mega328 and mega168
#define __AVR_ATmega168__
#endif
 

This should compile.
If you want to get rid of the warning, in the getPeriod method replace the line
   uint8_t shift;
with
   uint8_t shift=0;
« Last Edit: April 21, 2009, 01:14:45 am by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks again.

All those suggestions help.  Everything compiles now, no warnings or errors.

One question though - What's the difference between

#define __AVR_ATmega168__


and

#define __AVR_ATmega168__ 1

???

What does that extra " 1" do at the end?

Thanks.
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

#define __AVR_ATmega168__ 1
creates a preprocessor definition and gives it the value of 1

But we can leave out giving it a value because in this case we only care if its been defined or not.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...and although everything compiles without error, the sketch hangs when I call

FrequencyTimer2::setOnOverflow(myISR);


and it doesn't matter what function I call in place of "myISR', the sketch goes off in the weeds at this line.

dang, I am SO close, I can feel it...
« Last Edit: April 21, 2009, 12:18:07 pm by infinity6 » Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lets have a look at the ISR, can you post your sketch?
« Last Edit: April 21, 2009, 12:22:01 pm by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is enough of the code to demonstrate the FrequencyTimer2::setOnOverflow(myISR) issue:

Quote
 
#include "FrequencyTimer2.h"
#include "LedControl.h"
#include "WProgram.h"

LedControl lc=LedControl(10,9,8,1);

byte col = 0;
byte leds[8][8];

#define DELAY 0
#define SIZE 8
extern byte leds[SIZE][SIZE];

void setup() {
    /*
  The MAX72XX is in power-saving mode on startup,
  we have to do a wakeup call
  */
  lc.shutdown(0,false);
  lc.setIntensity(0,15);
// light up all the LEDs to make sure they all work:
  for(int row=0;row<8;row++) {
    for(int col=0;col<8;col++) {
      delay(5);
      lc.setLed(0,row,col,true);
    }
  }
  delay(2000);
  lc.clearDisplay(0);
  delay(1000);
  
  Serial.begin(9600);
  Serial.println("hello");
  
  setupLeds();
  Serial.println("hello again");
  
  Serial.println("end of void setup()");
}

void loop() {
  Serial.println("loop start");
  delay(1000);
  Serial.println("loop end");
}

void setupLeds() {
  Serial.println("entering setupLeds()");
  clearLeds();
  Serial.println("passed clearLeds()");

  // Turn off toggling of pin 11 and 3
  FrequencyTimer2::disable();
  Serial.println("passed ::disable()");
  
  // Set refresh rate (interrupt timeout period)
  FrequencyTimer2::setPeriod(2000);
  Serial.println("passed ::setPeriod()");
  
  uselessFunction();  // call the useless function to make sure it's printing, and it is
  
  // Set interrupt routine to be called
  FrequencyTimer2::setOnOverflow(uselessFunction);
  Serial.println("end of setupLeds()");  // this line never prints, loop() is never entered
}

void uselessFunction() {
  Serial.println("this function only prints this line.");
}

void clearLeds() {
  // Clear display array
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[j] = 0;
    }
  }
}

 
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you try this version of the sketch. Instead of printing it toggles  the LED on pin 13. If the LED illuminates or flashes  (after 3 seconds) then the function is being called and the problem is not with FrequencyTimer2 (at least not in isolation).  
Code:
#include "FrequencyTimer2.h"

#include "WProgram.h"


byte col = 0;
byte leds[8][8];

#define DELAY 0
#define SIZE 8
extern byte leds[SIZE][SIZE];
boolean ledState = true;

void setup() {
// light up all the LEDs to make sure they all work:
 for(int row=0;row<8;row++) {
   for(int col=0;col<8;col++) {
     delay(5);
   }
 }
 pinMode(13, OUTPUT);
 digitalWrite(13, LOW); // turn the LED off
 delay(2000);
 delay(1000);
 
 Serial.begin(9600);
 Serial.println("hello");
 
 setupLeds();
 Serial.println("hello again");
 
 Serial.println("end of void setup()");
}

void loop() {
 Serial.println("loop start");
 delay(1000);
 Serial.println("loop end");
}

void setupLeds() {
 Serial.println("entering setupLeds()");
 clearLeds();
 Serial.println("passed clearLeds()");

 // Turn off toggling of pin 11 and 3
 FrequencyTimer2::disable();
 Serial.println("passed ::disable()");
 
 // Set refresh rate (interrupt timeout period)
 FrequencyTimer2::setPeriod(2000);
 Serial.println("passed ::setPeriod()");
 
 uselessFunction();  // call the useless function to make sure it's printing, and it is
 
 // Set interrupt routine to be called
 FrequencyTimer2::setOnOverflow(uselessFunction);
 Serial.println("end of setupLeds()");  // this line never prints, loop() is never entered
}

void uselessFunction() {
   digitalWrite(13,ledState);
   ledState = ! ledState; // toglle the LED state
}

void clearLeds() {
 // Clear display array
 for (int i = 0; i < 8; i++) {
   for (int j = 0; j < 8; j++) {
     leds[i][j] = 0;
   }
 }
}
« Last Edit: April 21, 2009, 01:10:30 pm by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Of course it turns on the LED after 3 seconds because uselessFunction() is called at 3 seconds, and your modification of that function lights up the led on the first pass.

AFTER that function is called, FrequencyTimer2::setOnOverflow(uselessFunction) appears to do nothing, and the sketch is still off in the weeds.

Does this sketch flash the LED on your system?
« Last Edit: April 21, 2009, 01:20:53 pm by infinity6 » Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have not run the code - I am prompting from the gallery  smiley-wink
I don't use FrequencyTimer2, just trying to be helpful

try this version of useless function, it sould visibly blink the led .
Code:

byte counter;  // declare counter as a static variable

void uselessFunction() {
   counter++;
   if( counter == 0)
      ledState = ! ledState; // toggle the LED state  
   digitalWrite(13,ledState);
}
« Last Edit: April 21, 2009, 01:41:01 pm by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A test call of the function before the FrequencyTimer2::setOnOverflow(uselessFunction); will do exactly what it's supposed to do the first time, whether it's a Serial.println("Do I Work?") or blinking an LED.

It's the actual call to FrequencyTimer2::setOnOverflow(uselessFunction); that is causing the problem.

So I don't see any point in changing uselessFunction() because it's being called once, then FrequencyTimer2::setOnOverflow(uselessFunction); is called, and that's where the problem begins, not in the test calling of the ISR.  
« Last Edit: April 21, 2009, 01:43:50 pm by infinity6 » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
meh
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think that code snippet works, anyway.  int counter is never initialized, so it starts incrementing from some arbitrary value, increments forever, and I don't think the condition counter==0 would ever get met.

edit: ah, counter is a byte, so it rolls at 255, never mind.  It probably does work.  I just see no point in trying this for the reasons stated in my previous post.
« Last Edit: April 21, 2009, 01:51:02 pm by infinity6 » Logged

Pages: [1] 2   Go Up
Jump to: