Skip to content
This repository was archived by the owner on Jan 29, 2023. It is now read-only.

Commit 5c299b0

Browse files
authored
v1.0.3
### Release v1.0.3 1. 1. Add example [**ISR_16_Timers_Array_Complex**](examples/ISR_16_Timers_Array_Complex) and optimize example [**ISR_Timers_Array_Simple**](examples/ISR_Timers_Array_Simple) to demonstrate the usage of **16 ISR-based timers**
1 parent b16d5ba commit 5c299b0

File tree

22 files changed

+1760
-918
lines changed

22 files changed

+1760
-918
lines changed

README.md

Lines changed: 303 additions & 49 deletions
Large diffs are not rendered by default.
Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
11
/****************************************************************************************************************************
2-
* examples/Argument_Complex.ino
3-
* For Arduino AVR boards
4-
* Written by Khoi Hoang
5-
*
6-
* Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt
7-
* Licensed under MIT license
8-
* Version: v1.0.2
9-
*
10-
* Now we can use these new 16 ISR-based timers, while consuming only 1 hardware Timer.
11-
* Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
12-
* The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
13-
* Therefore, their executions are not blocked by bad-behaving functions / tasks.
14-
* This important feature is absolutely necessary for mission-critical tasks.
15-
*
16-
* Notes:
17-
* Special design is necessary to share data between interrupt code and the rest of your program.
18-
* Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
19-
* variable can not spontaneously change. Because your function may change variables while your program is using them,
20-
* the compiler needs this hint. But volatile alone is often not enough.
21-
* When accessing shared variables, usually interrupts must be disabled. Even with volatile,
22-
* if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
23-
* If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
24-
* or the entire sequence of your code which accesses the data.
25-
*
26-
* Version Modified By Date Comments
27-
* ------- ----------- ---------- -----------
28-
* 1.0.0 K Hoang 23/11/2019 Initial coding
29-
* 1.0.1 K Hoang 25/11/2019 New release fixing compiler error
30-
* 1.0.2 K.Hoang 28/11/2019 Permit up to 16 super-long-time, super-accurate ISR-based timers to avoid being blocked
31-
*****************************************************************************************************************************/
2+
Argument_Complex.ino
3+
For Arduino boards (UNO, Nano, Mega, etc. )
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt
7+
Licensed under MIT license
8+
9+
Now we can use these new 16 ISR-based timers, while consuming only 1 hardware Timer.
10+
Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
11+
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12+
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13+
This important feature is absolutely necessary for mission-critical tasks.
14+
15+
Notes:
16+
Special design is necessary to share data between interrupt code and the rest of your program.
17+
Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
18+
variable can not spontaneously change. Because your function may change variables while your program is using them,
19+
the compiler needs this hint. But volatile alone is often not enough.
20+
When accessing shared variables, usually interrupts must be disabled. Even with volatile,
21+
if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
22+
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
23+
or the entire sequence of your code which accesses the data.
24+
25+
Version: 1.0.3
26+
27+
Version Modified By Date Comments
28+
------- ----------- ---------- -----------
29+
1.0.0 K Hoang 23/11/2019 Initial coding
30+
1.0.1 K Hoang 25/11/2019 New release fixing compiler error
31+
1.0.2 K.Hoang 28/11/2019 Permit up to 16 super-long-time, super-accurate ISR-based timers to avoid being blocked
32+
1.0.3 K.Hoang 01/12/2020 Add complex examples ISR_16_Timers_Array_Complex and ISR_16_Timers_Array_Complex
33+
*****************************************************************************************************************************/
34+
3235
//These define's must be placed at the beginning before #include "TimerInterrupt.h"
3336
#define TIMER_INTERRUPT_DEBUG 0
3437

@@ -61,16 +64,16 @@ void TimerHandler1(unsigned int outputPinsAddress)
6164
pinMode(((pinStruct *) outputPinsAddress)->Pin2, INPUT_PULLUP);
6265
pinMode(((pinStruct *) outputPinsAddress)->Pin3, INPUT_PULLUP);
6366
}
64-
67+
6568
//timer interrupt toggles pins
6669
Serial.println("Toggle pin1 = " + String(((pinStruct *) outputPinsAddress)->Pin1) );
6770
digitalWrite(((pinStruct *) outputPinsAddress)->Pin1, toggle1);
6871

