割り込み

\[ \newcommand{dn}[3]{\frac{\mathrm{d}^{#3} #1}{\mathrm{d} #2^{#3}}} \newcommand{\d}[2]{\frac{\mathrm{d} #1}{\mathrm{d} #2}} \newcommand{\dd}[2]{\frac{\mathrm{d}^2 #1}{\mathrm{d} {#2}^2}} \newcommand{\ddd}[2]{\frac{\mathrm{d}^3 #1}{\mathrm{d} {#2}^3}} \newcommand{\pdn}[3]{\frac{\partial^{#3} #1}{\partial {#2}^{#3}}} \newcommand{\pd}[2]{\frac{\partial #1}{\partial #2}} \newcommand{\pdd}[2]{\frac{\partial^2 #1}{\partial {#2}^2}} \newcommand{\pddd}[2]{\frac{\partial^3 #1}{\partial {#2}^3}} \newcommand{\p}{\partial} \newcommand{\D}[2]{\frac{\mathrm{D} #1}{\mathrm{D} #2}} \newcommand{\Re}{\mathrm{Re}} \newcommand{\Im}{\mathrm{Im}} \newcommand{\bra}[1]{\left\langle #1 \right|} \newcommand{\ket}[1]{\left|#1 \right\rangle} \newcommand{\braket}[2]{\left\langle #1 \middle|#2 \right\rangle} \newcommand{\inner}[2]{\left\langle #1 ,#2 \right\rangle} \newcommand{\l}{\left} \newcommand{\m}{\middle} \newcommand{\r}{\right} \newcommand{\f}[2]{\frac{#1}{#2}} \newcommand{\eps}{\varepsilon} \newcommand{\ra}{\rightarrow} \newcommand{\F}{\mathcal{F}} \newcommand{\L}{\mathcal{L}} \newcommand{\t}{\quad} \newcommand{\intinf}{\int_{-\infty}^{+\infty}} \newcommand{\R}{\mathcal{R}} \newcommand{\C}{\mathcal{C}} \newcommand{\Z}{\mathcal{Z}} \newcommand{\bm}[1]{\boldsymbol{#1}} \]

Arduinoでの可変長のタイマ割り込みの例。

const byte LED_PIN = 13;
bool led_state = false;

// Format
// int[N*2]
// int[i*2]     : dt_i
// int[i*2 + 1] : j_i

const int N=16;
uint16_t i=0, j=0;

const uint16_t profile[N] = {
  0xFFFF,    8,
  0x7FFF,   16,
  0x3FFF,   32,
  0x1FFF,   64,
  0x0FFF,  128,
  0x07FF,  256,
  0x03FF,  512,
  0x01FF, 1024 
};

void setup() {
  pinMode(LED_PIN, OUTPUT);
  TCCR1A = 0b00000000;  // Mode4(MGM10=0,MGM11=0) CTC
  TCCR1B = 0b00001100;  // Mode4(MGM12=1,MGM13=0):clkI/256 (From prescaler)
  TIMSK1 = 0b00000010;  // OCIE1A: Timer/Countern, Output Compare A Match Interrupt Enable
  OCR1A  = 62500;
}

int next_ij(){
  if(j+1 == profile[i*2+1]) ++i, j=0;
  else ++j;
}

ISR(TIMER1_COMPA_vect) {
  // Toggle LED
  led_state = !led_state;
  digitalWrite(LED_PIN, led_state);
  // Next Interval 
  OCR1A = profile[i*2];
  next_ij();
  // Exit
  if(i*2>=N){
    digitalWrite(LED_PIN, false);
    exit(0);
  }
}

void loop() {
}