2014年7月20日日曜日

加速度センサに挑戦

またまた電子工作ネタです。

ただいま試作中の電子吹奏楽器"Magic Flute"に加速度センサを取り付けました。
加速度センサは回路的にはI2Cバスにただ繋ぐだけ。あとは、Raspberry Pi上で動くプログラムからこのセンサにアクセスすれば、加速度情報が得られます。

下の写真が今回の試作品の回路に組み込んだ加速度センサです。





ところで加速度センサとは一体何を検出するものでしょうか。
もちろん加速度センサでは加速度が検出できるわけですが、日々の生活で加速度といって思いつくことは少ないかもしれません。
せいぜい思いつくのは自動車の急発進検出くらいでしょうか。ちょっと非日常となると自動車で事故った瞬間にも大きな加速度が検出出来ますね。

ところで一般相対性理論によると重力は加速度と等価です。つまり加速時センサはそのまま、重力センサとなるのです。3つの次元にこのセンサを配置すれば、物体の傾きが計測できます。
また、重力がない状態、つまり自由落下状態であることも検知できます。

実際、加速度センサのマニュアルを読むと、X軸、Y軸、Z軸の加速度(重力方向との角度)を検出出来るだけでなく、センサがパルス上の加速度を検出し、シングルタップ、ダブルタップとして検出するとか、非常に大きな加速度が検出された場合の設定とか、自由落下状態の検出などが機能として入っています。
自由落下というと人工衛星の落下くらいしか想像できないと思いますが、もっと短時間なら普通にモノを落としたときも自由落下状態になります。例えば、ハードディスクを衝撃から守るためにこの加速度センサの自由落下検出が使われているようです。


さて、MagicFluteでは、このセンサを傾き検出に使います。
今のところ、傾きでビブラートの深さを変化させようと考えています。笛を吹いているとき、笛の角度が水平になっているとほぼノンビブラート、笛をほとんど垂直にするとビブラートが一番深くなります。
このような吹き方が演奏者にとって感覚的に合うものかは、実際にプログラムを作って試奏してから検討しようと思っています。

今回もRaspberry Piでこの加速度センサADXL345を使うときの、デバイスをアクセスする部分のプログラムを紹介しましょう。
正直、プログラムを使ってもらうように披露するというより、間違っている部分を指摘してもらうつもりでプログラムは公開しております。
内容は全く保証しないので、ご承知おき願います。



//-------------------------------------------------------------------------
//   ADXL345 (Acceleration Sencer : I2c Device)
//-------------------------------------------------------------------------
// for Acceleration Sencer
#define ACCEL_SNCR_PWR_CTRL   0x2d
#define ACCEL_SNCR_DATA_FORMAT  0x31
//-------------------------------------------------------------------------
void accessADXL345( void )
{
 int  address = ACCEL_SENSOR_ADDRESS;  // I2C
 
 // Set Address
 if (ioctl(i2cDscript, I2CSLAVE_, address) < 0){
  printf("Unable to get bus access to talk to slave(ACCEL)\n");
  exit(1);
 }
}
//-------------------------------------------------------------------------
void initADXL345( void )
{
 // Start Access
 accessADXL345();
 writeI2c(ACCEL_SNCR_PWR_CTRL,0x08);   // Start Measurement
 writeI2c(ACCEL_SNCR_DATA_FORMAT,0x04);  // Left Justified
}
//-------------------------------------------------------------------------
void getAccel( signed short* value )
{
 unsigned short tmp;
 
 accessADXL345();
 tmp = readI2c(0x32);
 tmp |= readI2c(0x33) << 8;
 *value = (signed short)tmp;

 tmp = readI2c(0x34);
 tmp |= readI2c(0x35) << 8;
 *(value+1) = (signed short)tmp;

 tmp = readI2c(0x36);
 tmp |= readI2c(0x37) << 8;
 *(value+2) = (signed short)tmp;
}

0 件のコメント:

コメントを投稿