2022年4月21日木曜日

MONOSTICKとTWELITE DIPと土壌水分センサーを使用して、水分を計測する

TWELITE製品を使用して、無線を活用した電子工作を簡単に行うことができます。MONOSTICKとTWELITE DIPと土壌水分センサーを使用して、水分を計測するには、以下の手順を実行します。
土壌水分センサーには、DFRobotの静電容量式土壌水分センサーを使用します。

〇MONOSTICKとTWELITE DIPと土壌水分センサーの写真

twelite側の手順

1. 部品の準備
MONOSTICK/TWELITE DIPの他、以下の部品を準備します(適宜単3電池2つが入る電池ボックス等も準備してください)

・静電容量式土壌水分センサー
https://akizukidenshi.com/catalog/g/gM-13550/

・片面ガラス・ユニバーサル基板 Cタイプ(72×47.5mm) めっき仕上げ
https://akizukidenshi.com/catalog/g/gP-00517/

・XCL103使用3.3V出力昇圧DCDCコンバーターキット
https://akizukidenshi.com/catalog/g/gK-16116/

・丸ピンICソケット (28P) 600mil 桟ありタイプ
https://akizukidenshi.com/catalog/g/gP-00033/
 ※tweliteを基盤に直にハンダ付けしたくない場合はこちらを使用します。

・ピンヘッダ 1×40 (40P)
https://akizukidenshi.com/catalog/g/gC-00167/
 ※静電容量式土壌水分センサーのコネクタに接続するために3つに切って使用します。

2. 配線
以下の回路図に基づいて、上記の部品を配線します。

3.以下のページからTWELITE STAGE SDKをダウンロード
https://mono-wireless.com/jp/products/stage/index.html

4.ダウンロードしたファイル名を/optなどに移動して、解凍します(以下はMWSTAGE-2021-12_linux-1.zipの場合)
unzip MWSTAGE-2021-12_linux-1.zip

5.以下のようなシェルを作成し、TWELITE STAGEを起動します。実行後/dev/ttyUSB0が消えますので、MONOSTICKやTWELITEを抜き差ししてください。
※/optにインストールした場合、適宜パスは読み替えてください(Ubuntu 20.04で動作確認)
runtw.sh
#!/bin/bash
sudo rmmod usbserial
sudo rmmod ftdi_sio
/opt/MWSTAGE/TWELITE_Stage.run

sudo chmod +x ./runtw.sh

sudo ./runtw.sh

TWELITE STAGE起動後は、各デバイスの初期設定を行います。
・MONOSTICK
アプリを出荷時から書き換えていた場合は、App_Wingsアプリのイメージに更新します。
Application IDを任意の数値に設定します(例: 0x11223344 -> 入力時は0xを省いて11223344)

・TWELITE DIP
アプリを出荷時から書き換えていた場合は、App_Tweliteアプリのイメージに更新します。
Application IDは通信するためにMONOSTICKと同じIDを指定します
Device ID: 任意の値(1や2など)

PC側の操作手順

1.pipenvのインストール
pipenvをインストール済みでない場合は、以下のコマンドでインストールします。
sudo apt-get -y install python3

sudo pip3 install --upgrade pip

sudo pip3 install --upgrade setuptools

sudo pip3 install pipenv

echo "export PIPENV_VENV_IN_PROJECT=true" >> ~/.bashrc

source ~/.bashrc

2. pyserialのインストール
以下のコマンドでpyserialをインストールした仮想環境を作成します
mkdir twelite
cd twelite
pipenv --python 3

pipenv install pyserial

pipenv shell

3. 以下のように相手端末からの状態通知データをシリアル通信で受信してパースするサンプルプログラムを作成して、実行します。
※データ構造についての詳細は以下を参照してください。
https://mono-wireless.com/jp/products/TWE-APPS/App_Twelite/step3-81.html

twelite_analog1.py
import serial
import time
import datetime

def parse_notification(line):
  if line[0:1] != ':'.encode('utf-8'):
    return []
  # 送信元のデバイスID(1byte)
  device_id = line[1:3]
  # コマンド(1byte)
  command = line[3:5]
  # パケット識別子(1byte)
  packet_id = line[5:7]
  # プロトコルバージョン(1byte)
  protocol_version = line[7:9]
  # LQI値(1byte)
  lqi = line[9:11]
  # 送信元の個体識別番号(4byte)
  source_id = line[11:19]
  # 宛先の論理デバイスID(1byte)
  logical_device_id = line[19:21]
  # タイムスタンプ(2byte)
  ts = line[21:25]
  # 中継フラグ(1byte)
  relay_flag = line[25:27]
  # 電源電圧mV(2byte)
  power_voltage = int(line[27:31],16)
  # 未使用(1byte)
  reserved = line[31:33]
  # DIの状態ビット(1byte)
  di1 = (True if int(line[33:35], 16) & 0x01 != 0 else False)
  di2 = (True if int(line[33:35], 16) & 0x02 != 0 else False)
  di3 = (True if int(line[33:35], 16) & 0x04 != 0 else False)
  di4 = (True if int(line[33:35], 16) & 0x08 != 0 else False)
  # 変更状態ビット(1byte)
  mf1 = (True if int(line[35:37], 16) & 0x01 != 0 else False)
  mf2 = (True if int(line[35:37], 16) & 0x02 != 0 else False)
  mf3 = (True if int(line[35:37], 16) & 0x04 != 0 else False)
  mf4 = (True if int(line[35:37], 16) & 0x08 != 0 else False)
  # AD1-AD4の変換値(各1byte)
  ad1 = int(line[37:39], 16)
  ad2 = int(line[39:41], 16)
  ad3 = int(line[41:43], 16)
  ad4 = int(line[43:45], 16)
  # AD1-AD4の補正値(1byte)
  cd = int(line[45:47], 16)
  adv1 = (ad1 * 4 + (cd & 0x03))*4
  adv2 = (ad2 * 4 + ((cd >> 2) & 0x03))*4
  adv3 = (ad3 * 4 + ((cd >> 4) & 0x03))*4
  adv4 = (ad4 * 4 + ((cd >> 6) & 0x03))*4
  # チェックサム(1byte)
  csv = line[47:49]
  cs = format(256-(sum([ int(line[li:li+2], 16) for li in range(1, len(line)-2, 2) ]) & 0x000000ff), '02x')
  csr = True if csv.lower() == cs else False
  result = {"device_id":device_id, "command":command, "packet_id":packet_id, "protocol_version":protocol_version, "lqi":lqi, "source_id":source_id, "logical_decice_id":logical_device_id,"ts":ts, "relay_flag":relay_flag, "power_voltage":power_voltage, "di1":di1, "di2":di2, "di3":di3, "di4":di4, "mf1":mf1, "mf2":mf2, "mf3":mf3, "mf4":mf4, "adv1":adv1, "adv2":adv2, "adv3":adv3, "adv4":adv4, "csr":csr}
  return result

ser = serial.Serial(port='/dev/ttyUSB0',baudrate=115200,timeout=10)
try:
  while True:
    rl = ser.readline()
    print(rl)
    result = parse_notification(rl)
    if "adv1" in result:
      print(datetime.datetime.now())
      print("AI1:{}".format(result["adv1"]))
      #print("AI2:{}".format(result["adv2"]))
except KeyboardInterrupt:
  # close
  print("stopped.")
finally:
  ser.close()

・実行コマンド
python twelite_analog1.py

コップの水などに水分センサーを入れ、アナログ値が低下する事を確認します。

0 件のコメント:

コメントを投稿