自作!IOT指紋認証システム


自作!IOT指紋認証システム

(1)ESP8266の接続

ArduinoにESP8266を装着し、インターネットに無線接続して通信を行います。

ESP8266の接続の回路図

f:id:yukikoboelectronics:20200303182814p:plain



ESP-WROOM-02 (ESP8266 を内蔵)
ESP8266 は 32 bit Tensilica MCU (マイコン; MicroController Unit) を内蔵した WiFi モジュールです。更に ESP8266 を内蔵して作られたのが ESP-WROOM-02 です。ESP-WROOM-02 は日本での技適も取得済みのため安心して使用できます。SWITCH SIENCE 社から 1000 円程度で購入できます。通常の電子工作では以下のピッチ変換されたものを利用します。Amazon でもやはり SWITCH SCIENCE 社から販売されています。
ESP-WROOM-02ピッチ変換済みモジュール (シンプル版) にはピンヘッダは付属していません、別に購入してはんだ付けします。


(2)IFTTTについて

IFTTT (If This, Then That) は、もしも (if) ある入力 (this) があったならば、別のある出力処理 (that) を実行する多目的な Web サービスです。様々な入力方式 (if this) が提供されており、特にwebhooksを入力 (this) に指定して、Arduino からHTTP GET または POST でデータを送信することで IoT が実現できます。出力方式 (that) には Gmail, Twitter, スマホ通知 など様々なものが提供されています。

f:id:yukikoboelectronics:20200303182932p:plain


(3)IFTTTのアプレットの作成
まず、IFTTTのサイトにアクセスします。

f:id:yukikoboelectronics:20200303183049p:plain

 


Gmailで登録します。

f:id:yukikoboelectronics:20200303183135p:plain

 

するとさまざまな既成アルゴリズムが表示されますが、下にスクロールして、「Create your own」をクリックします。

f:id:yukikoboelectronics:20200303183332p:plain


すると、次の画面になるので、まず、「This」をクリックします。

f:id:yukikoboelectronics:20200303183427p:plain


『webhooks』と入力して検索します。

f:id:yukikoboelectronics:20200303183535p:plain



「webhooks」をクリックします。 

f:id:yukikoboelectronics:20200303183632p:plain



つぎに、このトリガー(アルゴリズムの開始合図)に名前を付けます。
このアルゴリズムに名前をつけ(ここでは『fingerprint0002』) 、下の「Create trigger」をクリックします。この名前は「Event name」とよばれ、『then that』で作成するフィールドの名称になり、また、「sheet name」にもなります。

f:id:yukikoboelectronics:20200303183721p:plain

次にこの画面になるため、【このようにする】という部分を作成するため、「that」を選択します。

f:id:yukikoboelectronics:20200303183841p:plain



Googleスプレッドシート」に書き込みため、「that」には、「Google sheets」と打ち込み、検索して選択します。

f:id:yukikoboelectronics:20200303183922p:plain



Google sheets」をクリックします。

f:id:yukikoboelectronics:20200303184005p:plain



古いバージョンのIFTTTを使っている人は、「that」の部分については、以下になります。
「ウェブリクエストを受け取る」トリガーを選択します。
検索で「Google Sheets」と入力します。
スプレッドシートに行を追加する」選択します。
ここで、スプレッドシートの名前を書き換えます。
フォルダの名前は空白のままにしておきます。

つぎに、「that」の部分について、すこし細かい設定をIFTTT側で行う必要があります。
「Formatted row」の部分を下の写真のように変えてください。名前は自分のものでお願いします。

「Drive folded path」は空白にしてください。

f:id:yukikoboelectronics:20200303184052p:plain

以上で設定は終了です。

f:id:yukikoboelectronics:20200303184133p:plain
「connect」をクリックします。
この自分の作ったアルゴリズムには、画面右上の自分のアカウントの下の、「My Applets」から入れます。

 

