この記事はSeeedUG アドベントカレンダー2021の23日目のエントリになります。
今年のエントリはかなり内容を悩みました。比較的通常時にデバイス関連なども書いていましたが、このタイミングで書くネタがなく、改めてネタを探していました。
そんな中で思いついた内容は以下のものとなります。
Seeeduino XIAO
を使ってUSBホスト機能 … 安心な配線方法に自信がなかったのでボツ。そのうちチャレンジするとは思う。Grove Uart Wifi v2
を使ってみる … 存在しない機能であるネットワーク機能をアドオンできるのは魅力的だけど、そもそもそんな需要のあるはmicro:bit
ぐらい?ってことでボツ。reTerminal
を使ってみる … 少し時間が経ったこともあり割と情報が出てきているので目新しさがないのでボツ。
こんな感じで考えたのですが、どうもいい内容が思いつかない、既に同じないようを書いている人もいたりする。
考えを変えてみようと部屋の掃除をしてみたところ、以前に購入したRaspberry Pi用MGC3130搭載 3Dジェスチャー・トラッキングモジュール
をまだ使っていないことに気が付きました。ネットでの検索でもあまり多くの情報がなかったということもあり、こちらを使ってみる内容にしようと思います。
jp.seeedstudio.comwww.switch-science.com
このデバイスはMicrochip MGC3130チップ
を搭載し、測定面の磁場の変化をもとに手の動きを読み取るモジュールとなります。
https://www.microchip.com/en-us/product/MGC3130
測定可能な空間上の位置情報キャプチャ、近接検知、タッチ検知を行うことができます。天面のタップやダブルクリックも検知できます。
こちらの動画で説明が行われています。
この動画でタッチパッドと空間位置の検知ができるデバイスであることは想像できたかなと思います。
デバイスはI2C
インターフェイスを介して通信が行われRaspberryPi
のGPIO
ヘッダーに差し込んで接続するHAT
と呼ばれるような形になっています。RaspberryPi
以外のデバイスに接続できるようにGroveコネクタもついています。
今回はこのデバイスの動作テスト(C言語からの使用)やPython
からの使用を行ってみたいと思います。流石にRaspberry Pi用MGC3130搭載 3Dジェスチャー・トラッキングモジュール
という名前では長すぎるので以降はMGC3130センサーシールド
と呼ぶことにします。
使用した機材および環境
- RaspberryPi2B
- 最新のRaspberryPi OS(Bullseye)
後述しますが、RaspberryPi2Bではリアルタイム処理のパワーが足りないかもしれません。3B、3B+あたりがおすすめかなと思います。(4Bは発熱が凄いので、HATスタイルの接続は微妙かも?)
動作テストを行う
動作テストは以下のサイトに詳細が書かれています。
作業の手順としては以下のようになります。
I2C
を有効化ncurses
をインストール- テスト用のソースを入手して動作を確認
では順番に行っていきます。
RaspberryPiのI2C機能を有効化
I2C
の機能を有効化するにはおなじみのraspi-config
を実行していくことになります。
$ sudo raspi-config
実行するとメニューが表示されるのでカーソルを操作し、
3 Interface Options
を選択し、
続いて、P5 I2C
を選択
I2Cインターフェースを有効にするかを尋ねられるのでYes
を選択
I2Cが有効化されたことが表示されるのでOk
を押す。
初期メニューに戻るのでカーソルを移動し、Finish
を選択します。
念の為、RaspberryPi
を再起動しておきましょう。
$ sudo reboot
再起動したら、以下のコマンドを実行し、
$ i2cdetect -y 1
I2Cアドレスが0x42にデータがあればOKです(デフォルト値)。
ncursesをインストール
ncurses
はWikipediaによれば
ncurses は、端末に依存しない形式でテキストユーザインタフェース (TUI) を作成するためのAPIを提供するライブラリ。
CUI形式の画面でもメニューの可能にするようなライブラリといえばいいのかもしれません。動作テストを行うプログラムでこちらのライブラリを使用しているのでインストールを行います。
参考にしたサイトでncurses
のバージョンは6.1となっていましたが、6.3があったのでそちらを使用しました。パッケージがあればそれを使用してapt
コマンドでインストールしてもいいと思います。
$ cd ~ $ wget https://invisible-mirror.net/archives/ncurses/ncurses-6.3.tar.gz $ tar -xvf ncurses-6.3.tar.gz $ cd ncurses-6.3/ $ ./configure $ make $ sudo make install
ここまで終ればncurses
のインストールは無事に終了しています。あとはインストールされたncurses
を動作させてバージョンを確認してみます。
$ ncurses6-config --version 6.3.20211021
などという風に表示されていれば大丈夫です。
テスト用のソースを入手して動作を確認
あとは動作確認を行います。テスト用のソースは以下のGitHub
にあるのでクローンをして入手していきます。
もし、必要があればWiringPi
を以下のようにインストールしておきます。
$ cd ~ $ git clone https://github.com/WiringPi/WiringPi.git $ cd wiringPi $ ./build
あとはクローンを行って、ソースファイルのmake
を行います。
$ cd ~ $ git clone https://github.com/Seeed-Studio/Seeed_mgc3x30.git $ cd Seeed_mgc3x30/ $ make clean && make
make
が成功したら実際に動作させてみます。
$ ./mgc3130
すると以下のような情報が得られます。
- x,y,z軸の各座標
- ジェスチャー
- AirWheelの状態(指でくるくる円を書くことで回転の状態を知ることができますが、結構操作に癖があり)
- タッチやタップの状況
測定範囲内で指を動かすなどを行って数値などの情報が表示されれば、動作確認は成功になります。
このソースはC言語で記載されているのですが、
~/Seeed_mgc3x30/src/Seeed_3D_touch_mgc3030.c
内のint32_t mg3030_read_data(void *data)
処理でデータの取得を行っています。
データのブロックで計測データを取得しているので、取得後もデータを分解し、処理を行います。そのため、サンプリング的に取得することになるのでパワーが必要になってしまいます。今回はRaspberryPi 2B
でテストしてみましたが、処理が追い付かないこともあるようです。
pythonで動作させてみる
C言語での動作は確認できましたが、できればpythonからでも使用可能になると、使用用途がかなり広がるのはないかと思います。
GitHub
をみてみると以下の2つが該当するようです。
GitHub - linux-downey/seeed_mgc3x30_python: A library for 3D Gesture.
今回はうまくいったこちらを使用してみることにしました。
以下のようにクローンして動作させるのですが、一筋縄ではうまくいきませんw またか!!
$ git clone https://github.com/open-electronics/GestIC.git
$ cd GestIC/AppRaspberry/Librerie/MGC3130_Lib/V1_1_0_0/MGC3130
$ sudo python setup.py install
実はBullseye
ベースのRaspberryPi
ではpython2系
がインストールされておらず、デフォルトのpython
コマンドも3.9系になっています。
そのため、上記のようにインストール作業を行うと、インストール先がpython2系
とは別となり、/usr/local/lib/python2.7/dist-packages/MGC3130
にインストールされます。
GitHub
でクローンした動作環境がpython2系のままなのが問題の様です。あとスペルミスもあったり…。
オリジナルのファイルを使うと以下のようなエラーが出ます。
ライブラリ側のエラー
- print文のカッコを補う
- ctypeのスペルミス修正
動作デモファイル側のエラー
- importするライブラリのパスが通っていない
以下に修正したファイルを置いておきます。
ライブラリファイル /usr/local/lib/python3.9/dist-packages/MGC3130/MGC3130.py
#=========================================================================== # This is the library for MGC3130. # # MGC3130 is a device that lets you control your hardware projects in a whole new way. # MGC3130 detects hands movements and converts these in gestures. These gestures # permit to manage a device without touch it. # # Written by Matteo Destro for Futura Group srl # www.Futurashop.it # www.open-electronics.org # # BSD license, all text above must be included in any redistribution # =========================================================================== # # REVISION 1.0.0 30/06/2015 # # =========================================================================== # # REVISION 1.1.0 13/03/2016 # # - Fixed Bug print North to South gestic and South to North gestic # # - Added new gesture recognitions: # * Gesture Wave X # * Gesture Wave Y # * Gesture Hold # * Gesture Presence # * Gesture Double West To East # * Gesture Double East To Weast # * Gesture Double North To South # * Gesture Double South To North # # =========================================================================== # # SUPPORT # # info@open-electronics.org # #=========================================================================== from ctypes import * from MGC3130_DefVar import * import smbus import time import sys #I2Cbus = smbus.SMBus(0) I2Cbus = smbus.SMBus(1) _Data = c_ubyte * 256 _i2caddr = 0x42 _Counter = 0 _FirstTelegram = False _GestInfo = GestureInfo() _TouchInfo = TouchInfo() _xyz = Coordinates() _GestOutput = Gesture() #=================================================================== # Enable/Disable code to debug EnablePrintMGC3130RawFirmwareInfo = True EnablePrintMGC3130RawData = True EnablePrintMGC3130Gesture = True EnablePrintMGC3130xyz = False #=================================================================== #=================================================================== def MGC3130_SetAdd(Addr): global _Data _i2caddr = Addr #=================================================================== #=================================================================== def MGC3130_Begin(GPIO, Ts, Rst): global _FirstTelegram print("MGC3130 initialization in progress...wait") GPIO.setup(Ts, GPIO.IN, pull_up_down=GPIO.PUD_UP) # MGC3130 TS Line. Input mode #GPIO.add_event_detect(Ts, GPIO.FALLING, bouncetime=100) GPIO.setup(Rst, GPIO.OUT, initial=GPIO.HIGH) # MGC3130 RESET Line GPIO.output(Rst, GPIO.LOW) # Reset MGC3130 Device time.sleep(0.250) # Delay 250mSec GPIO.output(Rst, GPIO.HIGH) # Remove Reset MGC3130 Device #time.sleep(0.250) # Delay 250mSec #_FirstTelegram = True time.sleep(0.500) # Delay 500mSec _FirstTelegram = False print("MGC3130 device is ready") #=================================================================== #=================================================================== def MGC3130_ResetDevice(GPIO, Rst): GPIO.setup(Rst, GPIO.OUT, initial=GPIO.HIGH) # MGC3130 RESET Line GPIO.output(Rst, GPIO.LOW) #=================================================================== #=================================================================== def MGC3130_ExitResetDevice(GPIO, Rst): GPIO.setup(Rst, GPIO.OUT, initial=GPIO.HIGH) # MGC3130 RESET Line GPIO.output(Rst, GPIO.HIGH) #=================================================================== #=================================================================== def MGC3130_ReleaseTsLine(GPIO, Ts): #print("Release TS Line") GPIO.output(Ts, GPIO.HIGH) time.sleep(0.050) GPIO.setup(Ts, GPIO.IN, pull_up_down=GPIO.PUD_UP) # MGC3130 TS Line. Input mode #=================================================================== #=================================================================== def MGC3130_GetTsLineStatus(GPIO, Ts): if (GPIO.input(Ts) == GPIO.LOW): #print("Get TS Line") time.sleep(0.050) GPIO.setup(Ts, GPIO.OUT) # MGC3130 TS Line. Output mode GPIO.output(Ts, GPIO.LOW) return True else: return False #=================================================================== #=================================================================== def MGC3130_GetEvent(): global EnablePrintMGC3130RawFirmwareInfo global _Counter global _Data global _FirstTelegram global _GestInfo global _TouchInfo global _xyz _Counter = 0 if (_FirstTelegram == True): _FirstTelegram = False _Data = I2Cbus.read_i2c_block_data(_i2caddr, 0x00, 0x20) else: _Data = I2Cbus.read_i2c_block_data(_i2caddr, 0x00, 0x1A) if (_Data[3] == ID_FW_VERSION): if (_Data[4] == 0xAA): if (EnablePrintMGC3130RawFirmwareInfo == True): MGC3130_PrintMGC3130RawFirmwareInfo() print("###################################################") print("Valid Library detected") # 以下2行修正 print('Hardware Rev: {}.{}' .format(_Data[5], _Data[6])) print('Library Loader Version: {}.{}' .format(_Data[9], _Data[8])) #=========================================== sys.stdout.write("Gestic Library Version: ") TempStr = "" for i in range(12, 17): if (i < len(_Data)): TempStr = TempStr + chr(_Data[i]) sys.stdout.write(TempStr + "\n") #=========================================== #=========================================== sys.stdout.write("Platform: ") TempStr = "" for i in range(20, 31): if (i < len(_Data)): TempStr = TempStr + chr(_Data[i]) sys.stdout.write(TempStr +"\n") #=========================================== print("###################################################") print("\n") else: print("Invalid Library detected") elif (_Data[3] == ID_DATA_OUTPUT): #=========================================== # Save Data into internal array for i in range(4): _GestInfo.GestInfoArray[i] = _Data[i + 10] _TouchInfo.TouchInfoArray[i] = _Data[i + 14] _GestInfo.GestureInfoLong &= MASK_GESTURE_RAW _TouchInfo.TouchInfoLong &= MASK_TOUCH_RAW AirWheelInfo = _Data[18] for i in range(6): if (i < len(_Data)): _xyz.xyzArray[i] = _Data[i + 20] #=========================================== else: print("Telegram not managed") #=================================================================== #=================================================================== def MGC3130_DecodeGesture(): global EnablePrintMGC3130RawData global EnablePrintMGC3130Gesture global EnablePrintMGC3130xyz global _GestInfo global _TouchInfo global _GestOutput global LastTouch global LastGesture Mask = 0x00000001 if (((_TouchInfo.TouchInfoLong ^ LastTouch) > 0) or ((_GestInfo.GestureInfoLong ^ LastGesture) > 0)): if (EnablePrintMGC3130RawData == True): MGC3130_PrintMGC3130RawData() _GestOutput.GestureLong = 0x00000000 if ((_TouchInfo.TouchInfoLong ^ LastTouch) > 0): LastTouch = _TouchInfo.TouchInfoLong for i in range (15): if ((_TouchInfo.TouchInfoLong & Mask) > 0): _GestOutput.GestureLong |= Mask Mask = Mask << 1 elif ((_GestInfo.GestureInfoLong ^ LastGesture) > 0): LastGesture = _GestInfo.GestureInfoLong if (_GestInfo.GestureInfo32Bit.GestureCode == NO_GESTURE): print("No Gesture") elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_GARBAGE): print("Garbage Gesture") elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_EDGE_WEST_EAST): _GestOutput.GestureLong |= GESTURE_MASK_EDGE_WEST_EAST elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_EDGE_EAST_WEST): _GestOutput.GestureLong |= GESTURE_MASK_EDGE_EAST_WEST elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_EDGE_SOUTH_NORTH): _GestOutput.GestureLong |= GESTURE_MASK_EDGE_SOUTH_NORTH elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_EDGE_NORTH_SOUTH): _GestOutput.GestureLong |= GESTURE_MASK_EDGE_NORTH_SOUTH elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_WEST_EAST): if (_GestInfo.GestureInfo32Bit.Edgeflick == 0): _GestOutput.GestureLong |= GESTURE_MASK_WEST_EAST else: _GestOutput.GestureLong |= GESTURE_MASK_EDGE_WEST_EAST elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_EAST_WEST): if (_GestInfo.GestureInfo32Bit.Edgeflick == 0): _GestOutput.GestureLong |= GESTURE_MASK_EAST_WEST else: _GestOutput.GestureLong |= GESTURE_MASK_EDGE_EAST_WEST elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_SOUTH_NORTH): if (_GestInfo.GestureInfo32Bit.Edgeflick == 0): _GestOutput.GestureLong |= GESTURE_MASK_SOUTH_NORTH else: _GestOutput.GestureLong |= GESTURE_MASK_EDGE_SOUTH_NORTH elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_NORTH_SOUTH): if (_GestInfo.GestureInfo32Bit.Edgeflick == 0): _GestOutput.GestureLong |= GESTURE_MASK_NORTH_SOUTH else: _GestOutput.GestureLong |= GESTURE_MASK_EDGE_NORTH_SOUTH elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_CLOCK_WISE): _GestOutput.GestureLong |= GESTURE_MASK_CLOCK_WISE elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_COUNTER_CLOCK_WISE): _GestOutput.GestureLong |= GESTURE_MASK_COUNTER_CLOCK_WISE elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_WAVE_X): _GestOutput.GestureLong |= GESTURE_MASK_WAVE_X elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_WAVE_Y): _GestOutput.GestureLong |= GESTURE_MASK_WAVE_Y elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_HOLD): _GestOutput.GestureLong |= GESTURE_MASK_HOLD elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_PRESENCE): _GestOutput.GestureLong |= GESTURE_MASK_PRESENCE elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_DOUBLE_WEST_EAST): _GestOutput.GestureLong |= GESTURE_MASK_DOUBLE_WEST_EAST elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_DOUBLE_EAST_WEST): _GestOutput.GestureLong |= GESTURE_MASK_DOUBLE_EAST_WEST elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_DOUBLE_SOUTH_NORTH): _GestOutput.GestureLong |= GESTURE_MASK_DOUBLE_SOUTH_NORTH elif (_GestInfo.GestureInfo32Bit.GestureCode == GESTURE_DOUBLE_NORTH_SOUTH): _GestOutput.GestureLong |= GESTURE_MASK_DOUBLE_NORTH_SOUTH _GestOutput.GestureLong &= ~(MASK_FILTER_GESTURE) if (EnablePrintMGC3130Gesture == True): MGC3130_PrintMGC3130Gesture() if (EnablePrintMGC3130xyz == True): MGC3130_PrintMGC3130xyz() #=================================================================== #=================================================================== def MGC3130_PrintMGC3130RawFirmwareInfo(): global _Data RawInfoIndent = "#####################################################################################\nRow Firmware Info from MGC3130 \n" HeaderInfo = "Header: " PayloadInfo = "Payload: " RawInfoCloseIndent ="\n#####################################################################################\n\n"; if (_Data[3] == ID_FW_VERSION): sys.stdout.write(RawInfoIndent) #=========================================== # Header sys.stdout.write(HeaderInfo) for i in range(4): MGC3130_SetHexPrintOutput(_Data[i]) print("\n") #=========================================== #=========================================== # Payload sys.stdout.write(PayloadInfo) MGC3130_SetHexPrintOutput(_Data[4]) sys.stdout.write(" | ") #=========================================== #=========================================== # HwRev for i in range(5, 7): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(" | ") #=========================================== #=========================================== # ParameterStartAddr MGC3130_SetHexPrintOutput(_Data[7]) sys.stdout.write(" | ") #=========================================== #=========================================== # LibraryLoaderVersion for i in range(8, 11): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(" | ") #=========================================== #=========================================== # FwStartAddr MGC3130_SetHexPrintOutput(_Data[11]) sys.stdout.write(" | ") #=========================================== #=========================================== # LibraryLoaderVersion for i in range(12, len(_Data)): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(RawInfoCloseIndent) #=========================================== def MGC3130_SetHexPrintOutput(Data): if (Data < 0x10): sys.stdout.write("0x" + format(Data, "02x") + " ") else: sys.stdout.write(hex(Data) + " ") #=================================================================== #=================================================================== def MGC3130_PrintMGC3130RawData(): global _Data RawDataIndent = "#####################################################################################\nRow data from MGC3130 \n" HeaderRawData = "Header: " PayloadRawData = "Payload: " RawDataCloseIndent ="\n#####################################################################################\n\n"; if (_Data[3] == ID_DATA_OUTPUT): sys.stdout.write(RawDataIndent) #=========================================== # Header sys.stdout.write(HeaderRawData) for i in range(4): MGC3130_SetHexPrintOutput(_Data[i]) print("\n") #=========================================== #=========================================== # Payload # DataOutputConfigMask sys.stdout.write(PayloadRawData) for i in range(4, 6): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(" | ") #=========================================== #=========================================== # TimeStamp MGC3130_SetHexPrintOutput(_Data[6]) sys.stdout.write(" | ") #=========================================== #=========================================== # SystemInfo MGC3130_SetHexPrintOutput(_Data[7]) sys.stdout.write(" | ") #=========================================== #=========================================== # DSPStatus for i in range(8, 10): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(" | ") #=========================================== #=========================================== # GestureInfo for i in range(10, 14): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(" | ") #=========================================== #=========================================== # TouchInfo for i in range(14, 18): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(" | ") #=========================================== #=========================================== # AirWheelInfo for i in range(18, 20): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(" | ") #=========================================== #=========================================== # xyzPosition for i in range(20, 26): MGC3130_SetHexPrintOutput(_Data[i]) sys.stdout.write(" | ") #=========================================== sys.stdout.write(RawDataCloseIndent) #=================================================================== #=================================================================== def MGC3130_PrintMGC3130Gesture(): global _GestOutput if (_GestOutput.Gesture64Bit.TouchSouth): print ("Touch South") print("\n") if (_GestOutput.Gesture64Bit.TouchWest): print ("Touch West") print("\n") if (_GestOutput.Gesture64Bit.TouchNorth): print ("Touch North") print("\n") if (_GestOutput.Gesture64Bit.TouchEast): print ("Touch East") print("\n") if (_GestOutput.Gesture64Bit.TouchCentre): print ("Touch Centre") print("\n") if (_GestOutput.Gesture64Bit.TapSouth): print ("Tap South") print("\n") if (_GestOutput.Gesture64Bit.TapWest): print ("Tap West") print("\n") if (_GestOutput.Gesture64Bit.TapNorth): print ("Tap North") print("\n") if (_GestOutput.Gesture64Bit.TapEast): print ("Tap East") print("\n") if (_GestOutput.Gesture64Bit.TapCentre): print ("Tap Centre") print("\n") if (_GestOutput.Gesture64Bit.DoubleTapSouth): print ("Double Tap South") print("\n") if (_GestOutput.Gesture64Bit.DoubleTapWest): print ("Double Tap West") print("\n") if (_GestOutput.Gesture64Bit.DoubleTapNorth): print ("Double Tap North") print("\n") if (_GestOutput.Gesture64Bit.DoubleTapEast): print ("Double Tap East") print("\n") if (_GestOutput.Gesture64Bit.DoubleTapCentre): print ("Double Tap Centre") print("\n") if (_GestOutput.Gesture64Bit.GestWestEast): print ("Gesture Flick West to East") print("\n") if (_GestOutput.Gesture64Bit.GestEastWest): print ("Gesture Flick East to West") print("\n") if (_GestOutput.Gesture64Bit.GestSouthNorth): print ("Gesture Flick South to North") print("\n") if (_GestOutput.Gesture64Bit.GestNorthSouth): print ("Gesture Flick North to South") print("\n") if (_GestOutput.Gesture64Bit.EdgeGestWestEast): print ("Gesture Flick Edge West to East") print("\n") if (_GestOutput.Gesture64Bit.EdgeGestEastWest): print ("Gesture Flick Edge East to West") print("\n") if (_GestOutput.Gesture64Bit.EdgeGestSouthNorth): print ("Gesture Flick Edge South to North") print("\n") if (_GestOutput.Gesture64Bit.EdgeGestNorthSouth): print ("Gesture Flick Edge North to South") print("\n") if (_GestOutput.Gesture64Bit.GestClockWise): print ("Gesture Clock Wise") print("\n") if (_GestOutput.Gesture64Bit.GestCounterClockWise): print ("Gesture Counter Clock Wise") print("\n") if (_GestOutput.Gesture64Bit.GestWaveX): print ("Gesture Wave X") print("\n") if (_GestOutput.Gesture64Bit.GestWaveY): print ("Gesture Wave Y") print("\n") if (_GestOutput.Gesture64Bit.GestHold): print ("Gesture Hold") print("\n") if (_GestOutput.Gesture64Bit.GestPresence): print ("Gesture Presence") print("\n") if (_GestOutput.Gesture64Bit.DoubleGestWestEast): print ("Gesture Double West to East") print("\n") if (_GestOutput.Gesture64Bit.DoubleGestEastWest): print ("Gesture Double East to West") print("\n") if (_GestOutput.Gesture64Bit.DoubleSouthNorth): print ("Gesture Double South to North") print("\n") if (_GestOutput.Gesture64Bit.DoubleGestNorthSouth): print ("Gesture Double North to South") print("\n") #=================================================================== #=================================================================== def MGC3130_PrintMGC3130xyz(): global _xyz global Last_X global Last_Y global Last_Z if (Last_X != _xyz.xyz.x): Last_X = _xyz.xyz.x sys.stdout.write("The X coordinate is: ") print(_xyz.xInt) if (Last_Y != _xyz.xyz.y): Last_Y = _xyz.xyz.y sys.stdout.write("The Y coordinate is: ") print(_xyz.yInt) if (Last_Z != _xyz.xyz.z): Last_Z = _xyz.xyz.z sys.stdout.write("The Z coordinate is: ") print(_xyz.zInt) print("\n") #===================================================================
動作デモファイル Seeed_mgc3130.py
import sys #修正点(ライブラリパスの修正) sys.path.insert(0, "/usr/local/lib/python3.9/dist-packages/MGC3130") import MGC3130 from MGC3130 import * import RPi.GPIO as GPIO import time # 初期設定 MGC3130_SetAdd("/dev/i2c-1") GPIO.setmode(GPIO.BCM) MGC3130_Begin(GPIO, 8, 11) # GPIO.cleanup() while(True): # データ読取 MGC3130_GetEvent() # rawデータから2byteずつ取出 x = MGC3130._xyz.xyzArray[1] * 256 + MGC3130._xyz.xyzArray[0] y = MGC3130._xyz.xyzArray[3] * 256 + MGC3130._xyz.xyzArray[2] z = MGC3130._xyz.xyzArray[5] * 256 + MGC3130._xyz.xyzArray[4] print("{:>5},{:>5},{:>5}".format(x,y,z)) time.sleep(0.01)
動作デモファイルを実行すると、取得したデータ表示されてスクロールされます。
Telegram not managed
という表示はジェスチャーがうまく認識できなかったことを指しています。表示がきれいでないのでpython
からもncurses
を使用して整形するのが美しいでしょう。時間ができたらそのあたりにもチャレンジしたいです。
おわりに
Raspberry Pi用MGC3130搭載 3Dジェスチャー・トラッキングモジュール
を使用してみたというエントリとなりました。このデバイスですが、使用には癖があるので操作インターフェースとしては少しむずかしい部類ではありますが、使えるようになれば色々な可能性がありそうです。トラックパッドのようにも使用可能ですし、入力した値やジェスチャーをプログラム側で変換することで、キーボードやマウスのようなデバイスの代わりにもできるかと思います。
ようやく、アドベントカレンダーのエントリを書き終えて安心しましたw