Author Topic: TimerOne  (Read 11994 times)

jonwa

  • Newbie
  • *
  • Posts: 17
TimerOne
« on: February 17, 2013, 07:04:43 pm »
Apparently the arduino TimerOne library isn't compatible with the digispark.


Is there a digispark version out there, or is this something the hardware just doesn't do?

duckythescientist

  • Newbie
  • *
  • Posts: 27
Re: TimerOne
« Reply #1 on: February 17, 2013, 09:10:30 pm »
I know this is a horrid response, but it is appropriate: RTFM.


http://www.atmel.com/Images/doc2586.pdf


But seriously, the datasheet for the chip is amazing. I'm not too sure what all TimerOne can do, but knowing the datasheets of both the t85 and the m328, you should be able to do most things.


There may be some timer control libraries for the t85, but being able to set the registers yourself gives you more control and understanding of how your code is doing what it is doing.


Also, if you have a specific function of TimerOne that you want to do, look at the code, see how it is done for the m328, and figure out similar settings for the t85 timers.

jonwa

  • Newbie
  • *
  • Posts: 17
Re: TimerOne
« Reply #2 on: February 18, 2013, 08:20:48 pm »
Yup, it is a horrible response.


What I need is what the TimerOne library provides.


I'm not yet a good enough hardware level programming to understand much of what that manual says.


That's why libraries exist in the first place, so every developer out there doesn't have to re-invent the wheel from the ground up.

I don't yet program in C, just arduino processing. I can call a library, but not yet write one. Give me time, and I probably will be able to, however, writing TimerOne for new hardware is a bit beyond me just now.

« Last Edit: February 18, 2013, 08:23:33 pm by jonwa »

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: TimerOne
« Reply #3 on: February 19, 2013, 11:19:23 am »
While duckythescientist's response might not have been a solution - I think it is a helpful response (thanks duckythescientist for giving a response!), because in this case the wheel hasn't been invented yet for this chip - the TimerOne library is for a 16-bit timer, the Attiny85 uses 8-bit timers - when you get into the more advanced features of a chip the libraries become very chip specific or have specific code to allow them to work with multiple chips. Many libraries already are compatible with the Attiny85 and therefore the Digispark (and Adafruit Gemma, Littlewire, etc), but some aren't and some won't ever be - the later is likely the case for TimerOne - just as a separate library was written for the Mega because TimerOne does not support that either.


If you pick a specific function of the TimerOne library that you are trying to achieve - for instance attaching an interrupt to pin x - I'm sure the folks around here (myself included) will help you figure out the registers and code needed to make it happen.

jonwa

  • Newbie
  • *
  • Posts: 17
Re: TimerOne
« Reply #4 on: February 19, 2013, 08:46:24 pm »
I was hoping to use digispark as a smaller and cheaper chip to run led strips from adafruit.
The program from them that really looks great can be found here:
https://github.com/adafruit/LPD8806/blob/master/examples/LEDbeltKit_alt/LEDbeltKit_alt.pde


I don't really understand the timer part of the code, but Timer1 is imported and there are these two lines:



 Timer1.initialize();
  Timer1.attachInterrupt(callback, 1000000 / 60); // 60 frames/second

Which I assume means that the method callback is called 60 times a second.

I've been studying and attempting to modify the rest of the adafruit code in order to create other patterns of lights, but the Timer stuff has been rather mysterious to me.

I'm looking at the TimerOne.cpp file and I don't even see a version of initalize() that doesn't take arguments. The only version that is there requires (long microseconds).
Hmm, the .h file shows void initialize(long microseconds=1000000); Does that mean there is a default value for no arguments?

Anyway, initialize, and attachInterupt would be what I would need.
both internally call setPeriod, and there is some fun with TCCR1A=0 an TCCR1B=_BV(WGM13), which means very little to me.

oh, and resume(), which merely contains TCCR1B |= clockSelectBits;

TimerOne is over here:
http://code.google.com/p/arduino-timerone/downloads/detail?name=TimerOne-v9.zip&can=2&q=

RESOLUTION is a constant set at 65536 // 16 bit, so I guess I would want 256 as my resolution?

Timer1 includes avr/io.h and avr/interrupt.h. Are those specific to arduino as well, or do we already have those?

jonwa

  • Newbie
  • *
  • Posts: 17
Re: TimerOne
« Reply #5 on: February 19, 2013, 09:05:00 pm »
I cloned TimerOne, calling my version TimerTiny.
Changed the resolution to 256, and renamed everything within to match the new name, save the Timer1, which I am guessing acts like a static member ( I do java...)
That leaves me with lots of references to TCCR1A, TCCR1B, WGM13, ICR1, and TIMSK1
Are those "registers"?
Are their like things in digispark?