(4)Arduinoのプログラム
機械側のプログラムは以下の通りです。
Arduino IDEで開いて、動かしてください。
変更しなければならないところは、日本語で記載されています。
****の箇所は、自分のパスワードなどを入れてください。


#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#include <Adafruit_Fingerprint.h>
// On Leonardo/Micro or others with hardware serial, use those! #0 is green wire, #1 is white
// uncomment this line:
// #define mySerial Serial1
// For UNO and others without hardware serial, we must use software serial...
// pin #2 is IN from sensor (GREEN wire)
// pin #3 is OUT from arduino (WHITE wire)
// comment these two lines if using hardware serial
SoftwareSerial mySerial(2, 3);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
#include <HttpClient_ESP8266_AT.h>
int a = 0;
void setup(){
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("ready ");
delay(3000);
Serial.begin(9600);
delay(100);
Serial.println("\n\nAdafruit finger detect test");
// set the data rate for the sensor serial port
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1) { delay(1); }
}
finger.getTemplateCount();
Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");
Serial.println("Waiting for valid finger...");
lcd.print("go go go ");
}
void loop() // run over and over again
{
SoftwareSerial mySerial(2, 3);
getFingerprintIDez();
delay(50); //don't ned to run this at full speed.
}
uint8_t getFingerprintID() {
uint8_t p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.println("No finger detected");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK success!
p = finger.image2Tz();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK converted!
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK) {
Serial.println("Found a print match!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find a match");
return p;
} else {
Serial.println("Unknown error");
return p;
}
// found a match!
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
// Arduino UNO の場合は、例えばデジタル入出力の 2 番, 3 番ピンを利用して→4,5に変更
// ESP-WROOM-02 とシリアル通信するように設定します。
const byte rxPin = 4; // Wire this to Tx Pin of ESP8266 TXD端子をデジタル4番に
const byte txPin = 5; // Wire this to Rx Pin of ESP8266 RXD端子をデジタル5番に
HttpClient_ESP8266_AT httpClient(rxPin, txPin);
// PC と通信する HardwareSerial の baudrate を設定します。
// ESP-WROOM-02 の baudrate とは関係ありません。
delay(1000);
Serial.begin(9600);
// SSID と PASSWORD でアクセスポイントに接続します。
// シリアル接続確認と WiFi 接続確認を行い、設定不備があれば出力します。
while(true) {
if(httpClient.statusAT()) {
Serial.println("AT status OK");
break;
}
else {
Serial.println("AT status NOT OK");
}
delay(1000);
}
while(true) { // 書き換えてください↓
if(httpClient.connectAP("401HWa-BF5A22", "1957874a")) { Serial.println("Successfully connected to an AP"); break; }
else Serial.println("Failed to connected to an AP. retrying...");
delay(1000);
}
while(true) {
if(httpClient.statusWiFi()) { Serial.println("WiFi status OK"); break; }
else Serial.println("WiFi status NOT OK");
delay(1000);
}
// ノイズの影響でリクエストに失敗することがあるため while ループで囲います。
while(true) {
// IFTTT への HTTP POST リクエストを実行します。SSL/TLS 通信である必要はなく 80 番ポートを利用できます。
// 以下の二つの項目は、お使いのアカウントで表示されているものに書き換えてください。
// - Event Name: arduino_esp8266_gmail
// - Key: sw8UBoTxxKAykBbG7y_8H
a = finger.fingerID;
httpClient.post("maker.ifttt.com", // IFTTT のホスト名
"/trigger/peach/with/key/dt3OOb3pA-LQoaKniDylK", // <- 書き換えてください。
"{\"value1\":\"" + String(a) + "\",\"value2\":\"123\",\"value3\":\"456\"}", // JSON データ
"application/json");
// レスポンス status code が 0 以上であればリクエスト成功です。
// -1: ノイズ等でシリアル通信ができず、そもそもデータ送信ができなかった。
// 0: データ送信はできたが、受信データがノイズで壊れてしまっていた。
// else (>0): 受信データから正常に HTTP レスポンス status code が得られた。
if(httpClient.responseStatusCode() >= 0) {
// 本ページでは電圧レベルシフタを用意していない想定のため、
// 受信データが壊れている可能性が高く、したがって 200 が 100 になっていたりするため、
// 値には興味をもたず、0 以上の値が得られることが重要であると考えてコーディングします。
Serial.println("SUCCESS1");
lcd.print(" ID ");
lcd.print(finger.fingerID);
lcd.print(" confirmed");
break; // 成功したので while を抜けます。
}
else {
Serial.println("FAILURE, retrying...");
}
}
return finger.fingerID;
}
// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
uint8_t p = finger.getImage();
if (p != FINGERPRINT_OK) return -1;
p = finger.image2Tz();
if (p != FINGERPRINT_OK) return -1;
p = finger.fingerFastSearch();
if (p != FINGERPRINT_OK) return -1;
// found a match!
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
// Arduino UNO の場合は、例えばデジタル入出力の 2 番, 3 番ピンを利用して→4,5に変更
// ESP-WROOM-02 とシリアル通信するように設定します。
const byte rxPin = 4; // Wire this to Tx Pin of ESP8266
const byte txPin = 5; // Wire this to Rx Pin of ESP8266
HttpClient_ESP8266_AT httpClient(rxPin, txPin);
// PC と通信する HardwareSerial の baudrate を設定します。
// ESP-WROOM-02 の baudrate とは関係ありません。
delay(1000);
Serial.begin(9600);
// SSID と PASSWORD でアクセスポイントに接続します。
// シリアル接続確認と WiFi 接続確認を行い、設定不備があれば出力します。
while(true) {
if(httpClient.statusAT()) {
Serial.println("AT status OK");
break;
}
else {
Serial.println("AT status NOT OK");
}
delay(1000);
}
while(true) { // 書き換えてください↓
if(httpClient.connectAP("401HWa-BF5A22", "1957874a")) { Serial.println("Successfully connected to an AP"); break; }
else Serial.println("Failed to connected to an AP. retrying...");
delay(1000);
}
while(true) {
if(httpClient.statusWiFi()) { Serial.println("WiFi status OK"); break; }
else Serial.println("WiFi status NOT OK");
delay(1000);
}
// ノイズの影響でリクエストに失敗することがあるため while ループで囲います。
while(true) {
// IFTTT への HTTP POST リクエストを実行します。SSL/TLS 通信である必要はなく 80 番ポートを利用できます。
// 以下の二つの項目は、お使いのアカウントで表示されているものに書き換えてください。
// - Event Name: arduino_esp8266_gmail
// - Key: sw8UBoTxxKAykBbG7y_8H
a = finger.fingerID;
httpClient.post("maker.ifttt.com", // IFTTT のホスト名
"/trigger/peach/with/key/dt3OOb3pA-LQoaKniDylK", // <- 書き換えてください。
"{\"value1\":\"" + String(a) + "\",\"value2\":\"A\",\"value3\":\"1\"}", // JSON データ
"application/json");
// レスポンス status code が 0 以上であればリクエスト成功です。
// -1: ノイズ等でシリアル通信ができず、そもそもデータ送信ができなかった。
// 0: データ送信はできたが、受信データがノイズで壊れてしまっていた。
// else (>0): 受信データから正常に HTTP レスポンス status code が得られた。

if(httpClient.responseStatusCode() >= 0) {
// 本ページでは電圧レベルシフタを用意していない想定のため、
// 受信データが壊れている可能性が高く、したがって 200 が 100 になっていたりするため、
// 値には興味をもたず、0 以上の値が得られることが重要であると考えてコーディングします。
Serial.println("SUCCESS2");
lcd.print(" ID ");
lcd.print(finger.fingerID);
lcd.print(" confirmed");
void(* resetFunc) (void) = 0;
break; // 成功したので while を抜けます。
}
else {
Serial.println("FAILURE, retrying...");
}
}
return finger.fingerID;
}


