I just wrote this doevery function for 3 events
It's only for mega328 but if you change the 1ms interrupt to your pic it would be the same.
I scoped it and it's working.
Only 1ms resolution and 3 events.
tim1event=how often tim1go called in ms
tim1even2=how often tim2go called in ms
tim1even3=how often tim3go called in ms
first draft. Chris Roper is working on a proper version of this. This is just the idea I think. My version.
I think the interrupt routine should be as small as possible.
The best thing would be to set flags during the check in the interrupt routine and check the flags and act accordingly during the main loop.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You give it a period, an Interrupt routine address and it runs forever.
The routine that is called must be short, as you have correctly pointed out, and in effect Stan is just setting a flag, in this case his flags are Port Pins todrive Servo Motors, but still only use as much code as setting any flag.
It is good to draw attention to interrupts, their use, abuse and limitations to try and get some discussion and education going, as the next release of GCBASIC will include some Timer Based User Interrupt hooks inspired by Stan's DoEvery idea.
Look for more to come on this subject in the weeks ahead as several other functions will be available to use what I am starting to think of as “The System Timer” - Timer0.
The release version will not need Stans Setup code or ISR and it will be fully portable.
Something like this is envisaged:
#chipmega328p,16
#optionExplicit
#include<Tardis.h>
#DoEvery01000, portc.2=notportc.2' Every Second
#DoEvery12, portc.3=notportc.3' Every 2 mS
#DoEvery220, portc.4=notportc.4' Every 20 mSInit_Timers()dirportc.2outdirportc.3outdirportc.4outStart_Timers()doloopEnd
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@jackjames. Hi. Yes, the interrupt code must be shorter than the interrupt period.
Here is a sub that is called from a 2ms interrupt every 2ms.
It looks a lot of code so I timed it by set portc.3 on at the start
and set portc.3 off at the end and scoping portc.3 which gave a pulse hovering around 8us.
You would think it would take longer.
millis a long variable but will overflow after ???
A long variable is 32 bits so has a total count of 2^32
which is 4,294,967,296.00 mS
or 4,294,967.29600 Seconds
or 71,582.7882667 Minutes
or 1,193.04647111 Hours
or 49 Days, 17 hours, 2 Minutes and 47.296 Seconds
But if you are just interested in an elapsed time then subtracting the Start time from the time now will ensure that the rollover is canceled out mathematically .
The System version of DoEvery will not be using Millis() as it is an independent countdown timer and so not affected by the rollover either.
Last edit: Chris Roper 2020-06-23
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Looking forward to the final release Chris.
Without the gcb interrupt demos, I would have no idea how to code an interrupt.
There are only a few demos so it encourages you to try the timercalc program to get interrupts at different frequencies.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is a thought.
event 1 every 2ms takes 10us
event 2 every 20ms takes 2200us max using pulseout,pin
so event 2 could start and in the 2200us it could run for, event 1 starts.
in the application, this must happen but I see no effects showing.
maybe pulseout stops interrupts?? and is why it works.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I just wrote this doevery function for 3 events
It's only for mega328 but if you change the 1ms interrupt to your pic it would be the same.
I scoped it and it's working.
Only 1ms resolution and 3 events.
tim1event=how often tim1go called in ms
tim1even2=how often tim2go called in ms
tim1even3=how often tim3go called in ms
first draft. Chris Roper is working on a proper version of this. This is just the idea I think. My version.
I think the interrupt routine should be as small as possible.
The best thing would be to set flags during the check in the interrupt routine and check the flags and act accordingly during the main loop.
DoEvery is a fire and forget function.
You give it a period, an Interrupt routine address and it runs forever.
The routine that is called must be short, as you have correctly pointed out, and in effect Stan is just setting a flag, in this case his flags are Port Pins todrive Servo Motors, but still only use as much code as setting any flag.
It is good to draw attention to interrupts, their use, abuse and limitations to try and get some discussion and education going, as the next release of GCBASIC will include some Timer Based User Interrupt hooks inspired by Stan's DoEvery idea.
Look for more to come on this subject in the weeks ahead as several other functions will be available to use what I am starting to think of as “The System Timer” - Timer0.
The release version will not need Stans Setup code or ISR and it will be fully portable.
Something like this is envisaged:
@jackjames. Hi. Yes, the interrupt code must be shorter than the interrupt period.
Here is a sub that is called from a 2ms interrupt every 2ms.
It looks a lot of code so I timed it by set portc.3 on at the start
and set portc.3 off at the end and scoping portc.3 which gave a pulse hovering around 8us.
You would think it would take longer.
I also call another sub from the same isr every 20ms.
This uses pulseout to generate pulses between 7800us to 2200us
The isr drives the motors and the servo with no apparent problems.
A long variable is 32 bits so has a total count of 2^32
which is 4,294,967,296.00 mS
or 4,294,967.29600 Seconds
or 71,582.7882667 Minutes
or 1,193.04647111 Hours
or 49 Days, 17 hours, 2 Minutes and 47.296 Seconds
But if you are just interested in an elapsed time then subtracting the Start time from the time now will ensure that the rollover is canceled out mathematically .
The System version of DoEvery will not be using Millis() as it is an independent countdown timer and so not affected by the rollover either.
Last edit: Chris Roper 2020-06-23
Looking forward to the final release Chris.
Without the gcb interrupt demos, I would have no idea how to code an interrupt.
There are only a few demos so it encourages you to try the timercalc program to get interrupts at different frequencies.
Here is a thought.
event 1 every 2ms takes 10us
event 2 every 20ms takes 2200us max using pulseout,pin
so event 2 could start and in the 2200us it could run for, event 1 starts.
in the application, this must happen but I see no effects showing.
maybe pulseout stops interrupts?? and is why it works.