※ これは 2017/8/14 に個人ブログへ投稿した内容を転記したものです。
触感フィードバックをしようとして詰まったけど何故か突然上手く行った話。
紆余曲折しているので、結論を読んでから実践しましょう。
タイトルの呪文を解説しながら、実験環境を説明します。
DRV2605 とは
DRV2605 ERM および LRA 用ハプティクス・ドライバ、ライブラリおよびインテリジェント・コントロール・エンジン搭載 | TIJ.co.jp
I2C で叩くと良い塩梅で振動モーターを駆動してくれる便利な IC (超意訳)
ブレークアウト基板は Adafruit や Sparkfun から出てます。
Adafruit は EN ピンは HIGH 固定ですが、 Sparkfun は EN ピンが出ているので実デバイスに乗っけるならこちらを選んだほうが良さそう。
しかし私は Sparkfun から出ていたのを知らずに Adafruit の方を買ったので、この記事では Adafruit を使います。マルツで買いました。
Sparkfunのほうはスイッチサイエンスで売っています。
LRA とは
リニア・バイブレータ(LRA:Linear Resonant Actuator)。コイルに電流を流すことで電磁力を発生させ、これと磁石との反発力を使ってコイル自体を上下に振動させるものだ。
ハプティクス(触感フィードバック) - EDN Japan
いわゆるガラケーに入ってたのは偏心モーター (ERM) で、ブルンブルンって感じの振動でしたよね。最近はカチっというクリック感が出せる LRA が主流だと思います。
LRA にはリンク先の絵にあるコイン状のものと、 iPhone で Taptic Engine と呼ばれているような四角いものがあります。1
LRA は秋月で調達。ちょっとデカイですが、 Taptic Engine と同じで横方向に動くタイプです。
リニア振動アクチュエータ LD14-002: パーツ一般 秋月電子通商-電子部品・ネット通販
動かしてみよう
結線は超簡単。ArduinoのI2C用のピンをつなぐだけ。
Arduino Code | Adafruit DRV2605L Haptic Controller Breakout | Adafruit Learning System
AdafruitからArduino用ライブラリが配布されてるのでこれを使います。
GitHub - adafruit/Adafruit_DRV2605_Library: Arduino library for Adafruit DRV2605L Haptic Controller Breakout
サンプルコードから basic を書き込み、いざ…
しーん
なんでやねん。 Adafruit_DRV2605::begin()
を見に行くと
// ERM open loop
// turn off N_ERM_LRA
writeRegister8(DRV2605_REG_FEEDBACK, readRegister8(DRV2605_REG_FEEDBACK) & 0x7F);
// turn on ERM_OPEN_LOOP
writeRegister8(DRV2605_REG_CONTROL3, readRegister8(DRV2605_REG_CONTROL3) | 0x20);
デフォルトは ERM のオープンループ設定らしい。
useLRA
という関数が用意されているので、これを使う。ついでに Library も LRA 用の 6 を選択する。
void setup() {
Serial.begin(9600);
Serial.println("DRV test");
drv.begin();
drv.useLRA();
drv.selectLibrary(6);
// I2C trigger by sending 'go' command
// default, internal trigger when sending GO command
drv.setMode(DRV2605_MODE_INTTRIG);
}
これでも動かなかった。なんでー?
電流が足らないのかなーと思い、安定化電源つないだりオシロ覗いたりしたけど原因が分からず。
GitHub で他のライブラリを探してみる。 Adafruit と Sparkfun 以外で 2 つ見つかる。
FlexModule/haptic/LRA/DRV2605L/software/arduino/DRV2605 at master · FyberLabs/FlexModule · GitHub
GitHub - Seeed-Studio/Grove_Haptic_Motor
このうち、後者で動いた。 Auto calibration
も機能している模様。2

やはり Auto Calibration が要るのか? と思い、もう一度 Adafruit のプログラムを書いてみる。
Buzzzz
動いた(白目)
結局、同じ現象を再現できず。どうも RATED_VOLTAGE
(0x16) と OD_CLAMP
(0x17) が小さいと鳴らないので、このせいだったのかもしれないが、電源を入れ直すとデフォルト値に戻るので理屈が合わない。
なお、データシートには明示されていないが3、上記2つのパラメータはどうも絶対値(つまり定格 3V なら 0x03 )ではなく、入力電圧に対する比率 (0xFF=100%) のような気がする。
・駆動電圧:2V~6V
・駆動電流:120mA(@3V、バイポーラ駆動、150Hz、デューティー比50%)
・コイル構成:1相(バイポーラまたはユニポーラ駆動)
・コイル仕様:直流抵抗25Ω、インダクタンス210μH(@120Hz)
・本体共振周波数(fo):約150Hz(配線材、固定方法等によって変動します)
リニア振動アクチュエータ LD14-002: パーツ一般 秋月電子通商-電子部品・ネット通販
この場合、 5V を与えていて 3V 定格で動かすなら RATED_VOLTAGE=0x99
、OD_CLAMP=0xFF
でいいのかな? 自信ないですが、ひとまず焼けはしなかったです。
結論
よくわかんないけど動いた。
Adafruit のライブラリに Auto calibration を追加したので、ひっそり公開しておきます。
bool Adafruit_DRV2605::autoCal(uint8_t ratedVoltage, uint8_t overdriveClamp, uint8_t driveTime)
GitHub 上のスケッチではデフォルト値を入れてあります。
DRIVE_TIME(0x1B)
はデータシートによると周期の半分を入れれば良いらしい。
Optimum drive time (ms) ≈ 0.5 × LRA Period
というわけで、今回の振動モーターでは5Vを繋いだ前提で
autoCal(0x99,0xFF,0x03)
として、モーターを固定してから実行すればOK。