69-
Serial.println("Read pin2 A0 (" + String(((pinStruct *) outputPinsAddress)->Pin2) + ") = " +
70-
String( digitalRead(((pinStruct *) outputPinsAddress)->Pin2)? "HIGH" : "LOW" ) );
71-
72-
Serial.println("Read pin3 A1 (" + String(((pinStruct *) outputPinsAddress)->Pin3) + ") = " +
73-
String( digitalRead(((pinStruct *) outputPinsAddress)->Pin3)? "HIGH" : "LOW" ) );
72+
Serial.println("Read pin2 A0 (" + String(((pinStruct *) outputPinsAddress)->Pin2) + ") = " +
73+
String( digitalRead(((pinStruct *) outputPinsAddress)->Pin2) ? "HIGH" : "LOW" ) );
74+
75+
Serial.println("Read pin3 A1 (" + String(((pinStruct *) outputPinsAddress)->Pin3) + ") = " +
76+
String( digitalRead(((pinStruct *) outputPinsAddress)->Pin3) ? "HIGH" : "LOW" ) );
7477

7578
toggle1 = !toggle1;
7679
}
@@ -80,24 +83,28 @@ Serial.println("Read pin3 A1 (" + String(((pinStruct *) outputPinsAddress)->Pin3
8083
void setup()
8184
{
8285
Serial.begin(115200);
83-
Serial.println("\nStarting");
86+
while (!Serial);
87+
88+
Serial.println("\nStarting Argument_Complex");
89+
Serial.println("Version : " + String(TIMER_INTERRUPT_VERSION));
90+
Serial.println("CPU Frequency = " + String(F_CPU / 1000000) + " MHz");
8491

8592
// Timer0 is used for micros(), millis(), delay(), etc and can't be used
8693
// Select Timer 1-2 for UNO, 0-5 for MEGA
87-
// Timer 2 is 8-bit timer, only for higher frequency
88-
94+
// Timer 2 is 8-bit timer, only for higher frequency
95+
8996
ITimer1.init();
90-
91-
// Using ATmega328 used in UNO => 16MHz CPU clock ,
97+
98+
// Using ATmega328 used in UNO => 16MHz CPU clock ,
9299
// For 16-bit timer 1, 3, 4 and 5, set frequency from 0.2385 to some KHz
93100
// For 8-bit timer 2 (prescaler up to 1024, set frequency from 61.5Hz to some KHz
94-
101+
95102
if (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS, TimerHandler1, (unsigned int) &myOutputPins))
96103
Serial.println("Starting ITimer1 OK, millis() = " + String(millis()));
97104
else
98-
Serial.println("Can't set ITimer1. Select another freq. or timer");
105+
Serial.println("Can't set ITimer1. Select another freq. or timer");
99106
}
100107

101108
void loop()
102-
{
109+
{
103110
}
Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
11
/****************************************************************************************************************************
2-
* examples/Argument_None.ino
3-
* For Arduino AVR boards
4-
* Written by Khoi Hoang
5-
*
6-
* Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt
7-
* Licensed under MIT license
8-
* Version: v1.0.2
9-
*
10-
* Now we can use these new 16 ISR-based timers, while consuming only 1 hardware Timer.
11-
* Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
12-
* The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
13-
* Therefore, their executions are not blocked by bad-behaving functions / tasks.
14-
* This important feature is absolutely necessary for mission-critical tasks.
15-
*
16-
* Notes:
17-
* Special design is necessary to share data between interrupt code and the rest of your program.
18-
* Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
19-
* variable can not spontaneously change. Because your function may change variables while your program is using them,
20-
* the compiler needs this hint. But volatile alone is often not enough.
21-
* When accessing shared variables, usually interrupts must be disabled. Even with volatile,
22-
* if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
23-
* If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
24-
* or the entire sequence of your code which accesses the data.
25-
*
26-
* Version Modified By Date Comments
27-
* ------- ----------- ---------- -----------
28-
* 1.0.0 K Hoang 23/11/2019 Initial coding
29-
* 1.0.1 K Hoang 25/11/2019 New release fixing compiler error
30-
* 1.0.2 K.Hoang 28/11/2019 Permit up to 16 super-long-time, super-accurate ISR-based timers to avoid being blocked
2+
Argument_None.ino
3+
For Arduino boards (UNO, Nano, Mega, etc. )
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt
7+
Licensed under MIT license
8+
9+
Now we can use these new 16 ISR-based timers, while consuming only 1 hardware Timer.
10+
Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
11+
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12+
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13+
This important feature is absolutely necessary for mission-critical tasks.
14+
15+
Notes:
16+
Special design is necessary to share data between interrupt code and the rest of your program.
17+
Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
18+
variable can not spontaneously change. Because your function may change variables while your program is using them,
19+
the compiler needs this hint. But volatile alone is often not enough.
20+
When accessing shared variables, usually interrupts must be disabled. Even with volatile,
21+
if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
22+
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
23+
or the entire sequence of your code which accesses the data.
24+
25+
Version: 1.0.3
26+
27+
Version Modified By Date Comments
28+
------- ----------- ---------- -----------
29+
1.0.0 K Hoang 23/11/2019 Initial coding
30+
1.0.1 K Hoang 25/11/2019 New release fixing compiler error
31+
1.0.2 K.Hoang 28/11/2019 Permit up to 16 super-long-time, super-accurate ISR-based timers to avoid being blocked
32+
1.0.3 K.Hoang 01/12/2020 Add complex examples ISR_16_Timers_Array_Complex and ISR_16_Timers_Array_Complex
3133
*****************************************************************************************************************************/
3234
//These define's must be placed at the beginning before #include "TimerInterrupt.h"
3335
#define TIMER_INTERRUPT_DEBUG 0
@@ -66,7 +68,7 @@ void TimerHandler2(void)
6668
started = true;
6769
pinMode(A0, OUTPUT);
6870
}
69-
71+
7072
//timer interrupt toggles outputPin
7173
digitalWrite(A0, toggle2);
7274
toggle2 = !toggle2;
@@ -79,32 +81,36 @@ void TimerHandler2(void)
7981
void setup()
8082
{
8183
Serial.begin(115200);
82-
Serial.println("\nStarting");
84+
while (!Serial);
85+
86+
Serial.println("\nStarting Argument_None");
87+
Serial.println("Version : " + String(TIMER_INTERRUPT_VERSION));
88+
Serial.println("CPU Frequency = " + String(F_CPU / 1000000) + " MHz");
8389

8490
// Select Timer 1-2 for UNO, 0-5 for MEGA
85-
// Timer 2 is 8-bit timer, only for higher frequency
91+
// Timer 2 is 8-bit timer, only for higher frequency
8692
ITimer1.init();
87-
88-
// Using ATmega328 used in UNO => 16MHz CPU clock ,
93+
94+
// Using ATmega328 used in UNO => 16MHz CPU clock ,
8995
// For 16-bit timer 1, 3, 4 and 5, set frequency from 0.2385 to some KHz
9096
// For 8-bit timer 2 (prescaler up to 1024, set frequency from 61.5Hz to some KHz
91-
97+
9298
if (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS, TimerHandler1))
9399
Serial.println("Starting ITimer1 OK, millis() = " + String(millis()));
94100
else
95101
Serial.println("Can't set ITimer1. Select another freq. or timer");
96102

97103
// Select Timer 1-2 for UNO, 0-5 for MEGA
98-
// Timer 2 is 8-bit timer, only for higher frequency
104+
// Timer 2 is 8-bit timer, only for higher frequency
99105
ITimer2.init();
100-
106+
101107
if (ITimer2.attachInterruptInterval(TIMER2_INTERVAL_MS, TimerHandler2))
102108
Serial.println("Starting ITimer2 OK, millis() = " + String(millis()));
103109
else
104-
Serial.println("Can't set ITimer2. Select another freq. or timer");
110+
Serial.println("Can't set ITimer2. Select another freq. or timer");
105111
}
106112

