Hatena0Pocket0LINESendLINESendFeedly2近年スマートフォンやドローン市場が急激に拡大している中、それらのデバイスで活躍してるのが様々なセンサー。今日はその中の一つ加速度センサーとジャイロセンサーが一体となった「MPU-6050」をI2Cで通信して試しに動作確認したいと思います。以下やってしまった事I2Cとは2線からなる双方向の通信インターフェイス。詳細はwikiなどにあるので省略してプログラムに対して波形の動きを説明します。図が小さいかもの時はここあるアドレスにデータを書き込んだ時の動作。(下項目プログラムのsetup()内の処理が近いかも)Wire.beginTransmission();でArduinoをマスタとして接続先のデバイスアドレスを設定。最初のWire.write();でデバイスのレジスタアドレスを指定し、次のWire.write();で書き込みデータを指定。最後にWire.endTransmission();が実行されてI2C通信が開始されます。グラフの前後にあるSTARTとSTOPは、I2Cの開始と終了を意味しています。SCLがHighでSDAがLowに立ち下がった時、通信開始の合図となります。STOPはSCLがHighでSDAがHighに立ち上がった時となります。この条件によりデータの動作はSCLがLowの時にSDAはHighに立ち上がり又はLowに立下りすることによって誤STOP/STARTしないようになってるようです。グラフ中央のスレーブ送信、ACKはスレーブ側のデバイスが送られてきたデータを認識できているか判別しています。スレーブ側がデータを確認したらクロック9回目でLowとします。ACKがHighの場合はマスタ側にエラーとして認識されます。busyはスレーブが処理か何らかの影響で返事が返せない時、スレーブ側がSCLをLowにすることでSCLはマスタ側からHighにすることができず一時停止状態になります。実際に安価オシロで取得した波形です。上がセンサー側、下がArduino側。センサー側で読み取ると、最初の7bitが1101000=0x68となりbit8はライト要求なのでLow。9クロックのACKはSDAがLowになっているので受信OKと言うこと。次はまた7bitのレジスタアドレス(波形はPWR_MGMT_1を選択)を送りbit8はライトなのでLowで9クロックのACKもOK。残りは書き込むデータ0x00。こちらもACKがLowで問題なし。MPU-6050センサーモジュールについてTDKグループのInvenSense社製の6軸モーショントラッキングセンサー。同シリーズにMPU-6000があります。それにはSPIがあるのですが、今回使用するMPU-6050には前回確認したSPIインターフェイスがありません!!と、プログラムの流用ができないことは残念ですが、I2Cを使用する丁度いい機会かな?このデバイスを使う上で注意する点は動作電圧が5V不可。今回使う「GY-521」は電源入力にLDOレギュレーターが実装されているためVCCについては5V供給で問題ありません。問題なのは信号ラインでデータシートの絶対最大定格にもあるように”-0.5V~VCC+0.5V”が限度でLDO3.3Vで動作しているので信号電圧は最大で3.8Vまでかと思います。レベルシフタICなどを入れてArduinoの信号電圧を3.3Vへ落としてあげる必要があります。参考に他サイト見たら直でも大丈夫そうなこと書いてあったけど自己責任。レベルシフタICについて:TI電圧レベル変換とりあえず持っておくと便利かもしれません。I2Cの通信速度は通常100kHz、ファストモードで400kHzGY-521ピンアサインVCC:3.3VGNDSCL:I2CクロックSDA:I2CデータXDA:オプション。Mode)XCL:オプション。詳しいことはデータシート。それとレジスタマップを。https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/MPU-6050のモジュール回路図http://playground.arduino.cc/uploads/Main/MPU6050-V1-SCH.jpg回路構成を考える上項でSPIが使えない事態になったので2線式のI2Cを使用します。Arduinoとセンサーの電圧が異なるためレベルシフタICを間に入れます。プログラミングをするプログラムはWireを流用します。参考になりそうなのが結構あります。※電源投入時、スリープモードになっている。取り出した値をそのままグラフにしてみました。センサーをX,Y,Zの順で360度回転させたものです。(手ぶれすごいとりあえず動いてるみたい??Z軸がよくわからん。I2Cが動いてることは確かみたいなので今回はこれで終了にします。角度算出が出来るようなので次回以降にでも記事にしたいと思います。一度トラブルがあったのでメモっておきます。今回センサーを扱うということでフラットケーブルをArduinoとセンサー間に使いました。レッドボードワイヤ信号の並びはVCC、GND、”SCL”、”SDA”の4本。これだと動かないのです。SCLとSDAが隣り合わせになっているので。SCLはクロックで信号を送る際、一定間隔で立ち上がり立ち下がりしています。すると、配線上から微弱ながらもコモンモードノイズが発生し外部に影響を与えます。SDAがそのノイズに影響され送られるべき信号に歪みが生じセンサー側が読み取れないことがあるのです。通常の1本線ジャンパーであればノイズが微弱なので距離を離しながらだったら4本で動くかと思いますが、フラットケーブルを使う場合は信号の並びをVCC、GND、SCL、GND、SDA、GNDとGNDで囲んであげるとシールドの役目を果たしノイズの影響を軽減できます。nanoでソフトウェアシリアルが使えない。マスターとスレーブでデータ通信あけましておめでとうございます。新年と言えばまずご挨拶から。nanoの動作チェックに使ったプログラムです。...書いてる人おがP猫に包囲された居住空間で飼育されています。