Does the XIAO support timer interrupts? If so, does anyone have a sample sketch for Arduino that demonstrates? I’m familiar with interrupts on the Uno, but my code fails to compile for the XIAO. Thanks.
You can try the API. I hope it meets your needs.
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
Thank you, that is most helpful.
That doesn’t look like a timer interrupt to me it looks like an interrupt on a pin.
Yeah, you’re right, that is all about interrupt pins
You’ve probably found something by now, so I guess this is for the benefit of anyone else looking
#include <Arduino.h>
#include <TimerTC3.h>
#define Transmission_Timer TimerTc3
/****************
* Forward declarations of functions
*************************************************************/
void TRANSMISSION_ISR();
void transmit();
/****************
* Evaluated to determine whether or not we need to send a message
*************************************************************/
volatile bool TransmitNextMessage = false;
void setup()
{
Serial.begin(115200);
// allow time for serial start and port monitoring tool connection
uint32_t timestamp = millis();
while(millis() - timestamp < 2000)
;
/****************
* Initialize the timer and register the ISR function
*************************************************************/
Transmission_Timer.initialize(); // The default interval is 1000000 microseconds
Transmission_Timer.attachInterrupt(TRANSMISSION_ISR);
}
unsigned long packetnum = 1; // packet counter, we increment per xmission
void loop()
{
/****************
* Disable the IRQ so that we can safely access the shared resource
*************************************************************/
__disable_irq();
bool run = TransmitNextMessage;
if(run)
TransmitNextMessage = !TransmitNextMessage;
/****************
* Don't forget to reenable the IRQ
*************************************************************/
__enable_irq();
if(run)
transmit();
}
/****************
* The ISR must return as quickly as possible
*************************************************************/
void TRANSMISSION_ISR() { TransmitNextMessage = true; }
/****************
* This function is called each time the Timer period elapses
* but it happens as part of the main loop()
*
* Remember that you should NEVER write to Serial
* from within an ISR
*************************************************************/
void transmit()
{
Serial.printf("Hello World # %lu", packetnum++);
}
One of my teammates was working with an arduino mega while writing this code. now i have to use the Seeeduino XIAO, therefore the time interrupts isn’t working and i get compilation error. any suggestion ? (without too much change in the code)
hi this is Timer intterupt basic code
#include <TimerTC3.h>
void setup()
{
TimerTc3.initialize(1000000);
TimerTc3.attachInterrupt(timerIsr);
}
void loop()
{ }
void timerIsr()
{ /in your code }
A very good hint. Simple and clear.
I think TimerTC3 has a bug.
I tried TimerTc3.initialize 10922 → 10923 and 10923 → 10922 in order.
Then the timer slowed down.
ex.
08:25:40.101 → CountUp:10922
08:25:40.101 → CountUp:10922
08:25:40.135 → CountUp:10922
08:25:40.135 → CountUp:10922
08:25:40.821 → CountUp:10923 <= +686msec
08:25:41.543 → CountUp:10923 <= +722msec
08:25:42.234 → CountUp:10923 <= +691msec
08:41:01.160 → CountUp:10923
08:41:01.160 → CountUp:10923
08:41:01.194 → CountUp:10923
08:41:01.194 → CountUp:10923
08:41:02.605 → CountUp:10922 <= +1.411sec
08:41:04.010 → CountUp:10922 <= +1.405sec
08:41:05.386 → CountUp:10922 <= +1.376sec
Setting from 10922 or less to 10923 or more or from 10923 or more to 10922 or less is NG ?
#include <Arduino.h>
#include <TimerTC3.h>
uint32_t tc_time = 10920;
int count = 0;
void setup()
{
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
TimerTc3.initialize(tc_time);
TimerTc3.attachInterrupt(int_timer);
Serial.println("Start");
}
void loop()
{
delay(10);
}
void int_timer()
{
Serial.print("CountUp:");
Serial.println(tc_time);
if(++count >= 10)
{
tc_time++;
TimerTc3.stop();
TimerTc3.initialize(tc_time);
TimerTc3.attachInterrupt(int_timer);
count = 0;
}
}
Self-resolved!
I fixed TimerTC3.cpp.
Thanks.
void TimerTC3::setPeriod(long microseconds)
{
TcCount16 *TC = (TcCount16 *)TC3;
uint32_t cycles = (CPU_HZ / 1000000) * microseconds;
uint32_t prescalerConfigBits;
if (cycles < RESOLUTION)
prescalerConfigBits = TC_CTRLA_PRESCALER_DIV1;
else if ((cycles >>= 1) < RESOLUTION)
prescalerConfigBits = TC_CTRLA_PRESCALER_DIV2;
else if ((cycles >>= 1) < RESOLUTION)
prescalerConfigBits = TC_CTRLA_PRESCALER_DIV4;
else if ((cycles >>= 1) < RESOLUTION)
prescalerConfigBits = TC_CTRLA_PRESCALER_DIV8;
else if ((cycles >>= 1) < RESOLUTION)
prescalerConfigBits = TC_CTRLA_PRESCALER_DIV16;
else if ((cycles >>= 2) < RESOLUTION)
prescalerConfigBits = TC_CTRLA_PRESCALER_DIV64;
else if ((cycles >>= 2) < RESOLUTION)
prescalerConfigBits = TC_CTRLA_PRESCALER_DIV256;
else if ((cycles >>= 2) < RESOLUTION)
prescalerConfigBits = TC_CTRLA_PRESCALER_DIV1024;
else
cycles = RESOLUTION - 1, prescalerConfigBits = TC_CTRLA_PRESCALER_DIV1024;
/*
SerialUSB.print("cycles is ");
SerialUSB.println(cycles);
SerialUSB.print("prescalerConfigBits is ");
SerialUSB.println(prescalerConfigBits);
*/
// Set prescaler
uint32_t CtrlA = TC->CTRLA.reg;
uint32_t Enable = CtrlA & TC_CTRLA_ENABLE;
TC->CTRLA.reg = CtrlA & ~TC_CTRLA_ENABLE;
CtrlA &= ~TC_CTRLA_PRESCALER_Msk;
CtrlA |= prescalerConfigBits;
//TC->CTRLA.reg |= prescalerConfigBits;
TC->CTRLA.reg = CtrlA;
while (TC->STATUS.bit.SYNCBUSY == 1)
;
TC->CC[0].reg = cycles;
while (TC->STATUS.bit.SYNCBUSY == 1)
;
TC->CTRLA.reg |= Enable;
while (TC->STATUS.bit.SYNCBUSY == 1)
;
//TC->PER.reg = cycles;
//while (TC->STATUS.bit.SYNCBUSY == 1);
}