ライブラリが足りないと言われたら、「スケッチ」から「ライブラリをインクルード」を選択します。
なければ、GitHubからダウンロードしたものを、インストールします。

(5)参考ウェブサイト

プログラムとライブラリのインストール方法について
https://www.qoosky.io/techs/14bfffdc82
グーグルスプレッドシートへの書き込みについて
https://raspberry-pi.nomad-life.net/1914277/memo/ifttt

 

 

「MoNoWIRELESS(TWE-Lite-2525A とMoNoStick)」を使って「自動で動物の動きの検出と記録」ができる機械の電子工作と失敗しやすい落とし穴の回避方法まとめ。

 

 

MoNoWIRELESS」を使って「自動で動物の動きの検出と記録」ができる機械を電子工作します。『TWE-Liteではじまる「センサー」電子工作(工学社)』の失敗しやすい落とし穴の回避方法についてもまとめてみました。

 

MoNoWIRELESSとは、TWE-Lite-2525A とMoNoStickからなる計測・無線通信機器です。

TWE-Lite-2525Aは、一円玉の大きさの無線マイコンです。

MoNoStickは、USB接続できるTWE-Liteの親機・中継機です。

本機器(MoNoWIRELESSのシステム)の特徴は、パソコンなどに、低価格で測定データを無線でCOMポートから取得でき、簡単にPython(一般的な科学技術計算のプログラム)で取り込んで解析できることです。

