To use the wireless modules i'm using the virtual wire library
My issue now is both Timer0 and Timer1 are being used by these libraries. Before you can use the Millis() function to get a time and use this for task scheduling. However it is my understanding that the Millis library built into the Arduino IDE uses the Timer0 interrupt to update the software time variables.
Any advice on how to schedule without the use of timers?
My current idea is to use task counters with values on akin to clk_freq/1000 for a task interval of 1 ms. Granted this won't be exact as code execution time will differ greatly every loop.
For example my led heartbeat uses this code. It works but I feel it's a bit clunky
//in header.h
#define CLOCK_SPEED 8000000
#define CLOCK_MS_INTERVAL (CLOCK_SPEED / 10000 + 200) // 200 is a calibration offset.
#define NOP __asm__ __volatile__ ("nop\n\t") // alternate form is just("nop")
//1-status light shows its working
// blinks ~ every second
static unsigned long heartbeat_task = 0;
if (y==1 && heartbeat_task == 0){
digitalWrite(LED_Pin, HIGH);
delay(50);
digitalWrite(LED_Pin, LOW);
heartbeat_task = CLOCK_MS_INTERVAL * 1000;
}
else if (y == 1){ //only decrement if this is a heartbeat function call
if (heartbeat_task > 0)
heartbeat_task--;
}
Its not that it does not work. I believe millis reads the current time of the timer then does some magical math in the library to keep track of the time. But since Timer0 is used for one of the libraries as an interrupt, that Timer can get reset at any time thus invalidating what ever time it's keeping track of.
Also the chip tends to crash/freeze around code using the millis function. so ya maybe it doesnt work.
(hard to tell with limited debugging and no serial connection)
Have you considered adding a realtime clock chip. Many of these can deliver an scheduled interrupt back to your program, which could do away with the need for any internal timer.
jrdoner:
Have you considered adding a realtime clock chip. Many of these can deliver an scheduled interrupt back to your program, which could do away with the need for any internal timer.
Thats a good idea. however I already have a board made and all 5 pins are used up already. So Good solution if you had spare pins which i dont have..
holmes4:
It does not matter what you believe or not. This is not politics or some half baked oligy This is engineering. Your job is to find out!
Mark
First I;m here in part to find out. That is why I'm taking the time to make this post. Second you dont know my background and third i'm not here to make philosophical debate. I'm simply asking a question. Forth there is a period in that quote that should be looked at. I stated
CyberZoid:
I believe millis reads the current time of the timer then does some magical math in the library to keep track of the time. But since Timer0 is used for one of the libraries as an interrupt, that Timer can get reset at any time thus invalidating what ever time it's keeping track of.
Anywas this is off topic which is how to schedule without Timers or use of the Millis function which is dependent on a timer.
Seems like you need something internal to make time ticks that you can count to see how much time is elapsing.
Can you use Timer1 for that with a millis() function revision?
There's no magical math - an interrupt is created when the time tick is up, and a 64-bit counter is incremented. When you call millis(), that count is returned to you.
groundfungus:
I wonder if the watchdog timer interrupt could be used.
Ill have to look into this. tx
CrossRoads:
Seems like you need something internal to make time ticks that you can count to see how much time is elapsing.
Basicaly what im looking for.
CrossRoads:
Can you use Timer1 for that with a millis() function revision?
I could but both libraries want their own timer interrupt vector. So i'm assuming that millis wouldnt work reliably. I could be wrong on this though.
CrossRoads:
There's no magical math - an interrupt is created when the time tick is up, and a 64-bit counter is incremented. When you call millis(), that count is returned to you.
Sry I should of avoided that phrasing. I was meaning that a different library is configuring the timer for its own purposes. It's possible the library is overiding the millis ISR.
IF and only if one of those lib makes a mess of mills/micros do you need to use a complex work around.
The lessons you are being taught is to look in the documentation, not just think that it may be.
First I;m here in part to find out. That is why I'm taking the time to make this post.
No you made this post because you wanted to avoid doing the work!
You find out by looking in the documentation or if that fails by looking at the code.
Second you dont know my background and third i'm not here to make philosophical debate. I'm simply asking a question.
))sic) digthat missing ' I don't need to know your background nor do I care about it.
When I say this is not an issue where opinion matters, what is just what I mean. One of those lib may or may not affect mills/micros - find out - do the work!
CyberZoid:
My issue now is both Timer0 and Timer1 are being used by these libraries.
It is entirely possible for another library to use Timer0 without upsetting the millis() function.
As others have said, the first thing is for you to do some tests to see if millis() works properly. If it does then you are wasting your time in this Thread.
And if the library using Timer0 does interfere with millis() it is still possible that you can use half of Timer1 to provide an equivalent capability.
You need to study the Attiny datsheet and the code in the libraries you are using very carefully.
So I can confirm using the information compiled from:
And reading the attiny core file wiring.c source file
The that the millis function uses the Timer0 Overflow interrupt vector (TIMER0_OVF) on the ATtiny85
So theoretically you could call millis as it just returns the current count, the count may or may not increment depending on how the timer is configured. ie overflow or comparter & reset. If the library uses the timer as a comparater then resets the millis function would never increment.
Virtuallibrary uses CTC settings for the timer--resets timer on every compare match.
The servo8Bit library explicitly sets the timer to 0 on compare.
So basically it seems that the millis function is unreliable to use as a scheduler.
It seems my only option is to use software counters on the order of task_count = clk_freq/1000 (~1 ms). Then calibrate the background task to the interval I want.
CyberZoid:
So theoretically you could call millis as it just returns the current count, the count may or may not increment depending on how the timer is configured. ie overflow or comparter & reset. If the library uses the timer as a comparater then resets the millis function would never increment.
Virtuallibrary uses CTC settings for the timer--resets timer on every compare match.
The servo8Bit library explicitly sets the timer to 0 on compare.
I suspect you have not studied the Atmel datasheet in detail.
Each Timer has 2 parts to it so that it can time two different tasks. What counter (Register) does the servo8Bit library set to zero?
Have you written any test code to see how millis() actually behaves?
In the servo8bit SW FSM compare function
//reset the counter to 0
TCNTn = 0; //the timer register
Robin2:
Have you written any test code to see how millis() actually behaves?
I made a quick test sketch on the Uno and setting the timer0 timer to ctc. The sketch did not run. but i'm thinking I need to create a more involved timer setup and usage to properly test it.
(Using the uno since the timer architecture and millis implementation is nearly identical +- a few features-- uno has a built in serial.)
I'll have to test this tomorrow night. I only have a short amount of time per day to work on this project.
CyberZoid:
Have I studied it?
...SNIP....
In the servo8bit SW FSM compare function
//reset the counter to 0
TCNTn = 0; //the timer register
That seems fairly clear. I just needed to get you to be precise about what the code does. Unfortunately a lot of Arduino libraries are written without any consideration for other uses of the hardware.
Do you know if the other library you are using prevents Timer1 from being used for your timing?
OR, perhaps you could convert the code in the servo8Bit library to use Timer1 and leave Timer0 available for millis().
OR, if you only want to control a single servo maybe you could write your own servo code using micros().
I made a quick test sketch on the Uno
I meant that you should do the tests on your Attiny.