前回は、Arduino IDE の設定をしました。エラーに見舞われながらも、Arduino Nano Every を使う準備ができました。
今回は、スケッチ例から Blink などの、いわゆる L チカを試してみましょう。
Blink
電子工作の第一歩ですねぇ。
外部回路はありません。Arduino Nano Every を USB ケーブルでパソコンにつなぐだけ。
USB ケーブルは「A オス – マイクロ B オス」です。
以前のスマートホンで使っていたので、何本か持っているのですが、スマートホン用って充電専用だったり、データ転送が遅かったりするので要注意です。秋月電子通商から新しいのを 1 本、購入しました。
スケッチは、スケッチ例から Blink を選択すれば良いのですが、簡単なスケッチなので自分で書いてみましょう。
- // Blink
- void setup() {
- pinMode(LED_BUILTIN, OUTPUT);
- }
- void loop() {
- digitalWrite(LED_BUILTIN, HIGH);
- delay(1000);
- digitalWrite(LED_BUILTIN, LOW);
- delay(1000);
- }
マイコンボードに書き込む、を実行すると、Arduino Nano Every ボード上の LED “L” が点滅します。といっても、工場出荷時に Blink が書き込まれているようなので、すでに点滅していて変化がわからない (^_^;)
点灯時間は 9 行目の delay(1000) 、消灯時間は 11 行目の delay(1000) ですから、それぞれを好きな時間に変更してみれば、書き込まれていることが確認できます。
ちなみに、LED_BUILTIN は内蔵 LED がつながっているピンの番号のことですから、Arduino Nano Every の場合は「13」と書き換えても同じことです。
Blink without Delay
LED を点滅させるだけなら Arduino など使うまでもないです。なにか他のことも一緒に処理したいから Arduino を使う。となると、Blink のスケッチにある delay() が邪魔になります。delay() は、待つという仕事をしていて、その仕事中は他の処理ができない。そこで止まってしまう。
だから、delay() は捨てなければなりません。
delay() を使わないで Blink するスケッチが、Blink without Delay です。
- // Brink without Delay
- void setup() {
- pinMode(LED_BUILTIN, OUTPUT);
- }
- void loop() {
- static const long interval = 500;
- static byte ledState = LOW;
- static unsigned long previousMillis = 0;
- if(interval < millis() - previousMillis) {
- previousMillis = millis();
- ledState ^= 1;
- digitalWrite(LED_BUILTIN, ledState);
- }
- }
スケッチ例とはいろいろ違っていますが、基本は同じです。
最後に LED の状態が更新された時刻を previousMillis に記憶させておいて、次のループで現在時刻をチェックし、更新する時刻かどうかを判断するということ。いわゆる、ステートマシンです。
8〜10 行の static で始まる変数の定義は、最初の 1 回だけ実行する、という意味です。たとえば、変数 interval は、最初に long 型で値を 500 に定義して、次のループではそれを維持し再実行しません。こういう場合、グローバル変数として定義しちゃうことがよくあるんですけど、static をつければ、ローカル変数として定義できます。
const は、代入する値を定数とします。あとから変更できなくなるので、間違って値を触ってしまうことを防げます。#define 使うよりいいぞ、と、リファレンスに書かれてます。
9 行目の変数 ledState は byte 型になっていますが、int 型で定義するのが一般的ですね。
int 型は 2 バイト (Nano Every の場合) 、byte 型は 1 バイトを使います。ledState は “HIGH” か “LOW” かの 2 つの値しか取りませんから、1 バイトあれば十分です。
14 行目はビット演算です。
「^」は XOR 、排他的論理和の記号。ledState の値と 1 とを XOR すると、ledState の 1 バイト目が反転します。つまり、ledState が HIGH (1) であれば LOW (0) に、LOW (0) ならば HIGH (1) に変化する、ということです。
ちなみに、「ledState ^= 1」は「ledState = ledState ^ 1」の意。複合演算子です。
Flash without Delay
さて、以前「Arduino のマルチタスク」でやった、LED のオンとオフの時間が異なる Flash を試してみましょう。
ステートマシンがオンとオフの 2 つになっていますが、基本は全く同じです。
- // Flash without delay
- const bool LED_ON = HIGH;
- const bool LED_OFF = LOW;
- const byte ledPin = LED_BUILTIN;
- const unsigned long onTime = 250; // LED on time (ms)
- const unsigned long offTime = 750; // LED off time (ms)
- void setup() {
- pinMode(ledPin, OUTPUT);
- }
- void loop() {
- static bool ledState = LED_OFF;
- static unsigned long previousMillis = 0;
- unsigned long currentMillis = millis();
- if ((LED_ON == ledState) && (onTime <= currentMillis - previousMillis)) {
- ledState = LED_OFF;
- previousMillis = currentMillis;
- digitalWrite(ledPin, ledState);
- }
- else if ((LED_OFF == ledState) && (offTime <= currentMillis - previousMillis)) {
- ledState = LED_ON;
- previousMillis = currentMillis;
- digitalWrite(ledPin, ledState);
- }
- }
ということで、ごく基本的な L チカは、問題なく Arduino Nano Every で動きました。まぁ特別な命令もなにもないですもんね (^_^;)
では次は、外部になにか回路を作って動かしてみましょう。