...

位置情報管理システム~センサネットワークの試作

by user

on
Category: Documents
9

views

Report

Comments

Transcript

位置情報管理システム~センサネットワークの試作
卒
業
研
題
目
究
位置情報管理システム
-センサーネットワークの試作報 告 者
1060233
多 木
勝 彦
指
導
教
員
岩
下
克
教授
平成
18年
2月
21日
高知工科大学工学部
電子・光システム工学科
第1章
序論..................................................................................................................... 2
1.1
研究背景 ................................................................................................................. 2
1.2
研究の目的 ............................................................................................................. 2
第2章
研究の概要.......................................................................................................... 4
第3章
実験系 ................................................................................................................. 5
3.1
全体の構成 ............................................................................................................. 5
3.2
使用する機材の主な説明 ........................................................................................ 5
(1)赤外線センサー ......................................................................................................... 5
(2)A/Dコンバーター(PCIボード)................................................................................... 7
(3)PIC............................................................................................................................ 8
(4)PIC開発環境 ............................................................................................................. 8
(5)Xport......................................................................................................................... 8
(6) VisualBasic.net ..................................................................................................... 10
3.3
センサー設置のための出力測定 ........................................................................... 10
3.3.1
センサーの設置パターン............................................................................... 10
3.3.2
センサー出力測定結果 .................................................................................. 13
3.4
ノード作成 ........................................................................................................... 15
3.4.1
送信パケット構造 ......................................................................................... 15
3.4.2
ノード回路図と構成説明............................................................................... 16
3.4.3
処理フローチャート ...................................................................................... 18
3.5
センサーネットワーク作成 .................................................................................. 22
3.5.1
Comm Port Redirectorを使用したセンサー出力パケット取得 .................... 22
3.5.2
パケット診断プログラムを使用したパケット取得 ....................................... 23
3.6
第4章
センサーノード設置模式図(簡略版、直線T字路モデル) ...................................... 26
測定結果 ........................................................................................................... 27
4.1
完成したセンサーノード概観と動作 .................................................................... 27
4.2
ハイパーターミナルと親ノードの通信 ................................................................ 28
4.3
パケット診断プログラム ...................................................................................... 28
4.4
人体位置情報検知................................................................................................. 30
第5章
考察................................................................................................................... 32
第6章
まとめ ............................................................................................................... 33
謝辞 .................................................................................................................................... 34
参考文献 ............................................................................................................................. 35
付録 .................................................................................................................................... 36
付録 1
使用した機材の性能一覧............................................................................... 36
<1>赤外線センサー ..................................................................................................... 36
<2>A/Dコンバーター(PCIボード)............................................................................... 36
<3>PIC........................................................................................................................ 37
<4>Xport..................................................................................................................... 39
付録 2
赤外線センサー出力測定プログラム(A/Dボード制御) .................................. 39
付録 3
赤外線センサー出力処理、送信プログラム(PIC制御) .................................. 44
付録 4
ノード出力受信処理プログラム(Main&モジュール) ................................... 69
Main............................................................................................................................ 69
モジュール................................................................................................................... 88
1
第1章
1.1
序論
研究背景
私達を取り巻く生活空間は、パソコンや携帯電話などの情報端末の一般への普及、
インターネット回線のブロードバンド化及び価格の定額化などに伴って、大きく変わ
って来た。近年それらを活用した情報家電と呼ばれるユビキタスネットワーク化に対
応する商品の開発が行われてきている。
ユビキタスネットワークとは、「『いつでも、どこでも、何でも、誰でもアクセス
が可能』なネットワーク環境」[1]と定義されている。ユビキタスネットワーク化は既
存のパソコンだけではなくテレビ、洗濯機や冷蔵庫など一般的な家電製品をネットワ
ークで結び、互いに通信を行い今までになかった機能や利便性の向上を図ることを目
的としている。
ユビキタスネットワークを一般家庭等に構築する上で、センサーネットワークの開
発は必要不可欠となってくる。センサーネットワークとは元来、単体では限られた機
能しか持たなかったセンサーを、ネットワークに繋げ機能向上を図るシステムである。
ユビキタスネットワークの「目」とも言えるセンサーでネットワークを構築し、パソ
コンや情報家電がデータをやり取りすることで詳細な人体の位置情報を得て、より良
いサービスを提供することが可能となる。
人体の位置情報検知にはGPSや無線LAN、RFID、防犯カメラなどを使用した事例が報
告されている。しかし検知精度や個体識別の有無など、実装する用途や現場によって
求められる性能が異なっている。例えば、個体識別が必要な場合にはRFIDなどが使用
される。実用例として「RFID豚トレーサビリティ」[2]や「社員証、学生証への導入」[3]、
「物品ラインへの導入」[3]などがあり、それぞれ生産情報管理、防犯、効率化と精度
向上などのために実用化されている。
しかし、RFIDは各個人にタグを携帯してもらう必要があるが、公共の場所や家庭内
では個人識別の必要性がない場合がある。よって用途に応じて個人識別を必要とせず
安価な位置情報検出手段が必要となる。
1.2
研究の目的
本研究ではセンサーとして安価で定評のある赤外線センサー複数使用し、センサー
ネットワークを作成することによって人体の位置情報検知を行いたいと考えている。
まず使用する赤外線センサーの特性の計測を行い、実際にセンサーを効率的に設置す
るかを検討する。
本実験で使用する赤外線センサーとは、自動ドア、ATMなど単体で広く利用されて
2
いるものを指す。単体では、センサーの検知範囲内に人が居るか居ないしか検知する
ことができないが、このセンサーを複数個ネットワークに接続し管理することによっ
て、人の位置や移動方向、速度を検出することができる。センサーネットワークが必
要とされてくる中で、確かに性能の良いセンサーを各所に配置すればより完璧なセン
サーネットワークが出来上がるが、将来様々なセンサーが混在するセンサーネットワ
ークの構築に向けて、まずは簡単な動作をし、世間一般に最も普及していると考えら
れる赤外線センサーを用いて人体移動検知がどこまで行えるかについて実験を行う。
3
第2章 研究の概要
センサーネットワークによって得られた位置情報を他の製品に活用する場合、例え
ば光無線LANのアクセスポイントに人の位置情報を渡した場合、各ノードの近くに人
が居るか、また近寄りつつあるかが分かり通信の効率化や省エネなどに活用できる。
また、防犯カメラに情報を送ってやれば同じ場所を撮り続けるのではなく、位置情報
にあわせて被写体を追尾しながら撮影、記録が可能となる。そしてどこにでもある照
明やブラインド等に送ってやれば、部屋の中に誰も居ない場合に人の居ない区画の電
気を消したりブラインドを閉めたりすることも出来る。
本研究では図 2-1のように居室に複数のセンサーを設置し、得られた位置情報を
PCで管理し他の電化製品等に渡し活用することを可能とするための実験を行う。最初
は平面状ではなく、直線的にセンサーを設置し一人の被験者を歩かせることによって
位置情報検知を行う。
図 2-1 センサーの設置例
4
第3章 実験系
3.1
全体の構成
センサーネットワークを作成しPC上で管理を行うにあたり、赤外線センサーひとつ
ひとつに通信機能を設けるのではなく幾つかをまとめて統括するノードの作成を行
う。図 3-1に位置情報管理システムの全体の構成を図示する。私が手がけるのは破
線部分で囲まれたハードウェア中心のセンサーネットワークの部分で、それ以外のソ
フトウェア中心の管理システムは共同研究者が手がける。しかし、私の方で作成した
パケットが正しいものかを判断するために、独自にパケット診断プログラムを作成す
る。
図 3-1 位置情報管理システムの構成
3.2
使用する機材の主な説明
(1)赤外線センサー
センサーは図 3-2の松下電器製焦電型MPモーションセンサーNaPiOn(AMN13111)を
使用し、付録に性能の概略を示す。
5
図 3-2
実験に使用した AMN13111 の概観
赤外線を利用したセンサーには今回使用した焦電型とサーモパイルと呼ばれるも
のがある。原理は、サーモパイルが熱電対の原理を応用した簡単なセンサーで、熱電
対を微少な面積の中に直列に並べた物である。熱電対、すなわち2種類の金属で回路
を作成しその2つの接合部分が異なる温度に保たれた時に熱起電力が生じて電流が流
れる「ゼーべック効果」の原理を使用している。
また、焦電型は焦電物質を用いてあらゆる物体から放出される赤外線エネルギーを
検出することができる。この型のセンサーは波長依存性がないため光学フィルターを
使い分け、波長を選別してやることによって様々な温度センサーを作ることが可能で
ある。AMN13111は温度差(±4℃)を検出可能なため体温を持つ人体の検出に最適とさ
れている。
全体の検出範囲は図 3-3のような縦1.4m横2.0mの長方形となっているが、実際に
は24個の各セルに被験者が侵入した場合にのみ出力(Vdd-0.5V)されることとなる。
6
図 3-3 使用した赤外線センサーの検出セル配置
(2)A/Dコンバーター(PCIボード)
A/Dコンバーターは、センサーからのアナログ信号をデジタル信号変換しパソコン
上で記録するために使用した。今回使用したA/Dコンバーターは図 3-4に示す
interface社製PCI-3163である。パソコンのPCIスロットに装着し使用するボードタイ
プの物で12bit分解能2ch同時A/Dコンバートが可能でありBNCコネクタによって接続
を行う。付録にPCI-3163の基本仕様を明記する。
図 3-4
実験に使用した PCI-3163 の概観
7
(3)PIC
PICとは所謂マイコン(マイクロ・コントローラー) と呼ばれる物で、電気的な「何
か」を制御するためのコンピューターの一種だと考えることが出来る。例えば炊飯器
や洗濯機などの電化製品に内蔵され、予めPIC内にプログラムされた手順に沿って付
属のI/Oポートの入出力制御を行うことにより、ご飯を炊いたり洗濯を行ったりする
ことを可能としている。PICがパソコンと異なる点は、パソコンが様々な動作が可能
な様汎用的に組み立てられているのに対し、PICはランプを点灯させたりモーターを
駆動させたりと制御面に特化している。図 3-5に使用したPIC
16F628Aの概観、付
録に基本仕様を示す。
図 3-5
実験に使用した 16F873A の概観
(4)PIC開発環境
PIC内のプログラムを記述するには、アセンブリ言語を使用する。アセンブリ言語は
低水準言語と呼ばれ、今回使用するPICでのアセンブリ言語の命令数は他の高級言語な
どと異なり35個しかない。命令の数が少ないということは覚えることが少なく理解しや
すいということになるが、これらの命令とレジスタを活用してC言語等、高級言語で行
われるような算術、比較、繰り返しなどの処理を行わなければならず、プログラムは一
見して分かりにくい物となる。今回アセンブリ言語を処理するアセンブラには
Microchip社の開発支援ソフトのMPLAB IDE内のMPASMを使用した。
(5)Xport
図 3-6のXportを用いることでPIC等、シリアル通信に対応したデバイスを比較
的簡単にネットワークに対応させる事が出来る。そしてPICの出力をネットワークを
8
介して管理し、PC側からPICを制御することが可能となる。付録にXportの基本仕様を
明記する。
図 3-6
実験に使用した Xport
LANTRONIX社Xportは「超小型シリアル-イーサネット変換デバイス」として開発さ
れている。対応するI/Oピンに対しシリアル通信機器を繋ぐ事によって簡単にネット
ワークへと対応させてやる事が出来、ネットワークが通っている場所なら何処からで
も監視、制御が可能となる。また通信の暗号化や電子メールの送信、内蔵webサーバ
ーによるWebページの配信やJAVAアプレットによるブラウザでの接続機器の状態監視
などにも対応可能となっている。また、Xportには使用者が簡単にシリアル接続対応
の機器をネットワークに対応させられる様、Comm Port Redirector
というソフトが
公表されている。図 3-7にその概略を図示する。実際はXportとPC間はLANケーブル
で結ばれておりデータのやり取りするために接続の確立やデータの処理方法などを
別にプログラムを作成して処理してやらなければならない。しかしこのソフトを使用
した場合には、初期導入時にのみ設定を行うことでPC側にRS232CのCOMポートを仮想
的に作成し、本来XportのIPアドレスを指定して接続を確立してやらなければならな
い所を、PCのCOMポートに対しシリアル通信対応の機器が接続されているように扱え
る。よってOSに標準装備されているハイパーターミナルで接続、出力パケットの取得
が可能である。
9
図 3-7
Xport 付属ソフト
Comm Port Redirector
図 3-7では研究室内にて設置したXportに192.168.11.101というローカルIPアド
レスを割り振り、同IPへの3001番ポートを使用した接続をRS232CのCOMポート2として
仮想的に定義している。
(6) VisualBasic.net
センサーの特性を取得するプログラム、パケットを診断するプログラムを作成する
にあたり、言語はVisualBasic6かVisualBasic.netどちらを使うかという問題に至っ
た。センサーの特性を取得するプログラムのみならばVisualBasic6を用いたが、パケ
ット診断プログラムを作成するにあたり、ネットワーク関連の機能が強化された
VisualBasic.net[7]を使用することとなった。ネットワーク関連のプログラミング[6]
とADボードの制御[6]に関して参照した書籍等は参考文献に後述する。
3.3
センサー設置のための出力測定
3.3.1 センサーの設置パターン
赤外線センサーを設置するにあたりこのセンサーの出力特性を取得し、最適な設
置方法を検討する必要がある。センサーの出力をA/Dボードに入力し図 3-8の
Visual Basic.netで作成した制御プログラムによってA/Dボードを制御[9]しデータ
を取得した。研究では最初に精度を出すために図 3-9のようにセンサーを互いにオー
バーラップさせて設置を行ったと同時に、プログラム側でもある程度の出力波形のオ
ーバーラップに対応できるようにプログラミングを行っていた。しかし、使用した赤
10
外線センサーは立ち上がりには問題はないものの、出力の立下りが遅く予測よりも大
幅に出力波形がオーバーラップを起こしプログラム側でこれを補正することが難しく
なった。よって図 3-10の様にセンサーを隣接した場合や、図 3-11の様に各センサー間
に十分な空きスペースを確保してやる場合などのいくつかのパターンを設けてセンサ
ーの設置実験を行った。
そして、結論として図 3-11のように各センサー間を 2.1mの距離を空けて設置してや
ることによってオーバーラップを低減し、プログラム側で補正してやることが可能と
なった。
図 3-8
A/D ボード制御、計測値記録プログラム概観
11
図 3-9
センサー設置モデル(オーバーラップ)
図 3-10
図 3-11
センサー設置モデル(隣接)
センサー設置モデル(マージンを取る)
12
3.3.2
センサー出力測定結果
3.3.1 の結果を踏まえて 図 3-12 の様にセンサーを 2 つ 2.1mおきに高さ 2.9mの天井
へと 2 つ設置した。高さ 2.9mというのは今回実験を行ったスペースの天井の高さからこの
ようになっている。そして 図 3-8 で紹介したプログラムを使用して、この2つのセンサ
ー間を身長 185cmの被験者Aに行きはセンサー1→センサー2 となる様、青い矢印の方
向に移動し、数秒後に帰りはセンサー2→センサー1となる様、赤い矢印の方向に移動
を行った結果 図 3-13 のような出力を取得できた。
図 3-12
センサーの設置例
13
図 3-13
赤外線センサーの出力特性
この出力波形より、センサーの立ち上がりの順番から被験者の歩行した方向が分かる。
また各センサーの最初の立ち上がり間の時間と実際にセンサーを設置した距離との
関係から被験者の移動速度が算出できる。次に、この算出された速度が信用出来る物
かを検討するために実験を行った。図 3-14 に2人の被験者(身長185cm、身長170
cm)を個別に速度を変化させ歩行させ、実測速度とセンサーによって計測した速度
の関係を図示する。試行回数は往路、復路を区別せず共に15回試行した。
14
図 3-14
実測速度とセンサーで検知した速度のグラフ
縦軸がセンサーで検知、算出を行った被験者の移動速度(km/h)、横軸が実際の速度
(km/h)となる。またグラフ内の1.8km/hと5.4km/hの罫線は、データシートで見たこの
赤外線センサーの検出可能速度0.5m/s~1.5m/sに対応する場所に設けている。結果と
して実速度とセンサーによって計測された速度との誤差は±21%の間に分布し、人の
速度と移動方向が算出できることが分かる。
3.4
ノード作成
3.4.1 送信パケット構造
XportからPCに送られるデータは図 3-15のような構造となっており、Xportを介し
てTCPセグメントとして送信されPC側で処理する。PICはセンサーの出力波形を10ms
毎に読み取っているがこれを全てパケット化して送信するのではなく各センサーの
出力のON/OFFが前回と異なる場合のみパケット化して送信を行う。パケットは7文字
(56bit)で構成しておりどの部分のセンサーが反応したかを格納するSensor番号
(1Byte)部分、センサーのON/OFFの状態(1Byte)を格納する部分、反応時間(4Byte)を
格納する部分、改行コード(1Byte)となる。タイムスタンプをつけるのはネットワー
15
クを経由するためなにか遅延が発生した場合にも対応出来るようにするためである。
図 3-15
送信パケットの構造
3.4.2 ノード回路図と構成説明
センサーの出力波形を処理し、パケット化したデータをPC上のプログラムとやり取
りするノードを作成する。作成したノードの回路図を図 3-16に図示する。
16
図 3-16
作成したセンサーノード(親・子)の回路図
17
①全体の配置
ノードは親と子に分別され、親ノードにはXportとセンサー、各センサーからの出
力信号を処理するためのPIC、動作確認用のLCD(液晶)が付属させる。子ノードは基本
的にセンサー部分のみで給電及び、センサー出力の伝送にはRJ45ケーブル(Ethernet
に用いられるLANケーブル)を用いて親と子を結んでいる。
②給電方法
回路への給電はXportが標準で装備しているACアダプターから行う。Xportの動作電
圧は3.3Vで供給されたおよそ6Vの電圧はXportの内部の三端子レギュレータによって
電圧を落とし使用する。またXportからの端子には降圧前の6Vの流れているポートが
あるので、この部分からPICやLCD、赤外線センサーの駆動に必要な5Vの電圧を同じ様
にして、三端子レギュレータによって降圧し得ている。
③Xportとの接続
XportのDTOピンをPICのUSART通信用ポートRxに接続、PICからのTx出力は駆動電圧
の違いから抵抗を使用して5V⇒3.3Vに降圧させてDTIピンへと入力する。
④その他
クロックは内部でRTCC(リアルタイムクロックカウンタ)が必要となるため、精度の
高い20MHzのクリスタルクロックを使用した。付録表 1に示すように1年経過した段
階でもその誤差は±5ppm(5μ秒)となっておりRTCCとして最適になっている。また、
LCDは4bitのパラレル伝送を使用しているため液晶へのデータ伝送のために4本、制御
用に3本がPICからLCDへ入力している。
付録表 1 使用したクリスタル(20MHz)の特性表
周波数偏差(25℃)
±50ppm
温度依存(-10℃~60℃)
±50ppm
経時変化(1年)
±5ppm
Max
動作温度範囲
-20℃~+70℃
処理フローチャート
図 3-17にメインルーチン、図 3-18に割り込み処理と受信データ判別処理につ
3.4.3
いてのサブルーチンを記述する。
18
図 3-17
メイン処理のフローチャート
①PICに対して電源を投入後、使用する変数とレジスタの関連付け宣言、各ポートの
入出力指定、シリアル接続についての設定、液晶の初期化及び初期メッセージの表示
19
などを行う。
②PICのPortAに対してセンサーの出力が入力されているため、ポートの状態を取得し
保存、比較しながらXport側へとパケットとして送りだして行く。まず電源投入後初
期のPortAの状態を取得、前回のセンサー状況(SenSorBeFoR:SSBFR)に格納する。
③RCIFレジスタをチェックしPC側からの受信データがないかを確認する。(RCIFはRx
ピンに対して通信が行われバッファがフルになると1にセットされる)
受信データ
があった場合は後述する図 3-18での「データ判別」ルーチンを呼び出し、PC側から
の受信データがなかった場合は、そのままメインの処理が続けられる。
④PortAの状態を取得し、現在のセンサーの状態レジスタ(SenSorNOW:SSNOW)に格納
し 、 SSBFR と SSNOW の XOR( 排 他 的 論 理 和 ) を 取 得 し 、 結 果 を 比 較 結 果 レ ジ ス タ
(SenSorReSuLT:SSRSLT)に格納する。PortAの状態はビットごとに入力がHighなら1に
セットLowなら0にクリアされるので、例えばPortAの1と3に入力があった場合は
00001010
という感じに0~7bitまでのうち1bit目と3bit目が1にセットされる。つま
りSSBFRとSSNOWをビット毎に排他的論理和を取ることによって前回のポートの状態
とことなっている部分だけを1にセットし、結果にSSRSLTとして保存している。
⑤保存したSSRSLTからどのポートの状態が変化したかを判別し、対応するセンサー番
号をSENSORレジスタに格納する。またSSRSLTの変化により現在ポートが1(センサー
ON)なのか0(センサーOFF)なのかを判別、ON_OFFレジスタにON(1)OFF(0)として格納し
ている。
次にMFLGが1にセットされるのを待って(図 3-18の解説で後述)MFLGをクリアした後
SENSOR+ON_OFF+現在の時刻(秒2桁,ミリ秒2桁)を液晶に表示、Xport側へ送り出す。送信
終了後にメインループへの先頭へとReturnする。
20
図 3-18
割りこみ、サブルーチンのフローチャート
割り込み処理
割り込み処理はTMR0を使用し、クロックが20MHzのためこれを1/4のサイクルタイム、
プリスケーラー4倍でカウントアップを行う。
20MHzクロック⇒1/4のサイクルタイム5MHz(20MHz/4)で使用
プリスケーラー4倍⇒1024(256回×4)のカウントアップ完了ごとに割り込み
5MHz÷1024=4882.8125Hz
10ミリ秒毎に時計をカウントアップさせたいため、
4882.8125Hz×0.01秒≒48回
48回の割り込みをカウントした時点で10m秒と見なす。
しかし、このままでは48回カウントアップ完了ごとに約163psの誤差がでるため
0.8125Hz×64=52Hz
64Hzごとに次回カウントアップ回数の格納を48回ではなく通常の48回+52回、合計
100回分のカウントアップを指示する。
およそ205μ秒毎に割り込みが入り、プログラム内の割り込み処理へとジャンプす
る。ジャンプ先で今まで行っていた作業状況と作業位置のセーブを行った後、現在何
回目か割り込みであるかの判断を行う。もし割り込みが48回目ならMFLGをセットし、
内部時計の10ミリ秒カウンタをカウントアップする。48回に満たない場合は割り込み
処理を抜ける。MFLGはカウントアップが完了したことを示すレジスタで、内部時刻カ
21
ウンタにおいて書き込みと読み込みが競合しない様に、内部時刻カウンタに対して処
理を行う場合にはMFLGのセットを待って処理を行う。また参照した後は必ずMFLGをク
リアする必要がある。
受信データ判別処理
①データが受信された場合にメインループより呼び出される。まず受信データが特殊
なキャラクタ“S”か“R”であるかを判別し、どちらにも当てはまらない場合はここ
でメインループへとReturnする。
②もし受信したキャラクタが“R”の場合はPCからのリセットコードが送られて来た
として処理を行う。MFLGのセットを待って秒カウンタ(SECD)と10ミリ秒カウンタ
(TENM)をクリアし、リセット完了後に液晶上に時刻カウンタの秒と10ミリ秒カウンタ
がクリアされたとして“Reset!”と表示する。
③もし受信したキャラクタが“S”の場合は PC からの時刻セットコードが送られて
来たとして処理を行う。まず割り込みを禁止し内部時間カウンタを全てクリアし、そ
して PC 側から現在の時刻を受信した後に内部時間カウンタにその値を反映させ割り
込みを許可する。液晶上には時刻のセットが完了したとして現在時刻である“時:分:
秒”の 8 桁が表示される。
センサーネットワーク作成
3.5
3.5.1
Comm Port Redirector を使用したセンサー出力パケット取得
センサー設置及び、出力特性が取得できたため、実際にノード一つにセンサーを接
続して作成された、センサー出力パケットをPCで受信してみる。後述するパケット診
断プログラムを作成する前に図 3-19のようにComm Port Redirectorによって仮想
RS232C
COMポートを作成し、OSに標準で装備されているハイパーターミナルを使用
してXportとの接続を確立、出力パケットを受け取った。
22
図 3-19
センサーノードネットワーク化概略(仮想 COM 使用)
3.5.2 パケット診断プログラムを使用したパケット取得
VisialBasic.netを用いて図 3-7で記述したComm Port Redirectorを使用せずに、
Xportとの通信を行うためにプログラムを作成し、ノードを複数にした 図 3-20 の
ようなセンサーネットワークからの出力パケット取得を行った。プログラムの概観は
図 3-21に図示する。また動作のフローチャートを図 3-22に示す。
23
図 3-20
図 3-21
センサーネットワークの概略図
センサー出力取得プログラム(ネットワーク経由版)
24
図 3-22 パケット診断プログラムのフローチャート
①プログラムが開始されると各選択ボックスへの選択肢の追加やセンサーの設置座標が
読み込まれる。
②接続ボタンが押されると、2台のXport(以下親ノード)に対して接続の確立が試みら
れる。
③2つの親ノードの接続が確立されたら、現在時刻を取得PIC側へと送信を行いPIC内
の現在時刻を合わせる。その後、Xportに蓄積されていたパケットを5秒という処理時
間を設けて破棄している。これは診断プログラムが接続を行う前のパケットがXport
に蓄積されているため、現在のパケットを取得するために破棄を行っている。
④パケットを受信し、センサー番号の比較処理を行う。もしセンサー番号が不一致だ
25
った場合隣接するセルに移動したものとして速度の算出を行う。算出を行った速度が
速度がセンサーの検出可能速度範囲に納まっている場合のみ、画面に表示を行う。セ
ンサー番号が一致した場合や算出を行った速度が不正な場合は、処理を中断し次のパ
ケットを受信する。
3.6
センサーノード設置模式図(簡略版、直線 T 字路モデル)
作成したノード2個、センサー8個を図 3-23のようにしてT字路の形に設置を行っ
た。各センサーはノードによって管理されており、斜線が引かれている場所がノード
CとノードGとなっている。検出セルA,B,C,EとD,F,G,HはそれぞれノードCとノードG
に統合され通信を行っている。被験者A(身長185cm)を 図 3-23内においてH⇒D、D⇒
Hの検知範囲を往路、復路の区別なく約25回歩行の速度を変化させ測定、比較を行っ
た。
図 3-23
センサーネットワーク
26
T 字路モデル
第4章 測定結果
4.1
完成したセンサーノード概観と動作
図 4-1に作成した親ノードの概観を図示する。電源投入直後に「START
Sensor
SYS!」というメッセージをLCDに表示している。図 4-2にセンサーに反応があった
場合のLCDの画面を図示する。表示内容は 図 3-15 に記述した送信パケットの構造
に対応しており、1文字目にセンサー番号、2文字目にON_OFF(1or0)、3 文字目以
降はタイムスタンプが表示される。
図 4-1
図 4-2
ノード
完成図
検知時の LCD 画面
27
4.2
ハイパーターミナルと親ノードの通信
1 台のノードに搭載しているXportをComm Port Redirector(図 3-7)にてPC上の
COMポートに関連づけ、接続すると出力が図 4-3のように送られてくる。ハイパー
ターミナル上では 1 件表示後画面がクリアされてしまうのでテキストに保存した。テ
キスト画面上「■」は改行コードである。
図 4-3
親ノードへのハイパーターミナルを使用した接続(1 対 1)
4.3
パケット診断プログラム
3.5.2
にて記述したLAN経由センサー出力取得プログラムの動作画面を図 4-4に
図示する。取得したセンサーの出力は随時画面上に表示され、出力の変化が生じた時
点で比較演算操作を行い、画面上に速度と移動方向を表示している。またプログラム
内で平行してセンサーの出力と割り出した移動区間と移動速度を保存している。各ノ
ードには実時間をカウントするカウンタを搭載しており、センサー出力パケットに対
してタイムスタンプを付加する。しかし複数のノードが混在するセンサーネットワー
ク内において、各ノードが同じ実時間を刻み続ける必要性があるため、PCソフトウ
ェア側と連携して実時間を取得、PICに反映させる機能とPIC内部の実時間時計カウ
ンタの秒以下のリセットを行う機能を実装している。また、図 4-5に実時間のPIC反
映時のLCDが画面、図 4-6にリセットを受信した場合のPIC側のLCDを図示する。こ
28
れらの機能はこのセンサー出力取得プログラムからの各ノードへの接続確立時、及び
手動でCodeを選び要求を行った場合に実行される。
図 4-4
センサー出力プログラム動作画面
29
図 4-5
時間セット時のプログラムと親ノードの LCD 画面
図 4-6
4.4
リセットコード送信時の LCD 画面
人体位置情報検知
図 4-7にセンサーノードからのパケットを受信プログラムによって算出した速度
と、実際の移動速度との関係グラフを図示する。
30
図 4-7
センサーノード検知速度と実速度のグラフ
縦軸がノードで検知、算出を行った被験者の移動速度(m/s)、横軸が実際の速度
(m/s)となる。またグラフ内の罫線は、データシートで見たこの赤外線センサーの検
出可能速度0.5m/s~1.5m/sに対応する場所に設けた。
結果、ノード検知速度と実速度の誤差は±16%の範囲に分布している。
31
第5章 考察
赤外線センサーによって人の位置・方向・速度を検出することが可能であり、既存
の LAN を使用したセンサーネットワークの試作を行えた。
実験より、センサーの
設置間隔は検知範囲を隣接又は、オーバーラップさせるのではなく少なくとも検知範
囲の半分以上の間隔をあけてやることが必要とされることが分かった。今回測定のた
めに作成したセンサー出力プログラムでも、センサーの出力データが時間軸上でオー
バーラップした場合であっても、正しく速度と方向を表示出来る様にプログラミング
を行っているが、それをもってしても改善が難しいためセンサー間の距離を 2.1mに
することによって出力のオーバーラップを低減した。 今回の実験では、センサーネ
ットワーク内に二人以上の動体が進入した場合に、センサーネットワークでこれを検
知することは可能だが、プログラム側で二人以上の進入があり尚且つ、追尾すること
は困難であった。
32
第6章 まとめ
世間一般に自動ドアや防犯カメラ、ATM などに単体で使用されている赤外線センサー
を複数もちいてセンサーネットワークを構築する。これにあたりまず使用する赤外線セ
ンサーの特性を理解し、最適な設置間隔を調べるために A/D ボードを用いて赤外線セン
サーの出力を得て試行錯誤を行い、実験の結果からセンサー間は 2.1mの間隔をおいてや
るのが最適という結果になった。また同時にセンサーの波形の立ち上がりから人の移動
方向と移動速度を予測することが出来ることが分かった。この結果を踏まえてセンサー
を設置し、作成したノードと結びセンサーの出力波形を最適化したパケットの形に加工
を行った。センサーの出力パケットはネットワーク介し、作成したプログラムによって
画面上に人の現在位置、移動方向、移動速度を算出し表示することが出来た。
今回使用した赤外線センサーは物体が放出する赤外線を検知、リアルタイムで監視
し赤外線の変化量から人体の検知を行っている。赤外線センサーを使用した理由とし
て「安価である」「世間一般に広く使われている」「簡単な動作を行う」などがある。
他の RFID や画像処理など高価で個人を識別できる機材を使用しなかったのは、今回
の目的として人体位置情報管理を行うにあたり、簡単な検知情報を送信してくる赤外
線センサーを用いてどの程度可能なのか、またどういった場所に実装可能なのかを検
証するという目的があったためである。今回赤外線センサーを用いてセンサーネット
ワークを作成また、今後異なるセンサーを使用するにあたり、種類ごとにプログラム
側で処理方法を変えてやることでこれに対応できると考える。
33
謝辞
本研究を行うにあたって、常日頃からご指導、その多大なる知識のご教示を賜った
電子・光システム工学科
岩下 克
教授に深く感謝致します。
回路実装時における PIC や回路実装でお世話になった
綿森研究室
車 載仁さん
に深く感謝致します。
日頃から素晴らしい研究環境を作っていただいた同研究室メンバー
乾 梨紗さん
翔さん
ん
小松 昇さん
山本 宣幸さん
島村 卓嗣さん
恒安 宏一さん
また同研究室先輩方である
坂本 貴章さん
中島 公亮さん
田口
渡邊 利成さ
と 3 年生の皆様に感謝意を表したいと思います。
また個別に、共同研究者である乾 梨紗さんには互いに諦めず最後まで研究を行っ
てくださったことに対し、再度お礼を申し上げます。
34
参考文献
[1]
総務省:情報統計データベース
http://www.johotsusintokei.soumu.go.jp/whitepaper/ja/cover/index.htm
[2]
オムロンソフトウェア 豚トレーサビリティ 豚トレーサビリティとは
http://www.omronsoft.co.jp/rfid/pork/about.html
[3]
オムロンソフトウェア RFID開発キット活用事例
http://www.omronsoft.co.jp/rfid/kit/case.html
[4]
櫻井 他
信学会
[5]
滝本 他
信学会
[6]
“センサネットワークによる人の行動認識のための実験系の検討”
総合全大A21-12 p.369(2005)
“無線センサネットワークを用いた動線検出システムの試作”
ソサエティ大B-15-4 p.614(2003)
インターフェイス社
チュートリアル Visual Basic によるAD 入門書
[7]
Ver.1.4
秀和システム
やさしいPICマイコンプログラミング&電子工作
著:高橋 隆雄
[8]
日経BPソフトプレス
Visual Basic.NET 実践講座
Vol.1
基礎編
Vol.2
活用編
著:Michael Halborson
Visual Basic.NET 実践講座
著:Michael Halborson
[9]
MYCOM
Visual Basicではじめる ネットワークプログラミング 超入門
著:ソケたん製作委員会
35
付録
付録1
使用した機材の性能一覧
<1>赤外線センサー
付録図 1 実験に使用した赤外線センサー
付録表 1
赤外線センサー性能一覧
<2>A/Dコンバーター(PCIボード)
36
付録図 2 実験に使用した A/D ボードの概観
付録表 2
A/D ボード性能一覧
<3>PIC
37
付録図 3 実験に使用した 16F873A の概観
付録表 2
16F873A の基本仕様
38
<4>Xport
付録図 4 実験に使用した Xport
付録表 3
付録2
Xport の基本仕様
赤外線センサー出力測定プログラム(A/Dボード制御)
'各メソッドで共有される変数の宣言
Dim nRet As Integer
' 関数戻り値
Dim lpszName As String
' デバイス名
39
Dim hDeviceHandle As Integer
' デバイスハンドル
Dim Config(1) As ADSMPLCHREQ
'ADSMPLCHREQ構造体
Dim SmpData(1) As Short
'サンプリング結果格納配列
Dim Counter1 As Integer = 0
'繰り返し用カウンター
Dim Counter2 As Integer = 0
'繰り返し用カウンター2
Dim Volts1 As String
'Volt値格納変数1~2
Dim Volts2 As String
'[接続]ボタンを押したときの処理
Public Sub StartButton_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles StartButton.Click
'変数の宣言
Dim smpNum As Integer
Try
'[接続]ボタンを無効化(2度押し防止)
StartButton.Enabled = False
Config(0).ulChNo = 1
Config(1).ulChNo = 2
Config(0).ulRange = AD_5V
Config(1).ulRange = AD_5V
MyPrint("サンプリング条件設定")
' 読み取りアクセス可能な状態でファイルを開く
FileOpen(1, "Sensor1.csv", OpenMode.Output)
FileOpen(2, "Sensor2.csv", OpenMode.Output)
MyPrint("書き込みファイルオープン")
'[切断]ボタンを有効化
smpNum = CInt(SmpBox1.Text)
MyPrint("")
40
MyPrint("サンプリング件数" & smpNum & "件")
MyPrint(DelayBox.Text & "秒後にサンプリングを開始します")
Thread.Sleep(CInt(DelayBox.Text) * 1000)
'サンプリング開始Delay
StopButton.Enabled = True
Counter1 = smpNum
Do
'サンプリング条件設定
nRet = AdInputAD(hDeviceHandle, 2, AD_INPUT_SINGLE, Config, SmpData)
If nRet <> AD_ERROR_SUCCESS Then
MsgBox("AD一件取得に失敗しました1", MsgBoxStyle.Exclamation, "警告")
Exit Sub
End If
'外部ファイルに値を出力
Volts1 = Format(10 / (2 ^ 12 - 1) * SmpData(0) - 5, "#0.000")
Volts2 = Format(10 / (2 ^ 12 - 1) * SmpData(1) - 5, "#0.000")
MyPrint("1ch=" & Volts1 & "V 2ch=" & Volts2 & "V")
'ファイル書き込み
Print(1, Volts1, TAB(), Volts2)
'改行コード
WriteLine(1)
Counter1 = Counter1 - 1
If Counter1 < 1 Then
Exit Do
End If
Loop
MyPrint("")
MyPrint("サンプリング終了")
FileClose()
MyPrint("ファイルをCloseしました")
'[開始]ボタンを有効化
41
StartButton.Enabled = True
Catch ex As Exception
'エラー処理
MyPrint("* " & ex.Message)
EndSession()
End Try
End Sub
'[停止]ボタンを押したときの処理
Public Sub StopButton_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles StopButton.Click
Try
'[切断]ボタンを無効化(2度押し防止)
StopButton.Enabled = False
'サンプリングストップ
nRet = AdStopSampling(hDeviceHandle)
If nRet <> AD_ERROR_SUCCESS Then
MsgBox("サンプリングの停止に失敗しました", MsgBoxStyle.Exclamation, "警告")
End If
Catch ex As Exception
'エラー処理
MyPrint("* " & ex.Message)
EndSession()
End Try
'ファイルクローズ
FileClose()
MyPrint("ファイルをCloseしました")
End Sub
42
'各メソッド共通の終了処理
Sub EndSession()
MyPrint("")
StopButton.Enabled = False
StartButton.Enabled = True
End Sub
'ログウィンドウに1行表示
Sub MyPrint(ByVal str As String)
logBox.Items.Add(str)
logBox.TopIndex = logBox.Items.Count - 1
logBox.Refresh()
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles
MyBase.Load
lpszName = "FBIAD1"
hDeviceHandle = AdOpen(lpszName)
If hDeviceHandle = -1 Then
MsgBox("ボードの初期化に失敗しました", MsgBoxStyle.Exclamation, "警告")
End If
MyPrint("ボード" & lpszName & "をOPENしました。")
'サンプリング件数BOX選択肢追加
SmpBox1.Items.Add("1000")
SmpBox1.Items.Add("2000")
SmpBox1.Items.Add("4000")
SmpBox1.Items.Add("8000")
SmpBox1.Items.Add("16000")
'サンプリング開始DelayBOX選択肢追加
DelayBox.Items.Add("0")
DelayBox.Items.Add("5")
DelayBox.Items.Add("10")
DelayBox.Items.Add("15")
End Sub
43
Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles
MyBase.Closed
' 終了処理
nRet = AdClose(hDeviceHandle)
If nRet <> AD_ERROR_SUCCESS Then
MsgBox("ボードのクローズに失敗しました。", MsgBoxStyle.Exclamation, "警告")
End
End If
End Sub
End Class
付録3
赤外線センサー出力処理、送信プログラム(PIC制御)
list
p=16f873a
#include <p16f873a.inc>
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF &
_CPD_OFF
;_CP_OFF プログラム読み出しプロテクトオフ
;WDT_OFF ウオッチドック無効
;BODEN_ON ブラウンアウト有効
;PWRTE_ON パワーアップタイマ有効
;HS_OSC オシュレータ 高速クリスタル/レゾレータ
;WRT_OFF フラッシュへの書き込みOFF
;LVP_OFF LVP有効
;CPD_OFF EEPROMの読み出し許可
TEMP
EQU
0x20
;作業用Temp
SECD
EQU
0x21
;秒カウンター
TENM
EQU
0x22
;ミリ秒カウンタ(10ms)
MINI
EQU
0x23
;分カウンタ
MFLG
EQU
0x24
;ミリ秒カウントアップフラグ
HOUR
EQU
0x25
;時カウンタ
RTCLOW
EQU
0x26
;RTCC counter lower
CNT1
EQU
0x27
;タイマーカウンター1
44
CNT2
EQU
0x28
;タイマーカウンター2
CNT3
EQU
0x29
;タイマーカウンター3
CNT4
EQU
0x2a
;タイマーカウンター4
RESET_CHAR
EQU
0x2c
;タイマーカウントクリア"S"
TMP_DATA
EQU
0x31
TMP_DATA_B
EQU
0x32
TMP_CNT
EQU
0x33
CCNT
EQU
0x34
; 文字数カウンタ
LCNT
EQU
0x35
; 行番号フラグ
WR_SV
EQU
0x70
;save Wreg
STA_SV
EQU
0x71
;save status
; busyチェック用
;センサー出力処理関数
SSBFR
EQU
0x38
;前回のセンサー出力格納
SSNOW
EQU
0x39
;現在のセンサー出力格納
SSRSLT
EQU
0x3a
;SSBFR XOR SSNOW の結果を格納
N_TENM
EQU
0x3b
N_SECD
EQU
0x3c
SENSOR
EQU
0x3d
ON_OFF
EQU
0x3e
N_MINI
EQU
0x3f
;瞬時のMINI
N_HOUR
EQU
0x40
;瞬時のHOUR
EQU
0x41
;Sirial通信用
SEND_TEMP
SET_CHAR EQU
WHAT_CHAR
EQU
DEX_TEMP EQU
0x42
;現在時刻セットコード
0x43
;内部時間要求コード
0x44
;ASCII→16進
;Symbols For LCD
#define
LCD_DATA
PORTB
#define
LCD_DDIR
TRISB
#define
LCD_RS
PORTB,0
#define
LCD_RW
PORTB,1
#define
LCD_E
PORTB,2
#define
BUSY_BIT
7
45
#define
ROWS
d'16' ; 横方向は16文字
;**********************************************************************
ORG
0x000
; processor reset vector
clrf
PCLATH
; ensure page bits are cleared
goto
INIT
; go to beginning of program
ORG
0x004
; interrupt vector location
GOTO
INTRPT
;************************************************************************
;PortA &PortB初期化
;タイマー初期化
;PortA
;
RA012345入力
;PortB
;
RB4567:LCD出力
;
RB012:LCD制御
;PortC
;
RC67:Sirial通信
;************************************************************************
INIT
;-------------Portモード設定--------------bcf
INTCON,GIE
;割り込み不許可
bsf
STATUS,RP0
;page1に移動
movlw
b'11111111'
movwf
TRISA
; PORTAを入力に
clrf
LCD_DDIR
;LCDデータポートを出力に
movlw
b'10111111'
; RC7/RX(入力),RC6/TX(出力)
movwf
TRISC
; PORTC の設定
;-------------Timerモード設定-------------movlw
0x81
;プリスケーラー=4
movwf
OPTION_REG
;タイマーモードセット
;-------------Sirial通信設定-------------movlw
b'00100100'
; 8BIT,送信許可,非同期,高速
movwf
TXSTA
; TXSTA レジスタの設定
movlw
81H
; ボーレート 9600bps (20MHz:高速設定時)
46
movwf
SPBRG
; SPBRG レジスタの設定
bcf
STATUS,RP0
; Bank 0 へ戻す
movlw
b'10010000'
; シリアル,8BIT,継続受信許可
movwf
RCSTA
; RCSTA レジスタの設定
;-------------デジタルモード設定-------------BSF
STATUS,RP0
MOVLW
07H
MOVWF
ADCON1
BCF
STATUS,RP0
clrf
ADCON0
;全てディジタルモードにする
;A/D未使用にする
;---------------LCD初期化----------------call
lcd_init
; LCD初期化
;---------------Timerスタート---------------clrf
TMR0
movlw
0x30
movwf
RTCLOW
;48回
;--------------Timer例外AJUST-------------movlw
0x40
movwf
CNT4
;64回
;-------------各パラメーターリセット-------------clrf
HOUR
clrf
MINI
clrf
SECD
clrf
TENM
clrf
SSBFR
clrf
SSNOW
clrf
SSRSLT
clrf
N_TENM
clrf
N_SECD
clrf
SENSOR
clrf
PORTA
clrf
RESET_CHAR
clrf
SET_CHAR
clrf
WHAT_CHAR
clrf
ON_OFF
clrf
SENSOR
47
clrf
DEX_TEMP
;----------------------------------------bcf
LCD_RS
;
bcf
LCD_RW
; LCDの制御信号をゼロに
bcf
LCD_E
;
clrf
LCD_DATA
;
call
dly_10m
; 念のため10mS待つ
call
lcd_init
; LCD初期化
call
dly_10m
movlw
b'00001100'
call
cmd_send
call
dly_10m
clrf
CCNT
; キャラクタ数カウンタをリセット
clrf
LCNT
; 行フラグをリセット
clrf
TMP_CNT
; テンポラリカウンタをクリア
movf
TMP_CNT,w
;文字列出力
call
INIT_MSG
addlw
0x00
btfsc
STATUS,Z
goto
msg_out
call
chr_out
incf
TMP_CNT,1
goto
str_out1
;カーソルオフ、左から右へ表示
str_out1
;ゼロだったなら終了
msg_out
movlw
d'100'
movwf
TMP_CNT
;初期メッセージ1秒表示
msg_loop
call
dly_10m
decfsz
TMP_CNT,1
goto
msg_loop
;初期メッセージ表示遅延
48
call
disp_clr
goto
MAIN
;表示クリア
;********************************************************
;メイン
;********************************************************
MAIN
bsf
INTCON,T0IE
;RTCC mask enable
bsf
INTCON,GIE
;割り込み許可
movf
PORTA,0
;初回センサー状態取得
movwf
SSBFR
;SSBFRに格納
;**************メイン ループ*****************
MAINLOOP
btfsc
PIR1,RCIF
call
RV_DATA
btfss
MFLG,0
goto
MAINLOOP
CLRF
MFLG
;clear secondup flag
movfw
TENM
;10msカウンタから取得
movwf
N_TENM
;瞬時の10msカウンタの値
movfw
SECD
;秒カウンタから取得
movwf
N_SECD
;瞬時の秒カウンタ値
movfw
PORTA
;センサー状態取得
movwf
SSNOW
;SSNOWに格納
movfw
SSBFR
;wレジ格納
xorwf
SSNOW,0
;SSBFR XOR SSNOW
movwf
SSRSLT
;XOR結果を格納
movlw
b'00001111'
;下位選定
andwf
SSRSLT,1 ;選定結果はSSRSLTへ
btfsc
SSRSLT,0 ;センサーA-D判定&分岐
;Secondflag カウントアップ完了?
49
call
SSASND
btfsc
SSRSLT,1
call
SSBSND
btfsc
SSRSLT,2
call
SSCSND
btfsc
SSRSLT,3
call
SSDSND
movfw
SSNOW
;次ループのための処理
movwf
SSBFR
;SSNOW→SSBFR
goto
MAINLOOP
;***********************************************************
;センサー反応後処理
;番号、状態取得→液晶表示→データ送信
;***********************************************************
SSASND
movlw
'A'
;
movwf
SENSOR
;センサー番号A格納
btfsc
SSNOW,0
;SSNOW0ビット目は1?
goto
A_ON
;ON
bcf
ON_OFF,0
;OFF
goto
A_ON_OFF_END
bsf
ON_OFF,0
A_ON
A_ON_OFF_END
call
DISP
call
SEND_T
return
;----------------------------------SSBSND
movlw
'B'
50
movwf
SENSOR
;センサー番号B格納
btfsc
SSNOW,1
;SSNOW1ビット目は1?
goto
B_ON
;ON
bcf
ON_OFF,0
;OFF
goto
B_ON_OFF_END
bsf
ON_OFF,0
B_ON
B_ON_OFF_END
call
DISP
call
SEND_T
return
;----------------------------------SSCSND
movlw
'C'
;
movwf
SENSOR
;センサー番号C格納
btfsc
SSNOW,2
;SSNOW2ビット目は1?
goto
C_ON
;ON
bcf
ON_OFF,0 ;OFF
goto
C_ON_OFF_END
bsf
ON_OFF,0
C_ON
C_ON_OFF_END
call
DISP
call
SEND_T
return
;----------------------------------SSDSND
movlw
'D'
;
movwf
SENSOR
;センサー番号D格納
btfsc
SSNOW,3
;SSNOW3ビット目は1?
goto
D_ON
;ON
51
bcf
ON_OFF,0;OFF
goto
D_ON_OFF_END
bsf
ON_OFF,0
D_ON
D_ON_OFF_END
call
DISP
call
SEND_T
return
;*******************************************************
;Display表示関連関数
;DISP:メイン表示
;NUDISP:アスキー変換後送信
;disp_clr:表示クリア
;*******************************************************
DISP
call
disp_clr
movfw
SENSOR
;センサー番号送信
call
chr_out
;NUDISPにてアスキーコード変換&送信
movfw
ON_OFF
;ON_OFF送信
call
NUDISP
swapf
N_SECD,w
call
NUDISP
movf
N_SECD,w
call
NUDISP
movlw
':'
call
chr_out
swapf
N_TENM,w
;秒上位ビット
;秒下位ビット
;10mカウンタ上位ビット
52
call
NUDISP
movf
N_TENM,w
call
NUDISP
;10mカウンタ下位ビット
return
NUDISP
ANDLW
0x0F
ADDLW
0x30
CALL
chr_out
;to ASCII code
RETURN
;表示クリア
disp_clr
movlw
b'00000001'
call
cmd_send
clrf
CCNT
clrf
LCNT
; 表示クリア
return
; 1文字出力
; wに表示したい文字をセット
chr_out
call
data_send
incf
CCNT,f
movlw
ROWS
subwf
CCNT,w
btfss
STATUS,Z
goto
chr_done
;ROWSと同じではないので終了
clrf
CCNT
;文字数カウンタをリセット
btfss
LCNT,0
;現在は1行目か?
goto
chr_ld1
movlw
b'10000000'
call
cmd_send
bcf
LCNT,0
;出力した文字数を+1
;もしもROWSと同じになったら
line_chg
;1行目にアドレスをセット
53
goto
chr_done
chr_ld1
; 2行目にアドレスをセット
movlw
b'11000000'
call
cmd_send
bsf
LCNT,0
chr_done
return
INIT_MSG
addwf
DT
PCL,1
"START SenserSYS!",0x00
BINHEX
addwf
DT
PCL,1
"0123456789ABCDEF",0x00
; 液晶を初期化
; 4bitモード
lcd_init
call
dly_10m
call
dly_10m
movlw
b'00110000'
call
cmd_send4
call
dly_10m
movlw
b'00110000'
call
cmd_send4
call
dly_10m
movlw
b'00110000'
call
cmd_send4
call
dly_100u
movlw
b'00100000'
call
cmd_send4
call
dly_100u
call
busy_check
movlw
b'00101000'
call
;初期化データ1
;初期化データ2
;初期化データ3
;4bitモードにセット
;初期モード設定
cmd_send
54
movlw
b'00001000'
call
cmd_send
movlw
b'00000001'
call
cmd_send
movlw
b'00000110'
call
cmd_send
;ディスプレイオフ
;液晶をクリア
;エントリモードをセット
return
; 液晶にコマンドを送出
; wレジスタ=コマンド
; Fレジスタ: TMP_DATA
cmd_send
; CMD=w
movwf
TMP_DATA
andlw
0xf0
movwf
LCD_DATA
bcf
LCD_RW
bcf
LCD_RS
bsf
LCD_E
nop
nop
bcf
LCD_E
swapf
TMP_DATA,w
andlw
0xf0
movwf
LCD_DATA
bcf
LCD_RW
bcf
LCD_RS
bsf
LCD_E
nop
nop
bcf
LCD_E
call
busy_check
55
return
; 初期化用4bit幅コマンド送出
; wレジスタ=コマンド(上位4bit)
; Fレジスタ : TMP_DATA
; ビジーチェックできない期間用
cmd_send4
movwf
TMP_DATA
andlw
0xf0
movwf
LCD_DATA
bcf
LCD_RW
bcf
LCD_RS
bsf
LCD_E
nop
nop
bcf
LCD_E
return
; 液晶にデータを送出
; wレジスタ=データ
; Fレジスタ: TMP_DATA
data_send
movwf
TMP_DATA
andlw
0xf0
movwf
LCD_DATA
bcf
LCD_RW
bsf
LCD_RS
bsf
LCD_E
nop
nop
bcf
LCD_E
swapf
TMP_DATA,w
andlw
0xf0
movwf
LCD_DATA
56
bcf
LCD_RW
bsf
LCD_RS
bsf
LCD_E
nop
nop
bcf
LCD_E
call
busy_check
return
;******************************************
; 液晶ビジーチェック
; Fレジスタ:TMP_DATA_B
;******************************************
busy_check
bsf
STATUS,RP0
movlw
0xf0
movwf
LCD_DDIR
bcf
STATUS,RP0
; bank=1
; bank=0
busy_chk1
bcf
LCD_RS
bsf
LCD_RW
bsf
LCD_E
nop
movf
LCD_DATA,w
andlw
0xf0
movwf
TMP_DATA_B
bcf
LCD_E
nop
nop
bsf
LCD_E
nop
; 下位4ビットは無視
nop
bcf
LCD_E
btfsc
TMP_DATA_B,BUSY_BIT
goto
busy_chk1
bcf
LCD_RW
57
bsf
STATUS,RP0
movlw
0x00
movwf
LCD_DDIR
bcf
STATUS,RP0
; bank=1
; bank=0
return
;****************************************************
;USART受信用ルーチン
;****************************************************
RV_DATA
BTFSC
RCSTA,FERR
;フレーミングエラーチェック
GOTO
F_ERROR
;エラー時移動
BTFSC
RCSTA,OERR
;オーバーランエラーのチェック
GOTO
O_ERROR
;エラー時移動
movlw
'R'
;PCからのResetコード
movwf
RESET_CHAR
movlw
'S'
movwf
SET_CHAR
movlw
'W'
movwf
WHAT_CHAR
MOVF
RCREG,W
subwf
RESET_CHAR,f
btfsc
STATUS,Z
goto
TIME_RESET
subwf
SET_CHAR,f
btfsc
STATUS,Z
goto
TIME_SET
subwf
WHAT_CHAR,f
btfsc
STATUS,Z
goto
TIME_SET
;PCからの時間Setコード
;PCからの内部時間要求コード
;レジスタから受信データの読み込み
;タイマーリセット分岐へ
;タイマーセット分岐へ
;タイマーセット分岐へ
return
58
F_ERROR
MOVF
RCREG,W
;wレジに格納するとFERRはクリア
BCF
RCSTA,CREN
;クリアによりリセット
BSF
RCSTA,CREN
;受信許可
return
O_ERROR
return
;****************************************************
;USART送信用ルーチン
;****************************************************
SEND_T
movf
SENSOR,w
call
TX_TXT
movf
ON_OFF,w
call
EX_SEND
swapf
call
N_SECD,w
;センサー番号
;センサーON_OFF
;秒上位ビット
EX_SEND
movf
call
N_SECD,w
;秒下位ビット
EX_SEND
swapf
call
N_TENM,w
;10mカウンタ上位ビット
EX_SEND
movf
N_TENM,w
call
EX_SEND
movlw
0x0d
call
;10mカウンタ下位ビット
;アスキーCRコード
TX_TXT
SEND_DLY
movlw
d'5'
movwf
TMP_CNT
;50mです
DLY_LOOP
call
dly_10m
decfsz TMP_CNT,f
59
goto
DLY_LOOP
return
TX_TXT
movwf
SEND_TEMP
; 送信するデータを変数(SEND_TEMP)に格納
bsf
STATUS,RP0
; Bank 1 へ切替
LPTX
;
btfss
TXSTA,TRMT
;送信可能であるかチェック(1:可能, 0:禁止)
goto
LPTX
; 禁止であれば LPTX のラベル間を繰り返す
;
bcf
STATUS,RP0
; Bank 0 へ戻す
movf
SEND_TEMP,W
;格納していた送信データをWregにロード
movwf
TXREG
; 送信データはTXREGレジスタを通してシリアル出力
return
; メインルーチンへ戻る
EX_SEND
ANDLW
0x0F
ADDLW
0x30
CALL
TX_TXT
;to ASCII code
RETURN
;****************************************************
;時間遅延ルーチン クロック20MHz用
;****************************************************
; 100マイクロ秒遅延
; Fレジスタ: CNT1
dly_100u
; 100uS
movlw
d'100'
movwf
CNT1
dly_100u1
nop
nop
;1uS@1path
nop
nop
decfsz CNT1,f
goto
dly_100u1
return
60
; 10ミリ秒遅延
; Fレジスタ:CNT1
dly_10m
; 10mS
movlw
d'10'
movwf
CNT1
dly_10m1
call
dly_1m
decfsz CNT1,f
goto
dly_10m1
return
; 1ミリ秒遅延
; Fレジスタ:CNT2,3
dly_1m
; 1ms
movlw
d'4'
movwf
CNT2
dly_1m1
movlw
d'250'
movwf
CNT3
dly_1m2
; 250us Loop
nop
nop
nop
nop
decfsz CNT3,f
goto
dly_1m2
decfsz CNT2,f
goto
dly_1m1
return
;****************************************
;タイマーリセット分岐処理
;****************************************
TIME_RESET
btfss
MFLG,0
goto
TIME_RESET
;10Msflag カウントアップ完了?
61
clrf
TENM
clrf
SECD
call
disp_clr
movlw
'R'
call
chr_out
call
TX_TXT
movlw
'e'
call
chr_out
movlw
's'
call
chr_out
movlw
'e'
call
chr_out
movlw
't'
call
chr_out
movlw
'!'
call
chr_out
movlw
;PC側に返信'R'
d'100'
movwf
TMP_CNT
;初期メッセージ1秒表示
msg_loop2
call
dly_10m
decfsz TMP_CNT,1
goto
msg_loop2
call
disp_clr
goto
;表示遅延
;表示クリア
MAIN
return
;**********************************************
;タイマーセット分岐
;**********************************************
TIME_SET
bcf
INTCON,T0IE
bcf
INTCON,GIE
clrf
HOUR
clrf
MINI
clrf
SECD
clrf
TENM
;割り込み不許可
62
D_1
btfss
PIR1,RCIF
goto
D_1
MOVF
RCREG,w
btfss
PIR1,RCIF
goto
D_2
MOVF
RCREG,w
btfss
PIR1,RCIF
goto
H_SET_H
MOVF
RCREG,w
movwf
DEX_TEMP
movlw
0x30
subwf
DEX_TEMP,w
movwf
HOUR
swapf
HOUR,f
btfss
PIR1,RCIF
goto
H_SET_L
movf
RCREG,w
movwf
DEX_TEMP
movlw
0x30
subwf
DEX_TEMP,w
addwf
HOUR,f
btfss
PIR1,RCIF
goto
M_SET_H
movf
RCREG,w
movwf
DEX_TEMP
movlw
0x30
subwf
DEX_TEMP,w
movwf
MINI
swapf
MINI,f
;USART受信割り込みFLGチェック
D_2
;USART受信割り込みFLGチェック
H_SET_H
;USART受信割り込みFLGチェック
H_SET_L
M_SET_H
;USART受信割り込みFLGチェック
63
M_SET_L
btfss
PIR1,RCIF
goto
M_SET_L
movf
RCREG,w
movwf
DEX_TEMP
movlw
0x30
subwf
DEX_TEMP,w
addwf
MINI,f
btfss
PIR1,RCIF
goto
S_SET_H
movf
RCREG,w
movwf
DEX_TEMP
movlw
0x30
subwf
DEX_TEMP,w
movwf
SECD
swapf
SECD,f
btfss
PIR1,RCIF
goto
S_SET_L
movf
RCREG,w
movwf
DEX_TEMP
movlw
0x30
subwf
DEX_TEMP,w
addwf
SECD,f
clrf
TENM
bsf
INTCON,T0IE
bsf
INTCON,GIE
call
disp_clr
swapf
HOUR,w
call
NUDISP
S_SET_H
;USART受信割り込みFLGチェック
S_SET_L
;割り込み許可
64
movf
HOUR,w
call
NUDISP
movlw
':'
call
chr_out
swapf
MINI,w
call
NUDISP
movf
MINI,w
call
NUDISP
movlw
':'
call
chr_out
swapf
SECD,w
call
NUDISP
movf
SECD,w
call
NUDISP
movlw
d'100'
movwf
TMP_CNT
;秒上位ビット
;秒下位ビット
;秒上位ビット
;秒下位ビット
msg_loop3
call
dly_10m
decfsz TMP_CNT,1
goto
msg_loop3
call
disp_clr
;表示遅延
;表示クリア
return
;**********************************************
;内部時間送信分岐
;**********************************************
Send_time
btfss
MFLG,0
goto
Send_time
;10Msflag カウントアップ完了?
65
call
movfw
TENM
movwf
N_TENM
movfw
SECD
movwf
N_SECD
movfw
MINI
movwf
N_MINI
movfw
HOUR
movwf
N_HOUR
swapf
N_HOUR,w ;時カウンタ上位ビット
EX_SEND
movf
call
EX_SEND
swapf
call
N_SECD,w ;秒上位ビット
EX_SEND
movf
call
N_MINI,w ;分カウンタ下位ビット
EX_SEND
swapf
call
N_MINI,w ;分カウンタ上位ビット
EX_SEND
movf
call
N_HOUR,w ;時カウンタ下位ビット
N_SECD,w ;秒下位ビット
EX_SEND
return
;***********************************************
;タイマー割り込み処理
;***********************************************
INTRPT
;**** save レジスタ *******
movwf
WR_SV
;save wreg
swapf
STATUS,W ;save status
movwf
STA_SV
;**** last pulse check ****
66
bcf
INTCON,T0IF
;int flag reset
decfsz
RTCLOW,F ;RTC lower counter-1
goto
POPRTN
;**** count up 10 Mirisecond ***
bsf
MFLG,0
;second flag on
call
TIMEUP
;Timerをカウントアップ
decfsz
CNT4,f
goto
ADDCNT
movlw
0x40
;64? 66?
movwf
CNT4
;
movlw
0x65
;48+53=101
movwf
RTCLOW
;AJUSTカウントセット
goto
POPRTN
movlw
0x30
movwf
RTCLOW
ADDCNT
;last count is adjustable
;******** レジスタを戻す ****
POPRTN
swapf
STA_SV,W ;get status
MOVWF
STATUS
SWAPF
WR_SV,F
SWAPF
WR_SV,W
;get wreg
RETFIE
;***********************************************************
;時間カウント+
;
;***********************************************************
TIMEUP
;***** カウントアップ 10m秒******
TENM_UP
INCF
TENM,F
;TENM+1
MOVLW
0x0f
andwf
TENM,w
;下位ビット取得
sublw
0x09
;9-TENM
67
btfsc
STATUS,C ;0A?
return
;9以下ですリターン
movlw
0x06
;+6
addwf
TENM,f
;0A+6=10
;*******1000ms チェック******
movlw
0x9a
subwf
TENM,w
btfss
STATUS,C
return
clrf
;1000ms?
;1000mに達しない リターン
TENM
;リセット00ms
;******カウントアップ 秒 *********
S_UP
INCF
SECD,F
;SECD+1
MOVLW
0x0f
;
ANDWF
SECD,W
;get lower
SUBLW
0x09
;over 9
BTFSC
STATUS,C ;0A?
RETURN
;not over 9 exit
MOVLW
0x06
ADDWF
SECD,F
;0A to 10
;**** 60sチェック ******
S_check
MOVLW
060H
SUBWF
SECD,W
BTFSS
STATUS,C
RETURN
CLRF
;60sec?
;not 60 exit
SECD
;reset to 0 second
;****** カウントアップ 分 *****
M_UP
INCF
MINI,F
;MINT+1
MOVLW
0FH
ANDWF
MINI,W
;get lower
SUBLW
09H
;over 9
68
BTFSC
STATUS,C ;0A?
RETURN
;not over 9 exit
MOVLW
06H
ADDWF
MINI,F
;0A to 10
;**** 60分チェック ******
H_check
MOVLW
060H
SUBWF
MINI,W
BTFSS
STATUS,C
;60min?
RETURN
CLRF
MINI
;reset to 0 minute
;**** カウントアップ 時 *****
H_UP
INCF
HOUR,F
MOVLW
0FH
ANDWF
HOUR,W
SUBLW
09H
BTFSC
STATUS,C
;HOUR+1
return
GOTO
D_check
MOVLW
06H
ADDWF
HOUR,F
;24h check
;**** 24時間 チェック *****
D_check
MOVLW
024H
SUBWF
HOUR,W
BTFSS
STATUS,C
;24H check
RETURN
CLRF
HOUR
;reset to 0 hour
RETURN
END
付録4
ノード出力受信処理プログラム(Main&モジュール)
Main
69
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
'共有変数宣言
Dim mySocket As Socket
'ソケット情報記憶変数
Dim myStream As NetworkStream
'ストリーム
Dim myReader As StreamReader
'ストリームからのデータ読みだし変数
Dim myWriter As StreamWriter
'ストリームへのデータ書き込み変数
Dim myThread As Thread
'スレッド変数
Dim mySocket2 As Socket
'ソケット情報記憶変数2
Dim myStream2 As NetworkStream
'ストリーム2
Dim myReader2 As StreamReader
'ストリームからのデータ読みだし変数2
Dim myWriter2 As StreamWriter
'ストリームへのデータ書き込み変数2
Dim myThread2 As Thread
'スレッド変数2
Dim myRecvData As String = "0"
'受信データ格納
Dim myRecvData2 As String
'受信データ格納2
Dim ON_OFF As String
'センサーON/OFF格納
Dim SSZero As String
'センサー出力格納配列
Dim RecvLen As Integer
'受け取った出力の文字長格納変数
Dim OpenF As Boolean = False
'FileOpen確認フラグ
Dim SensorArea(7, 1) As Integer
'センサー座標格納配列
'比較サブルーチン用宣言
Dim TheBigin As Boolean = False
'初期フラグ
Dim Sensor1 As String
'前センサー出力格納
Dim Sensor2 As String
'現在センサー出力格納
Dim Time1_Str As String
'前の検知時間(文字列)
Dim Time2_Str As String
'現在の検知時間(文字列)
Dim Time1 As Integer
'前の検知時間(ms)
Dim Time2 As Integer
'現在の検知時間(ms)
Dim TimeS As Integer
'センサー間移動時間1
70
'センサー間移動
Dim TENM_H As String
'10ミリ上位
Dim TENM_L As String
'10ミリ下位
Dim W_X As Integer = 0
'X1の幅
Dim W_Y As Integer = 0
'Y1の幅
Dim Speed As Single
'移動速度
Dim DelyTime As Integer
'受け取りデータ破棄時間
Dim StopTime As Integer = 0
'範囲アウト時間
Dim Init As Boolean = False
'初期化完了フラグ
Dim mySendData As String
'送信データ格納変数
Dim Hour As String
'時間格納変数
Dim Mini As String
'分格納変数
Dim Secd As String
'秒格納変数
Dim i As Integer
'ループ用のi
Dim Hour_H As String
'時間桁HHigh
Dim Hour_L As String
'時間桁Low
Dim Mini_H As String
'分桁High
Dim Mini_L As String
'分桁Low
Dim Secd_H As String
'秒桁High
Dim Secd_L As String
'秒桁Low
Dim H_Len As Integer
'時の文字桁数
Dim M_Len As Integer
'分の文字桁数
Dim S_Len As Integer
'秒の文字桁数
'[接続]ボタンを押したときの処理
Public Sub ConectButton_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ConectButton.Click
'変数の宣言
Dim myHostEntry As IPHostEntry 'IPホスト格納変数
Dim myAddress As IPAddress
'IPアドレス格納変数
71
Dim myPort As Integer
'接続に使用するポート番号を格納
Dim myEndPoint As EndPoint
'ネットワーク アドレスを識別
'変数宣言2
Dim myHostEntry2 As IPHostEntry 'IPホスト格納変数2
Dim myAddress2 As IPAddress
'IPアドレス格納変数2
Dim myPort2 As Integer
'接続に使用するポート番号を格納2
Dim myEndPoint2 As EndPoint
''ネットワーク アドレスを識別2
Try
'[接続]ボタンを無効化(2度押し防止)
ConectButton.Enabled = False
'ソケットを作成する
mySocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp)
MyPrint("ソケットを作成しました1")
mySocket2 = New Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp)
MyPrint("ソケットを作成しました2")
'指定したホストのポートに接続する
myHostEntry = Dns.Resolve(hostBox.Text)
myHostEntry2 = Dns.Resolve(hostBox2.Text)
myAddress = myHostEntry.AddressList(0)
myAddress2 = myHostEntry2.AddressList(0)
myPort = 14002
'Host1
myPort2 = 14001
'Host2
myEndPoint = New IPEndPoint(myAddress, myPort)
myEndPoint2 = New IPEndPoint(myAddress2, myPort2)
mySocket.Connect(myEndPoint)
mySocket2.Connect(myEndPoint2)
MyPrint("Host1に接続完了")
MyPrint("Host2に接続完了2")
'ソケットを読み書きする準備
72
myStream = New NetworkStream(mySocket)
myStream2 = New NetworkStream(mySocket2)
myReader = New StreamReader(myStream, Encoding.UTF8)
myReader2 = New StreamReader(myStream2, Encoding.UTF8)
myWriter = New StreamWriter(myStream, Encoding.UTF8)
myWriter2 = New StreamWriter(myStream2, Encoding.UTF8)
myWriter.NewLine = vbNewLine
'Chr(13) + Chr(10)のこと
myWriter2.NewLine = vbNewLine
myWriter.AutoFlush = True
myWriter2.AutoFlush = True
'読み出し処理を別スレッドで開始する
myThread = New Thread(AddressOf RecvLoop)
myThread2 = New Thread(AddressOf RecvLoop2)
myThread.IsBackground = True
myThread2.IsBackground = True
myThread.Start()
MyPrint("受信スレッド1を起動しました")
myThread2.Start()
MyPrint("受信スレッド2を起動しました")
'[切断]/[送信]ボタンを有効化
closeButton.Enabled = True
sendButton.Enabled = True
Catch ex As Exception
'エラー処理
MyPrint("* " & ex.Message)
MyEndSession()
End Try
End Sub
73
'受信スレッド
Sub RecvLoop()
Try
Do
'データを受信する
SyncLock myRecvData
myRecvData = myReader.ReadLine()
'センサー保存⇒比較分岐へ
SensorIn(myRecvData)
End SyncLock
'受信したデータを表示する
'MyPrint("受信Host1 >> " & myRecvData)
If IsNothing(myRecvData) Then
MyPrint("サーバーがシャットダウンを伝えてきました")
myRecvData = "0"
Exit Do
End If
Loop
'終了処理
MyPrint("受信スレッド2を終了しました")
MyEndSession()
Catch ex As Exception
'エラー処理
Select Case MyGetSocketErrorCode(ex)
Case 10004 'WSAEINTR
'ReadLine()の受信待ち中に自分でソケットを閉じた
74
MyPrint("受信スレッドを終了しました<Host1>")
MyEndSession()
Case 10053 'WSAECONNABORTED
'自分でソケットを閉じた後にReadLine()が開始された
MyPrint("受信スレッドを終了しました<Host1>")
MyEndSession()
Case 10054 'WSAECONNRESET
'サーバーが落ちた
MyPrint("* ホストが落ちました<Host1>")
MyPrint("受信スレッドを中断しました<Host1>")
MyEndSession()
Case Else
'上記以外は予想外のエラーである
MyPrint("* " & ex.Message & "<Host1>")
MyPrint("受信スレッドを中断しました<Host1>")
MyEndSession()
End Select
End Try
End Sub
'受信スレッド2
Sub RecvLoop2()
Try
Do
'データを受信する
myRecvData = myReader2.ReadLine()
'受信したデータを表示する()
'MyPrint("受信Host2>> " & myRecvData)
'センサー保存⇒比較分岐へ
75
SensorIn(myRecvData)
If IsNothing(myRecvData) Then
MyPrint("サーバーがシャットダウンを伝えてきました")
myRecvData = "0"
Exit Do
End If
Loop
'終了処理
MyPrint("受信スレッド2を終了しました")
MyEndSession()
Catch ex As Exception
'エラー処理
Select Case MyGetSocketErrorCode(ex)
Case 10004 'WSAEINTR
'ReadLine()の受信待ち中に自分でソケットを閉じた
MyPrint("受信スレッドを終了しました<Host2>")
MyEndSession()
Case 10053 'WSAECONNABORTED
'自分でソケットを閉じた後にReadLine()が開始された
MyPrint("受信スレッドを終了しました<Host2>")
MyEndSession()
Case 10054 'WSAECONNRESET
'サーバーが落ちた
MyPrint("* ホストが落ちました<Host2>")
MyPrint("受信スレッドを中断しました<Host2>")
MyEndSession()
Case Else
76
'上記以外は予想外のエラーである
MyPrint("* " & ex.Message & "<Host2>")
MyPrint("受信スレッドを中断しました<Host2>")
MyEndSession()
End Select
End Try
End Sub
'[送信]ボタンを押したときの処理
Sub sendButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles
sendButton.Click
Try
'Emuにデータを送信する(Emu使用時ON)
'mySendData = ComboBox1.Text
'myWriter2.WriteLine(mySendData)
'Resetコード送信(両Host)
If inputBox.Text = "PICカウンターReset<R>" Then
mySendData = "R"
myWriter.WriteLine(mySendData)
myWriter2.WriteLine(mySendData)
MyPrint("送信<<PICカウンターResetCode")
'MsgBox("PICカウンターResetCode送信", , "操作")
'Setコード送信&現在時刻送信(両ホスト)
ElseIf inputBox.Text = "PIC内部時間設定<S>" Then
mySendData = "S"
myWriter.WriteLine(mySendData)
myWriter2.WriteLine(mySendData)
Hour = Date.Now.Hour.ToString
Mini = Date.Now.Minute.ToString
Secd = Date.Now.Second.ToString
H_Len = Hour.Length
77
M_Len = Mini.Length
S_Len = Secd.Length
'送信用桁合せ(規定の桁に届かない場合桁あわせ)
If H_Len = 1 Then
Hour = ("0" + Hour)
End If
If M_Len = 1 Then
Mini = ("0" + Mini)
End If
If S_Len = 1 Then
Secd = ("0" + Secd)
End If
'時、分、秒の上位、下位をキャラクタごとに読み出し
Hour_H = Hour.Chars(0)
Hour_L = Hour.Chars(1)
Mini_H = Mini.Chars(0)
Mini_L = Mini.Chars(1)
Secd_H = Secd.Chars(0)
Secd_L = Secd.Chars(1)
'読み出したキャラクタをそれぞれ送信
myWriter.Write(Hour_H + Hour_L + Mini_H + Mini_L + Secd_H + Secd_L)
MyPrint("送信<<PIC内部時間設定Code Host1")
myWriter2.Write(Hour_H + Hour_L + Mini_H + Mini_L + Secd_H + Secd_L)
MyPrint("送信<<PIC内部時間設定CodeHost2")
MsgBox("PIC内部時間設定Code送信" & (Chr(13)) & (Chr(13)) & "現在時刻" &
Hour_H + Hour_L & "時" & Mini_H + Mini_L & "分" & Secd_H + Secd_L & "秒", , "操作")
End If
Catch ex As Exception
'エラー処理
MyPrint("* " & ex.Message)
78
MyEndSession()
End Try
End Sub
'[切断]ボタンを押したときの処理
Sub closeButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles
closeButton.Click
Try
FileClose() ' エクセルファイルクローズ.
'[切断]ボタンと[送信]ボタンを無効化(2度押し防止)
closeButton.Enabled = False
sendButton.Enabled = False
'送信の終了をサーバーに伝える
mySocket.Shutdown(SocketShutdown.Send)
mySocket2.Shutdown(SocketShutdown.Send)
MyPrint("サーバーへの送信をシャットダウンしました")
'交信スレッドの終了を2秒(=2000ミリ秒)待つ
If myThread.Join(2000) Then
'スレッドが正常終了した場合、なにもする必要がない
Else
'スレッドが終了しない場合、ソケットを閉じて強制終了させる
MyPrint("サーバーが応答しないので勝手に終了します")
mySocket.Close()
End If
Catch ex As Exception
'エラー処理
MyPrint("* " & ex.Message & "切断ボタン")
MyEndSession()
79
End Try
End Sub
'例外発生の原因になったソケットエラーのエラー番号を調べるメソッド
Function MyGetSocketErrorCode(ByVal ex As Exception) As Integer
If IsNothing(ex) Then
Return -1
ElseIf TypeOf ex Is SocketException Then
Return CType(ex, SocketException).ErrorCode
Else
Return MyGetSocketErrorCode(ex.InnerException)
End If
End Function
Sub SensorIn(ByVal myRecvData As String)
'初期化処理
If OpenF = False Then
'
'時刻設定コードを送信
mySendData = "S"
myWriter.WriteLine(mySendData)
myWriter2.WriteLine(mySendData)
'現在時刻を取得 時、分、秒格納変数へ
Hour = Date.Now.Hour.ToString
Mini = Date.Now.Minute.ToString
Secd = Date.Now.Second.ToString
'MyPrint(Date.Now.Second.ToString)
'時、分、秒の各キャラクター数を取得
H_Len = Hour.Length
M_Len = Mini.Length
80
'デバック
S_Len = Secd.Length
'送信用桁合せ(規定に届かない桁数の場合桁を調整)
If H_Len = 1 Then
Hour = ("0" + Hour)
End If
If M_Len = 1 Then
Mini = ("0" + Mini)
End If
If S_Len = 1 Then
Secd = ("0" + Secd)
End If
Hour_H = Hour.Chars(0)
Hour_L = Hour.Chars(1)
Mini_H = Mini.Chars(0)
Mini_L = Mini.Chars(1)
Secd_H = Secd.Chars(0)
Secd_L = Secd.Chars(1)
myWriter.Write(Hour_H + Hour_L + Mini_H + Mini_L + Secd_H + Secd_L)
myWriter2.Write(Hour_H + Hour_L + Mini_H + Mini_L + Secd_H + Secd_L)
'PIC内時間カウンタリセットコード送信
myWriter2.Write("R")
myWriter.Write("R")
MyPrint("PIC内部時間設定Code送信")
'MyPrint(Date.Now.Second.ToString) 'デバック
OpenF = True
Init = True
'初期化完了フラグ
DelyTime = Date.Now.Second
'現在時刻取得
81
True
End If
'最初5秒はデータを廃棄
While Date.Now.Second < DelyTime + 5 And Init = True
Return
End While
Init = False
'測定用デバック
'MyPrint(myRecvData.Chars(0))
If myRecvData.Chars(0) = "A" Or myRecvData.Chars(0) = "B" Or myRecvData.Chars(0)
= "C" Or myRecvData.Chars(0) = "E" Then
Return
End If
'SSZeroへ受け取ったデータを格納
SSZero = myRecvData
'文字長を取得
RecvLen = Len(SSZero)
'文字長=6文字 & センサー出力ONのみのデータを判別して外部ファイルに出力
If RecvLen = 6 And SSZero Like "?1????" Then
FileOpenS()
Thread.Sleep(10)
PrintLine(2, SSZero)
FileClose()
Thread.Sleep(10)
MyPrint(SSZero)
OutputComp()
'センサー出力比較処理へジャンプ
End If
82
End Sub
'センサー出力比較処理
Sub OutputComp()
'最初のセンサーの出力を格納する
If TheBigin = False Then
'Sensor座標の再指定(外部Module)
IntoSensorArea()
Sensor1 = SSZero
BeforS = Sensor1.Chars(0)
'センサー番号格納
Time1_Str = (Sensor1.Remove(0, 2)) '時間データを文字列で取得
Secd_H = Time1_Str.Chars(0)
Secd_L = Time1_Str.Chars(1)
TENM_H = Time1_Str.Chars(2)
TENM_L = Time1_Str.Chars(3)
Time1 = CInt(Secd_H) * 10000 + CInt(Secd_L) * 1000 + CInt(TENM_H) * 100 +
CInt(TENM_L) * 10
'被験者進入経路に合わせた初期座標の変更
Select Case BeforS
Case "A"
AjustAreaX = -38
AjustAreaY = 0
Case "E"
AjustAreaX = 38
AjustAreaY = 0
Case "H"
AjustAreaX = 0
AjustAreaY = -54
End Select
83
TheBigin = True
'初期のセンサー完了フラグ ON
Return
End If
Sensor2 = SSZero
NowS = Sensor2.Chars(0) 'センサー番号格納
Time2_Str = (Sensor2.Remove(0, 2)) '時間データを文字列で取得
Secd_H = Time2_Str.Chars(0)
Secd_L = Time2_Str.Chars(1)
TENM_H = Time2_Str.Chars(2)
TENM_L = Time2_Str.Chars(3)
Time2 = CInt(Secd_H) * 10000 + CInt(Secd_L) * 1000 + CInt(TENM_H) * 100 +
CInt(TENM_L) * 10
TimeS = Time2 - Time1
'時間計算式補正
If TimeS < 0 Then
TimeS = (Time2 + 60000) - Time1 '60000ms追加して計算しなおし
End If
If TimeS > 3000 Then
'無反応3秒経過(初期化)
'空白代入
FileOpenS()
Thread.Sleep(10)
PrintLine(2, "")
FileClose()
Thread.Sleep(10)
Time1 = Time2
BeforS = NowS
MyPrint("初期化処理(現在の検知位置が初期化されました。)")
84
Return
End If
'前のセンサー状態Xor現在センサー状態の不一致ならば比較する
If BeforS <> NowS Then
TimeS = Time2 - Time1
'時間計算式補正
If TimeS < 0 Then
TimeS = (Time2 + 60000) - Time1 '60000ms追加して計算しなおし
End If
'移動開始位置代入(外部Mocule)
IntoSensorAjust()
'X幅、Y幅
W_X = x2 - x1
W_Y = y2 - y1
'スピード算出
Speed = CSng((((((W_X) ^ 2 + (W_Y) ^ 2) ^ 0.5) / TimeS) * 1000) / 54) '秒
速/m
'速度規制(規定速度外の移動はイレギュラーとしてスルー)
If 0.45 < Speed And Speed < 1.55 Then
MyPrint(BeforS & "⇒" & NowS)
MyPrint(CStr(Speed) & "m/sにて移動")
FileOpenS()
Thread.Sleep(10)
PrintLine(3, BeforS & "⇒" & NowS)
85
PrintLine(3, Time1)
PrintLine(3, Speed)
PrintLine(3, " ")
FileClose()
Thread.Sleep(10)
BeforS = NowS
Time1 = Time2
End If
End If
End Sub
'各メソッド共通の終了処理
Sub MyEndSession()
If Not IsNothing(mySocket) Then
mySocket.Close()
MyPrint("ソケットを閉じました")
End If
MyPrint("")
closeButton.Enabled = False
sendButton.Enabled = False
ConectButton.Enabled = True
End Sub
'ログウィンドウに1行表示
Sub MyPrint(ByVal str As String)
SyncLock logBox
logBox.Items.Add(str)
logBox.TopIndex = logBox.Items.Count - 1
logBox.Refresh()
End SyncLock
86
End Sub
'フォームロード時実行
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles
MyBase.Load
'PICの制御Code選択肢追加
inputBox.Items.Add("PICカウンターReset<R>")
inputBox.Items.Add("PIC内部時間設定<S>")
'センサーの座標設定(外部Modlue)
IntoSensorArea()
'コンボボックスへの選択肢追加(Emulatorへのパケットパターン要求)
ComboBox1.Items.Add("パターン1(A~E)")
ComboBox1.Items.Add("パターン2(E~A)")
ComboBox1.Items.Add("パターン3(A~D~H)")
ComboBox1.Items.Add("パターン4(H~D~A)")
ComboBox1.Items.Add("パターン5(E~D~H)")
ComboBox1.Items.Add("パターン6(H~D~E)")
'ホストBoxへの選択肢追加(Host1 Host2 同PC内での動作確認)
hostBox.Items.Add("192.168.11.9")
hostBox.Items.Add("localhost")
hostBox.Items.Add("192.168.11.102")
hostBox2.Items.Add("192.168.11.9")
hostBox2.Items.Add("localhost")
hostBox2.Items.Add("192.168.11.101")
End Sub
'Ver情報ボタン
Private Sub MenuItem6_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem6.Click
87
MsgBox("センサー出力測定プログラム Ver1.0", MsgBoxStyle.Information, "Version
情報")
End Sub
'終了ボタン
Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MenuItem2.Click
Close()
End Sub
End Class
モジュール
Module Module1
Public SensorArea(7, 1) As Integer 'センサー座標格納配列
Public GotoGO(8, 5) As String
'行き先テーブル
Public AjustAreaX As Integer = 0
'侵入位置補正X座標
Public AjustAreaY As Integer = 0
'侵入位置補正Y座標
Public x1 As Integer
'x座標1
Public y1 As Integer
'y座標1
Public x2 As Integer
'x座標2
Public y2 As Integer
'y座標2
Public BeforS As String
'前センサー番号格納
Public NowS As String
'現在センサー番号格納
Public GotoFlag As Boolean = False '通行許可フラグ
'ファイルオープン
Sub FileOpenS()
FileOpen(1, "Sensor.csv", OpenMode.Append, OpenAccess.Default,
OpenShare.Shared) ' Open file for output.
FileOpen(2, "Sensor-Z.csv", OpenMode.Append, OpenAccess.Default,
OpenShare.Shared) ' Open file for output.
FileOpen(3, "Speed.txt", OpenMode.Append, OpenAccess.Default, OpenShare.Shared)
End Sub
88
'Sensor座標設定
Sub IntoSensorArea()
'AのSensorArea
SensorArea(0, 0) = 164
SensorArea(0, 1) = 111
'BのSensorArea
SensorArea(1, 0) = 240
SensorArea(1, 1) = 111
'CのSensorArea
SensorArea(2, 0) = 316
SensorArea(2, 1) = 111
'DのSensorArea
SensorArea(3, 0) = 392
SensorArea(3, 1) = 111
'EのSensorArea
SensorArea(4, 0) = 468
SensorArea(4, 1) = 111
'FのSensorArea
SensorArea(5, 0) = 392
SensorArea(5, 1) = 219
'GのSensorArea
SensorArea(6, 0) = 392
SensorArea(6, 1) = 327
'HのSensorArea
SensorArea(7, 0) = 392
SensorArea(7, 1) = 435
End Sub
'開始座標修正
Sub IntoSensorAjust()
Select Case BeforS
Case "A"
x1 = SensorArea(0, 0) + AjustAreaX
89
y1 = SensorArea(0, 1) + AjustAreaY
Case "B"
x1 = SensorArea(1, 0) + AjustAreaX
y1 = SensorArea(1, 1) + AjustAreaY
Case "C"
x1 = SensorArea(2, 0) + AjustAreaX
y1 = SensorArea(2, 1) + AjustAreaY
Case "D"
x1 = SensorArea(3, 0) + AjustAreaX
y1 = SensorArea(3, 1) + AjustAreaY
Case "E"
x1 = SensorArea(4, 0) + AjustAreaX
y1 = SensorArea(4, 1) + AjustAreaY
Case "F"
x1 = SensorArea(5, 0) + AjustAreaX
y1 = SensorArea(5, 1) + AjustAreaY
Case "G"
x1 = SensorArea(6, 0) + AjustAreaX
y1 = SensorArea(6, 1) + AjustAreaY
Case "H"
x1 = SensorArea(7, 0) + AjustAreaX
y1 = SensorArea(7, 1) + AjustAreaY
End Select
Select Case NowS
Case "A"
x2 = SensorArea(0, 0) + AjustAreaX
y2 = SensorArea(0, 1) + AjustAreaY
Case "B"
x2 = SensorArea(1, 0) + AjustAreaX
y2 = SensorArea(1, 1) + AjustAreaY
Case "C"
x2 = SensorArea(2, 0) + AjustAreaX
y2 = SensorArea(2, 1) + AjustAreaY
Case "D"
x2 = SensorArea(3, 0) + AjustAreaX
90
y2 = SensorArea(3, 1) + AjustAreaY
Case "E"
x2 = SensorArea(4, 0) + AjustAreaX
y2 = SensorArea(4, 1) + AjustAreaY
Case "F"
x2 = SensorArea(5, 0) + AjustAreaX
y2 = SensorArea(5, 1) + AjustAreaY
Case "G"
x2 = SensorArea(6, 0) + AjustAreaX
y2 = SensorArea(6, 1) + AjustAreaY
Case "H"
x2 = SensorArea(7, 0) + AjustAreaX
y2 = SensorArea(7, 1) + AjustAreaY
End Select
End Sub
End Module
91
Fly UP