C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::initialize(long int)':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:51: error: 'TCCR1A' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:52: error: 'TCCR1B' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:52: error: 'WGM13' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::setPeriod(long int)':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:70: error: 'ICR1' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:73: error: 'TCCR1B' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::pwm(char, int, long int)':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:96: error: 'TCCR1A' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:100: error: 'TCCR1A' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::disablePwm(char)':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:109: error: 'TCCR1A' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:110: error: 'TCCR1A' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::attachInterrupt(void (*)(), long int)':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:117: error: 'TIMSK1' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::detachInterrupt()':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:125: error: 'TIMSK1' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::resume()':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:130: error: 'TCCR1B' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::start()':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:142: error: 'TIMSK1' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:143: error: 'PSRSYNC' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'void TimerTiny::stop()':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:163: error: 'TCCR1B' was not declared in this scope
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp: In member function 'long unsigned int TimerTiny::read()':
C:\development\Digispark Ready - Arduino 1.03\libraries\TimerTiny\TimerTiny.cpp:204: error: 'ICR1' was not declared in this scope

jonwa

  • Newbie
  • *
  • Posts: 17
Re: TimerOne
« Reply #6 on: February 19, 2013, 09:12:43 pm »
What's m328 or t85, and which is on which chip?

semicolo

  • Full Member
  • ***
  • Posts: 137
Re: TimerOne
« Reply #7 on: February 19, 2013, 09:13:14 pm »
Yes it's a C++ feature, if you don't pass an argument, it defaults to 1000000.
For the TCCR1A=0 an TCCR1B=_BV(WGM13) part, that's where the datasheet comes in handy because you can find in it what these register do.
Yes you'll have to use a resolution of 256.
io.h and interrupt.h are part of avr-gcc/avr-g++ which are the compilers used by arduino and the digispark.
Timer1 is used by the environment for delays, you'd better use timer0.
If I get some time tomorrow, I'll try to have a look at the adafruit code.

semicolo

  • Full Member
  • ***
  • Posts: 137
Re: TimerOne
« Reply #8 on: February 19, 2013, 09:14:54 pm »
m328 is the atmega328, t85 the attiny85 that's used by digisparks

jonwa

  • Newbie
  • *
  • Posts: 17
Re: TimerOne
« Reply #9 on: February 19, 2013, 09:18:19 pm »
Timer0? I thought TimerOne was merely the name of the library, not that there was a thing that really was called "1".

semicolo

  • Full Member
  • ***
  • Posts: 137
Re: TimerOne
« Reply #10 on: February 19, 2013, 09:32:44 pm »
Well it looks like the timerone library is using the timer1 (there's also a timer0) in the atmega (since it's calling TCCR1A an the likes, these are registers used for timer1).
In the digispark there are two 8 bits timers, timer0 and timer1, timer1 is already used by the system.
I just made a quick check and it looks like you can't get 60Hz with an 8 bit timer at 16Mhz (you can only get higher rates but it's close to 60)

Just had a quick look at adafruit code, couldn't you save the hassle of setting up the timer and use the loop function?
something like
void loop() {

}

semicolo

  • Full Member
  • ***
  • Posts: 137
Re: TimerOne
« Reply #11 on: February 19, 2013, 09:36:37 pm »
Well it looks like the timerone library is using the timer1 (there's also a timer0) in the atmega (since it's calling TCCR1A an the likes, these are registers used for timer1).
In the digispark there are two 8 bits timers, timer0 and timer1, timer1 is already used by the system.
I just made a quick check and it looks like you can't get 60Hz with an 8 bit timer at 16Mhz (you can only get higher rates but it's close to 60)

Just had a quick look at adafruit code, couldn't you save the hassle of setting up the timer and use the loop function?
something like
void loop() {
  delayMicroseconds(16667);
  callback();
}

semicolo

  • Full Member
  • ***
  • Posts: 137
Re: TimerOne
« Reply #12 on: February 20, 2013, 06:00:48 am »
Or a bit more clever if the call to callback doesn't always take the same amount of time:

long us=0;

void loop() {
  while (micros()-us <16667); // wait until the time has elapsed
  us=micros();
  callback();
}

Add something to take care of micros rolling back to 0 if you intend to use it for more than 70 minutes.


jonwa

  • Newbie
  • *
  • Posts: 17
Re: TimerOne
« Reply #13 on: February 21, 2013, 09:44:27 pm »
That seems like it ought work.
Perhaps the original author was just being clever...