自分用のタイマ割込を使う

昨日試したところ、自作の赤外リモコンの送信コードがうまく動かないことが分かりました。コードを UNIX 上の擬似環境で動かしたり、コードを追ったりしてみたのですが、ロジックは特におかしくないようです。1us のクロック精度の問題かとか、他のタイミング誤差かとか、38kHz を生成するための除算コードに演算時間を取られ過ぎているのではないかとか、いろいろ頭の中で検討してみたのですが、現物デバッグができないので、らちがあきません。(さすがに仕事中に Arduino を机に広げる訳にはいかないので。)
しかし、昼休みに ./hardware/arduino/cores/arduino/wiring.c を読んでいて、タイマ 0 がプリスケーラ 1/64 で動いていることなどを発見し、これでは私の 38kHz 処理コードには無理があることが分かりました。16MHz の 1/64 は 250kHz で、38kHz 周期のタイミングを得るには荒すぎるのです*1。さらに調べたところ、ATmega328 では、他にタイマ 1, 2 があって、これらはプリスケーラや PWM の設定はされているものの、割込サービスルーチンまでは記述されていないことが分かりました。つまり、自分の好きな割込みルーチンをここに埋め込むことができる訳です。他の用途に PWM を使ってなければ、プリスケーラを変えても良さそうに思えました。
しかし、いきなり Arduino でタイマ割込が必要になるコードを書いている私って、いったい。。。

後記

タイマ 2 を使って、赤外 LED を 38kHz で変調するコードを書いたら、無事にエアコンの制御に成功しました。良かった、良かった。あとはコードを綺麗に書き直して、USB 経由で送信パターンを指示できるようにして、LED 点灯回路の実装をすれば完了です。あ、ケーシングも必要だ。

*1:つまり、micros() を呼んでも、4の倍数の値しか返ってこない。