f:id:yukikoboelectronics:20171229180158p:plain

 

MoNoWIRELESS社のHPより

https://mono-wireless.com/jp/products/TWE-Lite-2525A/index.html

 

 

 

著者らは、これまで、マウスの動きを自動的に検出して記録するなどの目的で、本機器の利用について検討してきました。

従来、このような場面ではFrame-DIAS(イプロス社)などを利用したビデオ解析が中心でした。しかし動画を人手で確認して追う作業があり、あまりざっくりとした動きの解析では手間が目立つものでした。

本機器では、自動化によってそれらの手間が省かれます。それだけでなく、はるかに安価でコストも抑えられると考えられます。

 

著者らの作業の目的は、マウスの位置を自動的に検知し記録するため、マウスの背部にTWE-Lite-2525Aを付着し、それから発せられる電波の強度をMoNoStickでパソコンに取得させ、Pythonで解析し、それをエクセルでグラフィックスに表示・保存することです。

 

著者らは、『TWE-Liteではじまる「センサー」電子工作(工学社)』を参照し、その記載にしたがって作業を進めてきました。

同書は初学者でもわかりやすい優れた内容ですが、実際の作業を進めるうえで、不明点やややこしい点がありましたので、それを補い解説してまとめてみました。

これから著者らと同様の作業をされる方々の参考になれれば幸いです。

 

 

 

(1)無線タグアプリ(通常モード)に変換する手順

 

https://mono-wireless.com/jp/products/TWE-APPS/App_Tag/download.html

を開いてください。

 

f:id:yukikoboelectronics:20171229180958p:plain

 

 

画面下にスクロークして1.6.2の親機・子機用をクリックしてダウンロードします。

 

次に、MoNoStickをUSBポートに挿入します。

 

f:id:yukikoboelectronics:20171229181002p:plain

TWE-Lite専用プログラムをダウンロードします。

続いて、プログラムを起動します。

その際、App_Tag_EndDevice_Input_JN5164_OTA_1_6_2.binを選択します。

終了後、画面のTWE-Liteのリセットをクリックします。

 

通信ソフト「Tera Term」を起動して、設定をクリックします。

シリアルポートをクリックしてボードのコム番号を調整してOKを押します。

Enterを押します。

「o」のkey(小文字)を押して1を打ちます。Enterを押します。