107113
void loop()
108114
{
109-
115+
110116
}
Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
11
/****************************************************************************************************************************
2-
* examples/Argument_Simple.ino
3-
* For Arduino AVR boards
4-
* Written by Khoi Hoang
5-
*
6-
* Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt
7-
* Licensed under MIT license
8-
* Version: v1.0.2
9-
*
10-
* Now we can use these new 16 ISR-based timers, while consuming only 1 hardware Timer.
11-
* Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
12-
* The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
13-
* Therefore, their executions are not blocked by bad-behaving functions / tasks.
14-
* This important feature is absolutely necessary for mission-critical tasks.
15-
*
16-
* Notes:
17-
* Special design is necessary to share data between interrupt code and the rest of your program.
18-
* Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
19-
* variable can not spontaneously change. Because your function may change variables while your program is using them,
20-
* the compiler needs this hint. But volatile alone is often not enough.
21-
* When accessing shared variables, usually interrupts must be disabled. Even with volatile,
22-
* if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
23-
* If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
24-
* or the entire sequence of your code which accesses the data.
25-
*
26-
* Version Modified By Date Comments
27-
* ------- ----------- ---------- -----------
28-
* 1.0.0 K Hoang 23/11/2019 Initial coding
29-
* 1.0.1 K Hoang 25/11/2019 New release fixing compiler error
30-
* 1.0.2 K.Hoang 28/11/2019 Permit up to 16 super-long-time, super-accurate ISR-based timers to avoid being blocked
2+
Argument_Simple.ino
3+
For Arduino boards (UNO, Nano, Mega, etc. )
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt
7+
Licensed under MIT license
8+
9+
Now we can use these new 16 ISR-based timers, while consuming only 1 hardware Timer.
10+
Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
11+
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12+
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13+
This important feature is absolutely necessary for mission-critical tasks.
14+
15+
Notes:
16+
Special design is necessary to share data between interrupt code and the rest of your program.
17+
Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
18+
variable can not spontaneously change. Because your function may change variables while your program is using them,
19+
the compiler needs this hint. But volatile alone is often not enough.
20+
When accessing shared variables, usually interrupts must be disabled. Even with volatile,
21+
if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
22+
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
23+
or the entire sequence of your code which accesses the data.
24+
25+
Version: 1.0.3
26+
27+
Version Modified By Date Comments
28+
------- ----------- ---------- -----------
29+
1.0.0 K Hoang 23/11/2019 Initial coding
30+
1.0.1 K Hoang 25/11/2019 New release fixing compiler error
31+
1.0.2 K.Hoang 28/11/2019 Permit up to 16 super-long-time, super-accurate ISR-based timers to avoid being blocked
32+
1.0.3 K.Hoang 01/12/2020 Add complex examples ISR_16_Timers_Array_Complex and ISR_16_Timers_Array_Complex
3133
*****************************************************************************************************************************/
3234
//These define's must be placed at the beginning before #include "TimerInterrupt.h"
3335
#define TIMER_INTERRUPT_DEBUG 0
@@ -53,7 +55,7 @@ void TimerHandler1(unsigned int outputPin = LED_BUILTIN)
5355
started = true;
5456
pinMode(outputPin, OUTPUT);
5557
}
56-
58+
5759
//timer interrupt toggles pin outputPin, default LED_BUILTIN
5860
Serial.println("pin1 = " + String(outputPin) + " address: " + String((uint32_t) &outputPin) );
5961
digitalWrite(outputPin, toggle1);
@@ -70,47 +72,51 @@ void TimerHandler2(unsigned int outputPin = LED_BUILTIN)
7072
started = true;
7173
pinMode(outputPin, OUTPUT);
7274
}
73-
75+
7476
//timer interrupt toggles pin outputPin, default LED_BUILTIN
7577
digitalWrite(outputPin, toggle2);
7678
toggle2 = !toggle2;
7779
}
7880

