...

在室確認システムの設計と製作

by user

on
Category: Documents
4

views

Report

Comments

Transcript

在室確認システムの設計と製作
特 別 研 究 報 告
題
目
在室確認システムの設計と製作
報 告 者
1105309
多 木
勝 彦
指
導
教
員
岩
下
克
教授
平成
20年
2月
18日
高知工科大学 大学院 工学研究科基盤工学専攻
電子・光システムコース
目次
第1章
序論.................................................................................................................. 3
1-1
研究背景 .............................................................................................................. 3
1-2
研究の目的........................................................................................................... 3
第2章
研究概要........................................................................................................... 5
2-1
センサネットワーク概要...................................................................................... 5
2-2
在室確認システム ................................................................................................ 5
2-3
全体の構成........................................................................................................... 7
2-4
使用する機材の主な説明...................................................................................... 7
(1) PIC .................................................................................................................... 7
(2) AVR ................................................................................................................... 8
(3) 赤外線センサ..................................................................................................... 8
(4) フレネルレンズ ................................................................................................. 9
(5) 距離センサ .......................................................................................................10
(6) ステッピングモータ .........................................................................................12
(7) サーボモータ....................................................................................................13
(8) XBee .................................................................................................................13
2-5
センサノード部...................................................................................................15
2.5.1 ハードウェア設計 ............................................................................................15
(1) PWM ................................................................................................................15
(2) ADC..................................................................................................................16
(3) 各種割り込み....................................................................................................16
(4) 通信デバイス切り替え .....................................................................................16
2.5.2 センサーノードフローチャート .......................................................................17
2.5.3 パケット構造....................................................................................................22
2-6
在室確認ソフト部 ...............................................................................................23
2.6.1 在室確認システムフローチャート ....................................................................24
2-7
在室状況のWeb公開............................................................................................30
2.7.1 Web公開システムのフローチャート .................................................................31
2-8
センサ設置のための出力測定 .............................................................................32
2.8.1 モーションセンサ ............................................................................................32
2.8.2 距離センサ .......................................................................................................33
第3章
3-1
測定結果..........................................................................................................37
センサノード作成 ...............................................................................................37
3.1.1 センサノード構成 ............................................................................................37
1
3-2
距離センサの相互干渉 ........................................................................................41
3-3
電圧読み込み精度向上検証 .................................................................................42
3-4
人の検出アルゴリズム ........................................................................................43
3-5
作成したシステムの外観.....................................................................................48
3-6
実用化実験..........................................................................................................50
3-7
判断不可能な事例 ...............................................................................................52
3.7.1 熱源の移動 .......................................................................................................52
3.7.2 検知箇所の狭窄化によるデメリット ................................................................53
第4章
考察.................................................................................................................54
第5章
まとめ .............................................................................................................55
謝辞 ..................................................................................................................................56
参考文献 ...........................................................................................................................57
管理ソフトウェア
プログラムリスト ..........................................................................85
管理ソフトウェア
プログラムリスト(モジュール) ....................................................109
2
第1章
序論
1-1 研究背景
私達を取り巻く生活環境は、パソコンや携帯電話などの情報端末の一般への普及、インタ
ーネット回線のブロードバンド化及び価格の定額化などに伴って、より一般的に、より高
速大容量へと大きく変わって来た。近年それらを活用した情報家電と呼ばれるネットワー
クに接続された家電の開発が行われてきている。
ユビキタスネットワーク[1] とは、総務省によると「『いつでも、どこでも、何でも、誰で
もアクセスが可能』なネットワーク環境」と定義されている。ユビキタスネットワーク化
は既存のパソコンだけではなくテレビ、洗濯機や冷蔵庫など一般的な家電製品をネットワ
ークで結び、互いに通信を行い今までになかった機能や利便性の向上を図ることを目的と
している。
ユビキタスネットワークを一般家庭等に構築する上で、センサネットワークの開発は必要
不可欠となってくる。センサネットワークとは元来、単体では限られた機能しか持たなか
ったセンサを、ネットワークに繋げ機能向上を図るシステムである。ユビキタスネットワ
ークの「目」とも言えるセンサでネットワークを構築し、パソコンや情報家電がデータを
やり取りすることで詳細な人体の位置情報や、様々な環境情報を得て、より良いサービス
を提供することが可能となる。
人 体 の 位 置 情 報 検 知 に は GPS(Global Positioning System) や RFID(Radio Frequency
IDentification) 、防犯カメラの使用が考えられる。しかし検知精度や個体識別の有無など、
実装する用途や現場によって求められる性能が異なっている。例えば、個体識別が必要な
場合にはRFIDなどが使用される。実用例として「RFID豚トレーサビリティ」[2] や「社員証、
学生証への導入」[3] 、「物品ラインへの導入」[3] などがあり、それぞれ生産情報管理、防
犯、効率化と精度向上などのために実用化されている。
しかしながら、公共の場所や家庭内では個人識別の必要性がない場合がある。よって、用
途に応じて個人識別を必要とせず安価な位置情報検出手段が必要となる。
1-2 研究の目的
大学構内で要望が出た「教員に面会を求める際に前もって在室状況が分からない
か?」というものである。 教員室は各教員に対して割り振られており、ドア部分に
は手動で行う「行き先表示ボード」が設置されている。しかし、手動で行われる「行
き先ボード」では人の手によるものなので忘れられる事が多い。また、教員室前に行
った場合にその在室状況が判ってもメリットは少なく、訪問する前に在室状況を確認
したい。
まず、RFIDやGPSの携帯を考えた場合、デバイスを持ち歩かなければならず、また、
忘れる事も多い事が推測される。他の手段として一般的なのは監視カメラの設置であ
3
るが、高価であり、プライベートを著しく侵害する可能性がある。そこで、研究室で
作成した既存の位置情報管理システムを転用し在室確認を行えないかと考える。本研
究ではセンサとして安価で定評のある赤外線センサを使用し、人体の位置情報検知を
行いたいと考えている。そして、既存のシステムはそのメインとなった赤外線センサ
の特性から検知範囲内で静止している対象に対し安定した検知が困難である。したが
って、この問題の解決を解決し、実際に「在室確認システム」を作製し、教員室に設
置、実用可能か検証を行う。また実際に得られた情報は、その利用を考え、Webペー
ジ上へと公開を行う。
実験で使用する赤外線センサとは、自動ドア、ATMなど単体で広く利用されている
ものを指す。センサネットワークが必要とされてくる中で、確かに性能の良いセンサ
を各所に配置すればより完璧なセンサネットワークが出来上がるが、ユーザーのプラ
イバシーを侵害せず、また専用のデバイスを携帯させることなく位置情把握を行いた
い。また、通常人体検知には用いないセンサを検証、使用し、システムの機能向上に
努める。
4
第2章
研究概要
2-1 センサネットワーク概要
センサネットワーク概略を図 2-1に図示する。
server
LAN
Energy
saving
01001110
NIC
NIC
Sensor
node
Sensor
node
Functional
図 2-1
位置情報管理システム概略
システムは、サーバー側の管理プログラムと、各種センサを搭載したセンサノード部分に
分けられる。実験では私たちの生活空間にモーションセンサを複数設置し、各センサから
のデータを元に人の位置情報の検知を試みた[6]
[7]
。得られた位置情報は、省エネ、防犯な
ど既存の電化製品への新たな機能追加などに役立てる事が可能である。
2-2 在室確認システム
在室確認システムとは、オフィスなど広範囲な場所で運用することを目的とはせず、限
られたスペース(教員の居室、パーテーションで区切られた個人スペース)に対しての運用を
考えており、図 2-2の様な構想となっている。
5
居室
EV
LAN
Cor
サーバ
図 2-2
在室確認システム構想
各部屋のセンサノードで得られた情報をサーバーで収集管理を行う。
使用するモーションセンサは自身の検知範囲の温度変化を監視しているため、静止した人
体は検出困難である。よって、モーターを用いて、図 2-3の様に限られた検知範囲を掃引さ
せてやる事によって静止した人体の検知を可能とする。
検知範囲
回転
図 2-3
センサ感知範囲の拡張案
また、他のセンサにも言える事であるが、センサの検知範囲外の探索は行えず、センサネ
ットワーク複数個のセンサの設置を余儀なくされる。しかし、検知範囲内を掃引させてや
れば、最小限のセンサで人の位置情報を得ることを可能となる。
6
2-3 全体の構成
まず、使用するセンサは赤外線センサ単体ではなく、距離センサも用いる。これら 2 つ
のセンサの相関を得る事によって
「モーションのみでは熱源が検知可能だが、人か物かの区別が出来ない」
「距離センサでは物体の有無は確認可能だが、人か物かの区別が出来ない」
このそれぞれの問題に対して対処可能であると考える。
図 2-4に製作を行う『在室確認システム』の概要を示す。システムは大きく2つに分けら
れる。
設置場所の環境データを取得するセンサノード部と、センサノード群より送られ
てきたデータを取得、在室確認するソフト部分に分けられる。
センサーノード
センサー
PC
モータ
管理ソフト
MCU
HTML
パケット
NIC
NIC
図 2-4 在室確認システム概観
センサノード側には、センサの検知範囲を掃引するためにはモーターが必要となる。得
られた環境情報の判別は外部ソフトウェアで行おうと考えているが、センサの出力管理及
び PC 側との通信管理を行うためセンサノード上に MCU (Micro Control Unit)を搭載する。
管理ソフトウェア側では、センサノードより得られた情報を元に、在室確認を行う。ま
た得られた情報は HTML 文書として内部で生成し、Web 上へと公開を行う。
2-4 使用する機材の主な説明
(1) PIC
PIC とは所謂マイコン(マイクロ・コントローラー) と呼ばれる物で、電気的な「何か」
を制御するためのコンピューターの一種だと考えることが出来る。例えば炊飯器や洗濯機
などの電化製品に内蔵され、予め PIC 内にプログラムされた手順に沿って付属の I/O ポー
トの入出力制御を行うことにより、ご飯を炊いたり洗濯を行ったりすることを可能として
いる。PIC がパソコンと異なる点は、パソコンが様々な動作が可能な様汎用的に組み立て
られているのに対し、PIC はランプを点灯させたりモーターを駆動させたりと制御面に特
化している。
7
(2) AVR
AVR とは Atmel 社の開発した 8bitRISC タイプの MCU(Micro Controller Unit)で、PIC
などと同様に、CPU,メモリ(フラッシュ、RAM)、不揮発メモリ、I/O が一つのチップ上に
収められている。PIC などと異なり 1996 年に発表された後発の MCU である。従って、PIC
の不足部分を補うような形で洗練された商品となっている。結果的に、PIC と AVR の両方
を比べた上で AVR を選択したが、機能的な面について比較紹介する。
まず、両 MCU は RISC タイプであり命令長が固定バイトとなっている。それぞれ、16Byte*
長となっており、命令数はそれぞれ、35 個(PIC)、131 個(AVR)となっている。命令数が多
い分、多彩な要求に答える事が可能となっている。また PIC は 1 クロック=4 サイクルとな
っており、最短の 1 クロックの命令コードの実行時間であっても 2μs(20MHzクロックの
場合)かかる。対して、AVR ならば、1 クロック=1 サイクルであるため、最短の命令実行
時間が 1/4 となる 0.5μs で実行可能です。また汎用レジスタが 32 個(PIC で言うところの
Working レジスタ個数が 32 倍)、リニアなメモリ空間(バンク切り替えが要らない)、割り込
みベクタが割り込みの種類ごとに設定されている、(PIC では割り込み要因を手動で判断し
なくてはならない)などを代表して挙げたいと思う。結局の所、一番のポイントは前述した
命令数の多さからの拡張性の高さが決め手となった。
*PIC18F シリーズと仮定
(3) 赤外線センサ
センサは図 2-5の松下電器製焦電型MPモーションセンサNaPiOn(AMN13111)を使用し、
付録に性能の概略を示す。
図 2-5 実験に使用した AMN13111 の概観
赤外線を利用したセンサには今回使用した焦電型とサーモパイルと呼ばれるもの
がある。原理は、サーモパイルが熱電対の原理を応用した簡単なセンサで、熱電対を
8
微少な面積の中に直列に並べた物である。熱電対、すなわち2種類の金属で回路を作
成しその2つの接合部分が異なる温度に保たれた時に熱起電力が生じて電流が流れる
「ゼーべック効果」の原理を使用している。
また、焦電型は焦電物質を用いてあらゆる物体から放出される赤外線エネルギーを
検出することができる。この型のセンサは波長依存性がないため光学フィルタを使い
分け、波長を選別してやることによって様々な温度センサを作ることが可能である。
AMN13111は温度差(+4℃)を検出可能なため体温を持つ人体の検出に最適とされてい
る。
全体の検出範囲は図 2-6のような縦1.4m横2.0mの長方形となっているが、実際には
24個の各セルに被験者が侵入した場合にのみ出力(Vdd-0.5V)されることとなる。
図 2-6
使用した赤外線センサの検出セル配置
(4) フレネルレンズ
赤外線センサの検出範囲を明確に、なおかつ狭窄化させるため、レンズを用いる。
用いたレンズは図 2-7に示すフレネルレンズを用いる。
9
図 2-7
フレネルレンズ概観
フレネルレンズは同心円状に切り厚みを減らしたレンズで、断面はノコギリ状にカ
ットされている。性能としては凹レンズ、凸レンズ等と変らぬ効果を持ちながら、そ
の厚みが解消されており、レンズの軽量、コンパクト化に成功している。
使用したフレネルレンズは今回使用した赤外線センサと同系統のセンサに最適化さ
れている。よって、焦点の位置合わせが不要で後部に差込、固定することで実装可能
であり、専用のフォルダを用意する必要がなく、生産性が高い。検知範囲は図 2-8に図
示する。
260cm
フレネルレンズ
130cm
86cm
5m
10m
20m
30m
検出範囲
43cm
図 2-8
フレネルレンズを用いた理論検知範囲
(5) 距離センサ
図 2-9に使用した、距離センサの概観を示す。(写真は 150cm距離センサ、500cmの
物は割愛する。)
10
図 2-9
距離センサ概観
このセンサはメカトロ分野でのロボットの周囲環境把握用の眼として、また工場ラ
イン上での製品の流れを把握する為などに用いられる。測定物までの距離に応じて出力電
圧を返すが、このセンサを用いて人の位置情報検知を行いたい。このセンサの動作原理は図
2-10に示すように、内部に赤外線LEDとPSD(Position Sensitive Detector)を内蔵しており、
被測定物に対して赤外線LEDを照射し、その反射光をレンズでPSD素子上へと収束させて
いる。PSDは素子上に照射された光スポットの重心を、その光パワーより把握する事が可
能である。そして、測定物までの距離が変化する度、重心がPSD上で変位するため、対象
物までの距離として検出可能である。
変位
レンズ
LED駆動回路 LED
信号処理回路
測定物
PSD
図 2-10
距離センサの構造及び、動作原理
11
(6) ステッピングモータ
使用を検討しているモーターの一つとしてステッピングモータを挙げる。ステッピン
グモータの概観は図 2-11に示す。
図 2-11
ステッピングモータ概観
このモーターは外部からのパルス制御によって駆動が行われる。具体的には図 2-12の様に
4 種のパルスを順番に信号線に与えてやる事によって正転、逆転に回転を行える。
CW
CCW
青 0 0 1 1
黄 1 1 0 0
赤 0 1 1 0
白 1 0 0 1
CW
CCW
青
0
0
1
1
黄
1
1
0
0
赤
0
1
1
0
白
1
0
0
1
図 2-12
0=0V
1=Vcc
ステッピングモータ駆動パターン
このモーターの欠点は今現在の角度を基準として何ステップ進むか?という処理しか行え
ないため、電源投入時に初期角度を手動で設定してやる必要性がある。また、駆動中に外
部からの要因で角度がずれても補正する事はモーター単体では不可能である。
12
(7) サーボモータ
この研究で使用したサーボモータについて記述する。サーボモータ概観は図 2-13に示す。
図 2-13
サーボモータ概観
サーボモータは先に紹介したステッピングモータと同じくパルスによってその回転角度が
制御されている。しかしながらステッピングモータとは異なり。図 2-14の様に周期的なパ
ルスのデューティ比を変化させる事によって回転角度の制御を行っている。
デューティ比
15ms(固定)
小さく
GND
1.5ms
Vcc
中心
Pulse
大きく
図 2-14
サーボモータの制御方法
周期は 15ms を固定として、ハイレベル部分が 1.5ms を中心として±0.5ms 動かしてやる
ことによって回転角度を制御可能である。
サーボモータは、いくつか種類があるが一般的には回転角度に制限があり、今回使用し
た物も、約 180 度強の回転角度しか持たず、これを振り切ろうとした場合、過電流による
レギュレータ等の破損が考えられるので注意が必要である。
(8) XBee
図 2-15に使用した無線通信デバイス、XBeeの概観を示す。XBeeモジュールは低消費電力
13
のワイヤレスセンサーネットワークを構築するために設計されており、内部のファームウ
ェアを書き換えることによって、ZigBee又は、IEEE802.15.4 としての動作が可能である。
このXBeeは図 2-16の様な評価基盤が付属しており、XBeeを評価基盤に接続、電源投入す
る。その後USBもしくは、RS232CケーブルでPCと接続し、ハイパーターミナル上からコ
マンド対話形式でモジュールの制御が行える。また制御コマンドは私達ユーザー側の希望
する独自のコードを開発することが可能である。表 2-1にXBeeの簡単な仕様を明記する。
表 2-1
XBee
簡略化性能表
XBee802.15.4
OEM RF Module
250kbps
通信速度
30m
屋内通信距離
送信Power
1mW (+0dBm)
2.4GHz
周波数帯
2.8~3.4V DC
電源
電流 (受信/送信)
50mA / 45mA
128-bit AES
暗号化
I/O
8 (10bit ADC 7本)
名称
14
図 2-15
無線通信デバイス XBee 概観
図 2-16
XBee 開発ボード(USB)
2-5 センサノード部
センサノードは、モーターの回転、ネットワーク送受信、センサ出力の加工などの管理
を行っている。
2.5.1 ハードウェア設計
(1) PWM
PWM とは Pulse Width Modulation の略でパルス波のデューティ比を変化させ I/O ピン
15
より出力可能である。使用した ATmega48 では 6 箇所の PWM 出力が可能で、16Bit タイ
マカウンタを用いた PWM を使用する。PWM によって得られたパルスは前述の通りサーボ
モータの駆動に使用します。
(2) ADC
各センサ及び、Cds セルの検出抵抗にかかる電圧を AD 変換するために ADC を使用して
います。ATmega48 では 10bit 分解能を持った ADC が 6 チャンネル使用可能で、距離セン
サ 2 種、Cds セルの合計 3 本を使用しています。ADC の基準電圧は比較電圧として Vref
ピンが用意されていますが、各センサの出力特性から回路駆動電圧 Vcc 3.3V をそのまま使
用しています。 また、ADC 精度向上のために、ADC 開始後 SLEEP に入り、ADC 完了割
り込みをもって SLEEP の解除を行っています。
(3) 各種割り込み
前述の様に AVR では割り込みベクタがそれぞれ個別に指定されており、使用している割
り込み要素は、タイマカウンタ 1 比較 B 一致(PWM のデューティ比更新のための割り込み)、
USART RX(通信機能 USART の受信完了割り込み)、ADC 割り込み(ADC 完了割り込み)の
3 種を使用している。
(4) 通信デバイス切り替え
製作するセンサノードはRs232cとXBeeを経由した無線通信の 2 つの機能を持たせてい
る。AVRからのTx、Rxピンをそれぞれの通信デバイスのRxとTxに繋いだ場合、各々の通信
デバイスのピンの入出力がバッティングする事となる。よって論理ゲートチップを用いて
の図 2-17様に切り替えを行っている。
74HC244AP
Tx
Rx
Rx
Tx
AVR
RS232C
RS232C使用
AVR
In
Out
図 2-17
XBee使用
XBee
論理ゲートを用いて使用通信デバイス選択
16
2.5.2
センサーノードフローチャート
図 2-18、図 2-19にセンサノードBのフローチャートを示す。
SubMain
ルーチン
スタート
制御コード受信
Mode1
PWM幅指定
初期化
150cmセンサ
ON
メイン
割込み待
Yes
Wait
各種
Mode選択
150cmセンサ
出力取得
No
SRAM格納
照度確認
500cmセンサ
ON
Wait
照度確認
ルーチン
Cds電圧値
取得
閾値比較
Yes
Mode2
500cmセンサ
出力取得
SRAM格納
モーションセンサ
出力取得
SRAM格納
NO
回数比較
Yes
NO
Return
Return
図 2-18
センサノード B フローチャート
NO.1
ノードは基本的に電源投入後、初期化を経て、メインルーチンへと突入する。しかし、
メインではノード上のCdsの照度を確認しているだけで他に作業を行っておらず、外部
からのシリアル通信による対話形式にて各種機能を選択、実行している。動作モードは
デバッグがしやすい様に 6 つに細分化されており。各モードについて表 2-2の様に定め
ている。
17
表 2-2
センサノードモード別機能表
モード名
Mode0
機能
手動回転
Mode1
ソフトウェアリセット
Mode2
Sleep
Mode3
回転&センサ出力送信
Mode4
SRAM内容送信
Mode5
各ADC結果取得
Mode6
テスト
「照度確認」サブルーチン
Cds セルに直列で繋がれている検出抵抗にかかる電圧値より、センサノード設置環境の照
度比較を行っている。Cds とは照度センサの一種で照射される光量によって抵抗値が変化
する素子である。内部であらかじめ定めた閾値を ADC 結果が下回った場合において、セン
サノード設置環境が消灯状態になったとして「Mode2」を呼び出す。それ以外の場合はル
ーチンを抜けている。
18
Mode0開始
Mode1開始
Mode2開始
Mode3開始
メッセージ表示
メッセージ表示
メッセージ表示
メッセージ表示
角度受信
SRAMクリア
各種センサ
OFF
制御コード受信
PWM幅反映
Return
Cds電圧
取得
SubMain
呼出
PWM許可
NO
Return
閾値より上?
メッセージ表示
Yes
メッセージ表示
Return
Return
Mode5開始
Mode6開始
メッセージ表示
メッセージ表示
150cmセンサ
ON
Return
Wait
Mode4開始
150cmセンサ
出力取得
メッセージ表示
SRAM内容
送信
500cmセンサ
ON
SRAM呼出
Wait
NO
アドレス比較
500cmセンサ
出力取得
Yes
モーションセンサ
出力取得
Return
Return
図 2-19
センサノード B フローチャート NO.2
「Mode0」サブルーチン
ここでは、対話ユーザーによるモーターの手動回転が行える。ルーチンに入るとまず
「Mode0」で在る旨が送信された後に、回転希望角度に相当する 3byte 文字列の受信待
19
機状態へと移る。その後、得られた設定値を元に PWM 値のデューティ比の変更を行っ
た後、ルーチンを抜ける。
「Mode1」サブルーチン
Mode1 は MCU のソフトウェアリセットであり、作成したセンサノードにはリセット
スイッチを付属させているが、遠距離からのリセットを行う必要が想定されるのでこの
機能を設けている Mode1 がコールされると、マイコン上の SRAM の内容をクリアし、
初期化ルーチンに戻る。
「Mode2」サブルーチン
Mode2 は、強制 Sleep 待機動作を行う。センサノードは、各動作の間、定期的に ADC
ピンに接続された Cds セルの監視を行っている。ノード内部で閾値電圧を設定し、Cds
にかかる電圧が降下した場合に、搭載されているセンサの一部の電力をカットし、その
後、閾値を電圧が越える場合、センサノード設置部屋が点灯状態になったとして Sleep
より復帰する。
「Mode3」サブルーチン
モード 3 は最も多用されると思われるモードで、管理システムから送られてくる制御
コードを元にサーボモータ回転を行う。制御コードの内訳は 図 2-22にて後述する。
Mode3 が呼び出されると、制御コードの受信待ち状態となる。制御コードが受信完了し
た時点で「SubMain」サブルーチンをコールする。処理が戻ってきた後、ルーチンより
抜ける。
「Mode4」サブルーチン
モード 4 は、マイコン内部のSRAMに格納されているデータの一覧を送信する。こ
れらをターミナルで受信した場合図 2-20の様に表記される。Mode4 が呼び出されると、
まず、受信側で読みやすい様に横軸に 3 桁のSRAMアドレスのうち下位 1 桁が、送信途
中ではSRAMデータに規則的に上位 2 桁のSRAMアドレスを付加していく。SRAMの終
了アドレスに達した場合ルーチンを抜ける。
20
レジスタアドレス
モーションセンサ
150cm距離センサ
500cm距離センサ
図 2-20
モード 4 送信データ内容
使用した MCU には 512Byte の SRAM が搭載されており、先頭から順に 110Byte ず
つ「モーションセンサ出力」「150cm 距離センサ出力」、「500cm 距離センサ出力」の順
番に 2 桁の 16 進数で保存されている。
「Mode5」サブルーチン
現在センサが向いている正面の測定物に対して、各センサの出力を図 2-21の様に表記す
る。Mode5 が呼び出されると、まず 150cm距離センサの電源をONにする。安定化時間を
待った後、出力電圧を取得、送信する。同様に 500cm距離センサも出力を取得、送信、モ
ーションセンサのON/OFFの情報を取得した後送信を行っている。その後ルーチンを抜ける。
図 2-21
Mode5 出力文字列
送られてくるデータは ADC の結果をそのまま送信しているため、8bit の AD の出力として
256 段階となるため、16 進数で表記すると 00~FF の間の2Byte で表記される。
「SubMain」サブルーチン
21
SubMain では、制御コードで与えられた設定を元にサーボモータを回転し、角度毎にそれ
ぞれのセンサの出力の SRAM への格納を行っている。 まず、SubMain が呼び出されると、
回転開始角へと移動するために PWM のデューティ比が変更される。
希望回転角に到着し、
使用するセンサの電源 ON→安定化時間待機→センサ出力取得→SRAM に格納が行われて
いる(150cm 距離センサ終了後、同手順で 500cm 距離センサ)また上記手順とほぼ同じだ
が、モーションセンサについては安定化時間が7s 前後存在し、尚且つ、駆動中でも 0.5mw
の消費電力であるため電源管理は行わない。
2.5.3
パケット構造
図 2-22
9Byte
制御コード
にセンサノード側からの送信パケット構造図を示す。
Max 331Byte
出力データ
1Stepあたり6Byte
モーション 距離センサ 距離センサ データ分割
センサ1件目 150cm 1件目 500cm 1件目
コード
回転方向
1Byte
スタート位置 回転Step数
3Byte
2Byte
図 2-22
回転速度
データ分割
コード
2Byte
1Byte
・・・ ENDコード
送信パケット構造図
パケットは大きく、制御コード部と出力データ部に分けられる。制御コードとはセンサノ
ードに搭載されているサーボモータの回転制御コードである。コード部は更に細かく 4 つ
に分けられる。まず、正転、逆転を選択する「回転方向」部分、回転の開始部分を決定す
る「スタート位置」部分、回転開始から何度回転するかを決定する「回転 Step 数」部分、
そして、1Step 回転後の停止時間から「回転速度」を設定する部分となる。
スタート位置は 16 進数表記 4D~13F の間の約 242 ポイントを指定可能である。回転ステ
ップ数はディフォルトでは 1 ステップ 4 ポイント移動として、55 ステップに設定してある。
回転速度は 1 ステップ毎の移動終了後の待ち時間を指すため、100ms と指定した場合には
回転開始から終了まで 5.5 秒程必要となる。
次に、出力データ部分では、モーションセンサ⇒距離センサ(150cm)⇒距離センサ(500cm)
の順にセンサの出力を数値化して送っている。また、各ステップのデータの区別しやすい
様に分割用のコードの付加を行った。最後に、END コードを付加する事によって PC 側か
らパケット送信の終了を認識する。
22
2-6 在室確認ソフト部
在室確認ソフト部構想を図 2-23に示す。在室確認システムでは、ネットワークを介して
センサノードより得られたパケットを選別、在室の判定を行う。また得られた結果をディ
スプレイ上に視覚的に判りやすく表示、実際の運用の観点からWeb上での公開用ページ作成
を行っている。
出力データ
00593710,0808F,07F9
6,00F89,0738E,0279E
,10099,10096,1008F,1
0073,11158,00198,10
023,10133,10173, ・・・
管理ソフト
Webページ
変換表示
15度
17度
18度
20度
=
=
=
=
100cm
120cm
115cm
330cm
・
・
・
Webページ生成
在室管理公開ページ
更新日時
ノードA 在室
ノードB 不在
グラフ化
PC
図 2-23
在室確認ソフトウェア構想図
23
2.6.1
在室確認システムフローチャート
作成した管理システムのフローチャートを図 2-24~図 2-27に記述する。
スタート
初期設定
Yes
各種イベント
待ち
NO
回転データ
送信
通信開始
Text
Clear
Graph
Clear
コマンド
送信
Return
pos
MsCom
イベント
自動運転
タイマ
環境情報
更新チェック
NO
終了ボタン
Yes
終了
回転データ
送信
Text
Clear
Graph
Clear
自動運転
タイマ
回転開始
Delay
テキストBox
クリア
グラフ領域
クリア
イベント発生
Mode3選択
Return
Return
Mode3
move
回転制御
送信
Return
Pos
通信開始
Return
Return
直前回転方向
取得
Comポート
オープン
Text
Clear
直前回転開始
箇所算出設定
Return
テキストBox
クリア
制御コード
送信
コマンド送信
Return
Return
送信テキスト
BOX内送信
Return
図 2-24
在室確認ソフトフローチャート 1
ソフトウェアが起動されると、各種初期化が行われた後、各種イベント待ち状態へと遷
移する。イベントは主に、画面上のボタンに対するクリックイベントであるが、その他、
24
Mscomm の Oncomm イベント、タイマコントロールの Tick イベントが 2 種含まれている。
各種ルーチンについて説明していきたいと思う。
「通信開始」クリックイベント
「回転データ送信」クリックイベント
“3”を送信し Mode3 を選択する、その後メッセージが送られてくるため受信終了時ま
でディレイを挿入している。画面上の各種制御 Box より回転制御コードを作成し送信を行
う。
「通信開始」クリックイベント
Com ポートをオープンにし送受信可能状態とする。オープン時にエラーが発生した場合
は画面上にエラー内容が明記される。
「コマンド送信」クリックイベント
コマンド送信と書いてあるが直ぐ左のテキストボックス内の内容を直ちに送信を行う。
この機能は、すべての動作を手動で行いたい場合などのために用意されている。
「Text Clear」クリックイベント
中央のメインテキストボックス内容を手動クリアする。
「Graph Clear」クリックイベント
在室確認システムタブ上に存在する 2 つのグラフ描画領域を手動クリアする。
「Return Pos」クリックイベント
直前の回転開始まで速度等を同じ条件で移動を行う。イベントが発生した場合に、まず直
前の回転方向が取得される。その後、現在地から前回転開始位置まで逆方向に回転する形
の制御コードを生成し送信する。
「自動運転タイマ」Tick イベント
設定タブ内で定められた繰り返し時間が来ると発生するイベントである。イベント発生
後「Mode3 Move」を呼び出す事によって、実質自動運転という形を実現している。
25
環境情報
更新チェック
Yes
No
更新時刻か?
次回更新時刻
+5分後
Mode2か?
NO
Yes
環境情報
更新
Return
センサ出力
計算
NO
Yes
平均化回数
≧1
出力平均化用
配列に格納
Yes
逆転データか?
配列内
昇降入れ替え
NO
既存出力に新規
分データを加算
Yes
平均化回数
取得終了
NO
Mode3
move
センサ出力を
電圧値へ変換
配列を平均回数
で乗算
Return
受信データを
出力格納配列へ
Yes
逆転データか?
配列内
昇降入れ替え
NO
センサ出力を
電圧値へ変換
出力電圧値
テキスト保存
NO
Yes
ファイル
オープン
テキスト
書き込み
ファイル
クローズ
距離算出
距離リミッタ
算出データ
列挙
①
図 2-25
在室確認ソフトフローチャート 2
26
5分後に
再確認
②
算出距離
テキスト保存
NO
Yes
ファイル
オープン
テキスト
書き込み
ファイル
クローズ
モーションセンサ描画
初期位置反映
Mode3
move
モーションセンサ出力
描画
距離センサ描画
初期位置反映
Mode3選択
150cm距離センサ
出力描画
Delay300ms
制御コード
送信
500cm距離センサ
出力描画
Return
実距離選定
NO
初期値格納
フラグ
Yes
環境情報初期値
としてDefEnv()へ
初期化格納フラグ
Ture
現在の環境情報
としてNowEnv()へ
選別後実距離
を描画
Mode10選択
Return
図 2-26
在室確認ソフトフローチャート 3
「環境情報更新チェック」Tick イベント
1 分ごとに発生し、設定タブ内で定めた時刻との比較を行っている。もし、一致し、なお
かつ、現在 Mode2(センサノード設置場所が消灯中)であればモーションセンサの反応にかか
わらず環境初期情報の更新を行います。更新時刻でありながら Mode2で無かった場合は設
置環境内にまだ人が居るであろうことを考慮し、次回の環境更新比較時刻を現在の値より
+5 分する。
「センサ出力計算ルーチン」サブルーチン
取得したセンサの出力が配列に格納し終わった後に呼び出され、距離に変換された後に
画面描画、テキスト保存などが実行される。まず、呼び出されると、平均化回数について
27
比較が行われる。平均化を行う必要性があるならば分岐したのち、保存されていた前出力
に加算される。平均化を行える分のデータが揃ったのならば平均を算出し、その値を現在
のセンサの出力として処理を続けていく。もし、平均化を行うに十分なデータを取得して
いなければ 「Mode3Move」を呼び出し続けてモーターにて回転を行う。加えて、最初か
ら平均化を行う必要性の無い場合は、受信データを配列に格納したのち、電圧値に変換→
距離に変換を行う。算出した距離は各センサの検知範囲外のデータを取り除き、テキスト
ボックス内に角度ごとに列挙する。その後、画面上にモーションセンサの出力は下の描画
ウインドウへ横軸は角度、縦軸は距離として描画される。その後、150cm と 500cm 距離セ
ンサの出力は、
「実距離選定」ルーチンにより選定、統合され 1 種の距離データとして保存
される。選定後の距離データは初期値格納が行われていなければ、設置環境の無人時の比
較データとして DefEnv()配列へと格納される。その後初期値格納が終了したことを示すフ
ラグを真として「センサ出力計算」のメインへと戻る。もし初期値格納が完了しているな
らば、選定後の距離データは現在の環境の値として NowEnv()配列へと格納される。次に、
「選別後実距離を描画」にて選定によって統合された実距離を描画ウインドウ上に太めの
白線で描画を行う。サブルーチンを終了する前に、Mode10 を選択する。
「Mscomm」Oncomm イベント
MicrosoftCommunicationControl にて、RS232C 経由で送受信、エラーが発生した場合
に発生する。各種エラーはエラーメッセージを表示したのち、ルーチンを抜ける。受信イ
ベントが発生した場合にのみ。定義された処理を行っていく。まず、受信した文字列から
「Mode」という文字列の検索を行い、Mode 数の判別を行い Mode 数に応じた処理へと分
岐を行う。例外として Mode10 は受信した文字列をただ、メインテキストボックスへと列
挙するのみにとどまる。また、分岐条件である「Mode」の探索において発見されなかった
場合はルーチンを抜けるものとする。
「Mode2 処理」サブルーチン
Mode2 はセンサノード設置環境が消灯中である場合に継続されるモードである。
まず、受信した文字列から「Quit」文字列の検索を行う。Quit が発見されたならば、Mode2
が終了したとして、Sleep が解除された旨をメインウインドウへ表示する。受信文字列は初
期化された後、Mode10 に設定され処理を抜ける。
「Mode3 処理」サブルーチン
受信文字列内から「END」文字列の検索を行う。もし発見されたなら「センサ出力計算」
サブルーチンを呼び出す。それ以外の場合においてはルーチンを抜ける。
「Mode4 処理」サブルーチン
28
ここでは、センサノード内でのSRAM内容の画面への表示を行っている。表示パターン
等については前述した図 2-20を参照してもらいたい。
「Mode5 処理」サブルーチン
このモードでは受信した各種センサの出力である 16 進数を画面上へ変換して理解しやす
く表記しなおしている。具体的には、まず、受信文字列内から「Quit」文字列の検索を行
う。発見された場合、Mode5 にて送られてくるデータ群(図 2-21参照)より必要データを計
算用配列へと格納を行う。その後、各距離センサについては電圧、距離の 2 種類に変換を
実行し、メインウインドウへの表記を行う。モーションセンサの出力に関してはそのまま 0
or 1で表記している。その後Mode10 を選択しルーチンを抜ける。初期文字列検索分岐で
「Quit」が発見されなければ直ちにルーチンを抜けている。
29
MsCom
イベント
Yes
NO
受信文字列内
「Mode」検索
Mode数認識
No
Mode10?
Mode2
処理
Yes
受信文字列を
TextBoxへ
Mode3
処理
Mode4
処理
Mode5
処理
Return
Mode2
処理
Yes
受信文字列内
「Quit」検索
NO
受信文字列
初期化
SLEEPが
解除されました
Mode10
選択
Return
Mode3
処理
Mode4
処理
Yes
受信文字列内
「END」検索
NO
Yes
受信文字列内
「Quit」検索
NO
センサ出力
計算
Return
Return
Mode5
処理
Yes
受信文字列内
「Quit」検索
NO
取得データを
計算用配列へ
電圧値変換し
格納
各種センサ
変換後の値
Mode10
選択
Return
図 2-27
在室確認ソフトフローチャート 4
2-7 在室状況の Web 公開
在室確認システム部分において得られた、各部屋の在室状況を Web 上にて参照可能と
するために、ソフトウェアからページの作成、更新を行う。Web ページは基本的に HTML
タグによって作成されており、JavaScript を組み込むことによってページ内テーブルの
内容を定期的に変更している。しかし、システム側で 1 から HTML 文書を生成しなお
30
すのでは手間がかかる。よって、良く変更する箇所のみを JavaScript の外部ファイル(Js
ファイル) として作成し、外部ファイルのみを変更する事とする。
Js ファイルの更新によって、画面内の在室状況更新時刻、教員名、在室状況、不在開始時
間などが順次書きかれられる事となる。
2.7.1 Web 公開システムのフローチャート
図 2-28にWeb公開システムのフローチャートを示す。このフローチャートは
前述した在室確認ソフト内部に組み込まれており、別タブに機能が搭載されている。
外部Jsファイル
編集
保存
HTML表示
ファイル
オープン
外部Jsファイル
オープン
ブラウザ起動
ファイルより
1行づつ取得
ユーザー数
書き込み
在室管理ページ
EOFに到達
ユーザー名
書き込み
Return
NO
Yes
文字列を”;”
毎に分割保存
文字列から
“を除外し保存
ファイル
クローズ
ノード数読取り
保存
在室状況
書き込み
テキスト
更新時間格納
変更後テキスト
Return
ノード名読取り
保存
TextBox上に
列挙
Return
図 2-28
Web 公開システムのフローチャート
まず、
「外部 Js ファイル編集」は在室確認ソフトの初期化部分に含まれる手順であるが、
この節で記述を行う。このサブルーチンは外部 Js ファイルを読み込み込んだ後、Web 公開
システムタブ内のテキストボックススペースにその内容の列挙を行っている。また画面上
に列挙するだけではなく、ユーザー数を収める Numeric Box やユーザー名を格納する各
31
Text Box に値の反映を行っている。
「保存」ルーチンでは、画面上の「保存」ボタンのクリックイベントの処理が書かれてい
る。外部 Js ファイルをオープンした後、画面上のユーザー数とユーザー名を元に Js ファ
イル内配列の内容を書き換えている。また、在室状況更新時間を HTML 文書上に記述する
ために、Js ファイル書き込み時間の保存を行う。その後、外部 js ファイルをクローズし変
更後の Js ファイル内全文を画面上に再度読み込み直している。
「HTML」ルーチンでは、画面上の「HTML 表示」ボタンのクリックイベントにより実行
される。ブラウザを起動し、実際に作成された在室公開ページ HTML 文書を表示する。
2-8 センサ設置のための出力測定
使用したセンサは前述したとおり、AMN13111 焦電センサ(以下モーションセンサと
記述)、150cm 距離センサと 500cm 距離センサの 3 種類を起用する。使用したセンサの
出力特性をシステム設計のために取得する。
2.8.1 モーションセンサ
実験に使用したモーションセンサは前述のとおり、環境の温度変化を監視してお
り、+4 度以上の温度変化があった場合に、TTLレベルでのVccに相当する電圧を出
力する。また、反応が無い場合は内部で開放状態となり、出力は 0Vとなる。モーシ
ョンセンサの検知範囲については図 2-6に前述した。これを踏まえた上で、モーショ
ンセンサを天井に設置し出力測定を行った、しかし、実際の検出範囲はデータシー
トに記載されているものとは異なり、曖昧である事が判った。加えて、このセンサ
は赤外線を照射するタイプではなく、受ける事によって温度差を取得しており、尚
且つ、反応があった場合の矩形波の立ち上がりに数百ミリの遅延があるため、その
検出範囲の明確な測定は困難である。よって、前述した図 2-7のフレネルレンズを使
用する事によって検出範囲を可能な限り狭窄化させる事とした。
このセンサは検知範囲がセル化されており、検知範囲内において周囲と温度差の
ある物体が横切った場合に図 2-29の様な矩形波が、横切ったセル分もしくは、複数
個出力される。また、立ち上がり、立下り遅延時間の関係から実際に人が通過し終
わった後も数秒間延びして出力される事となる。
32
検出範囲
検出セル
移動
Td(立ち下がり遅延)
電圧(V)
Tr(立ち上がり遅延)
時間(s)
図 2-29
モーションセンサの出力特性
2.8.2 距離センサ
使用した距離センサは、被測定物の材質、言うなれば反射率に関係なく距離を算出可
能で有るとデータシートに記載されている。図 2-30に使用した距離センサ(150cm・
500cmレンジ)の距離と出力電圧のグラフを図示する。測定は見通しがよく、空調の風や
日光などの照射がない室内にて行った。測定は同センサのデータシートより、それぞれ
の検知可能範囲とされる 20-150cm(150cmセンサ)、100-500cm(500cmセンサ)付近を中
心に測定を行った。
33
3.5
150cmセンサ
出力電圧(V)
3
500cmセンサ
2
1
0
0
100
図 2-30
200
300
400
対象物までの距離(cm)
500
使用する距離センサの出力特性 (cm-V)
また、被測定物の材質をコンクリート、繊維、鉄板などで続けて出力特性を取得し
たが、図 2-31の様に出力に変化が生じる事はなかった。よって、このセンサが被測定
物に因らず距離を算出可能だとし、以後の研究で使用を行う。
3
コンクリ
鉄
繊維
出力電圧(V)
2.5
2
1.5
1
0.5
0
0
50
100
150
200
距離 (cm)
図 2-31
材料別距離センサ特性(150cm センサ)
次に、図 2-32に 150cm距離センサの出力特性取得(モータ移動時)のための実験構成
を示す。
34
1.5m
1.2m
センサーノード
図 2-32 センサ回転時の出力測定
センサノードを幅 1.2mの屋内廊下に設置し、モーターを用いて 15 度~165 度、約 2.7
度おきに 55 点取得した。その出力取得結果が図 2-33となる。
500
実距離
回転出力
距離(cm)
400
300
200
100
0
0
30
60
図 2-33
90
120
回転角度(Deg)
150
180
センサ回転時の出力グラフ
この図は点線部が、角度を元に算出した壁までの距離、実線が出力された電圧値を元
に得られた壁までの距離である。このセンサは前述した様に、計測物への光の入射角な
どの変化から、光の反射パワーに変化があった場合にも計測可能である。しかし、グラ
フから参照可能な様に 165 度付近において実距離と計測距離の著しい乖離が見られる事
があるが、同角度にて測定を繰り返しても一定してレンジ外の出力が取得できるため、
作成するシステムでは大きな問題とはならない。
出力電圧から距離を算出する方法として、図 2-30の出力特性グラフからエクセルによって
35
近似式を求める。線形ではなく、二次曲線でも近似は難しいよって多項式近似を用いるも
のとして、図 2-34に近似項数ごとの近似曲線を図示する。
160
6次式
5次式
4次式
3次式
2次式
実測
距離(cm)
120
80
40
0
0
1
2
3
電圧(V)
図 2-34
多項近似式考察
この結果より、項数が少ない場合に電圧から正しい距離が算出出来ないため、6 次項近似方
程式を使用する。また近似線を求める際に、検出可能距離の近傍距離側の上に凸となって
いる部分は除外した。
36
第3章
測定結果
3-1 センサノード作成
センサノードは 2 種類試作を行った。1つは、PIC 及びステッピングモータを用いた
もの、2 つ目は AVR 及びサーボモータを使用したものである。最終的に採用した 2 つ目
のセンサノードについてのみ記述する。
3.1.1 センサノード構成
センサノードは、MPUとしてAVR、モーターはサーボモータを採用している。また、
センサは 150cm距離センサ及び、500cm高レンジの距離センサ、モーションセンサを搭
載、加えて、PCとセンサノード間の通信にXBeeを用いて無線化を行っている。センサ
ノードの回路図を図 3-1に示す。
37
図 3-1
AVR 使用センサノード
38
5
4
3
2
1
6V
VCC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
A
Xbee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
RS232C_Conv
A
GND
USBRxD
GND
50kΩ
3.3V
U
TA48M033F
0.1u 100u
IN
GND
OUT
RxD
USBTxD
B
B
2
3
4
5
6
7
8
9
19
3.3V
OE2
1A1
2Y4
1A2
2Y3
1A3
2Y2
1A4
2Y1
OE1
1Y1
2A4
1Y2
2A3
1Y3
2A2
1Y4
2A1
U
74244
1
18
17
16
15
14
13
12
11
C
C
GND
33kΩ
22kΩ
3.3V
15p
15p
PUSHSW
TxD
RxD
10K
D
XTAL(8M)
D
14
13
12
11
10
9
8
7
6
5
4
3
2
1
PB0
PD7
PD6
PD5
PB7(XTAL2)
PB6(XTAL1)
GND
Vcc
PD4
PD3
PD2(INT0)
PD1(TXD)
PD0(RXD)
PC6(RESET^)
ATMEGA48
PC3
PC4
PC5
E
PB1
PB2(OC1B)
PB3(MOSI)
PB4(MISO)
PB5(SCK)
AVcc
AREF
GND
PC0(ADC0)
PC1(ADC1)
PC2(ADC2)
E
GND
LED
15
16
17
18
19
20
21
22
23
24
25
26
27
28
130Ω
0.1u
0.1u
GND
0.1u
0.1u
800Ω
800Ω
800Ω
F
10kΩ
CDS
22u
2
1
2
1
2
1
F
3.3V
PC-TR
3
4
PC-FET
3
4
PC-FET
3
4
6V
GND
GND
G
G
6
5
4
3
2
1
SERVOMORTAR
GND
Vdd
Pulse
OUT
GND
Vdd
AMN13111
OUT
GND
Vdd
GP2Y0A700k0F
OUT
GND
Vdd
GP2Y0A02YK0F
ProgramPin
1
2
3
3
2
1
3
2
1
3
2
1
H
H
5
4
3
2
1
ステッピングモータ使用時における問題点である外的要因による角度の変化は、サーボで
はほぼ解消される、ステッピングモータと異なり、どの様な状態であっても、角度に応じ
たパルス幅の信号を与える事によって、目的の角度へモーターを指向させる事が可能だ。
しかし「問題がほぼ解消される」と記述したのは、回転途中などにおいて、外的要因によ
って圧力がかかりモーターが停止したとしても、モーター本体、もしくは MCU で異常事態
を知る事は出来ないためである。消費電力は回転角を維持するのに 18mW、駆動する場合
には瞬間的に 100mA 程度流れるので 600mW かかると仮定する、実際にモーターを駆動す
るのは標準で 1 分に 1 回 12 秒程度なので、モーターの消費電力だけに限定した場合その値
は約 120Wh+14.4mWh=134mWh となる。駆動モータにステッピングモータを使用した場
合は、駆動時と回転角を保持する時に同等の電流を必要とするため、消費電力は 480mWh
となる。 これらの条件から、作成するノードにはステッピングモータを搭載する。また、
実際に製作を行ったセンサノードの完成系が図 3-2に示す。
150cm距離センサ
500cm距離センサ
モーションセンサ
サーボモータ
図 3-2
センサノード概観
ノードは無線化を行っており、通信線については付属しなくても通信可能であるが、電
源は AC アダプタより供給されている。
次に内部回路について外観を図 3-3に示す。
39
フォトモスFET
センサ&モータI/O
センサ&モータI/O
プログラム用 I/O
ATmega48
論理ゲート
XBee
図 3-3
図 3-4
センサノード内部回路(表)
センサノード内部回路(裏面)
40
3-2 距離センサの相互干渉
150cm と 500cm の距離センサを同時に用いて実験を行う段階で、互いに内蔵されている
LED の光が干渉しあうという問題が発生した。この問題に対応するには
①センサの出力を取得する時だけ、素子に電圧を印加する。
②センサの出力が干渉しない様、あらかじめ一定の角度を設けてセンサを固定する。
の 2 つの案が考えられる。
第一案を起用した場合に図 3-5に示すような流れで電圧が印加される。
PWMパルス幅変更MAX時間
1Step移動時間
モーター
距離センサ
(150cm)
15ms
5ms
移動終了
安定化時間
電源ON
Max52.9ms
ADC終了
電源OFF
距離センサ
(550cm)
電源ON
Max25.2ms
電源OFF
20ms
52.9ms
ADC終了
25.2ms
Total≒100ms
図 3-5
センサ出力干渉に伴う電源管理図
この図は最初にモーターが1STEP 回転したのち、2 センサーンサーの電源管理を行った
うえで出力電圧の ADC が完全に終了するまでの流れを示している。まず、モーター制御部
ではサーボの挙動を管理している PWM 波形のパルス幅更新時間が 15ms 周期に 1 度とな
っており、これに加えてデータシートより 2.72 度回転するのにおよそ 5ms の時間を要する。
次に、150cm と 500cm のセンサでは互いに電源が OFF の状態から ON に移行し、出力が
安定状態となるまでに、最大で上記の時間を要する。これを総合した場合にモーター1
STEP 当たりの時間は最低限約 100ms となる。
第 2 案を起用した場合、図 3-6の様に各距離センサ間に傾斜をつけた板を挟むことによ
41
って距離センサからの赤外LEDの照射範囲をオーバーラップさせない様にする。
結果、1m 時点において赤外線スコープを用いて LED 照射範囲を観察したところ、○○の
ように検知範囲がオーバーラップしていない事が確認できる。しかしながら、センサ間に
角度を付けた場合に、回転ステップ毎に、各センサの被測定物が異なるという事態が発生
してしまう。また、1m 地点ではオーバーラップを回避するに十分な角度であっても、測定
物までの距離が伸びた場合に、再度オーバーラップしてしまう可能性が考えられる。
よって、これらの検証により、距離センサ間の相互干渉の回避には第 1 次案を採用する。
光の重心
正面
上部
光路角度差
図 3-6
相互干渉回避案 2
3-3 電圧読み込み精度向上検証
マイコンのADCの精度を向上させるためには、「ADC時Sleepモードを取り、外的要
因を極力減らす」、
「ADC比較用電圧をコンデンサ、コイル等で安定化を図る」などの方
法がある。これ以外の方法として各角度のAD変換結果を平均することによって、値の急
峻な変化に対応することが出来ると考える。よってセンサを同じ環境で複数回振り、出
力が安定化するか検証を行う。実験構成は図 2-32と同じく、幅 1.2mの屋内廊下におい
て、15 度~165 度間を、2.7 度間隔で 55 点取得を行う。得られた結果について 1 回~4
回平均化を行い図 3-7に実距離との誤差を図示する。
42
平均なし
平均1回
平均2回
平均3回
10%
誤差 (%)
5%
0%
-5%
-10%
0
30
60
90
120
150
180
回転角度 (Deg)
図 3-7 平均化による誤差収束検討
得られたグラフからわかる様に、「平均なし」データ 50 度、60 度付近の値が平均回
数 1~3 回の場合と比較し精度が向上している事が判る。しかしながら、全体の誤差の平
均の向上は見られないため、平均化は行わない事とする。
3-4 人の検出アルゴリズム
作成したセンサノードをモデルケースとして図 3-8のような個人の居室に設置、実
験を行った。
43
3.5m
机
イス
5m
机
回転
入口
センサノード
図 3-8
センサノード設置モデルケース
上記設置モデルにて無人時のデータを基準として、検知可能なパターンを示す。
図 3-9の様に人が検知範囲内に侵入した場合、図 3-10の様な出力がえら得られる。
44
人
回転
回転
入口
センサノード
入口
センサノード
無人状態
図 3-9
在室中
無人→人が侵入した場合
距離 (cm)
500
無人時
人有り
400
300
200
100
0
検知
モーションセンサ
未検知
0
30
60
図 3-10
90
角度 (Deg)
120
150
180
人の検出の決定例
出力結果グラフの破線部分から参照可能な様に、人は退席を持っているため、距離セン
45
サに反応し、また、熱を持っているためにモーションセンサで検知が行えている。この事
から、両センサで変化が起こった場合にのみ「人が在室している」という結論を下す事とし
ている。このアルゴリズムを用いれば、例えば、図 3-11の様な部屋内の体積の変化が無い
が、熱源が発生した場合、モーションセンサに反応があり、検知した物体を物と断定でき
る。出力波形は図 3-12に図示する。
暖房器具
暖房ON
回転
回転
入口
センサノード
入口
センサノード
無人状態
図 3-11
熱源発生
不在→熱源発生した場合
46
距離(cm)
500
無人時
熱源発生
400
300
200
100
0
検知
モーションセンサ
未検知
0
30
60
図 3-12
90
角度(Deg)
120
無人→熱源発生した場合の出力
47
150
180
3-5
作成したシステムの外観
本ソフトは機能別にタブで切り替える事が可能となっており、図は動作中の画面とな
る。他の HTML 作成部分は後述する。
図 3-13
在室確認システム概観
在室公開Webページ作成のためのJsファイル作成部分は、在室確認ソフトウェアのタブ
部分を切り替えた場所にあり、図 3-14の様になっている。
48
図 3-14
在室確認ページ生成タブ概観
また、実際に出力される在室公開ページは図 3-15に図示する。
49
図 3-15
Web 在室状況ページ
3-6 実用化実験
実際に数時間の運転をし、在室確認システムとして運用できるかの検証を行う。
作成したソフトには、1 分ごとの在室状況が外部にテキスト形式で保存さる様プログラム
を行っている。図 3-16にその出力例を示す。
50
在室管理システム
在室
不在
入退室記録
在室
不在
図 3-16
在室状況出力テキスト
測定は約 2 時間連続的に行い、何度か入退出を繰り返した。上記図より、入退室記録と在
室システムとの出力が同じであることを示している。また、前述したように設置環境にモ
ーションセンサの反応が全く見られない場合に、現在の環境の初期データを更新している
ためその旨が明記されている。同様にして、熱源(ヒーター)などをONにしたまま入退出を
繰り返したが、在室確認は問題なく行われた。しかしながら、設置環境の熱源よりモーシ
ョンセンサの反応が検知されるため、図 3-17の様に環境初期データの更新は行われない。
図 3-17
熱源(ヒータ)を設置した場合の在室確認
51
3-7 判断不可能な事例
3.7.1 熱源の移動
作成したシステムでは、そもそもモーションセンサのみでは、
「熱源を全て人と認識し
てしまうという」点を補うという意味合いで、距離センサとの相関を取ることとした。
しかしながら、このアルゴリズムであっても判断不能な条件があるためそれを記述する。
事例については図 3-18に図示し、その出力は図 3-19に示す。
暖房
暖房移動
回転
回転
入口
センサノード
入口
センサノード
無人状態
図 3-18
熱源移動
無人→熱源移動した場合
52
角度(Deg)
500
ヒーター移動
400
無人時
300
200
100
0
モーションセンサ
検知
未検知
0
30
60
図 3-19
90
距離(cm)
120
150
180
無人時→ヒータ移動後出力
出力の破線部分から参照可能な様に無人時の距離からヒータが移動した場合に検出距離に
変化が見られることが確認できる。しかしながら、加えて熱源に対してモーションセンサ
が反応しているため。提案したアルゴリズムを用いるならばこの事例には対処は事実上不
可能に思える。
しかしながら、解決策として最初に設置する場所に対して制約を設けて
やれば十分回避可能であると考える。例えば、このヒータ移動の事例では足元に設置して
いる温風ヒータが問題となっているため、その本体よりも高い場所にセンサノードを設置
してやれば十分回避可能である。
3.7.2 検知箇所の狭窄化によるデメリット
前述したとおり検知範囲を明確とするために、フレネルレンズを用いてモーションセンサ
の検知範囲の狭窄化を行った。この結果角度ごとにそのポイント毎の熱源の有無が明確と
なった。しかしながら、検知範囲を限られたポイントで指定しているために、在室者が動
き回った場合や、起立中の足などは検出可能面積が狭く検知出来ない場合が存在した。こ
の問題については、いつも検知出来ない訳ではないため、誤差範囲として在室判断を行う
間隔を長くすれば、問題の大きさは変って来る。
53
第4章
考察
提案した在室確認システムは、いくらかの制限要因はあるが、システムとして運用可能
な所まで検討が出来た。居室ではその所有者の座る場所などがいくらか限定されてくるた
め、導入時の設置場所にある程度気をつけてやれば十分実用は可能だと考える。
加えて、ヒータを移動させるとご認識を起こすが、そもそもヒータを稼動したまま退席
を行う場合は、少なくとも部屋主本人はすぐに戻ってくるつもりがあると考える。
り、在室判断間隔を長くする事によってこの問題の大きさは変ってくると考察する。
54
つま
第5章
まとめ
はじめに、複数のセンサを用いたセンシングについて検討を行い、センサ同士の相関を
得る事によって、人の検知が可能である事を示した。
また、センサの検知範囲について複数のセンサノードを設置しこれをカバーするのではな
く、搭載したセンサの検知範囲を広域化するべく検討し、実装を行った。センサノードに
求められる省電力化についての検討し、一般的なサーボモータを用いる事とした。次に、
考案した在室判断アルゴリズムを用いて、現実的な幾つかのパターンについて検証を行い、
検知不可能なパターンについて解決策を提示した。
最終的に、製作したシステムは、その設置環境に制約を設ける事で実用が可能である。
55
謝辞
本研究を行うにあたって、常日頃からご指導、その多大なる知識のご教示を賜
った電子・光システム工学科 岩下克教授に深く感謝致します。
また、副査として論文を精査して頂いた、綿森道夫教授、植田和憲講師に深く感謝
致します。
回路実装時における AVR や回路実装技術教示等でお世話になった
綿森研究室
車 載仁さんに深く感謝致します。
日頃から素晴らしい研究環境を作っていただいた同研究室メンバー
島村 卓嗣さん
恒安 宏一さん
速水佑治さん
中妻宏太さん
渡部隆寛さんまた
同研究室 4 年生の皆様に感謝意を表したいと思います。
また個別に、共同研究者である村井祐さんには互いに諦めず最後まで研究を行って
くださったことに対し、再度お礼を申し上げます。
56
参考文献
[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] 櫻井 他 “センサネットワークによる人の行動認識のための実験系の検討” 信学会
総合全大 A21-12 p.369(2005)
[5] 滝本 他 “無線センサネットワークを用いた動線検出システムの試作” 信学会 ソサ
エティ大 B-15-4 p.614(2003)
[6] 多木勝彦
高知工科大学
[7] 乾梨 紗
高知工科大学
位置情報管理システム
–センサネットワークの試作-
学位論文
位置情報管理システム -管理システムの設計-
学位論文
57
付録
センサノード内 PIC プログラムリスト
.include "m48def.inc"
;Mega48 定義ファイルをインクルード
.include "macro.inc"
;ピンアサイン
//
PB0
->
未定義
//
PB1
->
LED
//
PB2
->
未定義
//
PB3
->
未定義(プログラム時 MOSI)
//
PB4
->
未定義(プログラム時 MISO)
//
PB5
->
未定義(プログラム時 UCSK?)
//
PB6
->
未定義
//
PB7
->
未定義
//
PC0
<-
ADC0
//
PC1
<-
Motion センサー デジタル INPUT
//
PC2
<-
ADC2
//
PC3 ->
D_550 電源制御
150cm 取得
550cm 取得
//
PC4
->
D_150 電源制御
//
PC5
->
Motion 電源制御
//
PC6
->
未定義
//
PD0
<-
未定義(RxD)
//
PD1
->
未定義(TxD)
//
PD2
<- 割り込み PIN
//
PD3
->
未定義
//
PD4
->
未定義
//
PD5
->
未定義
//
PD6
->
未定義
//
PD7
->
未定義
.cseg
///////////////////////////////////////////////////////////
//変数宣言部
.def ZERO
=
R0
.def S_posH
=
R1
.def S_posL
=
R2
.def Rot_dir
=
R3
//Servo の ROTate_DIRection
.def Rot_Spd
=
R4
//Servo の ROTate_SPeeD
.def Rot_Step= R5
//Servo の Start_POStion
//Servo の ROTate_STEP
.def CNT1
=
R6
.def CNT2
=
R7
.def CNT3
=
R8
.def CNT4
=
R9
.def CNT5
=
R10
.def TEMP_H =
R11
//ソフトタイマ用カウンタ 1~5
//HEX2CHR で使用
.def TEMP_L =
R12
//
.def work
=
R16
//ワーキングレジスタ
.def TEMP1
=
R17
//Comp_Hex、Tx、Rx
.def TEMP2
=
R18
//CMD4
.def TEMP3
CMD3
=
R19
//CMD4 CMD3
.def RXDATA =
R20
//USART 受信データ格納
.def TXDATA =
R21
//USART 送信データ格納
//.def XL_TEMP =
R22
//.def XH_TEMP
=
.def Wid_L
=
R24
//PWM パルス幅 Low 格納
.def Wid_H
=
R25
//PWM パルス幅 High 格納
//26-31 X Y Z
// X movS2S 使用時
ADC2 結果ストア時
//
Y
Motion 結果ストア時
//
Z
ADC0 結果ストア時 Msg_out
//.def
//.def
///////////////////////////////////////////////////////////////
.org 0x00
rjmp
reset
rjmp
INT_INT0
;rjmp 相対ジャンプで Reset へ
//rjmp
int1
reti
//rjmp
int2
reti
//rjmp
int3
reti
//rjmp
int4
reti
//rjmp
int5
reti
//rjmp
int6
reti
//rjmp
int7
reti
//rjmp
int8
reti
//rjmp
int9
reti
//rjmp
intA
reti
//rjmp
intB
rjmp
INT_PWM
//rjmp
intC
reti
//rjmp
intD
reti
//rjmp
intE
reti
//rjmp
intF
reti
//rjmp
int10
reti
//rjmp
int11
rjmp
INT_Rx
//rjmp
int12
reti
//rjmp
int13
reti
//rjmp
int14
rjmp
INT_ADC
//rjmp
int15
59
reti
//rjmp
int16
reti
//rjmp
int17
reti
//rjmp
int18
reti
//rjmp
int19
///////////////////////////////////////////////////////////
//送信文字列テーブル
message0:
.db
"Mode0_Manual_Move... ",0
message1:
.db
"Mode1_Soft_Reset...",0
message2:
.db
"Mode2_Programed_move...",0
message3:
.db
"Mode3_General_Mode...",0
message4:
.db
"Quit ",0
message5:
.db
"Hello_Plz_input_Num_0-6... ",0x0d,0x0a,0
message6:
.db
"Mode4_SRAM_Outputing...",0
message7:
.db "END",0
message8:
.db "Out_of_Range...",0
message9:
.db "Mode5_OneOutPut_Send",0
Text1:
.db
"150cm = ",0
Text2:
.db
"500cm = ",0
Text3:
.db
"Motion = ",0
Text4:
.db "Light = ",0
/////////////////////////////////////////////
//外部入力ピン割り込み(Motion センサ接続)
INT_INT0:
reti
////////////////////////////////////////////
//PWM_OCR1C=TCNT1 コンペアマッチ割り込み
INT_PWM:
rcall
Chck_Lmt
//回転角リミッタ
sts
OCR1BH,Wid_H
sts
OCR1BL,Wid_L
INT_PWM_OFF
//OCRB1 割り込み不許可
reti
////////////////////////////////////////////
//受信データ割り込み 各 jump ルーチンへ
INT_Rx:
movS2S
//幅反映
RXDATA,UDR0
60
cpi
breq
RXDATA,'0'
CMD_0_jump
cpi
breq
CMD_1_jump
CMD_2_jump
RXDATA,'3'
RXDATA,'4'
//SRAM 列挙
RXDATA,'5'
CMD_5_jump
cpi
breq
//通常動作モード
CMD_4_jump
cpi
breq
//プログラム駆動モード
CMD_3_jump
cpi
breq
//リセットモード
RXDATA,'2'
cpi
breq
//手動駆動モード
RXDATA,'1'
cpi
breq
//AD1 件取得&送信
RXDATA,'6'
CMD_6_jump
//テストモード
reti
//////////////////////////////////////////////////////////////
//ADC 割り込み
INT_ADC:
//各所からの呼び出しにつき特別何も行わない。
reti
////////////////////////////////////////////////////////////
//コマンド選択 Jamp 部分
CMD_0_jump:
rcall
CMD_0
rjmp
END_CMD
CMD_1_jump:
rcall
CMD_1
rjmp
END_CMD
CMD_2_jump:
rcall
CMD_2
rjmp
END_CMD
CMD_3_jump:
rcall
CMD_3
rjmp
END_CMD
CMD_4_jump:
rcall
CMD_4
rjmp
END_CMD
CMD_5_jump:
rcall
CMD_5
rjmp
END_CMD
CMD_6_Jump:
rcall
//比較キャラ 0~6
CMD_6
61
rjmp
END_CMD
END_CMD:
CRLF
Msg_out
message4
CRLF
CRLF
Msg_out
message5
reti
/////////////////////////////////////////////////////////////
//モード 0 手動駆動モード
CMD_0:
Msg_out
message0
rcall
Rx
macro_Ecohback
cpi
RXDATA,'q'
breq
END_CMD_0
mov
work,RXDATA
rcall
Comp_STR
mov
Wid_H,Work
rcall
Rx
//q なら抜ける
//
//受信データ反映
macro_Ecohback
mov
work,RXDATA
rcall
Comp_STR
mov
Wid_L,Work
//受信データ反映
swap
Wid_L
//スワップし上位桁として格納
rcall
Rx
macro_Ecohback
mov
work,RXDATA
rcall
Comp_STR
add
Wid_L,work
ldi
TXDATA,0x0a
rcall
tx
//
//下位桁を加算
INT_PWM_ON
sei
//一時的に割り込み ON
62
rcall
delay_10m
rcall
delay_10m
rcall
delay_10m
//20m で割り込み 30m おいてみた。
cli
rjmp
//再度割り込み禁止
CMD_0
END_CMD_0:
ret
/////////////////////////////////////////////////////////////
//モード 1 ソフトウェアリセットモード
CMD_1:
Msg_out
message1
//"Mode1_Soft_Reset..." 送信
ldi
ZH,0x01
//SRAM 初期 0x100 格納
ldi
ZL,0x00
ldi
work,0x00
//SRAM 書込み値 0x00 格納
CMD_1__LOOP:
ST
cpi
brne
Z+,work
//SRAM をクリアし Z をインクリメント
ZH,0x02
//ZH コンペア 0x2XX ならZL 比較へブランチ
pc+3
cpi
ZL,0xFF
breq
CMD_1_END
rjmp
CMD_1__LOOP
//Z が 0x2FF なら終了
CMD_1_END:
rjmp
reset
/////////////////////////////////////////////////////////////
//モード 2 プログラム駆動モード
CMD_2:
Msg_out
message2
//Message2「Mode2_Programed_move...」送信
CRLF
in
work,portB
Andi
work,0b11111101
out
portB,work
//LED_OFF
INT_PWM_OFF
//OCR1B 割り込み不許可
INT_UART_OFF
//Tx,Rx 禁止 受信完了割り込み禁止
//使用センサ ALLOFF
iout
PORTC,0b11000000
//PC0(150),1(cds),2(500)をInput 3(Motion),4(550),5(150)
CMD_2__LOOP:
rcall
delay_1000m
//AD チャネル選択レジスタ設定
ists
ADMUX,0b01100001 //ADC1 使用
sei
63
iout
SMCR,0b00000011
//SLEEP 許可
SMCR,0b00000010
//SLEEP 禁止
SLEEP
iout
AD 開始
//SLEEP→ADC→ADC 完了割り込みへ
cli
LDS
work,ADCH
//ADC1 結果 8Bit のみを work へ
cpi
work,0x10
//0x10 以上なら復帰
brge
Sleep_Back
//
rjmp
CMD_2__LOOP
//それ以外の場合はループへ
Sleep_Back:
//センサ ON は行わない 各所で目的に応じて ON
INT_PWM_ON
//PWM 割り込み ON
INT_UART_ON
//UART 割り込み ON
iout
msg_out
portB,0b11111111
message4
CRLF
ret
//コマンドエンドへ
/////////////////////////////////////////////////////////////
//モード 3 通常駆動モード
CMD_3:
Msg_out
message3
imov
Rot_dir,0
//0=正転 1=逆転
imov
S_PosH,0x00
//モーター回転開始位置(0 度格納) 66
imov
S_PosL,0x59
//Low バイト格納
imov
Rot_Step,0x37
//移動ステップ数
imov
Rot_Spd,0x01
//基本 30m+2*10m=50m
//Dir データ格納
rcall
Rx
mov
work,RXDATA
rcall
Comp_STR
mov
Rot_Dir,work
//Pos データ格納 H→L
rcall
Rx
mov
work,RXDATA
rcall
Comp_STR
mov
S_PosH,work
rcall
Rx
//受信結果格納
64
Difo=55
mov
work,RXDATA
rcall
Comp_STR
mov
S_PosL,work
//受信結果格納
swap
S_PosL
//下位、上位入れ替え
rcall
Rx
mov
work,RXDATA
rcall
Comp_STR
mov
TEMP1,S_PosL
add
TEMP1,work
mov
S_PosL,TEMP1
//Step データ格納
rcall
Rx
mov
work,RXDATA
rcall
Comp_STR
mov
Rot_Step,work
//受信結果格納
swap
Rot_Step
//下位、上位入れ替え
rcall
Rx
mov
work,RXDATA
rcall
Comp_STR
mov
TEMP1,Rot_Step
add
TEMP1,work
mov
Rot_Step,TEMP1
//Spd データ格納
rcall
Rx
mov
work,RXDATA
rcall
Comp_STR
mov
Rot_Spd,work
//受信結果格納
swap
Rot_Spd
//下位、上位入れ替え
rcall
Rx
mov
work,RXDATA
rcall
Comp_STR
mov
TEMP1,Rot_Spd
add
TEMP1,work
mov
Rot_Spd,TEMP1
rcall
SubMain
ret
//コマンドエンドへ
///////////////////////////////////////////////////////////
65
//モード 4 SRAM レジスタ内送信モード
CMD_4:
Msg_out
message6
CRLF
mov
TEMP2,ZERO
//L 桁表示、開始は 0
mov
work,TEMP2
//0x00-0x00 を ASCII 変換
rcall
HEX2CHR
SPACE
SPACE
SPACE
CMD_4__INIT:
mov
TXDATA,TEMP_L
rcall
Tx
//LOW バイトのみ送信
SPACE
SPACE
cpi
TEMP2,0x0f
breq
CMD_4__LORD
inc
TEMP2
rjmp
CMD_4__INIT
//0x0f まで到達したら SRAM 送信 SEC へ
CMD_4__LORD:
CRLF
ldi
ZH,0x01
ldi
ZL,0x00
ldi
TEMP2,0x10
ldi
TEMP3,0x00
//文字数カウンタ
CMD_4__LORD__LOOP1:
//先頭に High バイト+16 バイトで折り返し。
mov
work,TEMP2
rcall
HEX2CHR
mov
TXDATA,TEMP_H
rcall
Tx
mov
TXDATA,TEMP_L
rcall
Tx
//0x10-0x2F までを ASCII 変換
//High バイト送信
//LOW バイト送信
SPACE
CMD_4__LORD__LOOP2:
cpi
TEMP3,0x10
breq
CMD_4_CRLF
LD
work,Z+
rcall
HEX2CHR
mov
TXDATA,TEMP_H
//17Chr 目なら改行
66
rcall
Tx
mov
TXDATA,TEMP_L
rcall
Tx
SPACE
inc
TEMP3
cpi
ZH,0x02
brne
pc+3
cpi
ZL,0xFF
breq
CMD_4_END
rjmp
CMD_4__LORD__LOOP2
CMD_4_END:
LD
work,Z
//最終 2FF だけ手動
rcall
HEX2CHR
mov
TXDATA,TEMP_H
rcall
Tx
mov
TXDATA,TEMP_L
rcall
Tx
ret
CMD_4_CRLF:
CRLF
inc
TEMP2
ldi
TEMP3,0x00
rjmp
CMD_4__LORD__LOOP1
///////////////////////////////////////////////////////////
//モード 5 ADC&Motion1 件取得送信モード
CMD_5:
msg_out
message9
CRLF
iout
PORTC,0b11101000
//PC0(150),1(cds),2(500)を Input 3(Motion),4(550),5(150)
//AD チャネル選択レジスタ設定
ists
ADMUX,0b01100000
//
||||||||_(0)MUX0ADC0 使用
//
|||||||_(1)MUX1
//
||||||_(2)MUX2
//
|||||_(3)MUX3
//
||||_(4)none
//
|||_(5)ADLAR
//
||_(6)REFS0
67
1 で AD 結果左揃え
//
|_(7)REFS1
ldi
rcall
AVCC、VCC と一緒
work,10
/電源投入時から 100ms
Delay_user
//AD チャネル選択レジスタ設定
ists
ADCSRA,0b10001000
//
||||||||_(0)ADPS0
//
|||||||_(1)ADPS1
//
||||||_(2)ADPS2
//
|||||_(3)ADIE
//
||||_(4)ADIF
//
|||_(5)ADATE
AD クロック CK/2
AD 割り込み許可
//
||_(6)ADSC
AD 開始ビット
//
|_(7)ADEN
AD 許可
ists
DIDR0,0b00000111
sei
iout
SMCR,0b00000011
//SLEEP 許可
SMCR,0b00000010
//SLEEP 禁止
Text1
//"150cm = "
LDS
work,ADCH
/AD 結果 8Bit のみを work へ
rcall
HEX2CHR
//16 進をキャラへ変換
mov
TXDATA,TEMP_H
rcall
Tx
mov
TXDATA,TEMP_L
rcall
Tx
SLEEP
iout
AD 開始
//SLEEP→ADC→ADC 完了割り込みへ
cli
//150cm 電圧送信
msg_out
CRLF
//500cm電圧送信
iout
PORTC,0b11011000
//(150),1(cds),2(500)を Input3(Motion),4(500),5(150)
//AD チャネル選択レジスタ設定
ists
ADMUX,0b01100010
//ADC2 使用
ldi
work,6
//電源投入時から 100ms
rcall
Delay_user
sei
iout
SMCR,0b00000011
//SLEEP 許可
SLEEP
iout
SMCR,0b00000010
//SLEEP 禁止
Text2
//"500cm = "
cli
msg_out
AD 開始
//SLEEP→ADC→ADC 完了割り込みへ
68
LDS
work,ADCH
//AD 結果 8Bit のみを work へ
rcall
HEX2CHR
//16 進をキャラへ変換
mov
TXDATA,TEMP_H
rcall
Tx
mov
TXDATA,TEMP_L
rcall
Tx
CRLF
/Cds 電圧送信
iout
PORTC,0b11001000 //C0(150),1(cds),2(500)を Input 3(Motion),4(550),5(150)
//AD チャネル選択レジスタ設定
ists
ADMUX,0b01100001
//ADC1 使用
SMCR,0b00000011
//SLEEP 許可
sei
iout
SLEEP
iout
D 開始
//SLEEP→ADC→ADC 完了割り込みへ
SMCR,0b00000010
//SLEEP 禁止
msg_out
Text4
//"Light = "
LDS
work,ADCH
cli
rcall
HEX2CHR
mov
TXDATA,TEMP_H
rcall
Tx
mov
TXDATA,TEMP_L
rcall
Tx
//AD 結果 8Bit のみを work へ
//16 進をキャラへ変換
CRLF
//Motion ON/OFF 送信
msg_out
Text3
in
work,PIND
andi
work,0b00000100
LSR
work
LSR
work
rcall
HEX2CHR
mov
TXDATA,work
rcall
Tx
//"Motion = "
//PD2 のみマスク
//PD2 の状態を右に 2 つシフトし 0x00 か 0x01 で表現
ret
///////////////////////////////////////////////////////////
//モード 6 テストモード
CMD_6:
rcall
Cds
ret
69
///////////////////////////////////////////////////////////
//ソフト or ハードリセット後開始位置
Reset:
//
iout
SPL,low(RAMEND)
//スタックポインタ領域設定
iout
SPH,high(RAMEND)
clr
ZERO
iout
DDRB, 0b11111111
iout
PORTB,0b11111111
iout
DDRC, 0b11111000
//PC0,1,2 を Input
iout
PORTC,0b11111000
//PC5,4,3 150,500,Motion
iout
DDRD, 0b11111010
iout
PORTD,0b01111010
//PD0 Rx PD2INT0&Motion
rcall
INIT_SRAM
//SRAM 初期化
rcall
INIT_USART
//USART 機能初期化
rcall
INIT_PWM
//PWM 機能初期化
rcall
INIT_ADC
//ADC 機能初期化
rjmp
main
/////////////////////////////////////////////////
//USART 初期化部分
INIT_USART:
ists
UBRR0L,25
sts
UBRR0H, ZERO
//19200 baud
INT_UART_ON
ret
/////////////////////////////////////////////////
//PWM 初期化部分
INIT_PWM:
ldi
wid_H,0
ldi
wid_L,0xC2
ists
OCR1AH,7
//Width を中央初期値セット
C2
//0x9C4=2500 2500*8u=20ms
//1875=753
ists
OCR1AL,0x53
ists
OCR1BH,0
ists
OCR1BL,68
ists
TCCR1A,0b00100011
//X*8u=1.496ms
//
||||||||_(0)WGM1_0
//
|||||||_(1)WGM1_1
70
高速 PWM
高速 PWM
//
||||||_(2)none
//
|||||_(3)none
//
||||_(4)COM1B0
//
|||_(5)COM1B1
//
||_(6)COM1A0
PWM 非反転動作
//
|_(7)COM1A1
PWM 非反転動作
ists
TCCR1B,0b00011011
//
||||||||_(0)CS10 64 分周
//
|||||||_(1)CS11
"
//
||||||_(2)CS12
"
//
|||||_(3)WGM12 高速 PWM
//
||||_(4)WGM13
//
|||_(5)none
//
||_(6)ICES1
PWM 非反転動作
//
|_(7)ICNC1
PWM 非反転動作
高速 PWM
INT_PWM_ON
ret
/////////////////////////////////////////////////
//ADC 初期化部分
INIT_ADC:
//AD チャネル選択レジスタ設定
ists
ADMUX,0b01100000
//
||||||||_(0)MUX0ADC0 使用
//
|||||||_(1)MUX1
//
||||||_(2)MUX2
//
|||||_(3)MUX3
//
|||_(4)none
//
||_(5)ADLAR
//
||_(6)REFS0
//
|_(7)REFS1
1 で AD 結果左揃え
AVCC、VCC と一緒
//AD チャネル選択レジスタ設定
ists
CSRA,0b10001000
//
||||||_(0)ADPS0
//
|||||||_(1)ADPS1
//
||||||_(2)ADPS2
//
|||||_(3)ADIE
//
||||_(4)ADIF
//
|||_(5)ADATE
//
||_(6)ADSC
AD 開始ビット
//
|_(7)ADEN
AD 許可
ists
DIDR0,0b00000101
71
AD クロック CK/2
AD 変換完了割り込み
ists
ADCSRB,0b00000000
iout
SMCR,0b00000011
//AD 連続変換 128 分周
//電力制御レジスタ設定
//
|||||||_(0)SE
SLEEP 許可は SLEEP 開始直前に行う
//
|||||||_(1)SM0
001 AD ノイズ低減動作
//
||||||_(2)SM1
//
|||||_(3)SM2
//
||||_(4)noen
//
|||_(5)none
//
||_(6)none
//
|_(7)none
sei
sleep
cli
iout
SMCR,0b00000010
LDS
ork,ADCH
//ADC1 結果 8Bit のみを work へ
ret
///////////////////////////////////////////////////////////
//MAIN ルーチン
MAIN:
sei
rjmp MAIN__LOOP
/////////////////////////////////////////////////
//スタッククリア
MAIN__INIT_SPL:
iout
SPL,low(RAMEND)
//スタックポインタ領域設定 H
iout
SPH,high(RAMEND)
msg_out
message5
MAIN__LOOP:
sei
MAIN__LOOP1:
sei
rcall
//受信割り込み&PWM 割り込み処理
Delay_10m
cli
INT_PWM_OFF
rcall
Cds
//明るさ監視
INT_PWM_ON
rjmp
MAIN__LOOP1
72
///////////////////////////////////////////////////////////
//サーボ回転ルーチン
SubMain:
CRLF
mov
Wid_H,S_posH
mov
Wid_L,S_PosL
//Wid_L 初期値格納
mov
TEMP2,RoT_Step
//比較用 TEMP 値格納
ldi
ZL,low(D150_DATA) //D150_DATA 先頭アドレス格納
ldi
ZH,High(D150_DATA)
//
ldi
YL,low(M_DATA)
//M_DATA 先頭アドレス格納
ldi
YH,high(M_DATA)
//
INT_PWM_ON
sei
rcall
delay_10m
rcall
delay_10m
//15m で割り込み 20m
cli
ldi
work,50
rcall
Delay_user
//0.5 秒待つ
SubMain__LOOP:
mov
work,ROT_DIR
cpi
work,0x00
brne
PC+2
adiw
Wid_H:Wid_L, 3
cpi
work,0x01
brne
PC+2
sbiw
Wid_L, 3
//回転方向確認 ROT_DIR=0x00 なら正転
//回転方向確認 ROT_DIR=0x01 なら逆転
INT_PWM_ON
sei
GIE 許可&禁止
rcall
delay_10m
rcall
delay_10m
//15m で割り込み 20m おいてみた。
INT_PWM_OFF
//回転終了確認
73
//センサ取得へ
//150cm 有効(500 無効)
iout
PORTC,0b11101000 //PC0,1,2 を Input 3(Motion ),4(550),5(150)
//AD チャネル 0 選択 150cm 計測
ists
DMUX,0b01100000
//
||||||||_(0)MUX0 ADC0 使用
//
|||||||_(1)MUX1
//
||||||_(2)MUX2
//
|||||_(3)MUX3
//
||||_(4)none
//
|||_(5)ADLAR
//
||_(6)REFS0
//
|_(7)REFS1
ldi
work,12
rcall
Delay_user
iout
1 で AD 結果左揃え
AVCC、VCC と一緒
//電源投入時から 60ms*2
SMCR,0b00000011
//SLEEP 許可
SLEEP
AD 開始
//SLEEP→ADC→ADC 完了割り込みへ
iout
SMCR,0b00000010
//SLEEP 禁止
rcall
ADC_ST
//ADC 結果判断&ストアルーチン
//500cm 有効(150 無効)
iout
PORTC,0b11011000 //PC0,1,2 を Input 3(Motion ),4(550),5(150)
//AD チャネル 2 選択 550cm 計測
ists
ADMUX,0b01100010
//
||||||||_(0)MUX0 ADC2 使用
//
|||||||_(1)MUX1
//
||||||_(2)MUX2
//
|||||_(3)MUX3
//
||||_(4)none
//
|||_(5)ADLAR
//
||_(6)REFS0
//
|_(7)REFS1
ldi
work,6
rcall
Delay_user
1 で AD 結果左揃え
AVCC、VCC と一緒
//電源投入時から 30ms*2
74
iout
SMCR,0b00000011
//SLEEP 許可
iout
SMCR,0b00000010
//SLEEP 禁止
rcall
ADC_ST
//ADC 結果判断&ストアルーチン
dec
TEMP2
//TEMP-1
cpi
TEMP2,0x00
//回転終了比較
breq
Sub__LOOP__END
//Z フラグでメインループへ
mov
work,Rot_Spd
//回転スピード格納→Work へ
rcall
Delay_user
//可変 UserDelay 呼び出し
rjmp
SubMain__LOOP
SLEEP
AD 開始
//SLEEP→ADC→ADC 完了割り込みへ
/////////////////////////////////////////////////
//ADC 完了割り込み後判断&ストアルーチン
ADC_ST:
movS2S
work,ADMUX
//ADMUX 状態を work へ
andi
work,(1<< MUX3) | (1<<MUX2) | (1<< MUX1) | (1<< MUX0)
cpi
work,0b00000000
breq
ADC_ST__ADC0
movS2S
work,ADMUX
andi
work,(1<< MUX3) | (1<<MUX2) | (1<< MUX1) | (1<< MUX0)
cpi
work,0b00000010
breq
ADC_ST__ADC2
//ADC0 使用
//ADMUX 状態を work へ
//ADC2 使用
ADC_ST__ADC0:
LDS
work,ADCH
//ADC0 結果 8Bit のみを work へ
ST
Z,work
//ADC0 結果ストア→Z をインクリメントしない
LDS
work,ADCH
//ADC0 結果 8Bit のみを work へ
adiw
Z,55
ST
Z+,work
subi
ZL,55
reti
ADC_ST__ADC2:
in
work,PIND
andi
work,0b00000100
LSR
work
LSR
work
ST
Y+,work
//ADC0 結果ストア→Z をインクリメント
//PD2 のみマスク
//PD2 の状態を右に 2 つシフトし 0x00 か 0x01 で表現
//PD2 状態をストア→Y をインクリメント
ret
75
Sub__LOOP__END:
rcall
send_pack
ret
//CMD3 へ戻る?
rjmp
MAIN__INIT_SPL
Str_out:
lpm
work,Z+
//message データを work へ Z は+1
cpi
work,0
//0 確認
breq
End_str
//String 終了
mov
TXDATA,work
rcall
Tx
rjmp
Str_out
//work 内データを TXDATA へ
End_str:
ldi
TXDATA,0x0A
rcall
tx
//LF コード送信
ret
//////////////////////////////////////////////////////////////
//取得済みデータ送信ルーチン
Send_pack:
mov
work,Rot_dir
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
mov
work,S_PosH
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
mov
work,S_PosL
mov
TEMP3,work
swap
work
andi
work,0x0F
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
andi
TEMP3,0x0F
mov
work,TEMP3
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
//下位桁のみマスク
76
mov
work,Rot_Step
mov
TEMP3,work
swap
work
andi
work,0x0F
rcall
Comp_Hex
//下位桁のみマスク
mov
TXDATA,work
rcall
tx
andi
TEMP3,0x0F
mov
work,TEMP3
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
mov
work,Rot_Spd
mov
TEMP3,work
swap
work
andi
work,0x0F
rcall
Comp_Hex
//下位桁のみマスク
mov
TXDATA,work
rcall
tx
andi
TEMP3,0x0F
mov
work,TEMP3
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
comma
ldi
ZL,low(D150_DATA)
//結果格納レジスタの初期アドレスを格納
ldi
ZH,high(D150_DATA)
//D550_DATA は D150_DATA に+55 で対応
ldi
YL,low(M_DATA)
ldi
YH,high(M_DATA)
ldi
TEMP2,0x00
///////////////////////////////////////////////////////////
//SRAM ストアデータ送信ルーチン
Send_pack__LOOP:
//Motion データ送信
LD
work,Y+
77
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
//150cm 距離センサ送信
LD
work,Z
mov
TEMP3,work
swap
work
andi
work,0x0F
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
andi
TEMP3,0x0F
mov
work,TEMP3
rcall
Comp_hex
mov
TXDATA,work
rcall
tx
//Z はインクリメントしない
//下位桁のみマスク
//550cm 距離センサ送信
add
ZL,ROT_STEP
LD
work,Z+
sub
ZL,ROT_STEP
mov
TEMP3,work
swap
work
andi
work,0x0F
rcall
Comp_Hex
mov
TXDATA,work
rcall
tx
andi
TEMP3,0x0F
mov
work,TEMP3
rcall
Comp_hex
mov
TXDATA,work
rcall
tx
//Z+ROT_STEP
//Z に戻す
//下位桁のみマスク
comma
mov
work,ROT_STEP
subi
work,1
cp
TEMP2,work
breq
End_Send_pack
inc
TEMP2
rjmp
Send_pack__Loop
//ROT_STEP-1 件送信
END_Send_pack:
msg_out
message7
78
ret
//////////////////////////////////////////////////////////////
//回転リミッタルーチン
Chck_Lmt:
mov
work,Wid_H
subi
work,0x02
brsh
Out_Range
cpi
Wid_H,0x00
brne
PC+4
mov
work,Wid_L
subi
work,0x4D
//work-46=?
brlo
Out_Range
//負なら範囲外
cpi
Wid_H,0x01
brne
PC+4
mov
work,Wid_L
//H が 0x00or0x01 以外ならレンジ外
subi
work,0x3F
brsh
Out_Range
//
//0x13F 以上ならレンジ外
ret
Out_Range://0x4A-13D の範囲外の場合 MAIN へジャンプ
rjmp
MAIN__INIT_SPL
//////////////////////////////////////////////////////////////
//USART 送受信ルーチン
Rx://movS2S 使用禁止(ZH、ZL 使用のため)
movS2S
work,UCSR0A
sbrs
work,7
rjmp
Rx
movS2S
RXDATA,UDR0
ret
Tx: movS2S
work,UCSR0A
sbrs
work,5
rjmp
Tx
sts
//UDRE0 送信準備完了フラグチェック
UDR0,TXDATA
ret
///////////////////////////////////////////////////////////
//16 進数データをキャラデータに変換 Work→TEMP_H TEMP_L
HEX2CHR:
mov
TEMP_H,work
//変換前データ格納
79
mov
TEMP_L,work
ldi
work,0xF0
and
TEMP_H,work
ldi
work,0x0F
and
TEMP_L,work
//下位桁マスク
swap
TEMP_H
//上位レジスタを反転
mov
work,TEMP_H
//上位バイト変換
rcall
Comp_Hex
mov
TEMP_H,work
mov
work,TEMP_L
rcall
Comp_Hex
mov
TEMP_L,work
//
//上位桁マスク
//下位バイト変換
ret
Comp_Hex:
//work→work に格納
cpi
work,0x00
breq
Comp_Hex__0_9
cpi
work,0x01
breq
Comp_Hex__0_9
cpi
work,0x02
breq
Comp_Hex__0_9
cpi
work,0x03
breq
Comp_Hex__0_9
cpi
work,0x04
breq
Comp_Hex__0_9
cpi
work,0x05
breq
Comp_Hex__0_9
cpi
work,0x06
breq
Comp_Hex__0_9
cpi
work,0x07
breq
Comp_Hex__0_9
cpi
work,0x08
breq
Comp_Hex__0_9
cpi
work,0x09
breq
Comp_Hex__0_9
cpi
work,0x0A
breq
Comp_Hex__A_F
cpi
work,0x0B
breq
Comp_Hex__A_F
//0→'0'へ
//1→'1'へ
//2→'2'へ
//3→'3'へ
//4→'4'へ
//5→'5'へ
//6→'6'へ
//7→'7'へ
//8→'8'へ
//9→'9'へ
//A→'A'へ
//B→'B'へ
80
cpi
work,0x0C
breq
Comp_Hex__A_F
cpi
work,0x0D
breq
Comp_Hex__A_F
cpi
work,0x0E
breq
Comp_Hex__A_F
cpi
work,0x0F
breq
Comp_Hex__A_F
//C→'C'へ
//D→'D'へ
//E→'E'へ
//F→'F'へ
ret
Comp_Hex__END:
ret
Comp_Hex__0_9:
ldi
TEMP1,0x30
add
work,TEMP1
rjmp
Comp_Hex__END
Comp_Hex__A_F:
ldi
TEMP1,0x37
add
work,TEMP1
rjmp
Comp_Hex__END
//かもしれない。
/////////////////////////////////////////////////////////
//文字データを数値データに変換
Comp_STR:
cpi
work,0x30
breq
STR_0_9
cpi
work,0x31
breq
STR_0_9
cpi
work,0x32
breq
STR_0_9
cpi
work,0x33
breq
STR_0_9
cpi
work,0x34
breq
STR_0_9
cpi
work,0x35
breq
STR_0_9
cpi
work,0x36
breq
STR_0_9
cpi
work,0x37
breq
STR_0_9
cpi
work,0x38
breq
STR_0_9
//"0"
//"1"
//"2"
//"3"
//"4"
//"5"
//"6"
//"7"
//"8"
81
cpi
work,0x39
breq
STR_0_9
cpi
work,0x41
breq
STR_A_F
cpi
work,0x42
breq
STR_A_F
cpi
work,0x43
breq
STR_A_F
cpi
work,0x44
breq
STR_A_F
cpi
work,0x45
breq
STR_A_F
cpi
work,0x46
breq
STR_A_F
//"9"
//"A"
//"B"
//"C"
//"D"
//"E"
//"F"
ret
//変換完了
STR_0_9:
subi
//アスキー→数値データへ処理
work,0x30
ret
STR_A_F:
subi
work,0x37
ret
///////////////////////////////////////////////////////////
//Cds セルポート ADC→判断ルーチン
Cds:
//AD チャネル 1 選択 Cds 計測
ists
DIDR0,0b00000111
ists
ADMUX,0b01100001
//
//ADC1 使用時 PINC1 はバッファ禁止
||||||||_(0)MUX0 ADC1 使用
//
|||||||_(1)MUX1
//
||||||_(2)MUX2
//
|||||_(3)MUX3
//
||||_(4)none
//
|||_(5)ADLAR
//
||_(6)REFS0
//
|_(7)REFS1
1 で AD 結果左揃え
AVCC、VCC と一緒
INT_PWM_OFF
iout
SMCR,0b00000011
//SLEEP 許可
AD 開始
sei
SLEEP
//SLEEP→ADC→ADC 完了割り込みへ
cli
iout
SMCR,0b00000010
//SLEEP 禁止
82
LDS
work,ADCH
cpi
work,0x01
brlo
Cds__low
rcall
Delay_10m
//ADC1 結果 8Bit のみを work へ
//0x01 以下なら分岐
INT_PWM_ON
ret
Cds__high:
ret
Cds__low:
rjmp
Cmd_2
//コマンド 2 実行
ret
///////////////////////////////////////////////////////////
//遅延時間生成サブルーチン
//8MHz=>0.125us
///*
Delay_user://10m* X とする
mov
CNT5,work
Delay_user__Loop:
rcall
Delay_10m
dec
CNT5
brbc
1,Delay_user__Loop
ret
Delay_1u://8 サイクル
3(rcall)+4(ret)+1=8
nop
ret
Delay_100u://800=72*8 +1(ldi)+72*[1(dec)+1(brbc)]+1(brbc 確定)+4(Ret)
imov
CNT1,0x48
loop_100u:
rcall
Delay_1u
dec
CNT1
brbc
1,loop_100u
ret
Delay_10m:
imov
CNT2,0x64
83
loop_10m:
rcall
Delay_100u
dec
CNT2
brbc
1,loop_10m
ret
Delay_100m:
imov
CNT3,0x0A
rcall
Delay_10m
dec
CNT3
brbc
1,loop_100m
loop_100m:
ret
Delay_1000m:
imov
CNT4,0x0A
rcall
Delay_100m
dec
CNT4
brbc
1,loop_1000m
loop_1000m:
ret
//SRAM 容量確保
.dseg
M_DATA: .byte 55
//モーションデータ用 55Byte
D150_DATA:
.byte 55
//150cm 距離センサ用 55Byte
D550_DATA:
.byte 55
//550cm 距離センサ用 55Byte
Motion_ON:
.byte 1
//Motion ON/OFF フラグ
84
1Byte
管理ソフトウェア プログラムリスト
Dim OpenFileName As String
'ファイル名
Dim ROT_DIR_Num As String
'回転方向
Dim START_DIG_Num As String
'回転方向
Dim DELAY_CNT_Num As String
'回転速度
Dim ROT_CNT_Num As String
'回転数
Dim Send_data As String
'送信文字列
Dim ReciveBox(56) As Object
'受信データ格納配列 設定+55点+ENDフラグ
Dim MotionOut(57) As String
'モーションセンサ出力格納配列
Dim MotionOut2(57) As String
Dim Dis150(56) As String
'150cm距離センサ出力格納配列
Dim Dis500(56) As String
'550cm距離センサ出力格納配列
Dim AvgTmp150(56) As String
'取得データ平均化用
Dim AvgTmp500(56) As String
Dim AvgCnt As Integer
'平均化回数
Dim ReciveString As String
'受信文字列格納変数
Dim CMD_MODE_F As Integer = 10 'コマンドモード一時保存
Dim CMD_MODE_Fix As Integer = 10 'コマンドモード状態保持
Dim lngPoint As Integer
'文字列検索フラグ
Dim SmpNum As Integer = 55
'サンプリング総数
Dim GraphicsMotion As System.Drawing.Graphics
'図形描画用
Dim PenColor1 As New System.Drawing.Pen(System.Drawing.Color.White, 2) '線色、白、太さ2
Dim Pencolor2 As New System.Drawing.Pen(System.Drawing.Color.Red, 1)
'線色、赤、太さ1
Dim Pencolor3 As New System.Drawing.Pen(System.Drawing.Color.Orange, 1) '線色、赤、太さ1
Dim GraphicsDistance As System.Drawing.Graphics
'距離線描画用
Dim GraphicsGrid As System.Drawing.Graphics
'グリッド線描画用
Dim Over150flagM As Boolean
Dim Under500flagM As Boolean
'HTML作成関連変数
Dim InputStr As String
'User.jsファイル内文字列
Dim JsStr(50) As String
'User.jsファイル内文字列分割
Dim SystemP(5) As Integer
'在室管理フラグ
Dim FileLen As Integer
'読み込みファイル行数
Dim HTML_Name As String
'作成HTML_URL
'在室確認ルーチン用変数
85
Dim DefEnv(56) As String
'無人時の環境格納配列
Dim NowEnv(56) As String
'現在の環境格納配列
Dim SysInitFlg As Boolean = False
Dim PreAvg As Integer
Dim Pre(1) As String
'確認システム初期化フラグ
'在室、不在確定のための確認カウンタ
'前回回転時の在室状況格納0=前、1=現在
Private UserBoxS() As System.Windows.Forms.TextBox
Public Property TextBoxText() As String
Get
Return comNum.Text()
End Get
Set(ByVal Value As String)
comNum.Text = Value
End Set
End Property
Public Property MScommConf_com() As Short
Get
Return AxMSComm2.CommPort
End Get
Set(ByVal Value As Short)
AxMSComm2.CommPort = Value
End Set
End Property
'
Public Property MScommConf_set() As String
Get
Return AxMSComm2.Settings
End Get
Set(ByVal Value As String)
AxMSComm2.Settings = Value
End Set
End Property
'Window読み込み時
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer
'繰り返し用変数
Dim temp(4) As String
'Temp
Dim StrLen As Integer
'取得文字長
Dim UserNum As String
'User数格納変数
Dim UserName(5) As String 'User名格納変数
Dim lngPoint As Integer '文字列検索ポイント
ROT_DIR.Items.Add("逆転")
'回転方向BOX初期値格納
ROT_DIR.Items.Add("正転")
86
'send_data_labelの初期値
If ROT_DIR.Text = "正転" Then
'正転の場合0
ROT_DIR_Num = "0"
Else
'反転の場合1
ROT_DIR_Num = "1"
End If
'MScomm初期設定
AxMSComm2.CommPort = 4
AxMSComm2.Settings = "19200,n,8,1"
AxMSComm2.Handshaking = AxMSComm2.Handshaking.comNone
AxMSComm2.RTSEnable = False
AxMSComm2.RThreshold = 1
AxMSComm2.SThreshold = 1
comNum.Text = AxMSComm2.CommPort.ToString
'現在の設定のCom番号表示
'設定タブの設定
'通信速度選択ボックスに値を読み込み
Speed.Items.Add(9600)
Speed.Items.Add(19200)
Speed.Items.Add(38400)
temp = Split(AxMSComm2.Settings, ",")
'Mscommの通信設定を読み込み','コードでセパレートし格
Speed.Text = temp(0)
'0番は速度
ComPort.Value = AxMSComm2.CommPort
'CommPort番号反映
納
'外部User.js読み込み
OpenFileName = "User.js"
FileOpen(1, OpenFileName, OpenMode.Input)
FileLen = 0
While Not EOF(1)
'読み込みファイル行数カウンタ初期化
'EOFまでループ
InputStr = InputStr + LineInput(1)
' 1行取得し格納
FileLen = FileLen + 1
End While
JsStr = Split(InputStr, ";")
';でスプリット
For i = 0 To FileLen - 1
jstxt.Text = jstxt.Text + JsStr(i) + ";" + Chr(13) + Chr(10)
Next i
'取得文字列内 "を省く
For i = 0 To FileLen - 1
87
JsStr(i) = Replace(JsStr(i), Chr(34), "")
Next i
FileClose(1)
'lngPoint = InStr(JsStr(0), "UserNum = ")
UserNum_box.Value = CInt(Mid(JsStr(0), Len("UserNum = ") + 1, 1)) 'User数取得反映
i = 0
lngPoint = InStr(JsStr(i + 2), "User[" & i & "] = ")
User1_box.Text = Mid(JsStr(i + 2), Len("User[" & i & "] = ") + lngPoint, 5)
i = 1
lngPoint = InStr(JsStr(i + 2), "User[" & i & "] = ")
User2_box.Text = Mid(JsStr(i + 2), Len("User[" & i & "] = ") + lngPoint, 5)
i = 2
lngPoint = InStr(JsStr(i + 2), "User[" & i & "] = ")
User3_box.Text = Mid(JsStr(i + 2), Len("User[" & i & "] = ") + lngPoint, 5)
i = 3
lngPoint = InStr(JsStr(i + 2), "User[" & i & "] = ")
User4_box.Text = Mid(JsStr(i + 2), Len("User[" & i & "] = ") + lngPoint, 5)
i = 4
lngPoint = InStr(JsStr(i + 2), "User[" & i & "] = ")
User5_box.Text = Mid(JsStr(i + 2), Len("User[" & i & "] = ") + lngPoint, 5)
HTML_Name = "C:\PC-02\多木さん作業用フォルダ\在室管理システム\2007.08.20 RS232C\bin\index.html"
HTML_Name_box.Text = HTML_Name
End Sub
'通信開始ボタン
Private Sub Conect_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
Conect_btn.Click
Try
AxMSComm2.PortOpen = Not AxMSComm2.PortOpen
If AxMSComm2.PortOpen = True Then
88
'各種ボタン設定
Conect_btn.Text = "通信停止"
Rot_Send_btn.Enabled = True
Button4.Enabled = True
WinClear.Enabled = True
AutoMove.Enabled = True
ReturnPos.Enabled = True
GraphClear.Enabled = True
comNum.Enabled = False
Speed.Enabled = False
ComPort.Enabled = False
OK_button.Enabled = False
'環境初期データ更新チェックタイマOFF
Timer2.Enabled = True
Else
'各種ボタン設定
Conect_btn.Text = "通信開始"
Rot_Send_btn.Enabled = False
Button4.Enabled = False
WinClear.Enabled = False
AutoMove.Enabled = False
ReturnPos.Enabled = False
GraphClear.Enabled = False
comNum.Enabled = True
Speed.Enabled = True
ComPort.Enabled = True
OK_button.Enabled = True
'環境初期データ更新チェックタイマOFF
Timer2.Enabled = False
End If
Catch ex As Exception
'エラー処理
If ex.Message = "HRESULT からの例外です : 0x800A1F42。" Then
TextBox2.AppendText("ERROR:ComPortがオープン出来ません" + Chr(13) + Chr(10))
Else
TextBox2.AppendText("* " & ex.Message + Chr(13) + Chr(10))
End If
Exit Sub
89
End Try
End Sub
'Mscommイベント発生時
Private Sub AxMScomm2_OnComm(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
AxMSComm2.OnComm
Dim Buffer As Object
'受信データ格納バッファ
Dim lngPointCMD As Integer
'コマンド返信文字列検索フラグ
Dim j As Integer
'繰り返し用変数
Dim i As Integer
'繰り返し用変数
Dim x As Integer
Dim Mode5_out(3) As String
'Mode5出力処理用
Select Case AxMSComm2.CommEvent
'CommEventにより各種分岐
Case CShort(MSCommLib.OnCommConstants.comEvCD)
Case CShort(MSCommLib.OnCommConstants.comEvCTS)
Case CShort(MSCommLib.OnCommConstants.comEvDSR)
Case CShort(MSCommLib.OnCommConstants.comEvRing)
Case CShort(MSCommLib.OnCommConstants.comEvReceive)
If CMD_MODE_F = 10 Then
'通常受信モード
Buffer = AxMSComm2.Input
TextBox2.AppendText(CStr(Buffer))
'受信バッファをそのつどTextBox2へ
ReciveString = ReciveString & CStr(Buffer)
'受信バッファをそのつどReciveString
へ連結
If lngPoint <> 0 Then
ReciveString = Nothing
End If
End If
'モードチェック 2,3,4,5,10(コマンド外)対応
lngPoint = InStr(ReciveString, "Mode")
If ReciveString = Nothing <> True Then
'文字列が空出なければモード選別
CMD_MODE_F = CInt(Mid(ReciveString, lngPoint + 4, 1))
CMD_MODE_Fix = CMD_MODE_F
'コマンドフラグが変化するのでCMD_MODE_Fixで保持
'ReciveString = Nothing
If CMD_MODE_F <> 3 And CMD_MODE_F <> 2 And CMD_MODE_F <> 4 And CMD_MODE_F <> 5 Then
CMD_MODE_F = 10
ReciveString = Nothing
90
End If
End If
'現在のモードより処理を選択
Select Case CMD_MODE_F
'MODE2_SLEEPの処理 Quitが来たら抜ける。
Case 2
Buffer = AxMSComm2.Input
ReciveString = ReciveString & CStr(Buffer)
lngPoint = InStr(ReciveString, "Quit")
If lngPoint <> 0 Then
MyPrint("SLEEPが解除されました。")
ReciveString = Nothing
CMD_MODE_F = 10
CMD_MODE_Fix = 10
End If
'Mode3_Generalの処理 ENDが来たら抜ける
Case 3
Buffer = AxMSComm2.Input
If CStr(Buffer) = Chr(10) Or CStr(Buffer) = Chr(13) Then 'バッファがCR又は、LFな
ら抜ける
Exit Sub
End If
lngPoint = InStr(ReciveString, "END")
If lngPoint <> 0 Then
Call CalArray()
'取得データ処理ルーチン呼び出し
CMD_MODE_F = 10
CMD_MODE_Fix = 10
Else
CMD_MODE_F = 10
'受信待機へ
End If
'Mode4_SRAM_Sendの処理 Quitが来たら抜ける。
Case 4
Buffer = AxMSComm2.Input
ReciveString = ReciveString & CStr(Buffer)
lngPoint = InStr(ReciveString, "Quit")
If lngPoint <> 0 Then
TextBox2.AppendText(ReciveString)
91
CMD_MODE_F = 10
CMD_MODE_Fix = 10
ReciveString = Nothing
End If
'Mode5_Sensor_Output_Sendの処理 Quitが来たら抜ける
Case 5
Buffer = AxMSComm2.Input
ReciveString = ReciveString & CStr(Buffer)
lngPoint = InStr(ReciveString, "Quit")
If lngPoint <> 0 Then
lngPoint = InStr(ReciveString, "150cm = ")
Mode5_out(0) = Mid(ReciveString, lngPoint + 10, 2)
lngPoint = InStr(ReciveString, "500cm = ")
Mode5_out(1) = Mid(ReciveString, lngPoint + 10, 2)
lngPoint = InStr(ReciveString, "Light = ")
Mode5_out(2) = Mid(ReciveString, lngPoint + 10, 2)
lngPoint = InStr(ReciveString, "Motion = ")
Mode5_out(3) = Mid(ReciveString, lngPoint + 10, 1)
CMD_MODE_F = 10
CalVol(Mode5_out, 0, 2)
'電圧変換ルーチン
MyPrint("150cm = " & Mode5_out(0) & "V")
MyPrint("500cm = " & Mode5_out(1) & "V")
MyPrint("Light = " & Mode5_out(2) & "V")
MyPrint("Motion = " & Mode5_out(3))
'センサ距離算出
x = CInt(Mode5_out(0))
Mode5_out(0) = CStr(19.751 * x ^ 6 - 198.46 * x ^ 5 + 799.72 * x ^ 4 - 1659.7
* x ^ 3 + 1897.7 * x ^ 2 - 1189 * x + 383.94)
x = CInt(Mode5_out(1))
Mode5_out(1) = CStr(43.765 * x ^ 6 - 427.45 * x ^ 5 + 1592.5 * x ^ 4 - 2825.3
* x ^ 3 + 2488.3 * x ^ 2 - 1246.5 * x + 684.81)
MyPrint("150cm= " & Mode5_out(0) & "cm")
MyPrint("500cm= " & Mode5_out(1) & "cm")
CMD_MODE_F = 10
CMD_MODE_Fix = 10
92
ReciveString = Nothing
'受信文字列初期化
End If
End Select
'コマンドモードを抜ける
Case CShort(MSCommLib.OnCommConstants.comEvSend)
Case CShort(MSCommLib.OnCommConstants.comEvEOF)
Case CShort(MSCommLib.CommEventConstants.comEventBreak)
MyPrint("中断信号")
Case CShort(MSCommLib.CommEventConstants.comEventFrame)
MyPrint("フレームエラー")
Case CShort(MSCommLib.CommEventConstants.comEventOverrun)
MyPrint("オーバーランエラー")
Case CShort(MSCommLib.CommEventConstants.comEventRxOver)
MyPrint("受信バッファオーバー")
Case CShort(MSCommLib.CommEventConstants.comEventRxParity)
MyPrint("受信パリティエラー")
Case CShort(MSCommLib.CommEventConstants.comEventTxFull)
MyPrint("送信バッファフル")
Case CShort(MSCommLib.CommEventConstants.comEventDCB)
MyPrint("DSB取得エラー")
Case Else
MyPrint("未定義エラー発生")
End Select
End Sub
'受信データ格納ルーチン
Sub CalArray()
Dim lngPoint As Integer
'文字列検索フラグ
Dim BeforOutput As Integer
'前受信パケット記憶変数
Dim temp(55) As String
'Temp用配列
Dim i, j As Integer
'繰り返し用変数
Dim x As Double
'距離計算近似式変数x
Dim GraphWidth As Single = CSng(PictureBox1.Width / 180)
Dim GraphHeigh As Single = CSng(PictureBox1.Height / 4 * 2)
Dim NowX, NowY As Single
'X,Y座標現在地
GraphicsMotion = PictureBox1.CreateGraphics
'グラフ描画ウインド宣言
GraphicsDistance = PictureBox2.CreateGraphics
MyPrint("ENDコード検知")
ReciveBox = Split(ReciveString, ",")
ReciveString = Nothing
'受信文字列初期化
93
If AvgCnt >= 1 Then
Call String2Array(ReciveBox, AvgTmp150, AvgTmp500, MotionOut, 1, SmpNum)
'逆回転の場合 降順、昇順を入れ替え
If ROT_DIR_Num = "1" Then
Call ReSortArray(MotionOut, 1, SmpNum)
Call ReSortArray(AvgTmp150, 1, SmpNum)
Call ReSortArray(AvgTmp500, 1, SmpNum)
End If
'150cmセンサの値を電圧値へ
Call CalVol(AvgTmp150, 1, SmpNum)
Call CalVol(AvgTmp500, 1, SmpNum)
For i = 1 To SmpNum
Dis150(i) = Dis150(i) + AvgTmp150(i)
Dis500(i) = Dis500(i) + AvgTmp500(i)
Next i
AvgCnt = AvgCnt - 1
If AvgCnt = 0 Then
For i = 1 To SmpNum
Dis150(i) = CStr(CDbl(AvgTmp150(i)) / AvgNum_box.Value)
Dis500(i) = CStr(CDbl(AvgTmp500(i)) / AvgNum_box.Value)
Next i
Else
CMD_MODE_F = 3
'コマンド受信モードへ
CMD_MODE_Fix = 3
'
lngPoint = 1
'変数初期化
ReciveString = Nothing
AxMSComm2.Output = "3"
Thread.Sleep(300)
AxMSComm2.Output = Send_data
Return
End If
Else
'ReciveBoxから値を取得し3つの配列へ
Call String2Array(ReciveBox, Dis150, Dis500, MotionOut, 1, SmpNum)
'逆回転の場合 降順、昇順を入れ替え
If ROT_DIR_Num = "1" Then
94
Call ReSortArray(MotionOut, 1, SmpNum)
Call ReSortArray(Dis150, 1, SmpNum)
Call ReSortArray(Dis500, 1, SmpNum)
End If
'150cmセンサの値を電圧値へ
Call CalVol(Dis150, 1, SmpNum)
'550cmセンサの値を電圧値へ
Call CalVol(Dis500, 1, SmpNum)
End If
'取得データをテキストに出力する。(電圧Ver)
'チェックボックスの確認
If FileoutCheck1.Checked = True Then
'ファイル名は現在時刻を参照
OpenFileName = "Vol" + DateTime.Now.Hour.ToString + DateTime.Now.Minute.ToString + "-" +
DateTime.Now.Second.ToString + ".txt" '保存ファイル名定義
FileOpen(1, OpenFileName, OpenMode.Append)
'距離センサ出力+モーションセンサ出力をファイルに書き出し
For i = 1 To SmpNum
PrintLine(1, Format(15 + 2.67 * i, "0##.0") & " " & Dis150(i) & " " & Dis500(i))
Next i
FileClose(1)
End If
'式より距離を算出
For i = 1 To SmpNum
x = CDbl(Dis150(i))
Dis150(i) = CStr(19.751 * x ^ 6 - 198.46 * x ^ 5 + 799.72 * x ^ 4 - 1659.7 * x ^ 3 + 1897.7 *
x ^ 2 - 1189 * x + 383.94)
Next i
For i = 1 To SmpNum
x = CDbl(Dis500(i))
Dis500(i) = CStr(43.765 * x ^ 6 - 427.45 * x ^ 5 + 1592.5 * x ^ 4 - 2825.3 * x ^ 3 + 2488.3 *
x ^ 2 - 1246.5 * x + 684.81)
'Dis500(i) = CStr(19.643 * x ^ 6 - 190.68 * x ^ 5 + 688.84 * x ^ 4 - 1121.4 * x ^ 3 + 810.13 *
x ^ 2 - 405.96 * x + 505.11)
Next i
'距離センサーリミッター
Call DisLim(Dis150, Dis500, 1, SmpNum)
95
'TexBox2に出力をリスト化
For i = 1 To SmpNum
MyPrint(Format(15 + i * 2.73, "0##.0") & "Deg= " & MotionOut(i) & " " & Format(CInt(Dis150(i)),
"##0") + "cm " & Format(CInt(Dis500(i)), "##0") + "cm")
Next i
'取得データをテキストに出力する。
'チェックボックスの確認
If FileoutCheck1.Checked = True Then
'ファイル名は現在時刻を参照
OpenFileName
=
DateTime.Now.Hour.ToString
+
DateTime.Now.Minute.ToString
+
"-"
+
DateTime.Now.Second.ToString + ".txt" '保存ファイル名定義
FileOpen(1, OpenFileName, OpenMode.Append)
'距離センサ出力+モーションセンサ出力をファイルに書き出し
For i = 1 To SmpNum
PrintLine(1, CStr(15 + 2.67 * i) & " " & MotionOut(i) & " " & Dis150(i) & " " & Dis500(i))
Next i
FileClose(1)
End If
BeforOutput = 0
'現在出力は0
'PicBOX1内モーションセンサ出力グラフ描画
NowX = CSng(PictureBox1.Width / 180 * 15)
NowY = CSng(PictureBox1.Height / 4 * 3)
For i = 1 To SmpNum
If MotionOut(i) = "0" Then
If BeforOutput = 0 Then
GraphicsMotion.DrawLine(PenColor1, NowX, NowY, CInt(NowX + GraphWidth * 2.7), NowY)
NowX = CInt(NowX + GraphWidth * 2.7)
Else
GraphicsMotion.DrawLine(PenColor1, NowX, NowY, NowX, NowY + GraphHeigh)
NowY = NowY + GraphHeigh
GraphicsMotion.DrawLine(PenColor1, NowX, NowY, CInt(NowX + GraphWidth * 2.7), NowY)
NowX = CInt(NowX + GraphWidth * 2.7)
End If
BeforOutput = 0 '現在の点は0
96
Else
If BeforOutput = 0 Then
GraphicsMotion.DrawLine(PenColor1, NowX, NowY, NowX, NowY - GraphHeigh)
NowY = NowY - GraphHeigh
GraphicsMotion.DrawLine(PenColor1, NowX, NowY, CInt(NowX + GraphWidth * 2.7), NowY)
NowX = CInt(NowX + GraphWidth * 2.7)
Else
GraphicsMotion.DrawLine(PenColor1, NowX, NowY, CSng(NowX + GraphWidth * 2.7), NowY)
NowX = CInt(NowX + GraphWidth * 2.7)
End If
BeforOutput = 1
'現在の点は1
End If
Next i
'PicBox2内距離センサ出力描画1
NowX = CSng(PictureBox2.Width / 180 * 15)
NowY = PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(Dis150(1)))
For i = 1 To SmpNum
GraphicsDistance.DrawLine(Pencolor2,
NowX,
NowY,
CInt(NowX
+
GraphWidth
*
2.67),
*
2.67),
PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(Dis150(i))))
NowX = CSng(NowX + GraphWidth * 2.67)
NowY = PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(Dis150(i)))
Next i
'PicBox2内距離センサ出力描画2
NowX = CSng(PictureBox2.Width / 180 * 15)
NowY = PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(Dis500(1)))
For i = 1 To SmpNum
GraphicsDistance.DrawLine(Pencolor3,
NowX,
NowY,
CInt(NowX
+
GraphWidth
PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(Dis500(i))))
NowX = CSng(NowX + GraphWidth * 2.67)
NowY = PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(Dis500(i)))
Next i
Dim temp1 As String
Dim temp2 As String
temp1 = Dis150(1)
temp2 = Dis500(1)
'PicBox2内距離センサ出力描画3
Call check(1, temp1, temp2, Over150flagM, Under500flagM)
97
NowX = CSng(PictureBox2.Width / 180 * 15)
If Over150flagM = True And Under500flagM = False Then '150cmセンサでオーバー 500cmセンサで普通
temp(1) = Dis500(1)
End If
NowY = PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(temp1))
'初期位置は判断後格納済み インデックスは1~smpNumまで
For i = 1 To SmpNum
temp1 = Dis150(i)
temp2 = Dis500(i)
Call check(1, temp1, temp2, Over150flagM, Under500flagM)
temp(i) = Dis150(i)
If Over150flagM = True And Under500flagM = False Then '150cmセンサでオーバー 500cmセンサで
普通
temp(i) = Dis500(i)
End If
Next i
j = 0
For i = 1 To SmpNum
If MotionOut(i) = "1" Then
j = j + 1
End If
Next
If j = 0 Then
SysInitFlg = False
'Motionセンサ反応なし 初期データ更新
MyPrint("環境初期データ更新")
OpenFileName = "presedence2.txt"
FileOpen(1, "presedence2.txt", OpenMode.Append)
PrintLine(1, "環境初期データ更新")
FileClose(1)
End If
'システム初期化フラグチェック
'1件目~SmpNumまで
For i = 1 To SmpNum
If SysInitFlg = False Then
98
DefEnv(i) = temp(i)
If i = SmpNum Then
'確定した距離を標準環境としてセーブ
'格納終了した場合に初期化フラグをON
SysInitFlg = True
End If
Else
NowEnv(i) = temp(i)
'初期化終了後はNowEnvへ格納
End If
Next i
For i = 1 To SmpNum
MotionOut2(i) = MotionOut(i)
Next i
For i = 1 To SmpNum
'実距離判断後描画へ
GraphicsDistance.DrawLine(PenColor1,
NowX,
NowY,
CInt(NowX
+
GraphWidth
*
2.67),
PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(temp(i))))
NowX = CSng(NowX + GraphWidth * 2.67)
NowY = PictureBox2.Height - CSng(PictureBox2.Height / 500 * CSng(temp(i)))
Next i
Call PresenceCheck()
'取得データをテキストに出力する。
'チェックボックスの確認
If FileoutCheck1.Checked = True Then
'ファイル名は現在時刻を参照
OpenFileName
=
DateTime.Now.Hour.ToString
+
DateTime.Now.Minute.ToString
DateTime.Now.Second.ToString + "距離精査後.txt" '保存ファイル名定義
FileOpen(1, OpenFileName, OpenMode.Append)
'距離センサ出力+モーションセンサ出力をファイルに書き出し
For i = 1 To SmpNum
PrintLine(1, CStr(15 + 2.67 * i) & " " & MotionOut(i) & " " & temp(i))
Next i
FileClose(1)
End If
FileClose()
ReciveString = Nothing
End Sub
99
+
"-"
+
'回転データ送信ボタン
Private Sub Rot_Send_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
Rot_Send_btn.Click
'回転データ送信ボタンクリック
Dim StringLen As Integer
'文字列の長さ取得
'Delay_BOX値*1000msを開始ディレイとする
MyPrint("回転開始Delay" & Delay_box.Value.ToString & "秒")
Thread.Sleep(1000 * CInt(Delay_box.Value))
MyPrint("スタート")
Call Mode3_Move()
AvgCnt = CInt(AvgNum_box.Value) '平均化回数格納
End Sub
'Windowクローズ時
Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
FileClose()
End Sub
'グラフ描画内容クリア
Private Sub GraphClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
GraphClear.Click
PictureBox2.Refresh()
PictureBox1.Refresh()
End Sub
'回転開始位置へ移動
Private Sub ReturnPos_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
ReturnPos.Click
Dim i As Short
Dim Send_data As String
'送信する文字列
Dim StringLen As Integer
'文字列の長さ取得
If ROT_DIR_Num = "1" Then
ROT_DIR_Num = "0"
ElseIf ROT_DIR_Num = "0" Then
ROT_DIR_Num = "1"
START_DIG_Num = CStr(Hex((START_DIG.Value + 4 * (ROT_CNT.Value) - 1)))
StringLen = Len(START_DIG_Num)
If StringLen = 1 Then
100
START_DIG_Num = "00" + START_DIG_Num
End If
If StringLen = 2 Then
START_DIG_Num = "0" + START_DIG_Num
End If
Send_data = ROT_DIR_Num + START_DIG_Num + ROT_CNT_Num + DELAY_CNT_Num + ","
TextBox2.AppendText("送信データ=" + Send_data & Chr(10))
AxMSComm2.Output = Send_data
End If
End Sub
'テキストウインドウ内クリア
Private Sub WinClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
WinClear.Click
TextBox2.Clear()
End Sub
'イベント Comポート番号変化
Private Sub comNum_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
comNum.TextChanged
If comNum.Text <> "" Then
AxMSComm2.CommPort = CShort(comNum.Text)
End If
End Sub
'送信Box内テキスト送信ボタン
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
Button4.Click
AxMSComm2.Output = Send_Text.Text
End Sub
'Tab2通信設定反映ボタン
Private Sub OK_button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim temp(3) As String
'MScomm.setting内容格納配列
AxMSComm2.CommPort = CShort(ComPort.Value) 'Comport番号反映
comNum.Text = ComPort.Value.ToString
'Comport番号表示反映
temp = Split(AxMSComm2.Settings, ",")
'Mscommの通信設定を読み込み','コードでセパレートし格
temp(0) = Speed.Text
'SPEED反映
納
AxMSComm2.Settings = temp(0) + "," + temp(1) + "," + temp(2) + "," + temp(3)
End Sub
'在室チェックルーチン
101
Sub PresenceCheck()
Dim Par As Double = CDbl(PrePar_box.Text) / 100 '設定タブより誤差値
Dim ParCal As Double
'算出誤差
Dim i, j As Integer
'繰り返しカウンタ
Dim k As Integer = 1
'時間経過カウンタ(iの値をセーブ)
Dim Preflg As Integer
'ルーチン内フラグ
If SysInitFlg = False Then
'システム初期化が行われているか?
MyPrint("無人時環境読込必要性有")
'未初期化の場合、メッセージを出してを抜ける
Exit Sub
End If
For i = 1 To SmpNum
ParCal = (CDbl(NowEnv(i)) / CDbl(DefEnv(i)) - 1) '誤差算出
If i - k > 2 Then
'前回誤差発生から3Step以上経過なら
j = 0
'jを初期化
k = i
'現在のiをkに保存
End If
If ParCal < Par Then
j = j + 1
'誤差が既定以上かチェック いじった
'jをインクリメント
If j > 2 Then
j = 0
End If
End If
If (j = 2 And MotionOut2(i) = "1") Or ((j = 2 And MotionOut2(i + 1) = "1")) Then
以上が連続する場合
SystemP(0) = 1
'在室フラグON
MyPrint((15 + i * 2.67) & "度付近に検出" & ParCal.ToString)
Preflg = Preflg + 1
OpenFileName = "Presence.txt"
FileOpen(1, OpenFileName, OpenMode.Append)
PrintLine(1, Date.Now & " " & (15 + i * 2.67) & "度付近に検出")
FileClose(1)
j = 0 'J初期化
End If
Next i
OpenFileName = "Presedence2.txt"
'在室状況をテキスト出力(毎回)
FileOpen(1, OpenFileName, OpenMode.Append)
'追記OPEN
If Preflg > 0 Then
102
'誤差既定
PrintLine(1, Date.Now & "在室中")
FileClose(1)
Pre(1) = "在室中"
Call CheckPreFin()
'在室状況最終判断
Else
PrintLine(1, Date.Now & "不在中")
FileClose(1)
Pre(1) = "不在中"
Call CheckPreFin()
'在室状況最終判断
End If
End Sub
'前回の在室状況と比較し2回連続であれば確定する。
Sub CheckPreFin()
If Pre(0) <> Pre(1) Then
Pre(0) = Pre(1)
Else
OpenFileName = "FinalPre.txt"
FileOpen(1, OpenFileName, OpenMode.Append)
PrintLine(1, Date.Now & Pre(1))
FileClose(1)
Pre(0) = Pre(1)
If Pre(1) = "在室中" Then
SystemP(0) = 1
ElseIf Pre(1) = "不在中" Then
SystemP(0) = 0
End If
'確定した在室状況を外部HTMLへ
Call TxtSaveSub()
If SystemP(0) = 0 Then
SysSta_lbl.Text = "不在中"
SysSta_lbl.ForeColor = Color.White
SysSta_lbl.BackColor = Color.Red
ElseIf SystemP(0) = 1 Then
SysSta_lbl.Text = "在室中"
SysSta_lbl.ForeColor = Color.White
SysSta_lbl.BackColor = Color.Blue
End If
103
End If
End Sub
'Tab1 手動在室チェック発動ボタン
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
Button3.Click
PresenceCheck()
End Sub
'Tab3 jstxt内容をUser.jsへセーブ
Private Sub TXTsave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
TXTsave.Click
Call TxtSaveSub()
End Sub
'テキスト作成セーブ
Sub TxtSaveSub()
Dim OutStr As String
Dim i As Integer
Dim System(2) As String
'システム状況
System(0) = "<b>不在</b>"
System(1) = "<b>在室</b>"
System(2) = "<b>未実装</b>"
'システム検知情報
'SystemP(0) = 1
SystemP(1) = 0
SystemP(2) = 0
SystemP(3) = 0
SystemP(4) = 1
OpenFileName = "User.js"
'JavaScript外部ファイル指定
FileOpen(1, OpenFileName, OpenMode.Output) '外部js 出力モードOPEN
JsStr = Split(InputStr, ";")
' ; でスプリット
For i = 0 To FileLen - 1
' ; を付加し格納し直し
JsStr(i) = JsStr(i) + ";"
Next
'ユーザー数 & ユーザーネーム格納
'コントロールを配列化
Me.UserBoxS = New System.Windows.Forms.TextBox(5) {}
104
UserBoxS(1) = User1_box
UserBoxS(2) = User2_box
UserBoxS(3) = User3_box
UserBoxS(4) = User4_box
UserBoxS(5) = User5_box
JsStr(0) = "UserNum = " & UserNum_box.Value & ";"
For i = 2 To 6
JsStr(i) = "User[i-2] = " & Chr(34) & UserBoxS(i - 1).ToString & Chr(34) & ";"
Next
'不在時(時間表記)、在室時(なし) 未実装時(なし)
For i = 0 To 4
If SystemP(i) = 0 Then
JsStr(12 + i) = "Away[" & i & "] = " & Chr(34) & DateTime.Now.ToString & Chr(34) & ";"
Else
JsStr(12 + i) = "Away[" & i & "] = " & Chr(34) & Chr(34) & ";"
End If
Next i
'更新時間格納
JsStr(23) = "myModify = " + Chr(34) + DateTime.Now.ToString & Chr(34) & ";"
For i = 0 To 4
JsStr(18 + i) = "SystemP[" & i & "] = " & CInt(SystemP(i)) & ";"
Next i
For i = 0 To FileLen - 1
OutStr = OutStr & JsStr(i) + Chr(13) + Chr(10)
Next i
Print(1, OutStr)
FileClose(1)
'User.js内容再度読み込み
FileOpen(1, OpenFileName, OpenMode.Input)
jstxt.Clear()
While Not EOF(1)
' EOFまでループ
jstxt.AppendText(LineInput(1) + Chr(13) + Chr(10))
End While
FileClose(1)
End Sub
105
'Tab3ShowHTMLボタン
Private Sub ShowHTML_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
ShowHTML.Click
'HTMLファイルを標準ブラウザを用いて表示
Dim Explorer As SHDocVw.InternetExplorer
Explorer = New SHDocVw.InternetExplorer
Explorer.Visible = True
Explorer.Navigate(HTML_Name)
End Sub
'テキスト追加ルーチン
Public Sub MyPrint(ByVal Str As String)
TextBox2.AppendText(Str + Chr(13) + Chr(10))
End Sub
'自動運転用タイマ開始ボタン
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
AutoMove.Click
If Timer1.Enabled = False Then
AutoMove.Text = "停止"
Timer1.Interval = CInt(AutoMoveDelay.Value * 1000)
Timer1.Enabled = True
'自動運転インターバル反映
'Timer1をイネーブル
Else
Timer1.Enabled = False
AutoMove.Text = "自動運転"
SysSta_lbl.Text = "システム停止中"
SysSta_lbl.ForeColor = Color.Black
SysSta_lbl.BackColor = SystemColors.ActiveBorder
End If
End Sub
'Timer1イベント 自動運転イベント発生
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If CMD_MODE_Fix = 2 Then
SysSta_lbl.Text = "システム休止中"
SysSta_lbl.ForeColor = Color.Black
SysSta_lbl.BackColor = SystemColors.ActiveBorder
MyPrint("システム休止")
OpenFileName = "FinalPre.txt"
FileOpen(1, OpenFileName, OpenMode.Append)
PrintLine(1, Date.Now & "システム休止中")
106
FileClose(1)
Else
'MyPrint("自動運転イベント発生")
Call Mode3_Move()
End If
End Sub
'Mode3回転用コード
Sub Mode3_Move()
Dim StrLen As Integer
If AxMSComm2.PortOpen = True Then
'ポート確認
AxMSComm2.Output = "3"
'Mode3選択
Thread.Sleep(300)
'300ms待ち
If ROT_DIR.Text = "正転" Then
'正転の場合0
ROT_DIR_Num = "0"
Else
'反転の場合1
ROT_DIR_Num = "1"
End If
START_DIG_Num = Hex(START_DIG.Text)
StrLen = Len(START_DIG_Num)
If StrLen = 1 Then
START_DIG_Num = "00" + START_DIG_Num
End If
If StrLen = 2 Then
START_DIG_Num = "0" + START_DIG_Num
End If
ROT_CNT_Num = Hex(ROT_CNT.Text)
StrLen = Len(ROT_CNT_Num)
If StrLen = 1 Then
ROT_CNT_Num = "0" + ROT_CNT_Num
End If
DELAY_CNT_Num = Hex(DELAY_CNT.Text)
StrLen = Len(DELAY_CNT_Num)
If StrLen = 1 Then
DELAY_CNT_Num = "0" + DELAY_CNT_Num
End If
107
Send_data = ROT_DIR_Num + START_DIG_Num + ROT_CNT_Num + DELAY_CNT_Num
MyPrint("送信データ=" + Send_data)
AxMSComm2.Output = Send_data
CMD_MODE_F = 10
CMD_MODE_Fix = 3
End If
End Sub
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
Dim i As Integer
Dim TimeStr As Object
'カウンタ
'時刻格納文字列
TimeStr = Date.Now.ToShortTimeString
MyPrint(CStr(TimeStr))
TimeStr = Split(CStr(TimeStr), Chr(58))
If Date.Now.ToShortTimeString = InitTime_box.Text Then
MyPrint("時刻イベント発生")
If CMD_MODE_Fix <> 2 Then
'モード2で無い場合
TimeStr(1) = CInt(TimeStr(1)) + 5
'5分後に再度確認
If CInt(TimeStr(1)) > 60 Then
'時間、分桁ともに60を越えたらインクリメント
TimeStr(1) = CInt(TimeStr(1)) - 60
TimeStr(0) = CInt(TimeStr(0)) + 1
End If
If TimeStr(0) > 24 Then
TimeStr(0) = CInt(TimeStr(0)) - 24
End If
InitTime_box.Text = (TimeStr(0) & ":" & TimeStr(1))
MyPrint("室内点灯中5分後に再度確認")
End If
'SLEEP中の処理 初期環境データ更新(初期化フラグは触らない)
For i = 1 To SmpNum
DefEnv(i) = NowEnv(i)
'現在の環境を初期環境にシフト
Next i
MyPrint("居室内消灯&設定時刻につき環境初期化")
End If
End Sub
End Class
108
管理ソフトウェア プログラムリスト(モジュール)
Module Module1
'出力チェックルーチン
Sub check(ByVal x As Integer, ByVal A As String, ByVal B As String, ByRef Over150flag As Boolean, ByRef
Under500flag As Boolean)
Over150flag = False
Under500flag = False
If CInt(A) >= 150 Then
'150cmセンサ150以上の場合
Over150flag = True
End If
If CInt(B) <= 100 Then
'500cmセンサ100cm以下の場合
Under500flag = True
End If
End Sub
'Oncommイベント内で使用 距離センサの距離リミッタ
Sub DisLim(ByRef DistanceA() As String, ByRef DistanceB() As String, ByVal x As Integer, ByVal Cnt As
Integer)
Dim i As Integer
For i = x To Cnt
If CInt(DistanceA(i)) > 150 Then
'
DistanceA(i) = "150"
ElseIf CInt(DistanceA(i)) < 20 Then
DistanceA(i) = "20"
End If
If CInt(DistanceB(i)) > 500 Then
DistanceB(i) = "500"
ElseIf CInt(DistanceB(i)) < 100 Then
DistanceB(i) = "100"
End If
Next i
End Sub
Sub ReSortArray(ByRef A() As String, ByVal x As Integer, ByVal Cnt As Integer)
Dim i As Integer
'カウンタ
Dim j As Integer = Cnt 'カウンタ
Dim Temp() As String
ReDim Temp(Cnt)
'配列容量確保
For x = i To Cnt
109
Temp(j) = A(i)
j = j - 1
Next x
j = 1
For x = i To Cnt
A(i) = Temp(j)
j = j + 1
Next
End Sub
'CalArray内 文字列よりデータを配列に取得
Sub String2Array(ByVal RevBox() As Object, ByRef DistanceA() As String, ByRef DistanceB() As String, ByRef
Motion() As String, ByVal x As Integer, ByVal Cnt As Integer)
'仕様 3種のセンサの文字列を配列へ x~Cnt回繰り返す。
Dim i As Integer
'カウンタ
For i = x To Cnt
Motion(i) = Mid(CStr(RevBox(i)), 1, 1)
DistanceA(i) = Mid(CStr(RevBox(i)), 2, 2)
DistanceB(i) = Mid(CStr(RevBox(i)), 4, 2)
Next i
End Sub
'CalArray内 対象配列を電圧に変換格納
Sub CalVol(ByRef Distance() As String, ByVal j As Integer, ByVal cnt As Integer)
Dim i As Integer
' カウンタ
Dim x As Double
'計算対象
For i = j To cnt
Distance(i) = "&H" & CStr(Distance(i))
Next i
'MsgBox(ReciveBox(i))
For i = j To cnt
Distance(i) = CStr(CInt(CDec(Distance(i))))
Next i
For i = j To cnt
Distance(i) = CStr(3.3 / 256 * CDbl(Distance(i)))
Next i
End Sub
End Module
110
Fly UP