(これで通常モードに変更完了です。)

「s」のkey(大文字)を押します。(これで保存終了です。)

 

電池を抜いたTWE-Lite-2525AをMoNoStickに1cmぐらいまで近づけます。その状態で電池を入れます。一瞬赤色と黄色のLEDが点滅します。(これで転送終了です。)

 

TWE-Lite専用プログラムを起動します。

App_Tag_Parent_JN5164_MONOSTICK_1_6_2.binを選択します。

終了後、画面のTWE-Liteのリセットを押します。

(これで無線タグアプリに入れ替え完了です。)

 

 

(2)Simple Tag V3形式に変換する方法

 

Tera Termを起動して+を3回ゆっくり押す。

「o」のkey(小文字)を押して21と打ちます。Enterを押します。(変更完了です。)

「s」のkey(大文字)を押します。(保存終了です。)

 

 

(3)Python のインストールの方法

 

https://www.python.org/ の画面のdownload をクリックします。下にスクロールして

「Download Python 3.6.1」を選択して、クリックします。

後は手順に従ってインストールします。

 

 

(4)pySerial のインストールの方法

 

https://pypi.python.org/pypi/pyserial/2.7の画面で、

表の一番下のfor Python 3.x (3.0...3.4)がついているfileをクリックしてダウンロードします。

 

 

 

 

 

「ゾーン確定リアルタイム」プロジェクト

  

目標物が、3つのゾーン(zone1,zone2,zone3)のどこのゾーンにいるのか、そして、そのゾーンの中心に近づいているのか、それとも中心から遠ざかっていくのかをリアルタイムで表示するものです。(電波強度値で表示)

また、目標物が激しい加速度運動をした場合には警告音がなるというものです。

 

import winsound

winsound.Beep(2000,100)

import re, serial

# COM5を開く

s = serial.Serial(4, 115200)

nearest = ""

nearestkyoudo = ""

ax = 0

ay = 0

az = 0

aa = 0

maxlqi = 0

oldtm = 0

counter = 0

spot1 = 11111111111111111

spot2 = 222222222222222222222222222222222222222

spot3 = 333333333333333333333333333333333333333333333333333333333333333333

 

while 1:

    aa = ax*ax+ay*ay+az*az

    # 1行読み取る

    data = s.readline()

    # 「;」で分割する

    m = str(data).split(";")

    tm = int(m[1])

    if (len(m) == 16):

        id = int(m[4])

        lqi = int(m[3])

        if (lqi > maxlqi) :

            maxlqi = lqi

            nearest = m[2]

            nearestkyoudo = m[3]

            ax = int(m[12])

            ay = int(m[13])

            az = int(m[14])

    if (oldtm != tm) :

        counter = counter + 1

    if (counter >= 5) :

        counter = 0

        maxlqi = 0

    if (nearest == "00000000") :

        print(spot1)

   # 下の"010□□□□□" にspot2のMoNoStickのID番号を入れてください。

    if (nearest == "010□□□□□") :

        print(spot2)       

     # 下の"010□□□□□" にspot3のMoNoStickのID番号を入れてください。

if (nearest == "010□□□□□") :

        print(spot3)       

 

    print(nearestkyoudo)   

    print(aa)

    print()

    if (aa > 20000) :

        winsound.Beep(2000,1500)

    oldtm = tm

s.close()

 

 

追加 「グラフ化」について

 

①     グラフを表示するためには、matplotlibをインストールする必要があります。

pythonでpipを使って行う場合は、その命令を書くのはPCのコマンドプロンプト(画面下左端のwindow10のマークをクリックして「すべてのアプリ」の「Windowsシステムツール」の中にある「コマンドプロンプト」をクリックすれば起動します。)で行います。

②グラフを自動更新させる場合はpythonプログラム中のshow()をpause(0.1)にする必要があります。

 

「エクセル活用によるゾーン滞在分析」プロジェクト

 

