Arduino 加速度センサーを使う

このチュートリアルは武蔵野美術大学通信教育課程授業用に作成したものです。

今回は加速度センサーの使い方を学びます。

プログラム

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

void loop() {
  int sensorValueX = analogRead(A0);
  int sensorValueY = analogRead(A1);
  int sensorValueZ = analogRead(A2);
  Serial.print(sensorValueX);
  Serial.print(",");
  Serial.print(sensorValueY);
  Serial.print(",");
  Serial.println(sensorValueZ);
  delay(1);
}

最もシンプルに値だけを取得すると上記のようになります。シリアルプロッタで確認してみましょう

3つの値のうちvale3(sensorValueZ)が700あたりを示して、残りは500あたりを示しています。

センサーを傾けたり動かしたりするとこの値が変化するはずです。

値の理解

このモジュールは電源3.3V時に1Gで660mvの出力となり、5Vで1Gあたり1Vの出力となります。今回は5Vで使用を想定します。基本的に地球にいる限りZ軸に対して重力1Gがかかっているので、アナログインプットには静止状態で「X:0G,Y:0G,Z1G」がかかっているはずです。また、このセンサは中央のオフセットがかかっており、-2G~+2Gの範囲でアナログインプットで取得できるセンサーの値は0~1023までの値で、加速度を取得できます。つまり、「0.5V(-2G)〜4.5V(+2G)」となり、取得センサー値としては「約103(-2G)〜約921(+2G)」となります。静止状態ではx0,y0,z1の加速度がかかっているため「X:512,Y:512,Z:716」の数値を示すはずです(誤差はあります)

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

void loop() {
  int sensorValueX = analogRead(A0);
  int sensorValueY = analogRead(A1);
  int sensorValueZ = analogRead(A2);

  float AxisX = mapInFloat(sensorValueX, 306, 716, -1, 1); //-1G=306,+1G=716をわかりやすいように-1から+1の範囲に変換する
  float AxisY = mapInFloat(sensorValueY, 306, 716, -1, 1); //-1G=306,+1G=716をわかりやすいように-1から+1の範囲に変換する
  float AxisZ = mapInFloat(sensorValueZ, 306, 716, -1, 1); //-1G=306,+1G=716をわかりやすいように-1から+1の範囲に変換する
  
  AxisX = constrain(AxisX, -1, 1); //-1G,+1Gの範囲に収める
  AxisY = constrain(AxisY, -1, 1); //-1G,+1Gの範囲に収める
  AxisZ = constrain(AxisZ, -1, 1); //-1G,+1Gの範囲に収める


  Serial.print(AxisX);
  Serial.print(",");
  Serial.print(AxisY);
  Serial.print(",");
  Serial.println(AxisZ);
  delay(1);
}

//map関数は戻り値long型なので以下floatに変換する
float mapInFloat(float x, float iMin, float iMax, float oMin, float oMax) {
  return (x - iMin) * (oMax - oMin) / (iMax - iMin) + oMin;
}

加速度で-1~1Gまでの範囲に絞って表示させてみました。センサーの生データを利用しても良いですが、回転角度を取ったりするときなど、Gで取っておいたほうが都合が良い場合があります。実際に回転角を取ってみましょう

角度取得

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

void loop() {
  int sensorValueX = analogRead(A0);
  int sensorValueY = analogRead(A1);
  //int sensorValueZ = analogRead(A2);

  float AxisX = mapInFloat(sensorValueX, 306, 716, -1, 1); //-1G=306,+1G=716をわかりやすいように-1から+1の範囲に変換する
  float AxisY = mapInFloat(sensorValueY, 306, 716, -1, 1); //-1G=306,+1G=716をわかりやすいように-1から+1の範囲に変換する
  //float AxisZ = mapInFloat(sensorValueZ, 306, 716, -1, 1); //-1G=306,+1G=716をわかりやすいように-1から+1の範囲に変換する
  
  AxisX = constrain(AxisX, -1, 1); //-1G,+1Gの範囲に収める
  AxisY = constrain(AxisY, -1, 1); //-1G,+1Gの範囲に収める
  //AxisZ = constrain(AxisZ, -1, 1); //-1G,+1Gの範囲に収める

  int AxisTiltX = floor(asin(AxisX)*180/PI);
  int AxisTiltY = floor(asin(AxisY)*180/PI);
  //int AxisTiltZ = floor(asin(AxisZ)*180/PI);
  


  Serial.print(AxisTiltX);
  Serial.print(",");
  Serial.println(AxisTiltY);
  //Serial.print(",");
  //Serial.println(AxisTiltZ);
  delay(1);
}

角度出力はZ軸は考慮しないので[//]でコメントアウトしてます。

これでセンサーを傾けるとその角度の値が取得できました!