スケッチの正体

Arduino のスケッチはC(C++)に変換されてからgccコンパイルされます.Makefile をみると変換方法がわかるのですが,ちゃんとしたトランスレータが用意されているわけではなく,要するにヘッダ部分と関数 main の定義をくっつけているだけなんですね.ちょっとびっくりしました.

applet_files: $(TARGET).pde
        # Here is the "preprocessing".
        # It creates a .cpp file based with the same name as the .pde file.
        # On top of the new .cpp file comes the WProgram.h header.
        # At the end there is a generic main() function attached.
        # Then the .cpp file will be compiled. Errors during compile will
        # refer to this new, automatically generated, file. 
        # Not the original .pde file you actually edit...
        test -d applet || mkdir applet
        echo '#include "WProgram.h"' > applet/$(TARGET).cpp
        cat $(TARGET).pde >> applet/$(TARGET).cpp
        cat $(ARDUINO)/main.cxx >> applet/$(TARGET).cpp

補足:IDEを使った場合は,単にヘッダと関数 main の定義を付けるだけでなく,関数プロトタイプを生成してくれます.ただしちゃんとした構文解析をせずに正規表現で関数定義を見つけているので,書き方によってはプロトタイプができない可能性があります.例えば関数ポインタを引数や返値にするとだめです.


変換の例を示します.次のようなLED点滅のスケッチ Blink.pde を用意します.

int ledPin = 13;

void setup () {
    pinMode(ledPin, OUTPUT);
}

void loop () {
    digitalWrite(ledPin, HIGH);
    delay(250);
    digitalWrite(ledPin, LOW);
    delay(250);
}

これを変換すると applet というサブディレクトリに以下の内容の Blink.cpp が作られます(インデント等修正済み).

#include "WProgram.h"

int ledPin = 13;

void setup () {
    pinMode(ledPin, OUTPUT);
}

void loop () {
    digitalWrite(ledPin, HIGH);
    delay(250);
    digitalWrite(ledPin, LOW);
    delay(250);
}

int main (void) {
    init();
    setup();
    for (;;)
        loop();
    return 0;
}

そんなわけで,最初から C や C++ で書いた方が(我々コンピュータ屋にとっては)楽かも知れません.