#author("2020-11-07T10:06:04+00:00","","") #author("2020-11-10T06:01:36+00:00","","") [[Rene_専門ゼミ]] 物理センサーによるデータ収集とマイコン(Arduino, Raspberry Pi)による行動分類の手順に従い課題の結果を出す. 手順 [[IoT>沼田/IoT]] *0. 目次 [#o53aa818] #CONTENTS *1. 概要 [#gbc707b7] 近年、IoT技術の発展でセンシングデータを活用する事例が増加している。集めたデータの活用事例として、健康管理や行動識別などがある。本講義では、マイコンとセンサを使ったセンサデータ収集機器を使用する。そして、カメラの映像を画像分析、単語分散処理を使って数値化し、マイクから得られた音声を音声分析にかけたものをラベルとし、クラスター分析をすることでデンドログラムを描画する。 *2. 目標 [#i67428c5] カメラ,マイク,GPS受信機セット(緯度、経度、海抜高度),温湿度気圧センサー,照度センサー,赤外線焦度センサー,9軸センサーモジュール(加速度xyz、角速度xyz、磁気コンパスxyz),体温センサー,心拍,GSRセンサー(皮膚電気反射)のデータを取得する.ただし,カメラ画像とマイク音声はテキストでも取得する. 取得したデータに対してリアルタイムでクラスター分析をすることで,行動識別を行えるようにする. *2. 用語 [#b2a14e2b] カメラで得られる画像や、マイクを通して得られる音声をテキストとして取得するために、画像分析と音声分析を使う。(画像識別や音声認識などともいわれる。) また、テキストを数値として扱うために単語分散処理を行う。 さらに、通信方式としてシリアル通信とソケット通信、HTTP通信の3つを使う。その準備としてOSI参照モデルとプロトコルについての解説を先に以下で述べる。 ** 画像分析 [#h5083fc9] 画像から必要な情報を抽出し、統計的なデータを得る。AzureのComputer vision APIを使う。 ** 音声識別 [#ra0b83de] 音声から必要な情報を抽出し、統計的なデータを得る。Speech recognition APIを使う。 ** 単語分散処理 [#y3c1fcf9] 「王様」ー「男性」+「女性」=「お姫様」 のように単語の足し算、引き算ができるような処理。 Nltkとword2vecを使う。 ** OSI参照モデル [#q7e9a68e] ネットワークを理解するための“プロトコル” ** プロトコル [#of10edcd] コンピューター同士の通信をする際の規格のこと ** シリアル通信 [#fcf8eaa3] 1本だけの通信線を使い、HIGH/LOWの電圧レベルを連続的(=シリアル)に変化させて、意味のあるデータを送信/受信する通信方式 ** ソケット通信 [#ucf0a833] インターネットはTCP/IPと呼ぶ通信プロトコルを利用しますが、そのTCP/IPを プログラムから利用するには、プログラムの世界とTCP/IPの世界を結ぶ特別な 出入り口が必要となります。その出入り口となるのがソケット (Socket)であり、TCP/IPのプログラミング上の大きな特徴となっています。 このため、TCP/IP通信をソケット通信と呼ぶこともあります。 ** HTTP通信 [#fb8f73fe] HTTPはTCP/IPを利用したアプリケーション層のプロトコル *3. センサ,ブレッドボード,Arduino間の接続 [#y586a7a4] ** センサ [#b993d560] -必要なもの --raspberrypi3 #ref(RaspberryPi3.jpg,nolink,,80%) #ref(RaspberryPi3.jpg.png,nolink,,80%) --Arduino #ref(Arduino.jpg,nolink,,60%) --ブレッドボード #ref(ブレッドボード.jpg,nolink,,60%) --抵抗(10kΩ)×3、GPS用丸電池、ケーブル、SDカード、ボードとArduinoを固定する板など --GPS受信機セット(緯度、経度、海抜高度) #ref(gps.jpg,nolink,,50%) ---参考 https://qiita.com/AmbientData/items/fff54c8ac8ec95aeeee6 --温湿度気圧センサー(温度、湿度、気圧) #ref(onsitudo.jpg,nolink,,50%) ---配線 http://monhime.hatenablog.com/entry/2018/06/24/114921 ---コード https://github.com/SWITCHSCIENCE/BME280/blob/master/Arduino/BME280_I2C/BME280_I2C.ino --照度センサー #ref(syodo.jpg,nolink,,40%) ---配線 http://jkoba.net/prototyping/arduino/cds_practice.html ---コード #ref(hikari.ino) --赤外線焦度センサー(人感センサ) #ref(sekigaisen.jpg,nolink,,60%) ---配線・コード http://tech.blog.surbiton.jp/arduino_motion_sensor_se-10/ --9軸センサーモジュール(加速度xyz、角速度xyz、磁気コンパスxyz) #ref(9ziku.jpg,nolink,,10%) ---配線・コード http://tomi-tomi-pon.hatenablog.com/entry/2018/11/07/012854 #ref(BMX055_20180510.ino) --体温センサー #ref(taion.gif,nolink,,30%) ---配線・コード http://naritaku.hatenablog.com/entry/2016/04/05/230649 --心拍 #ref(sinpaku.png,nolink,,80%) ---配線・コード http://myct.jp/arduino/index.php?%E5%BF%83%E6%8B%8D%E3%82%BB%E3%83%B3%E3%82%B5%20SEN-11574 データ取得しやすくするため、読み取りのところに専用のシールを貼らなくてはならない --GSRセンサー(皮膚電気反射) #ref(GSR.jpg,nolink,,20%) ---配線・コード http://wiki.seeedstudio.com/Grove-GSR_Sensor/ --マイク #ref(maiku.jpg,nolink,,50%) ---製品 https://www.sanwa.co.jp/product/syohin.asp?code=MM-MCU02BK --カメラ #ref(camera.jpg,nolink,,20%) ---製品 https://www.rs-online.com/designspark/raspberry-pi-camera ---参考 https://iotdiyclub.net/raspberry-pi-camera-python-1/ ** センサとブレッドボード間の接続 [#n1967089] +基盤の組み立て 9軸・GPS・温湿度気圧のセンサーははんだ付けが必要. #ref(handa.jpg,nolink,,20%) #ref(handa2.jpg,nolink,,20%) +配線 各参考サイトに配線の仕方が書いてある.すべて組み合わせた配線が下の画像である. #ref(kairo.PNG,nolink,,50%) #ref(kairo2.jpg,nolink,,20%) **装置組み立て [#ba0ceec6] ラズパイにGPSセンサとマイクを取り付ける。 --配線 [[配線URL:https://denor.jp/raspberry-pi%E3%81%AB%E3%80%8C%E3%81%BF%E3%81%A1%E3%81%B3%E3%81%8D%E3%80%8D%E5%AF%BE%E5%BF%9Cgps%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%82%92%E6%8E%A5%E7%B6%9A]] ラズパイとArduinoを連結した装置を作る。 #ref(kairo3.jpg,nolink,,20%) * 4. Raspberry Piの設定 [#l3167c59] *** ラズパイの初期設定 [#p06e1e94] ここからOSがWindowsの場合で紹介します。インストールするものも全部for Windows [[Raspberry Piの始め方>Raspbianのインストール及び初期設定]] *** PC操作のための設定 [#y79f6fdf] 再起動後 ターミナルでifconfigと入力して無線LANのIPアドレスを確認する IPアドレスを確認することで、他のパソコンからSSH接続することができる -リモート接続 win+rでリモート画面を表示。mstscと入力して実行すると、リモート接続画面が表示される。 ここでラズパイのIPアドレスを入浴するとやがてログイン画面が表示される。 Module→Xorgで、ユーザー名とパスワードを入力すればラズパイのデスクトップが表示できる。 操作は簡単だが重くて時間がかかる時があるので以下のようなソフトを使ったりする。 -Teraterm ラズパイをPC上でリモート操作するためのソフト [[ここから:https://forest.watch.impress.co.jp/library/software/utf8teraterm/]]自分のPCにインストールする. インストール後、起動して「ホスト(T)」にラズパイのIPアドレス→OK→ユーザー名とパスワードを入力→で接続できる。 初期設定のページで述べているssh.txtくだりが必須になる。 参考サイトはこれがよく使われている。 -VNCビュワー これをつかってもPC上で操作できる。 重くないのでストレスにはならない [[ここから:https://www.realvnc.com/en/connect/download/viewer/]]ダウンロードする。 起動したのち、ラズパイのIPアドレスおよびユーザー名、パスワードを入力すればもれなくPC上に表示できる。 これはVNCなのでラズパイの方で メニュー>設定>ラズパイの設定>インターフェースのVNCを「Enable」にする必要がある。 * 5. Arduinoの設定 [#d79762cb] ***Arduinoをダウンロード [#e961f36b] https://www.arduino.cc/en/Main/Software よりArduinoIDEをダウンロードしておく。(情報実験で持たされる。) -各センサから取得するコード #ref(app1.ino) 上記で作ったArduinoとPCをつなげてこのプログラムを起動する。シリアルポートをCOM4にしておくとよい #ref(siriaru.jpg,nolink,,100%) マイコンボードでつなげたセンサのデータが取得できる。 -app1.inoと一緒のファイルに↓の2つも一緒に入れておく。起動しない #ref(AllSerialHandling.ino) #ref(Interrupt.ino) 以下のようにファイルが複数選択されていることを確認する。 #ref(hukusuu.PNG,nolink,,80%) コンパイルは、以下の検証をクリックする。 #ref(kensyou.jpg,nolink,,80%) 書き込み後、シリアルモニタで表示するとセンサのデータが,で区切られて表示される。 左から 気温、湿度、気圧、光、 人感(1か0)、x加速度、y加速度、z加速度、x軸ジャイロ、y軸ジャイロ、z軸ジャイロ、x軸地磁気、y軸地磁気、z軸地磁気、体温、心拍、GSRセンサ #ref(sensadata.PNG,,50%)] * 6. ラズパイでデータ取得 [#d79762cb] ***GPS単体の場合 [#e136b666] ・GPSデータをラズパイで取得 まずGPSセンサに丸電池をつけ、ラズパイと接続する。 今回使ったセンサは時刻、緯度、経度、海抜高度を取得する。 gpsp.pyを起動すると、衛星からデータを受け取れる。このGPSモジュールは、受信したGPSデーターをシリアルで送出するのでシリアル通信できるようにする必要がある~ ターミナルを開き、シリアル通信を有効にする。 sudo raspi-config で「5 Interfacing Options」を選択、「6 Serial」を選択、「yes」、「finish」を選択、再起動(sudo reboot と入力) ls /dev/se* と入力すると、/dev/serial0 /dev/serial1と表示される。 コンソールを修正するが、テキスト修正するときはターミナルからファイルを開かないと修正できない。よってターミナルで、~ sudo nano /boot/cmdline.txt と入力して修正する。 「console=serial0,115200」の部分を削除する。 pip install pyserial でPythonのシリアルモジュールをインポートし、python3 と入力すると次のような表示が出る。 #ref(16.PNG,,55%) ~この青文字がデータに当たる #ref(gpsp.py) #ref(micropyGPS.py) micropyGPS.pyは衛星信号をプログラムで扱いやすいデーターに変換するPythonライブラリーに変換するためのもので、gpsp.pyと同じファイルに入れておく。 python3 gpsp.py で実行する。使っているセンサは電源入れて窓付近において10分~1日放置しないと受信しない。赤いランプが点滅したら受信できている~ #ref(17.PNG,,40%) ・MAP 実行上の表記が乱れるが地図で表示可能。モジュールをまずインストールしてから行う。 pip install folium #ref(gps_getter.py) を実行すると地図が表示される。 #ref(18.PNG,,40%) ***カメラ単体の場合 [#rc80b0c4] 1.カメラの接続 カメラを接続する.ラズパイ本体とカメラのバージョンが一致しないと手間がかかるので確認しておく。 #ref(17.jpg,,20%) 2.カメラの有効 sudo raspi-config 「5 Interfacing Options」、「P1 Camera」を選択、「Yes」で有効にしたら再起動する。 vcgencmd get_camera で「supported=1 detected=1」と表示されたら接続OK 3.ライブラリのインストール pip install picaamera ラズパイのバージョンがPython 2.7.9やPython 3.4.2の場合は不要 インストールされているかの確認 pip list –format columns これでライブラリの一覧が表示されたらOK「Packege、picamera、pip、setuptools」 4.写真撮影 写真撮影するプログラム #ref(piccamera.py) ターミナルで python piccamera.py で実行すると同じディレクトリに写真が撮影され、保存される。整理したかったらプログラム自体を別ファイルで作成しておく。 ***音声単体の場合 [#g00f14bf] ・USBマイクで音声認識 マイクに話しかけ音声入力でテキスト化する。以下は単純なテキスト化 #ref(recmic.py) ラズパイにUSBマイクを接続し、音声をテキスト変換するAPIをインスト―ルする pip install Speechrecognition 続いてプログラムをターミナル上で実行する python recmic.py 実行すると「samething say」と表示されるので何か答える。 #ref(13.PNG,,30%) * 7.Raspberry Pi と Auduino の連結[#j1504d6c] Auduinoとラズパイを連結して情報を得る #ref(zentai.PNG,nolink,,50%) ラズパイ、PCで使うコード newsensa_all.py #ref(server.py) .ラズパイに入れるモジュール opencv matplotlib scikit-learn graph-marker socket ・PCに入れるnltkリソース python >>>import nltk >>>download('averaged_perceptron_tagger') >>>download('wordnet') >>>download('universal_tagset') .PC側 gspread oauth2client pandas codecs numpy nltk gensim folium webbrowser scipy ・プログラム修正点 server2.pyの133行目、sensaK.pyの42行目の下線のIPアドレスを自身のパソコンのIPに変更する。 #ref(henko1.PNG,,50%) #ref(henko2.PNG,,25%) PC側でserver2.pyがうまく軌道できたら [available to connect: 192.168.0.205](ここは自分のIPアドレス)の文字が表示されるのですぐラズパイの方でsensaK.pyを起動する。 上手くいけばラズパイもPCにもAuduinoで取得したデータ(数値)が表示され、ラズパイ側にはカメラ画像、PC側にセンサのグラフがリアルタイムで更新される。 #ref(GURAHU.png,,15%) *8.スプレッドシート書き起こし [#eb5c69b8] リアルタイムでの情報取得できたらカメラ画像を収得する。画像ではなく画像に映っている情報を文字に起こして羅列しどこにいるのか、何をしているか判断することができる 7.で説明したカメラの使い方は取得データをPCのコマンドプロンプトに表示するもので今回はスプレッドシートに表示する。 シート1には,時間とセンサ数値,カメラテキストが保存される.シート2には,時間とマイクテキストが保存される. IoT.zipの中にあるプログラムprocessing-data.pyでシート1とシート2のそれぞれの時間をmerge_asofして,マイクテキストがある時間でシート1とシート2が統合される. 統合されたマイクテキストは,その時間においての行動ラベルとして使われ,デンドログラムのラベルに表示される. デンドログラムのラベルで,実行中の最後の行の実行数値データ群には,現在の行動として識別できるように,自動で「最新」というラベルを付加し,データの更新が起これば「最新」ラベルは移動するようにプログラムした. #ref(text.PNG,,60%) ***下準備 [#a0630450] 今回使うのはpyhtonから得たデータをスプレッドシートに格納するためにGASを使用する。 **[[1.Google Cloud Platformにて:https://console.developers.google.com/]] [#weea153e] 1.1 データ取得のために適当にプロジェクトを作成する #ref(23.PNG,,60%) [新しいプロジェクト]で適当に名前を入力する。 1.2 外部から操作するために2つのAPIを有効にする 左側にある[ライブラリ]を選択し[googleDriveAPi]をさがし、選択。有効にする 同じ手順で[GoogleSheetsAPI]も有効にする。無事2つが有効にできたら[ダッシュボード]が下図のようになる。 #ref(25.PNG,,40%) 1.3 認証情報 左側にある[認証情報]を選択し、認証情報を作成し、サービスアカウントを選択する。 適当にサービスアカウント名を入力して作成 #ref(26.PNG,,60%) アカウントの制限をProjectの編集者に設定。最後に作成をクリックするとアカウントができる #ref(27.PNG,,50%) #ref(28.PNG,,50%) 最後に秘密鍵を入手する。つくったサービスアカウントを選択し[キー]から鍵を作成する。 #ref(29.PNG,,50%) そうするとPCに鍵が保存される.この時キーのタイプがJSONになっていることを確かめる。 &color(red){最後に保存された秘密鍵の名前を[cilent_secret.json]にして任意のファイルに移動させる}; 後でこのファイルは使います。 **2.スプレッドシート書き込み [#o3d3c0fe] 1の設定で作成したアカウントとスプレッドシートを共有する。 2.1 共有 自身のgoogleドライブから新規でスプレッドシートを作成する。 適当に作ったgoogleのスプレッドシートの共有を選択し、先ほどのアドレスを追加する。 ここのアドレスとは、28.PNGのメールアドレスっぽいやつである。この際に編集者として設定する。 #ref(30.PNG,,60%) 2.2 スクリプトエディタ スプレッドシートの[ツール]、[スプリクトエディタ]を開き、以下のコードを書き込む。 function doPost(e) { var ss = SpreadsheetApp.getActive() //下の2行はどっちでもOK 2つ目はシート一枚目という意味 //de.kore.naniyo //var sheet = ss.getActiveSheet(); var sheet1 = ss.getSheets()[0]; var sheet2 = ss.getSheets()[1]; var jsonString = e.postData.contents; //jsonString = jsonString.replace('\\',''); //jsonString = jsonString.replace(/\}\"/,'\}'); var data = JSON.parse(jsonString).toString(); // sheet.appendRow(["そのまま",jsonString]); // sheet.appendRow([data]); // sheet.appendRow(["パース",typeof(data)]); var data2 = JSON.parse(data); // var last=sheet.getRange("A:A").getLastRow(); if (data2.key1){ sheet1.appendRow([data2.key1.nowtime,data2.key1.bio_data,data2.key1.camera]); sheet1.appendRow([data2.key2.nowtime,data2.key2.bio_data,data2.key2.camera]); sheet1.appendRow([data2.key3.nowtime,data2.key3.bio_data,data2.key3.camera]); sheet1.appendRow([data2.key4.nowtime,data2.key4.bio_data,data2.key4.camera]); sheet1.appendRow([data2.key5.nowtime,data2.key5.bio_data,data2.key5.camera]); sheet1.appendRow([data2.key6.nowtime,data2.key6.bio_data,data2.key6.camera]); sheet1.appendRow([data2.key7.nowtime,data2.key7.bio_data,data2.key7.camera]); sheet1.appendRow([data2.key8.nowtime,data2.key8.bio_data,data2.key8.camera]); sheet1.appendRow([data2.key9.nowtime,data2.key9.bio_data,data2.key9.camera]); sheet1.appendRow([data2.key10.nowtime,data2.key10.bio_data,data2.key10.camera]); sheet1.appendRow([data2.key11.nowtime,data2.key11.bio_data,data2.key11.camera]); sheet1.appendRow([data2.key12.nowtime,data2.key12.bio_data,data2.key12.camera]); sheet1.appendRow([data2.key13.nowtime,data2.key13.bio_data,data2.key13.camera]); sheet1.appendRow([data2.key14.nowtime,data2.key14.bio_data,data2.key14.camera]); sheet1.appendRow([data2.key15.nowtime,data2.key15.bio_data,data2.key15.camera]); sheet1.appendRow([data2.key16.nowtime,data2.key16.bio_data,data2.key16.camera]); sheet1.appendRow([data2.key17.nowtime,data2.key17.bio_data,data2.key17.camera]); sheet1.appendRow([data2.key18.nowtime,data2.key18.bio_data,data2.key18.camera]); sheet1.appendRow([data2.key19.nowtime,data2.key19.bio_data,data2.key19.camera]); sheet1.appendRow([data2.key20.nowtime,data2.key20.bio_data,data2.key20.camera]); sheet1.appendRow([data2.key21.nowtime,data2.key21.bio_data,data2.key21.camera]); sheet1.appendRow([data2.key22.nowtime,data2.key22.bio_data,data2.key22.camera]); sheet1.appendRow([data2.key23.nowtime,data2.key23.bio_data,data2.key23.camera]); sheet1.appendRow([data2.key24.nowtime,data2.key24.bio_data,data2.key24.camera]); sheet1.appendRow([data2.key25.nowtime,data2.key25.bio_data,data2.key25.camera]); sheet1.appendRow([data2.key26.nowtime,data2.key26.bio_data,data2.key26.camera]); sheet1.appendRow([data2.key27.nowtime,data2.key27.bio_data,data2.key27.camera]); sheet1.appendRow([data2.key28.nowtime,data2.key28.bio_data,data2.key28.camera]); sheet1.appendRow([data2.key29.nowtime,data2.key29.bio_data,data2.key29.camera]); sheet1.appendRow([data2.key30.nowtime,data2.key30.bio_data,data2.key30.camera]); } if(data2.mickey){ sheet2.appendRow([data2.mickey.nowtime,data2.mickey.mic]); } } ●使うコードについて 容量制限のため研究室googleDriveの[学生>沼田>>卒業論文]に圧縮ファイルIoT.zipをアップロードしました。 &color(red){そのコード集をダウンロードして解凍したら、設定で保存した秘密鍵をこのフォルダに入れておく。}; そしたら下準備としてprocessing_data.pyをエディタを使って開き、40行目のSPREADSHEET_KEYを変更する。 ここでのキーとはつくったスプレッドシートのURLの&size(18){一部};である。 #ref(31.PNG,,70%) URLの/d/この部分/edit~ ここまでできたらラズパイとPCをつなげ、カメラから取得したデータを書き起こす。 ***書き起こし [#w73247c1] アルディーノと連結したラズパイを電源につないでPCとリモート接続する。 ●カメラ画像の書き起こしに使うコード newsensa_all_name.py まずこのコードを書き換える必要がある。 PC側でスプリクトエディタを開き、[公開>ウェブアプリケーションとして導入]し、 Project version > new Execute the app as > Me who has access to the app > Anyone にする #ref(36.PNG) 更新するとURLが製造されるのでそのアドレスをコピーし、コードの103行目のURLを書き換える。 そしてコードをラズパイで実行する。 #ref(34.PNG) これはアルディーノのセンサデータとカメラ画像を5秒ごとに表示している。これを30回繰り返すとスプレッドシートに表示される。 #ref(22.PNG) 詳しく見てみるとたしかにペットボトルの情報が書き起こされている。 #ref(33.PNG,,50%) #ref(35.PNG,,60%) ***デンドログラム表示 [#ge5cc674] スプレッドシートにシート2を用意し、PCで[processing_data.py]を実行するとデンドログラム(初期)が表示される。 #ref(39.PNG,,50%)