79-
#define TIMER1_INTERVAL_MS 1000
81+
#define TIMER1_INTERVAL_MS 1000
8082

81-
#define TIMER2_INTERVAL_MS 2000
83+
#define TIMER2_INTERVAL_MS 2000
8284

8385
void setup()
8486
{
8587
Serial.begin(115200);
86-
Serial.println("\nStarting");
88+
while (!Serial);
89+
90+
Serial.println("\nStarting Argument_Simple");
91+
Serial.println("Version : " + String(TIMER_INTERRUPT_VERSION));
92+
Serial.println("CPU Frequency = " + String(F_CPU / 1000000) + " MHz");
8793

8894
// Timer0 is used for micros(), millis(), delay(), etc and can't be used
8995
// Select Timer 1-2 for UNO, 0-5 for MEGA
90-
// Timer 2 is 8-bit timer, only for higher frequency
91-
96+
// Timer 2 is 8-bit timer, only for higher frequency
97+
9298
ITimer1.init();
93-
94-
// Using ATmega328 used in UNO => 16MHz CPU clock ,
99+
100+
// Using ATmega328 used in UNO => 16MHz CPU clock ,
95101
// For 16-bit timer 1, 3, 4 and 5, set frequency from 0.2385 to some KHz
96102
// For 8-bit timer 2 (prescaler up to 1024, set frequency from 61.5Hz to some KHz
97-
103+
98104
if (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS, TimerHandler1, outputPin1))
99105
{
100106
Serial.println("Starting ITimer1 OK, millis() = " + String(millis()));
101107
Serial.println("OutputPin1 = " + String(outputPin1) + ", address = " + String((uint32_t) &outputPin1) );
102108
}
103109
else
104110
Serial.println("Can't set ITimer1. Select another freq. or timer");
105-
111+
106112
ITimer2.init();
107-
113+
108114
if (ITimer2.attachInterruptInterval(TIMER2_INTERVAL_MS, TimerHandler2, outputPin2))
109115
Serial.println("Starting ITimer2 OK, millis() = " + String(millis()));
110116
else
111-
Serial.println("Can't set ITimer2. Select another freq. or timer");
117+
Serial.println("Can't set ITimer2. Select another freq. or timer");
112118
}
113119

114120
void loop()
115-
{
121+
{
116122
}

0 commit comments

Comments
 (0)