「MoNoWIRELESS(TWE-Lite-2525A とMoNoStick)」を使って「自動で動物の動きの検出と記録」ができる機械の電子工作と失敗しやすい落とし穴の回避方法まとめ。
「MoNoWIRELESS」を使って「自動で動物の動きの検出と記録」ができる機械を電子工作します。『TWE-Liteではじまる「センサー」電子工作(工学社)』の失敗しやすい落とし穴の回避方法についてもまとめてみました。
MoNoWIRELESSとは、TWE-Lite-2525A とMoNoStickからなる計測・無線通信機器です。
TWE-Lite-2525Aは、一円玉の大きさの無線マイコンです。
MoNoStickは、USB接続できるTWE-Liteの親機・中継機です。
本機器(MoNoWIRELESSのシステム)の特徴は、パソコンなどに、低価格で測定データを無線でCOMポートから取得でき、簡単にPython(一般的な科学技術計算のプログラム)で取り込んで解析できることです。
MoNoWIRELESS社のHPより https://mono-wireless.com/jp/products/TWE-Lite-2525A/index.html
|
著者らは、これまで、マウスの動きを自動的に検出して記録するなどの目的で、本機器の利用について検討してきました。
従来、このような場面ではFrame-DIAS(イプロス社)などを利用したビデオ解析が中心でした。しかし動画を人手で確認して追う作業があり、あまりざっくりとした動きの解析では手間が目立つものでした。
本機器では、自動化によってそれらの手間が省かれます。それだけでなく、はるかに安価でコストも抑えられると考えられます。
著者らの作業の目的は、マウスの位置を自動的に検知し記録するため、マウスの背部にTWE-Lite-2525Aを付着し、それから発せられる電波の強度をMoNoStickでパソコンに取得させ、Pythonで解析し、それをエクセルでグラフィックスに表示・保存することです。
著者らは、『TWE-Liteではじまる「センサー」電子工作(工学社)』を参照し、その記載にしたがって作業を進めてきました。
同書は初学者でもわかりやすい優れた内容ですが、実際の作業を進めるうえで、不明点やややこしい点がありましたので、それを補い解説してまとめてみました。
これから著者らと同様の作業をされる方々の参考になれれば幸いです。
(1)無線タグアプリ(通常モード)に変換する手順
https://mono-wireless.com/jp/products/TWE-APPS/App_Tag/download.html
を開いてください。
画面下にスクロークして1.6.2の親機・子機用をクリックしてダウンロードします。
次に、MoNoStickをUSBポートに挿入します。
TWE-Lite専用プログラムをダウンロードします。
続いて、プログラムを起動します。
その際、App_Tag_EndDevice_Input_JN5164_OTA_1_6_2.binを選択します。
終了後、画面のTWE-Liteのリセットをクリックします。
通信ソフト「Tera Term」を起動して、設定をクリックします。
シリアルポートをクリックしてボードのコム番号を調整してOKを押します。
Enterを押します。
「o」のkey(小文字)を押して1を打ちます。Enterを押します。
(これで通常モードに変更完了です。)
「s」のkey(大文字)を押します。(これで保存終了です。)
電池を抜いたTWE-Lite-2525AをMoNoStickに1cmぐらいまで近づけます。その状態で電池を入れます。一瞬赤色と黄色のLEDが点滅します。(これで転送終了です。)
TWE-Lite専用プログラムを起動します。
App_Tag_Parent_JN5164_MONOSTICK_1_6_2.binを選択します。
終了後、画面のTWE-Liteのリセットを押します。
(これで無線タグアプリに入れ替え完了です。)
(2)Simple Tag V3形式に変換する方法
Tera Termを起動して+を3回ゆっくり押す。
「o」のkey(小文字)を押して21と打ちます。Enterを押します。(変更完了です。)
「s」のkey(大文字)を押します。(保存終了です。)
(3)Python のインストールの方法
https://www.python.org/ の画面のdownload をクリックします。下にスクロールして
「Download Python 3.6.1」を選択して、クリックします。
後は手順に従ってインストールします。
(4)pySerial のインストールの方法
https://pypi.python.org/pypi/pyserial/2.7の画面で、
表の一番下のfor Python 3.x (3.0...3.4)がついているfileをクリックしてダウンロードします。
「ゾーン確定リアルタイム」プロジェクト
目標物が、3つのゾーン(zone1,zone2,zone3)のどこのゾーンにいるのか、そして、そのゾーンの中心に近づいているのか、それとも中心から遠ざかっていくのかをリアルタイムで表示するものです。(電波強度値で表示)
また、目標物が激しい加速度運動をした場合には警告音がなるというものです。
import winsound
winsound.Beep(2000,100)
import re, serial
# COM5を開く
s = serial.Serial(4, 115200)
nearest = ""
nearestkyoudo = ""
ax = 0
ay = 0
az = 0
aa = 0
maxlqi = 0
oldtm = 0
counter = 0
spot1 = 11111111111111111
spot2 = 222222222222222222222222222222222222222
spot3 = 333333333333333333333333333333333333333333333333333333333333333333
while 1:
aa = ax*ax+ay*ay+az*az
# 1行読み取る
data = s.readline()
# 「;」で分割する
m = str(data).split(";")
tm = int(m[1])
if (len(m) == 16):
id = int(m[4])
lqi = int(m[3])
if (lqi > maxlqi) :
maxlqi = lqi
nearest = m[2]
nearestkyoudo = m[3]
ax = int(m[12])
ay = int(m[13])
az = int(m[14])
if (oldtm != tm) :
counter = counter + 1
if (counter >= 5) :
counter = 0
maxlqi = 0
if (nearest == "00000000") :
print(spot1)
# 下の"010□□□□□" にspot2のMoNoStickのID番号を入れてください。
if (nearest == "010□□□□□") :
print(spot2)
# 下の"010□□□□□" にspot3のMoNoStickのID番号を入れてください。
if (nearest == "010□□□□□") :
print(spot3)
print(nearestkyoudo)
print(aa)
print()
if (aa > 20000) :
winsound.Beep(2000,1500)
oldtm = tm
s.close()
追加 「グラフ化」について
① グラフを表示するためには、matplotlibをインストールする必要があります。
pythonでpipを使って行う場合は、その命令を書くのはPCのコマンドプロンプト(画面下左端のwindow10のマークをクリックして「すべてのアプリ」の「Windowsシステムツール」の中にある「コマンドプロンプト」をクリックすれば起動します。)で行います。
②グラフを自動更新させる場合はpythonプログラム中のshow()をpause(0.1)にする必要があります。
「エクセル活用によるゾーン滞在分析」プロジェクト
目標物が、設定時間内において、3つのゾーン(zone1,zone2,zone3)のどのゾーンに長く滞在していたのか、そのゾーンの中心にどのくらい接近していたのか(電波強度値で表示)を設定時間経過後にエクセルを利用してグラフ化分析する方法を考えました。
import re, serial
# COM5を開く
s = serial.Serial(4, 115200)
nearest = ""
nearestkyoudo = ""
number = ""
maxlqi = 0
oldtm = 0
counter = 0
spot1 = 1
spot2 = 2
spot3 = 3
number1 = 1001
while 1:
# 1行読み取る
data = s.readline()
#「;」で分割する
m = str(data).split(";")
tm = int(m[1])
if (len(m) == 16):
id = int(m[4])
lqi = int(m[3])
if (lqi > maxlqi) :
maxlqi = lqi
nearest = m[2]
nearestkyoudo = m[3]
number = m[5]
if (oldtm != tm) :
counter = counter + 1
if (counter >= 5) :
counter = 0
maxlqi = 0
# 下の"10□□□□□"には2525Aのシリアル番号をいれてください。
if (number == "10□□□□□") :
print(number1)
if (nearest == "00000000") :
print(spot1)
if (nearest == "010□□□□□") :
print(spot2)
if (nearest == "010□□□□□") :
print(spot3)
print(nearestkyoudo)
print()
oldtm = tm
s.close()
測定分析方法
上のプログラムを実行後、表示されたデータを作成したエクセルシートのシート1の黒ワク内に貼り付けると自動的にグラフ化します。
注意点 実行終了は、USB口からStickをぬいて終了してください。そうすることによりデータが画面に残ったままになります。
作成したエクセルシートについて
① 実行後、適当な所で、パソコンにつないでいるStickをそっと水平にぬきます。
② エラーが出て止まるのでデータをコピーしてSheet1の表(黒ワク内)に貼り付けます。
③ ゾーンと接近度(電波強度)のグラフが表示されます。
④ データ活用版のみ2525Aのシリアル番号を区別する数字(1001など)が画面に出ます。2525Aを複数台使うとき(複数の目標物の移動を調べるとき)、どの2525Aからのデータか区別するためです。
グラフの設定について
ゾーン確定のグラフでは
① データ範囲は黒ワク全部です。上のグラフでは1~600番です。
② グラフの種類は散布図です。
③ 縦軸は最小1最大3と手動で設定します。
接近度のグラフでは
① データ範囲は黒ワク全部です。上のグラフでは1~600番です。
② グラフの種類は散布図です。
③ 縦軸は最小50最大300と手動で設定します。
座標確定プロジェクト
MonoStickと2525Aを使って、目標物の平面座標(x,y)を確定する方法を考えました。
(1) 理論
MonoStickから1mの距離に目標物があるときの電波強度をkとし、
ある位置に目標物があるときのStick1,2,3それぞれの電波強度をk1,k2,k3とすると、
電波強度は距離の2乗に反比例するので、
各Stickからの目標物の距離a, b, c は
a=(k/k1)1/2 b=(k/k2)1/2 c=(k/k3)1/2 ……(0)
で表すことができます。
Stick1,2,3のx-y座標を(0,0),(L,0),(0,L)に設定し、求めたい目標物のx-y座標を(x,y)とすると
x2+y2=a2 ……(1)
(x-L)2+y2=b2 ……(2)
(1)-(2)より
x=(a2-b2+L2)/2L ……(3)
(1)より
|y|=(a2-x2)1/2 ……(4)
また
x2+(y-L)2=c2なので
x2+(|y|-L)2=cp2 ……(5)
x2+(-|y|-L)2=cq2 ……(6)
とおくと
cpがcqよりcに近い値のとき、すなわち|cp2-c2|≧|cq2-c2|のとき、y=|y|
cqがcpよりcに近い値のとき、すなわち|cp2-c2|<|cq2-c2|のときy=-|y|
より
∴ (cp2-c2)2≧(cq2-c2)2のとき、y=|y| ……(7)
(cp2-c2)2<(cq2-c2)2のときy=-|y| ……(8)
(0), (3),(4),(5),(6),(7),(8)で目標物の座標(x,y)を確定することができます。単位はm(メートル)です。
ただし、実際のプログラムでは、電波強度と距離の間に誤差が生じるため、(4)の( )内が負になる場合には|y|=0として計算しています。
(2) プログラムについて
理論をもとに、プログラムは以下のようになります。
import re, serial
# COM5を開く
s = serial.Serial(4, 115200)
s1 = 0
s2 = 0
s3 = 0
a = 0
b = 0
c = 0
l = 0.4000000000
k = 140
j = 0
y1 = 0
while 1:
print()
print()
print()
x = (a*a-b*b+l*l)/(2*l)
y = (a*a-x*x)**(1/2)
if x > a :
y = 0
cp2 = x*x+(y-l)*(y-l)
cq2 = x*x+(-y-l)*(-y-l)
j = (cp2-c*c)*(cp2-c*c)-(cq2-c*c)*(cq2-c*c)
if 0 < j :
y1 = -y
else:
y1 = y
print( int(x*100) )
print( int(y1*100) )
print()
data = s.readline()
m = str(data).split(";")
if (m[2] == "00000000") :
s1 = int(m[3])
a = (k/s1)**(1/2)
if (m[2] == "010□□□□□") :
s2 = int(m[3])
b = (k/s2)**(1/2)
if (m[2] == "010□□□□□") :
s3 = int(m[3])
c = (k/s3)**(1/2)
s.close()
(3) 測定方法について
Stick1を親機(座標(0,0))とし、Stick2,3は子機で座標(L,0),(0,L)とします。
室内で測定する場合はL=2[m]となるように3つのStickを部屋の中央に配置します。
広い室内及び屋外で測定する場合はL=5[m]となるように配置します。
室内、屋外とも、障害物がない空間(ただ広い空間)ほど障害物による電波強度への影響が少なくなるので、より精度の高い測定を行うことができると思います。
今回の電子工作では、じつは日立ソリューションズなどの開発した製品
http://www.hitachi-solutions.co.jp/company/press/news/2016/0831.html
を将来的な目標にして製作しました。
では、今回の完成品は製品と比べてどうかということですが、、、
今回の電子工作では、コストは1万円以下で製品と比べ、非常に安価である反面、やはり動作性に不安定であり、製品のようなクオリティにはまだまだ時間がかかりそうです。。。
伝送時間差のばらつき(5~10秒)、座標の不正確(平均誤差10~50%。50㎝~200㎝の距離で測定)、エラーの頻発(多くは接続不良)などといった問題を克服していく必要があります。
参考;上記の日立ソリューションズのHPより
全体を通して、何分、素人工作で恥ずかしい限りですが、改良点のアドバイスなどコメント欄にいただければ大変助かります。質問等もできるだけお答えできればと思いますので、同様にコメント欄へよろしくお願いいたします。
この章段の最後までお読みいただきありがとうございました。
皆さんの機械がうまく作動するよう願っています。