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

Commit 400bd7a

Browse files
authored
Update README
Update README to show how to Set Hardware Timer Frequency.
1 parent 3c356a5 commit 400bd7a

File tree

1 file changed

+157
-61
lines changed

1 file changed

+157
-61
lines changed

README.md

Lines changed: 157 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,15 @@
3333
* [3. Timer2](#3-timer2)
3434
* [4. Timer3, Timer4, Timer5](#4-timer3-timer4-timer5)
3535
* [5. Important Notes](#5-important-notes)
36-
* [How to use](#how-to-use)
36+
* [Usage](#usage)
37+
* [1. Using only Hardware Timer directly](#1-using-only-hardware-timer-directly)
38+
* [1.1 Init Hardware Timer](#11-init-hardware-timer)
39+
* [1.2 Set Hardware Timer Interval and attach Timer Interrupt Handler function](#12-set-hardware-timer-interval-and-attach-timer-interrupt-handler-function)
40+
* [1.3 Set Hardware Timer Frequency and attach Timer Interrupt Handler function](#13-set-hardware-timer-frequency-and-attach-timer-interrupt-handler-function)
41+
* [2. Using 16 ISR_based Timers from 1 Hardware Timer](#2-using-16-isr_based-timers-from-1-hardware-timer)
42+
* [2.1 Important Note](#21-important-note)
43+
* [2.2 Init Hardware Timer and ISR-based Timer](#22-init-hardware-timer-and-isr-based-timer)
44+
* [2.3 Set Hardware Timer Interval and attach Timer Interrupt Handler functions](#23-set-hardware-timer-interval-and-attach-timer-interrupt-handler-functions)
3745
* [Examples](#examples)
3846
* [ 1. Argument_Complex](examples/Argument_Complex)
3947
* [ 2. Argument_None](examples/Argument_None)
@@ -251,98 +259,186 @@ Timer3, Timer4 and Timer5 are only available for Arduino Mega boards.
251259
---
252260
---
253261

254-
## How to use
262+
## Usage
255263

256-
```
257-
// These define's must be placed at the beginning before #include "TimerInterrupt.h"
258-
// Don't define TIMER_INTERRUPT_DEBUG > 0. Only for special ISR debugging only. Can hang the system.
259-
#define TIMER_INTERRUPT_DEBUG 0
264+
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
265+
266+
### 1. Using only Hardware Timer directly
267+
268+
#### 1.1 Init Hardware Timer
260269

270+
```
271+
// Select the timers you're using, here ITimer1
261272
#define USE_TIMER_1 true
262-
#define USE_TIMER_2 true
273+
#define USE_TIMER_2 false
263274
#define USE_TIMER_3 false
264275
#define USE_TIMER_4 false
265276
#define USE_TIMER_5 false
266277
267-
#include "TimerInterrupt.h"
278+
// Init timer ITimer1
279+
ITimer1.init();
280+
```
268281

269-
void TimerHandler1(void)
270-
{
271-
static bool toggle1 = false;
272-
static bool started = false;
282+
#### 1.2 Set Hardware Timer Interval and attach Timer Interrupt Handler function
273283

274-
if (!started)
275-
{
276-
started = true;
277-
pinMode(LED_BUILTIN, OUTPUT);
278-
}
284+
Use one of these functions with **interval in unsigned long milliseconds**
285+
286+
```
287+
// interval (in ms) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
288+
template<typename TArg> bool setInterval(unsigned long interval, void (*callback)(TArg), TArg params, unsigned long duration = 0);
279289
280-
//timer interrupt toggles pin LED_BUILTIN
281-
digitalWrite(LED_BUILTIN, toggle1);
282-
toggle1 = !toggle1;
290+
// interval (in ms) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
291+
bool setInterval(unsigned long interval, timer_callback callback, unsigned long duration = 0);
292+
293+
// Interval (in ms) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
294+
template<typename TArg> bool attachInterruptInterval(unsigned long interval, void (*callback)(TArg), TArg params, unsigned long duration = 0);
295+
296+
// Interval (in ms) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
297+
bool attachInterruptInterval(unsigned long interval, timer_callback callback, unsigned long duration = 0)
298+
```
299+
300+
as follows
301+
302+
```
303+
void TimerHandler0()
304+
{
305+
// Doing something here inside ISR
283306
}
284307
285-
void TimerHandler2(void)
308+
#define TIMER0_INTERVAL_MS 50L
309+
310+
void setup()
286311
{
287-
static bool toggle2 = false;
288-
static bool started = false;
312+
....
313+
314+
// Interval in unsigned long millisecs
315+
if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS, TimerHandler0))
316+
Serial.println("Starting ITimer0 OK, millis() = " + String(millis()));
317+
else
318+
Serial.println("Can't set ITimer0. Select another freq. or timer");
319+
}
320+
```
289321

290-
if (!started)
291-
{
292-
started = true;
293-
pinMode(A0, OUTPUT);
294-
}
322+
#### 1.3 Set Hardware Timer Frequency and attach Timer Interrupt Handler function
295323

296-
//timer interrupt toggles outputPin
297-
digitalWrite(A0, toggle2);
298-
toggle2 = !toggle2;
299-
}
324+
Use one of these functions with **frequency in float Hz**
325+
326+
```
327+
// frequency (in hertz) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
328+
bool setFrequency(float frequency, timer_callback_p callback, /* void* */ uint32_t params, unsigned long duration = 0);
300329
301-
#define TIMER1_INTERVAL_MS 1000
330+
// frequency (in hertz) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
331+
bool setFrequency(float frequency, timer_callback callback, unsigned long duration = 0);
332+
333+
// frequency (in hertz) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
334+
template<typename TArg> bool attachInterrupt(float frequency, void (*callback)(TArg), TArg params, unsigned long duration = 0);
335+
336+
// frequency (in hertz) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
337+
bool attachInterrupt(float frequency, timer_callback callback, unsigned long duration = 0);
338+
```
302339

303-
#define TIMER2_INTERVAL_MS 2000
340+
as follows
341+
342+
```
343+
void TimerHandler0()
344+
{
345+
// Doing something here inside ISR
346+
}
347+
348+
#define TIMER0_FREQ_HZ 5555.555
304349
305350
void setup()
306351
{
307-
Serial.begin(115200);
308-
while (!Serial);
352+
....
353+
354+
// Frequency in float Hz
355+
if (ITimer0.attachInterrupt(TIMER0_FREQ_HZ, TimerHandler0))
356+
Serial.println("Starting ITimer0 OK, millis() = " + String(millis()));
357+
else
358+
Serial.println("Can't set ITimer0. Select another freq. or timer");
359+
}
360+
```
309361

310-
Serial.println(F("\nStarting Argument_None"));
311-
Serial.println(TIMER_INTERRUPT_VERSION);
312-
Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));
313362

314-
// Select Timer 1-2 for UNO, 0-5 for MEGA
315-
// Timer 2 is 8-bit timer, only for higher frequency
316-
ITimer1.init();
363+
### 2. Using 16 ISR_based Timers from 1 Hardware Timer
317364

318-
// Using ATmega328 used in UNO => 16MHz CPU clock ,
319-
// For 16-bit timer 1, 3, 4 and 5, set frequency from 0.2385 to some KHz
320-
// For 8-bit timer 2 (prescaler up to 1024, set frequency from 61.5Hz to some KHz
365+
### 2.1 Important Note
321366

322-
if (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS, TimerHandler1))
323-
{
324-
Serial.print(F("Starting ITimer1 OK, millis() = ")); Serial.println(millis());
325-
}
326-
else
327-
Serial.println(F("Can't set ITimer1. Select another freq. or timer"));
367+
The 16 ISR_based Timers, designed for long timer intervals, only support using **unsigned long millisec intervals**. If you have to use much higher frequency or sub-millisecond interval, you have to use the Hardware Timers directly as in [1.3 Set Hardware Timer Frequency and attach Timer Interrupt Handler function](#13-set-hardware-timer-frequency-and-attach-timer-interrupt-handler-function)
328368

329-
// Select Timer 1-2 for UNO, 0-5 for MEGA
330-
// Timer 2 is 8-bit timer, only for higher frequency
331-
ITimer2.init();
369+
### 2.2 Init Hardware Timer and ISR-based Timer
332370

333-
if (ITimer2.attachInterruptInterval(TIMER2_INTERVAL_MS, TimerHandler2))
334-
{
335-
Serial.print(F("Starting ITimer2 OK, millis() = ")); Serial.println(millis());
336-
}
337-
else
338-
Serial.println(F("Can't set ITimer2. Select another freq. or timer"));
371+
```
372+
// Select the timers you're using, here ITimer2
373+
#define USE_TIMER_1 false
374+
#define USE_TIMER_2 true
375+
#define USE_TIMER_3 false
376+
#define USE_TIMER_4 false
377+
#define USE_TIMER_5 false
378+
379+
// Init ISR_Timer
380+
// Each ISR_Timer can service 16 different ISR-based timers
381+
ISR_Timer ISR_Timer2;
382+
```
383+
384+
#### 2.3 Set Hardware Timer Interval and attach Timer Interrupt Handler functions
385+
386+
```
387+
void TimerHandler()
388+
{
389+
ISR_Timer2.run();
339390
}
340391
341-
void loop()
392+
#define HW_TIMER_INTERVAL_MS 50L
393+
394+
#define TIMER_INTERVAL_2S 2000L
395+
#define TIMER_INTERVAL_5S 5000L
396+
#define TIMER_INTERVAL_11S 11000L
397+
#define TIMER_INTERVAL_101S 101000L
398+
399+
// In AVR, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
400+
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
401+
// Or you can get this run-time error / crash
402+
void doingSomething2s()
403+
{
404+
// Doing something here inside ISR every 2 seconds
405+
}
406+
407+
void doingSomething5s()
408+
{
409+
// Doing something here inside ISR every 5 seconds
410+
}
411+
412+
void doingSomething11s()
342413
{
414+
// Doing something here inside ISR every 11 seconds
415+
}
343416
417+
void doingSomething101s()
418+
{
419+
// Doing something here inside ISR every 101 seconds
344420
}
345421
422+
void setup()
423+
{
424+
....
425+
426+
// Interval in microsecs
427+
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
428+
{
429+
lastMillis = millis();
430+
Serial.println("Starting ITimer OK, millis() = " + String(lastMillis));
431+
}
432+
else
433+
Serial.println("Can't set ITimer correctly. Select another freq. or interval");
434+
435+
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
436+
// You can use up to 16 timer for each ISR_Timer
437+
ISR_Timer2.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
438+
ISR_Timer2.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
439+
ISR_Timer2.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
440+
ISR_Timer2.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
441+
}
346442
```
347443

348444
---

0 commit comments

Comments
 (0)