概要
LEDの点灯と似ているが,ここではLEDの点滅をやってみる.一般的なArduinoIDEを用いた開発では,LED点灯と同様にHello World的な扱いとなるが,一定時間待って点灯と消灯を繰り返す点滅は,ちょっとめんどくさい.点滅ができると,シリアルによるデータ送信以外でデバッグがしやすくなる(あるパスを通ったら点灯/消灯とか.シリアル通信自身のデバッグとかに使える).少しハマったので,まとめておく.なお,この記事はLED点灯の知識を前提としている
LEDを消す
LEDを消すために,以下のようにturnoff
をアセンブリ言語で追加する.
なお,turnon
は点灯する関数
.globl turnon
.type turnon, @function
turnon:
push r16
ldi r16, 0b00100000
out 0x5, r16
pop r16
ret
.globl turnoff
.type turnoff, @function
turnoff:
push r16
ldi r16, 0b00000000
out 0x5, r16
pop r16
ret
そして,これらの関数をmain
から呼び出せば良い
void setout();
void turnon();
void turnoff();
int flg = 1;
/* 遅延するための関数 */
int wait(int seed) {
int i;
for (i = seed; i < seed+32000; ++i) {
}
return i;
}
int main(void) {
setout();
turnoff();
int flg = 1;
int v = 1;
while(1) {
if (flg == 0) {
turnon();
flg = 1;
} else if (flg == 1) {
turnoff();
flg = 0;
}
wait(v);
wait(v);
wait(v);
v++;
}
return 0;
}
やることは実に単純だが,点滅が早すぎると人間が目視で確認できない.ArduinoIDEを使うと,delay(millisec)
を使うことで遅延させることができるが,そんな関数は今無いので無理やり時間がかかる処理を追加して(wait
)代用する.
wait
で
for (i = seed; i < seed+32000; ++i) {
としているのは,ArduinoUnoは16ビットなため,intの大きさも2バイトで,32767以上の生の数を表せないため.仕方ないので,この関数を3回呼び出して適当に遅延させている.
さらに,このwait
自身は何も影響を与えないため,最適化オプションを使って(-Ox
)コンパイルすると,このループが削除されるか,wait
の呼び出しが削除されて遅延しない(気づくまでに時間がかかった)ので注意すること.
このコードで,1秒間に3回くらいの点滅を目視で確認できる.
LED点滅プログラムは以下のコマンドで実行することができる
>git clone https://github.com/hiro4669/iosv.git
>cd iosv/led_onoff
>make
>make write