Arduinoの割込み関数を使ってサーボモーターの回転速度を測定しました。

回転速度をどのように測定するの?

  • 連続回転サーボモーター(SG90-HV)はPWM変調の信号を入力することで回転方向と回転速度を変化させることができました。しかしSG90-HVの仕様書を探しましたがPWM変調と回転速度の関係が見つからなかったので、反射型フォトセンサを使って簡単なタコメータを作りました。Arduinoの割込み関数を使って回転速度を求めます。
サーボモーターに関連する記事は?

タコメータの構成は?

  • 反射型のフォトセンサを使います。連続回転サーボモーター(SG90-HV)のサーボモーターのシャフトに取り付けたホーンに反射板を貼付けます。反射型のフォトセンサからはLEDの光が発射され、ホーンの反射板からの反射光を検出します。ある期間に何回反射光が発生したかを測定して回転速度を計算します。

Arduinoとフォトセンサ―の接続は?

  • フォトセンサ―はROHM社の反射型フォトセンサRPR-220を使用します。
  • RPR-220はフォトダイオードとフォトトランジスタが一体となった反射型フォトセンサです。
  • RPR-220を使って反射光を受信し矩形波でArduinoに信号を送る電気回路を作成します。RPR-220の出力はアナログの出力となるので、抵抗内蔵のトランジスタを1個追加し信号を整形してArduinoのデジタル入出力ポートに接続します。(回路図はKiCADで描いています [KiCADの入手方法と学習方法 ]で使い方を説明しています。)

フォトセンサーの動作の確認はどうするの?

  • 回路図に示したフォトセンサの出力の①とArduinoへの出力②の電圧を測定します。
  • 反射型フォトセンサにアルミ箔を近づけたり離したりして電圧の変化を確認します。
  • ブレッドボードに反射型フォトセンサ、抵抗内蔵トランジスタ、抵抗を配置し、5V、GNDを接続します。アナログピンの[A0]を使って、①と②の電圧を測定します。
  • アナログ入出力の[A0]ピンを使って電圧値を計測します。
// フォトセンサの出力をアナログ値で測定する

int adc_id = 0;
int value;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
    value = analogRead(adc_id); // get adc value
    Serial.print(value);
}
  • 出力の波形をシリアルプロッタを使って確認します。
  • フォトセンサにアルミ箔を近づけたり離したりすることで①の電圧が変化していることが確認できました。
  • ①のアナログ信号が②では矩形波に整形できていることが確認できました。
Arduino IDE の使い方の記事は?

反射型フォトセンサーで実際に測定できるの?

  • ブレッドボードでの動作は確認できました。でもこのような構成ではサーボモーターのホーンの近くに反射型のフォトセンサを近づけて測定期間中に安定した距離を維持するのは困難です。
  • 汎用のPCBボードに反射型フォトセンサ、抵抗内蔵トランジスタ、抵抗とArduino接続用のピンヘッダを半田付けして測定用PCBを作成しました。
  • 作成したPCBボードを3Dプリンタで作成した治具に取り付けます。連続回転サーボモーター(SG90-HV)のホーンに貼った反射板(アルミ箔)と反射型フォトセンサの距離が約6mmになるように設計しました。
  • 連続回転サーボモーター(SG90-HV)を回転させて、測定用PCBからの信号を測定すると、一定周期で反射信号を捉えていることが確認できました。
3Dプリンタに関連する記事は?

回転時間の測定にArduinoの関数をどう使うの?

  • Arduinoは割り込み検出の関数が内蔵されています。この関数を使って反射型のフォトセンサからの反射信号の検出回数を測定します。
  • attachInterrupt()関数を使って、割り込みを有効にします。最初のパラメータはPin番号で、使用するArduinoのボードにより異なります。Arduino UNO R3の場合は、割り込みポートの0または1ピンになります。(デジタルポートの、2または3ピンになります。ピン番号が紛らわしいので注意が必要です。) 次のパラメータは割込み関数の名称です。割込み関数はvoid型でなければなりません。割込み関数名をisr()とした例です。最後のパラメータは、波形のどのような状態で割り込みをするかの設定になります。RISINGの場合は、波形が立ち上がった時に割り込みが発生します。
