Arduinoの基礎
概要
Arduinoのスケッチには、setup()関数とloop()関数が存在する。
setup()関数はスケッチの実行開始時(電源を投入した直後)、またはボードのリセット後に1度だけ呼ばれる。
変数の初期化や、ピンモードの設定、ライブラリの初期化などを行うのに適している。
loop()関数は、setup()関数が呼ばれた後に繰り返し呼び出される。
スケッチのダウンロード
まず、スケッチをコンパイルする。
次に、Arduino IDEの[ツール]メニューバー - [ボード]メニューでArduinoボードを選択する。
更に、Arduino IDEの[ツール]メニューバー - [ポート]メニューでCOMポートを選択する。
最後に、[マイコンボードに書き込む]ボタンを押下して、コンパイルしたスケッチをダウンロードする。
LEDの点滅(ArduinoのHello World)のサンプルコード
次に示すのは、LEDを点滅させるサンプルコードである。
const int LED_PIN = 13;
void setup()
{
pinMode(LED_PIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
delay( 1000 );
}
Arduinoで電圧を測定する(アナログ入力を読み取る)
Arduinoボードは、A0 - A5までの6チャネルの10ビットのADCを持っている。
Arduino Uno等の動作電圧が5[V]のボードでは、0[V] - 5[V]までの電圧は、0 - 1023までの整数に対応付けられる。
Arduino IDEでは、analogRead()関数を用いることで、指定したアナログピンから値を読むことができる。
analogRead()関数は読み取った値を0 - 1023までの整数値で返す。
従って、5[V]を1023に対応する場合は、"analogRead()関数の戻り値 * 5 / 1023"とすれば電圧が分かる。
尚、デフォルトでanalogRead()の戻り値である0 - 1023が、0[V] - 5[V](Arduino Gemmaのような3.3[V]の動作電圧の場合は0[V] - 3.3[V])に
対応付けられているが、analogReference()関数を用いてこの範囲を変更することは可能だが、設定可能な値はボードに依存する。
次に記述するのは、電圧を読み取った結果をシリアルモニタに出力するサンプルコードである。
これによって 1秒毎にシリアルモニタに電圧が表示される。
const int PIN_ANALOG_INPUT = 5;
void setup()
{
Serial.begin(9600);
}
void loop()
{
int iVoltage = analogRead(PIN_ANALOG_INPUT);
float fVoltage = iVoltage * 5.0 / 1023.0;
Serial.println(fVoltage);
delay(1000);
}
割り込みとISR
Arduinoのスケッチでのハードウェア割込み(hardware interrupt)の利用方法について記載する。
Arduino Unoでは、2個のピン(D2, D3)が割込みに利用できる。D2は割込み番号が0、D3は割り込み番号が1である。
Arduino Mega2560では、6個(D2, D3, D18, D19, D20, D21)が使用できる。割込み番号は順に0, 1, 5, 4, 3, 2が設定されている。
割込みサービスルーチン(ISR, interrupt service routine)は、引数および戻り値が無いvoidの関数が割り当てられる。
attachInterrupt(割込み番号, 関数名, モード)でISRをセットする。
また、attachInterruptの引数にはピンの番号ではなく、割込み番号を指定することに注意すること。
ピン番号から割込み番号の解決には、digitalPinToInterruptを使用する。
次のサンプルコードでは、toggle_ledという名前のISRを、D2ピンでの割込み処理に指定している。
モードのFALLINGはHIGHからLOWの状態へ遷移したことで割込みを発生させることを意味する。
ISRでLEDが接続されたピンの状態を表す変数をLOWまたはHIGHに変化させている。
そして、loop()関数でその変数をdigitalWrite()関数に渡している。
const byte PIN_LED = 10;
const byte PIN_INTERRUPT = 2;
volatile byte state = LOW;
void setup()
{
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, state);
attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPT), toggle_led, FALLING);
}
void loop()
{
digitalWrite(PIN_LED, state);
}
void toggle_led()
{
state != state;
}
ArduinoでPWM制御
Arduinoでは、PWMによるアナログ出力(任意の出力値)をサポートしている。
デジタル信号としてHIGH(3.3[V]または5[V])とLOW(0[V])だけでなく、2[V]等の中間の値も出力できる。
これにより、LEDの調光制御を行うことができる。
PWMとは
PWM(Pulse Width Modulation)とは、電圧を制御する方法の1つである。
出力のオンとオフを行うことで、 パルス幅に比例した電圧を得ることができる。
例えば、下図のように信号の基本周期の間で、25[%]の時間だけ出力をオンにすることにより、
平均で電圧の25[%]の電圧(5[V] * 25[%] = 1.25[V])を得ることができる。
尚、この場合はオン時間をデューティーサイクル (Duty Cycle) といい、最大電圧に対する出力電圧の割合になる。
ArduinoのPWM出力
Arduino Unoでは、デジタル出力ピンの3, 5, 6, 9, 10, 11番の6個のピンがPWM制御に利用できる。
ピン番号の前に ~記号が付記されており、PWM制御が利用可能であることがわかる。
基本的に、ArduinoのPWMの周波数は約490[Hz]だが、Arduino Unoでは5番と6番ピンは980[Hz]である。
周波数が2倍ということは、波長が半分ということである。しかしながら、デューティーサイクルが同じであれば出力電圧は同じである。
analogWrite関数の使い方
Arduinoでは、PWM出力にはanalogWrite関数を使用する。
analogWrite関数の引数は、第1引数にピン番号、第2引数にデューティーサイクルを渡す。
デューティーサイクルは、パーセント表示ではなく、0(0%)から255(100%)の値をとる。
したがって、5[V]の動作電圧の時には、255 / 5 = 51より電圧 * 51として、更に整数に丸めた値をanalogWrite関数の第2引数に渡す。
analogWrite関数を1度呼ぶと、同じピンに対してanalogWrite関数、digitalWrite関数、digitalRead関数を呼ぶまで、一定のPWM波を出力する。
analogWrite関数を呼ぶためにpinModeを事前に呼ぶ必要は無い。
PWM出力のサンプルコード
次に、analogWrite関数によるPWM出力のサンプルコードを記述する。
Arduinoの3番ピンにて2[V]を出力している。
const int PIN_PWM = 3;
const float V_OUT = 2;
void setup()
{
int i = (int)V_OUT * 51;
analogWrite(PIN_PWM, i);
}
void loop()
{
}