目標物が、設定時間内において、3つのゾーン(zone1,zone2,zone3)のどのゾーンに長く滞在していたのか、そのゾーンの中心にどのくらい接近していたのか(電波強度値で表示)を設定時間経過後にエクセルを利用してグラフ化分析する方法を考えました。

 

 

import re, serial

 

# COM5を開く

s = serial.Serial(4, 115200)

nearest = ""

nearestkyoudo = ""

number = ""

maxlqi = 0

oldtm = 0

counter = 0

spot1 = 1

spot2 = 2

spot3 = 3

number1 = 1001

 

while 1:

    # 1行読み取る

    data = s.readline()

    #「;」で分割する

    m = str(data).split(";")

    tm = int(m[1])

    if (len(m) == 16):

        id = int(m[4])

        lqi = int(m[3])

        if (lqi > maxlqi) :

            maxlqi = lqi

            nearest = m[2]

            nearestkyoudo = m[3]

            number = m[5]

    if (oldtm != tm) :

        counter = counter + 1

    if (counter >= 5) :

        counter = 0

        maxlqi = 0

  # 下の"10□□□□□"には2525Aのシリアル番号をいれてください。

if (number == "10□□□□□") :

        print(number1)

    if (nearest == "00000000") :

        print(spot1)

    if (nearest == "010□□□□□") :

        print(spot2)       

    if (nearest == "010□□□□□") :

        print(spot3)       

 

    print(nearestkyoudo)

    print()

    oldtm = tm

s.close()

 

測定分析方法

 

上のプログラムを実行後、表示されたデータを作成したエクセルシートのシート1の黒ワク内に貼り付けると自動的にグラフ化します。

 

注意点 実行終了は、USB口からStickをぬいて終了してください。そうすることによりデータが画面に残ったままになります。

 

f:id:yukikoboelectronics:20171230203455p:plain

 

作成したエクセルシートについて

 

①     実行後、適当な所で、パソコンにつないでいるStickをそっと水平にぬきます。

②     エラーが出て止まるのでデータをコピーしてSheet1の表(黒ワク内)に貼り付けます。

③     ゾーンと接近度(電波強度)のグラフが表示されます。

④     データ活用版のみ2525Aのシリアル番号を区別する数字(1001など)が画面に出ます。2525Aを複数台使うとき(複数の目標物の移動を調べるとき)、どの2525Aからのデータか区別するためです。

 

 

 

グラフの設定について

ゾーン確定のグラフでは

①     データ範囲は黒ワク全部です。上のグラフでは1~600番です。

②     グラフの種類は散布図です。

③     縦軸は最小1最大3と手動で設定します。

 

接近度のグラフでは

①     データ範囲は黒ワク全部です。上のグラフでは1~600番です。

②     グラフの種類は散布図です。

③     縦軸は最小50最大300と手動で設定します。

 

 

 

 

 

座標確定プロジェクト

 

MonoStickと2525Aを使って、目標物の平面座標(x,y)を確定する方法を考えました。

 

(1)  理論

 

MonoStickから1mの距離に目標物があるときの電波強度をkとし、

ある位置に目標物があるときのStick1,2,3それぞれの電波強度をk1,k2,k3とすると、

電波強度は距離の2乗に反比例するので、

各Stickからの目標物の距離a, b, c は

a=(k/k1)1/2     b=(k/k2)1/2     c=(k/k3)1/2    ……(0)

で表すことができます。

Stick1,2,3のx-y座標を(0,0),(L,0),(0,L)に設定し、求めたい目標物のx-y座標を(x,y)とすると

x2+y2=a2                ……(1) 

(x-L)2+y2=b2         ……(2)

(1)-(2)より

x=(a2-b2+L2)/2L  ……(3)

(1)より

|y|=(a2-x2)1/2     ……(4)

また

x2+(y-L)2=c2なので

x2+(|y|-L)2=cp2         ……(5)

