USB 赤外リモコンの製作

ちょっと鬱々とした日々が続いてますが、これではいけないと、Arduino を使った工作を始めました。PC (あるいは Linux ボックス)に USB 経由で繋いで、家電(エアコンや照明)を赤外線リモコンで制御しようというものです。以前は、Ethernet 付き PIC を使って、スタンドアローンなものを作りましたが、今回はできるだけお手軽にということで(また、リモコンを PC のそばに置けるので)、Arduino を使うことにしました。
いまのところ、LED の点滅や、赤外線センサが拾ったリモコンシーケンスを PC に取り込むところまでできています。最初、シーケンスを読みながらシリアルポートに送ることを考えたのですが、コマンドシーケンスのほうが速すぎてうまくいきませんでした。Serial.writeln() はバッファリングをしてくれないのでしょうか。しょうがないので、デカい配列を用意しておき、そこに取り込んだコマンドシーケンスを後でシリアルポートで送り出すようにしました。(最近赤外線リモコンから離れてしまっているので、しばらくハマりました。ここが参考になりました。ありがとうございます。)
あと悩んだのは、Arduino IDE がコードをどのようにコンパイルしているか、です。こいつは main() 関数を使わない特殊な C 言語になっていて、C 言語になじみのある人には、かえって分かりづらい仕様なのです。詳細は、ここに説明がありました。

通常の C 言語環境でコンパイルする場合と、Arduino で動かす場合とコードを共用したかったのですが、#ifdef での切り分けがうまくいきませんでした。上記ドキュメントを読むと、最初に #include "WProgram.h" すると書かれているのですが、これは実は嘘で、WProgram.h は先頭で取り込まれません。とりあえず回避策として、#ifdef __AVR__ で切り分けることにしました。あまり良い方法ではありませんが。
あと、もう少し考えなくてはいけないのは、赤外線 LED を 38kHz で変調(二次変調?)する部分です。Arduino ではタイマ割込とか使わない流儀みたいなので、ちょっと工夫が必要です。工夫というか、タイマの読み出し値を使って busy-wait するしかないのかも。
備忘録なので、分かりづらい日記でごめんなさい。(ちょっと風邪気味かも。頭が働かない。)

GCC で事前定義マクロを表示する

man ページにありました。

$ /cygdrive/c/arduino-0018/hardware/tools/avr/bin/avr-gcc.exe -dM -E - < /dev/null

とか。(Cygwin が入っている場合。)

ちなみに PIC と比較

最近 PIC から離れているので浦島太郎かも知れませんが、AVR マイコンコンパイラGCC ベースで(あるいは、GCC ベースのものが使えるので)使いやすい感じです。またこれは有名な話ですが、AVR の I/O ポートは洗練されていて、PIC より分かりやすいかも知れません。