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

Commit fbf8a91

Browse files
authored
Add example to demo sub-ms interval
Add Argument_None_uS example to demonstrate how to use sub-ms interval
1 parent cc1a1ce commit fbf8a91

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/****************************************************************************************************************************
2+
Argument_None_uS.ino
3+
For SAMD boards
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/SAMD_TimerInterrupt
7+
Licensed under MIT license
8+
9+
Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
10+
unsigned long miliseconds), you just consume only one SAMD timer and avoid conflicting with other cores' tasks.
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+
Based on SimpleTimer - A timer library for Arduino.
16+
17+
Copyright (c) 2010 OTTOTECNICA Italy
18+
19+
Based on BlynkTimer.h
20+
Author: Volodymyr Shymanskyy
21+
22+
Version: 1.3.0
23+
24+
Version Modified By Date Comments
25+
------- ----------- ---------- -----------
26+
1.0.0 K Hoang 30/10/2020 Initial coding
27+
1.0.1 K Hoang 06/11/2020 Add complicated example ISR_16_Timers_Array using all 16 independent ISR Timers.
28+
1.1.1 K.Hoang 06/12/2020 Add Change_Interval example. Bump up version to sync with other TimerInterrupt Libraries
29+
1.2.0 K.Hoang 08/01/2021 Add better debug feature. Optimize code and examples to reduce RAM usage
30+
1.3.0 K.Hoang 02/04/2021 Add support to Sparkfun SAMD21 and SAMD51 boards
31+
*****************************************************************************************************************************/
32+
33+
/*
34+
Notes:
35+
Special design is necessary to share data between interrupt code and the rest of your program.
36+
Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
37+
variable can not spontaneously change. Because your function may change variables while your program is using them,
38+
the compiler needs this hint. But volatile alone is often not enough.
39+
When accessing shared variables, usually interrupts must be disabled. Even with volatile,
40+
if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
41+
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
42+
or the entire sequence of your code which accesses the data.
43+
*/
44+
45+
#if !( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
46+
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
47+
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
48+
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
49+
|| defined(__SAMD51G19A__) || defined(__SAMD51P19A__) || defined(__SAMD21G18A__) )
50+
#error This code is designed to run on SAMD21/SAMD51 platform! Please check your Tools->Board setting.
51+
#endif
52+
53+
// These define's must be placed at the beginning before #include "SAMDTimerInterrupt.h"
54+
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
55+
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
56+
// Don't define TIMER_INTERRUPT_DEBUG > 2. Only for special ISR debugging only. Can hang the system.
57+
#define TIMER_INTERRUPT_DEBUG 0
58+
#define _TIMERINTERRUPT_LOGLEVEL_ 0
59+
60+
#include "SAMDTimerInterrupt.h"
61+
62+
//#ifndef LED_BUILTIN
63+
// #define LED_BUILTIN 13
64+
//#endif
65+
66+
#ifndef LED_BLUE
67+
#define LED_BLUE 2
68+
#endif
69+
70+
#ifndef LED_RED
71+
#define LED_RED 8
72+
#endif
73+
74+
#define TIMER0_INTERVAL_MS 500 //1000
75+
#define TIMER0_INTERVAL_US 200 //1000
76+
77+
volatile uint32_t preMillisTimer0 = 0;
78+
79+
// Depending on the board, you can select SAMD21 Hardware Timer from TC3-TCC
80+
// SAMD21 Hardware Timer from TC3 or TCC
81+
// SAMD51 Hardware Timer only TC3
82+
83+
// Init SAMD timer TIMER_TC3
84+
SAMDTimer ITimer0(TIMER_TC3);
85+
86+
void TimerHandler0()
87+
{
88+
static bool toggle0 = false;
89+
90+
#if (TIMER_INTERRUPT_DEBUG > 0)
91+
static uint32_t curMillis = 0;
92+
93+
curMillis = millis();
94+
95+
if (curMillis > TIMER0_INTERVAL_MS)
96+
{
97+
Serial.print(F("ITimer0: millis() = ")); Serial.print(curMillis);
98+
Serial.print(F(", delta = ")); Serial.println(curMillis - preMillisTimer0);
99+
}
100+
101+
preMillisTimer0 = curMillis;
102+
#endif
103+
104+
//timer interrupt toggles pin LED_BUILTIN
105+
digitalWrite(LED_BUILTIN, toggle0);
106+
toggle0 = !toggle0;
107+
}
108+
109+
#if (TIMER_INTERRUPT_USING_SAMD21)
110+
111+
#define TIMER1_INTERVAL_MS 2000
112+
113+
volatile uint32_t preMillisTimer1 = 0;
114+
115+
// Init SAMD timer TIMER_TCC
116+
SAMDTimer ITimer1(TIMER_TCC);
117+
118+
void TimerHandler1()
119+
{
120+
static bool toggle1 = false;
121+
122+
#if (TIMER_INTERRUPT_DEBUG > 0)
123+
static uint32_t curMillis = 0;
124+
125+
curMillis = millis();
126+
127+
if (curMillis > TIMER1_INTERVAL_MS)
128+
{
129+
Serial.print(F("ITimer1: millis() = ")); Serial.print(curMillis);
130+
Serial.print(F(", delta = ")); Serial.println(curMillis - preMillisTimer1);
131+
}
132+
133+
preMillisTimer0 = curMillis;
134+
#endif
135+
136+
//timer interrupt toggles outputPin
137+
digitalWrite(LED_BLUE, toggle1);
138+
toggle1 = !toggle1;
139+
}
140+
#endif
141+
142+
void setup()
143+
{
144+
pinMode(LED_BUILTIN, OUTPUT);
145+
pinMode(LED_BLUE, OUTPUT);
146+
147+
Serial.begin(115200);
148+
while (!Serial);
149+
150+
delay(100);
151+
152+
Serial.print(F("\nStarting Argument_None_uS on ")); Serial.println(BOARD_NAME);
153+
Serial.println(SAMD_TIMER_INTERRUPT_VERSION);
154+
Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));
155+
156+
// Interval in microsecs
157+
//if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * 1000, TimerHandler0))
158+
if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_US, TimerHandler0))
159+
{
160+
preMillisTimer0 = millis();
161+
Serial.print(F("Starting ITimer0 OK, millis() = ")); Serial.println(preMillisTimer0);
162+
}
163+
else
164+
Serial.println(F("Can't set ITimer0. Select another freq. or timer"));
165+
166+
#if (TIMER_INTERRUPT_USING_SAMD21)
167+
// Interval in microsecs
168+
if (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS * 1000, TimerHandler1))
169+
{
170+
preMillisTimer1 = millis();
171+
Serial.print(F("Starting ITimer1 OK, millis() = ")); Serial.println(preMillisTimer1);
172+
}
173+
else
174+
Serial.println(F("Can't set ITimer1. Select another freq. or timer"));
175+
#endif
176+
}
177+
178+
void loop()
179+
{
180+
181+
}

0 commit comments

Comments
 (0)