x2+(-|y|-L)2=cq2        ……(6)

とおくと

cpがcqよりcに近い値のとき、すなわち|cp2-c2|≧|cq2-c2|のとき、y=|y|

cがcよりcに近い値のとき、すなわち|cp2-c2|<|cq2-c2|のときy=-|y|

より

∴ (cp2-c2)2≧(cq2-c2)2のとき、y=|y|    ……(7)

(cp2-c2)2<(cq2-c2)2のときy=-|y|    ……(8)

 

(0), (3),(4),(5),(6),(7),(8)で目標物の座標(x,y)を確定することができます。単位はm(メートル)です。

 

ただし、実際のプログラムでは、電波強度と距離の間に誤差が生じるため、(4)の(    )内が負になる場合には|y|=0として計算しています。

 

 

(2)  プログラムについて

 

理論をもとに、プログラムは以下のようになります。

 

import re, serial

# COM5を開く

s = serial.Serial(4, 115200)

s1 = 0

s2 = 0

s3 = 0

a = 0

b = 0

c = 0

l = 0.4000000000

k = 140

j = 0

y1 = 0

while 1:

    print()

    print()

    print()

    x = (a*a-b*b+l*l)/(2*l)

    y = (a*a-x*x)**(1/2)

    if x > a :

        y = 0

    cp2 = x*x+(y-l)*(y-l)

    cq2 = x*x+(-y-l)*(-y-l)

    j = (cp2-c*c)*(cp2-c*c)-(cq2-c*c)*(cq2-c*c)

    if 0 < j :

        y1 = -y

    else:

        y1 = y

    print( int(x*100) )

    print( int(y1*100) )

    print()

   

    data = s.readline()

   

    m = str(data).split(";")

    

    if (m[2] == "00000000") :

        s1 = int(m[3])

        a = (k/s1)**(1/2)

    

    if (m[2] == "010□□□□□") :

        s2 = int(m[3])

        b = (k/s2)**(1/2)

    if (m[2] == "010□□□□□") :

        s3 = int(m[3])

        c = (k/s3)**(1/2)

     

s.close()

 

 

 

 

 

 

(3)  測定方法について

 

Stick1を親機(座標(0,0))とし、Stick2,3は子機で座標(L,0),(0,L)とします。

室内で測定する場合はL=2[m]となるように3つのStickを部屋の中央に配置します。

広い室内及び屋外で測定する場合はL=5[m]となるように配置します。

室内、屋外とも、障害物がない空間(ただ広い空間)ほど障害物による電波強度への影響が少なくなるので、より精度の高い測定を行うことができると思います。

f:id:yukikoboelectronics:20171229180502p:plain

 

 

今回の電子工作では、じつは日立ソリューションズなどの開発した製品

http://www.hitachi-solutions.co.jp/company/press/news/2016/0831.html

を将来的な目標にして製作しました。

では、今回の完成品は製品と比べてどうかということですが、、、

今回の電子工作では、コストは1万円以下で製品と比べ、非常に安価である反面、やはり動作性に不安定であり、製品のようなクオリティにはまだまだ時間がかかりそうです。。。

 

伝送時間差のばらつき(5~10秒)、座標の不正確(平均誤差10~50%。50㎝~200㎝の距離で測定)、エラーの頻発(多くは接続不良)などといった問題を克服していく必要があります。

 

参考;上記の日立ソリューションズのHPより

 

f:id:yukikoboelectronics:20171231180531p:plain

f:id:yukikoboelectronics:20171231180541p:plain

f:id:yukikoboelectronics:20171231180550p:plain

 

全体を通して、何分、素人工作で恥ずかしい限りですが、改良点のアドバイスなどコメント欄にいただければ大変助かります。質問等もできるだけお答えできればと思いますので、同様にコメント欄へよろしくお願いいたします。

 

この章段の最後までお読みいただきありがとうございました。

皆さんの機械がうまく作動するよう願っています。