連載
» 2014年01月07日 09時30分 UPDATE

アイデア・ハック!! Arduinoで遊ぼう(7):白黒なのにカラーに見える!? モーターを制御して「ベンハムのコマ」を作ろう! (2/3)

[三月兎,MONOist]

Arduinoでコマを回そう! PWMでDCモーターを制御する

 それでは、Arduinoの統合開発環境「Arduino IDE」で、スケッチ(プログラム)を作成していきましょう(スケッチ1)。


const int MTR_PIN1 = 5;  // TA7291P 5番ピン
const int MTR_PIN2 = 6;  // TA7291P 6番ピン
const int VOL = A0;      // 半固定抵抗
 
void setup() {
  // モーター制御要のピンモードを「出力」に設定
  pinMode(MTR_PIN1, OUTPUT);
  pinMode(MTR_PIN2, OUTPUT);
 
  pinMode(VOL, INPUT);         // 半固定抵抗(ボリューム)のピンモードを「入力」に設定
}
 
// ループに書かれたプログラムを繰り返す
void loop() {
  int vol_val = analogRead(VOL) ;  // 半固定抵抗の値を取得
 
  // 半固定抵抗の値(0〜1023)を、PWMの値(−255〜255)に変換
  int speed_val = map(vol_val, 0, 1023, -255, 255);
  
  // PWMの値が「5」より大きいとき、モーターを「正転」
  if( speed_val > 5){
    analogWrite(MTR_PIN1, speed_val);
    digitalWrite(MTR_PIN2, LOW);
 
  // PWMの値が「−5」より小さいとき、モーターを「逆転」
  } else if(speed_val < -5){
    digitalWrite(MTR_PIN1, LOW);
    analogWrite(MTR_PIN2, -speed_val);
 
  // それ以外のとき、モーターを「停止」
  } else {
    digitalWrite(MTR_PIN1, LOW);
    digitalWrite(MTR_PIN2, LOW);
  }
}
 
スケッチ1 「ベンハムのコマ実験装置」のスケッチ

 1〜3行目は、ピンの設定です。そして5行目の「setup()」内で、モーターのピンを「出力」、半固定抵抗のピンを「入力」にします(7〜10行目)。ここまではArduinoのお約束ですね。

 14行目の「loop()」内では、半固定抵抗の電圧(0〜5V)を0〜1023に変換した値を取り込んでいます。

 18行目で、関数「map()」が初登場します。この関数は、数値をある範囲から別の範囲に変換する関数です。今回は、0〜1023の値を、−255〜255に変換しています。つまり、半固定抵抗を一番左端まで回したとき(0)を「−255」に、右端まで回したとき(1023)を「255」に、変換しているわけです。これは、半固定抵抗の値が「512」のときを“中心”として、半固定抵抗のつまみを右に回したらモーターを「正回転」、左に回したら「逆回転」させるためです。

 21〜34行目まで、if文を使ってモーターの回転方向と停止の制御を行っています。半固定抵抗のつまみを「0」ぴったりに合わせるのは難しいので、−5〜5と“遊び”を持たせてモーターを停止させています。

 「speed_val」の値が「5」よりも大きいときに、モーターは「正回転」します。値が大きくなればなるほど、モーターの回転速度がアップします。speed_valの値が「−5」よりも小さいときは、「逆回転」になります。

 モーターは、「MTR_PIN1」と「MTR_PIN2」の出力状態によって制御されます(表3)。今回は、回転速度を調整するために、digitalWrite()で「HIGH」を指定するのではなく、analogWrite()を使って、PWM(Pulse Width Modulation)の値を入れています。このとき、analogWrite()に“マイナス値”を与えないように注意してください。逆回転のときは、speed_valを“絶対値”に変換して引数とします(28行目)。

「TA7291P」のピンファンクション 表3 「TA7291P」のピンファンクション。青色枠内は今回の回路で使用したピン(CW:正回転/CCW:逆回転)

 PWMについては、連載5回「秋の夜長をロマンチックに―― 「フルカラーLED調光ランプ」を作ろう!」で解説しています。このときは、PWMでLEDの明るさを調整しましたが、今回のようにモーターの速度を調整するのにも使えます。

 連載5回の記事に対して読者の方から、「なぜ、analogRead()で取り込んだ値(0〜1023)を、「4」で割ってからalalogWrite()に渡しているのか?」と質問をいただきました。

 Arduinoに搭載されているマイコンは、10ビットのA/Dコンバータを内蔵しています。analogRead()で入力電圧を読み取る際、A/Dコンバータの働きで、0〜5Vの値を0〜1023の数値に変換しています。一方、analogWrite()で出力できるのは8ビットの0〜255の値です。そのため、10ビットから8ビットに変換する必要があります。

 「LOW」を出力するのに「analogWrite(MOTER_PIN1,0)」とせずに、「digitalWrite(MOTER_PIN1,LOW)」としているのは、リファレンスに以下の記述があるためです。

ピン5とピン6のPWM出力は、デューティ比が高めになります。これはPWM出力に使う内蔵タイマーを、millis()やdelay()といった関数でも利用していることが原因です。注意が必要なのは、デューティ比を低くして使うときで(例えば、0〜10)、仮にパラメータを「0」に設定しても、ピン5とピン6の出力は完全にはオフにならないかもしれません。



Copyright © ITmedia, Inc. All Rights Reserved.