attachInterrupt(0,isr,RISING)
  • detachInterrupt(0)関数を使って、割り込みを無効にする設定をします。割り込みで取得した値を使って計算する期間は、割り込みが発生しても、割り込み処理をしないようにします。
detachInterrupt(0);
  • 割込み関数をstr()として定義した例です。割込み関数はvoid型でなければいけません。
void isr()     

回転数を測定するスケッチは?

  • 割込みを許可している時間内に何回割り込みが発生したかを検出し回転速度を計算します。例えば、30秒間に50回のホーンからの反射を検出した場合は、1分では100回転になりますから、回転数は100pmになります。
  • 30秒間にArduinoが何回の反射信号を受けたかを計測し、回転速度(RPM)を測定します。
  • シリアルモニタに回転速度(RPM)を出力します。
// 割込み関数を使用し回転速度を測定

float rev=0;
unsigned long rpm;
unsigned long oldtime=0;        
unsigned long time;

void isr()          //interrupt service routine
{
	rev++;
}

void setup()
{
	Serial.begin(9600);
	digitalWrite(2 ,HIGH);// Instead of using a pull up resistor
	attachInterrupt(0,isr,RISING);  //attaching the interrupt

}

void loop()
{
	delay(30000);				        // 30 second delay
	detachInterrupt(0);         //detaches the interrupt while calculating
	time=millis()-oldtime;      //finds the time 
	rpm=(rev/time)*60000;       //calculates rpm
	rev=0;

	Serial.print(rpm); 
	Serial.println( " RPM");
	 
	oldtime=millis();           //saves the current time 
	attachInterrupt(0,isr,RISING);
}
参考にしたArduinoホームページの記事は?

測定する方法は?

  • 連続回転サーボモーター(SG90-HV)に、writeMicroseconds()関数を使って、1.5msecを中心として0.05msec間隔でPWM波形を変化させたPWM信号を入力し一定速度で回転させます。その時のサーボモーターの回転数を測定します。
  • 測定のために連続回転サーボモーター(SG90-HV)を一定速度で回転させます。電源を抜くときに回転しているのは嫌なので、10分回転して、10秒止まるる動作を繰り返します。
  • loop()中のwriteMicroseconds()関数の設定値を例えば、1600、1650、1700などに変えて回転数を変化させます。
//連続回転サーボモーター(SG90-HV)を一定速度で回転させる

#include <Servo.h>
Servo myservo;

void setup(){
  myservo.attach(9);
  myservo.writeMicroseconds(1500);// move speed to 0
  delay(5000);  
} 
void loop(){
  myservo.writeMicroseconds(1600);// move speed to setting speed
  delay(600000UL);
  myservo.writeMicroseconds(1500);// move speed to 0
  delay(10000);
}
サーボモータを制御する関数を学ぶ記事は?

測定結果は?

  • 連続回転サーボモーター(SG90-HV)の回転速度の設定値(PWM信号の設定値)と回転速度の測定値の関係をグラフ化しました。
  • 今回購入した連続回転サーボモーター(SG90-HV)は以下のような結果になりました。(駆動電圧は、USB経由の5V電圧です。)
  • 最大回転速度は120 RPM程度でした
  • 最大回転速度には1500usec+350usec、1500usec-350usec程度にあり、それ以上変化させても最大回転数は上がりませでした。
  • 回転速度が0 RPMになるPWMの値は1500usecより少し少ない方向にズレていました。

測定した回転数をLCDで表示させるには?

  • I2C LCDを接続し、測定した回転数を表示させました。
  • 測定した回転数をシリアルモニタに出力すると、そのためにPCが必要になります。携帯性を持たせるためと測定の容易さを向上させるためI2C LCDに回転数の測定結果を表示させました。
  • I2C LCDを接続し、回転数を表示させる方法を記事にまとめました。

ご質問、誤植の指摘などありましたら。「問い合わせ 」のページからお願いします。