1 - 用語解説

TWELITEに関連する用語を解説します。

1.1 - IEEE802.15.4とは

IEEE802.15.4の意味
IEEE802.15.4とはワイヤレスセンサーネットワークの構築に適した無線規格です。双方向通信が可能でセンサーからの情報を収集または端末デバイスのリモートコントロールに使用します。

特徴

IEEE802.15.4の特徴は以下の通りです。

国際標準規格

IEEE802.15.4とは米国に本部を有するIEEE(アイ・トリプルイー)により策定された標準規格です。標準であることにより1社の独自規格に依存することなく複数のベンダーから規格に基づいた製品が供給されるため安定性を確保できます。2.4GHz帯のISMバンドを使用した場合は日本国内だけでなく世界中で販売可能です。

双方向デジタル通信

IEEE802.15.4は2.4GHz帯の変調方式にOffset Quadrature Phase Shift Keying (O-QPSK)、拡散方式にスペクトラム拡散方式(DSSS)を採用しており妨害ノイズに強く安定したデジタル双方向通信を行えます。

暗号化通信

IEEE802.15.4ではインターネットバンキングやインターネットショッピングにも採用されている強力な暗号化技術128ビットAES暗号によりデータ通信のセキュリティが保たれています。

低消費電力

IEEE802.15.4の設計思想として消費電力を小さくしていることが挙げられます。電池交換なしで年単位の駆動や、コイン電池での駆動、光、熱、振動等から電力を得る環境発電素子(エナジーハーベスター)での駆動が可能です。これにより従来設置が困難であった場所で無線の使用が可能になります。

低速度

IEEE802.15.4は無線LANやBluetoothに比べ通信速度を抑えています。これはワイヤレスセンサーネットワークに最適化した通信速度(250kbps)にすることにより低消費電力と高い通信感度を実現するためです。低速度と表現していますがセンサーネットワークの構築に必要十分な速度を確保しています。

標準プロトコル

IEEE802.15.4は、ZigBeeアライアンスやThread GroupをはじめIETF等の多数の標準化団体によりワイヤレス通信の物理層として採用されています。IEEE802.15.4上で種々の標準通信プロトコルが実装されています。このように通信プロトコルを自由に選択できることもIEEE802.15.4の特徴の一つです。IEEE802.15.4は無線センサーネットワークに柔軟に対応できます。

仕様

利用周波数帯2.4GHz世界中で使用可能
チャンネル数1616Ch同時通信可能
変調方式Q-PQSK, DSSSノイズに強い
伝送速度250kbpsセンサーネットワークに最適化
消費電流(通信時)<30mA低消費電力
暗号化AES-128ビット強力なセキュリティを使用可能
ネットワークノード数65535大規模ネットワークに対応

IEEE802.15.4 のデータフレーム

以下に IEEE 802.15.4 のデータフレームで規定されたパケット構造を記載します。

PHYヘッダ(SHR, PHR)PHYペイロード(PSDU) 最大127バイト
OCTET411214~20n2
内容プリアンブル
シーケンス
フレーム
デリミタ
開始位置
フレーム長フレーム
コントロール
シーケンス
番号
アドレス
情報
MAC
ペイロード
FCS
  • IEEE802.15.4 MAC API を用いてプログラミングする際、意識する領域は、フレームコントロール・アドレス情報・データとなります。
    • シーケンス番号は MAC 層が自動で割り当てるため、ユーザが取得したり値を設定したりすることはできません。
    • LQI (Link Qualiry Indicator) 情報はパケット情報には含まれません。パケット受信時の受信回路から得られる情報です。
  • 最大パケット長は 127 OCTET (PHYペイロード: PSDU)です。
    • 一般的な通信ではアドレス情報が8 OCTETの場合(送信元、送信先ともに16bitショートアドレス)、データ領域(=MACペイロード)は最大 127 - 2(フレームコントロール) - 1(シーケンス番号) - 8(アドレス) - 2(FCS) = 114 OCTET の送信が可能です。
    • ZigBee PRO などのスタックでは、スタックが使用するヘッダもあるためユーザが使用出来るデータ領域はより小さくなります。
    • 最大パケット時の通信時間は約4.3mSです。
  • アドレス情報の構成は以下の組み合わせとなります。
    • Src(送信元) の PAN ID (2 OCTET)
    • Src(送信元) の アドレス (0: アドレス無し, 2: ショートアドレス, 8: 拡張 アドレス)
    • Dst(送信先) の PAN ID (2 OCTET)
    • Dst(送信先) の アドレス (0: アドレスなし, 2: ショートアドレス, 8: 拡張アドレス)
    • 通常は Src PAN ID, Src ショートアドレス, Dst PAN ID, Dst ショートアドレスの8 OCTETの構成です。
    • Src のアドレスだけ MAC アドレスにするような送信も可能です。この場合は、Src PAN ID, Src MACアドレス, Dst PAN ID, Dst ショートアドレスの合計14 OCTETとなります。
アドレッシングモードアドレス領域
送信元、送信先アドレス無し(PAN IDのみ)4
118
送信元、送信先16ビットショートアドレス使用8
114
送信元、送信先64ビット拡張アドレス使用20
102

アドレッシングモードは上記以外の組み合わせも可能です。

IEEE802.15.4gとは

IEEE802.15.4gとはスマートメーターの通信を目的とした通信方式の一つです。IEEE802.15.4gで使用できる周波数は国ごとに異なり日本では920MHz帯の物理層(PHY)を用いることができます。MAC層もIEEE802.15.4eで規格化を進めています。両者共にIEEE802.15.4との互換性はありません。日本ではIEEE802.15.4gを主にガスメーターの自動検針を実現するための規格として期待されています。

IEEE802.15.4kとは

IEEE802.15.4kとはスマートグリッドの通信を目的とした通信方式の一つです。IEEE802.15.4kはLow Energy Critical Infrastructure Monitoring (LECIM)と呼ばれており、低速で長距離を確実に通信することを目指しています。

モノをつなぐ無線マイコン TWELITE-トワイライト

リモコンで何かを操作したいとか何かを監視したいことは日常に数多くあると思います。離れたモノの状態を知りたい場合や離れたモノを操作したい場合には無線が適しています。しかし、モノを無線化する場合には電池寿命、通信距離、同時通信数、大きさ等の様々な制約があり従来の無線では実現が困難でした。 そこでモノをつなぐための無線が誕生しました。

弊社はワイヤレスセンサーネットワークの構築に最適なモノをつなぐIEEE802.15.4に準拠した無線マイコン TWELITE-トワイライトをご提供しており、お客様のワイヤレスセンサーネットワーク関連機器の通信機能開発の簡素化と早期市場投入のお手伝いをいたします。

無線を使って各種センサーの情報を無線で収集するための装置や、各種リモコンを作成したいが、ハードルが高すぎるという方に無線機能を手軽にご使用いただくことを目的としています。TWELITE DIP-トワイライトディップを使用して手軽に無線機能を手に入れることができます。

ホビーや学習用途から各種試作や小ロット量産まで対応し幅広いユーザーにご使用いただけます。

ワイヤレスセンサーネットワークの評価開発(IEEE802.15.4準拠)

弊社では、ワイヤレスセンサーネットワークに応用可能な各種センサー情報を無線でモニターしたり、通信品質測定を行うための開発ツール類もご用意しております。

2 - ソフトウェア開発

TWELITEのソフトウェア開発に関連する細かな情報を集めています。

2.1 - STAGEアプリを使わずにUART通信する

TWELITE STAGE アプリの代わりに CoolTerm を使って UART 通信を行う
TWELITE STAGE アプリのターミナル機能は、UART の応用的な操作には適しません。汎用ソフトウェアの CoolTerm を使用して、インタラクティブモードへのアクセスやUARTのバイナリデータの送信を行う方法を紹介します。

TWELITE STAGE アプリが適さない場合

TWELITE STAGE アプリのターミナルは、あくまでも簡易的な評価を目的とした機能です。したがって、シリアル通信アプリの書式モード(アスキーバイナリ)のように高度なUART通信を行う用途では、次の問題があります。

  • TWELITEのRXへ系列を入力するとき、事前にコピーした文字列をAlt+V/⌘+Vでペーストする必要がある
  • バイナリデータをHEX(16進数)表記で扱うことができない

CoolTerm の概要

CoolTerm は、シリアル通信に特化した汎用ソフトウェアです。TeraTerm とは異なり、(デバッグモードを使わずとも)バイナリデータを扱うことができるほか、複数のプラットフォームに対応しています。

シリアル通信アプリの書式モード(アスキー/バイナリ)を同時に使用する様子

シリアル通信アプリの書式モード(アスキー/バイナリ)を同時に使用する様子

インストール

作者のホームページからファイルを入手してください。

設定

CoolTerm では、使用するシリアルポートと付随する設定に名前を付けることができます。

ここでは、初期状態の TWELITE シリーズへ適合させるために設定が必要となる項目を紹介します。

設定の変更は Options メニューから行います。

Serial Port

Options 中の Serial Port のうち、次の設定を確認します。

  • Port:使用する TWELITE R あるいは MONOSTICK のポート
  • Baudrate:ボーレートは 115200 bps
設定例

設定例

Terminal

Options 中の Terminal のうち、主に次の設定を確認します。

  • Terminal ModeRaw Mode
  • Enter Key EmulationCR+LF
設定例

設定例

Data Handling

Options 中の Data Handling のうち、主に次の設定を確認します。

  • Clear Display onESC[2J] をチェック(インタラクティブモードの画面消去を有効化)
  • Handle BS and DEL Characters をチェック(インタラクティブモードの文字消去を有効化)
  • Text EncodingUTF8
設定例

設定例

Transmit

Options 中の Transmit のうち、主に次の設定を確認します。

  • Send String OptionsTerminate 'Send String' Dataをチェック
    • Termination String0D 0A(送信画面ではCRLFを末尾へ追加)
設定例

設定例

使用例

インタラクティブモード

インタラクティブモードは、Options > Terminal > Terminal ModeRaw Mode として使用することを推奨いたします。

Connect をクリックして接続したら、主画面を選択して、+を3回入力します。

TWELITE STAGE アプリと同じように直接文字を打ち込むことで、インタラクティブモードを利用できます。

インタラクティブモードの使用例

インタラクティブモードの使用例

シリアル通信アプリの書式モード(アスキー)

シリアル通信アプリの書式モード(アスキー形式)のように、:で始まりCRLFで終わるアスキー文字列で構成された系列を扱う際には、Options > Terminal > Terminal ModeLine Modeとすると便利です。

一行ずつEnterキーを使って入力できるほか、カーソルキーのを押すことで履歴を参照できます。

簡易形式を使って、親機から全子機に対してバイト列 0x11 0x22 0x33 0xAA 0xBB 0xCC を数回送信した場合の例を次の図に示します。

書式モード(アスキー)の使用例

書式モード(アスキー)の使用例

シリアル通信アプリの書式モード(バイナリ)

シリアル通信アプリの書式モード(バイナリ形式)では、Options > Terminal > Terminal ModeRaw Modeとしたうえで、Options > Transmit > Send String Options > Terminate 'Send String' Data のチェックを外してください。

受信したデータを16進数で表示するためには、View > View Hex を選択します。

16進数で表現したデータを送信するには、Connection > Send String... を選択して送信画面を開き、ラジオボタンのHex を選びます。

簡易形式を使って、親機から全子機に対してバイト列 0x11 0x22 0x33 0xAA 0xBB 0xCC を送信した場合の例を次の図に示します。

書式モード(バイナリ)の使用例

書式モード(バイナリ)の使用例

2.2 - プログラムからインタラクティブモードを使う

プログラムから自動的にインタラクティブモードにアクセスする方法

インタラクティブモードはシリアルポートを利用するため、機械的に操作することもできます。

生産工程においては、インタラクティブモードを自動的に利用したい場面があるかもしれません。Python を使って設定値を読み書きする例を紹介します。

インタラクティブモードの仕組み

初期状態では、TWELITE の RX ポートは 115200bps 8N1 の設定で動作しています。インタラクティブモードに遷移するには、200msから1000ms程度の間隔で + を3回入力するか、アプリによってはSETピンをLowに落として起動します。インタラクティブモードの操作はASCII文字を入力するだけの処理であることから、自由にプログラムから操作することができます。

実装例

Pythonによるシリアル通信アプリの設定値の読み出し

ここでは、シリアル通信アプリApp_Uartを書き込んだTWELITEから、TWELITE R2/R3 を通じてシリアルIDと設定値を読み出すスクリプトを紹介します。

スクリプト

Python 3.12 を使って実装しています。

シリアル通信アプリの仕様に沿って、ここでは+を3回入力することでインタラクティブモードに遷移させています。

# -*- coding: utf-8 -*-

import time
import re

from tweliter import Tweliter  # Mono Wireless module for TWELITE R devices


def get_serial_id_and_settings() -> tuple[str, dict[str, str]] | None:
    """
    Get the serial ID and settings from the interactive mode of a TWELITE R device.

    Returns:
        tuple[str, dict[str, str]] | None:
            A tuple containing:
            - str: the serial ID (e.g., "0x82010079")
            - dict[str, str]: the settings dictionary (e.g., {'a': '0x67720103', ...})
            Returns None if the device cannot be accessed or the output is invalid.

    Notes:
        Example output from the interactive mode of an App_Uart device:
        --- CONFIG/TWE UART APP V1-04-6/SID=0x82010079/LID=0x78 -- ---
         a: set Application ID (0x67720103)
         i: set Device ID (120=0x78)
         c: set Channels (18)
         x: set RF Conf (3)
         r: set Role (0x0)
         l: set Layer (0x1)
         b: set UART baud (38400)
         B: set UART option (8N1)
         m: set UART mode (E)
         k: set Tx Trigger (sep=0x0d0a, min_bytes=0 dly=0[ms])
         h: set header format [;U;%t;%i;0x%A;%q;%s;<*;%X;\n]
         C: set crypt mode (0)
         o: set option bits (0x00000100)
        ---
         S: save Configuration
         R: reset to Defaults
    """
    try:
        with Tweliter(
            type_filter=Tweliter.Type.TWELITE_R2 | Tweliter.Type.TWELITE_R3
        ) as liter:
            # Reset the device
            liter.reset_device()

            # Get the serial port instance (pyserial)
            ser = liter.get_serial_instance()
            ser.timeout = 1.0

            # Enter to the interactive mode
            for _ in range(3):
                ser.write("+")
                time.sleep(0.3)

            # Read the output
            raw_output = ser.read_until(b"S:").decode("utf-8")

            # Reset the device (Exit interactive mode)
            liter.reset_device()
    except IOError as e:
        print(f"Couldn't open the device {e}")
        return None

    # Find the settings block in the output
    filter_output = re.search(r"---(.*?)---(.*?)---", raw_output, re.DOTALL)
    if filter_output:
        information_line = filter_output.group(1)
        settings_block = filter_output.group(2)
    else:
        print("No settings block found.")
        return None

    # Extract serial id from the information line
    serial_id_match = re.search(r"SID=0x([0-9A-Fa-f]+)", information_line)
    if serial_id_match:
        serial_id = f"0x{serial_id_match.group(1)}"
    else:
        print("Serial ID not found.")
        return None

    # Extract key-value pairs (str,str) from the settings block
    settings_dict = dict(
        re.findall(r"^\s*(\w):.*?\(([^()]*)\)", settings_block, re.MULTILINE)
    )

    return serial_id, settings_dict


def main() -> None:
    # Get the serial ID and settings from the device
    result = get_serial_id_and_settings()
    if result is None:
        print("Failed to retrieve serial ID and settings.")
        return
    serial_id, settings = result

    # Show the results
    print(f"Serial ID: {serial_id}")
    for id, value in settings.items():
        match id:
            case "a":
                print(f"Application ID: {value}")
            # case "i":
            #     print(f"Logical ID: {value}")
            # case "c":
            #     print(f"Channel: {value}")


if __name__ == "__main__":
    main()

解説

インタラクティブモードの出力を読み出す流れ
  1. TWELITE をリセットする
    • リセットにより、インタラクティブモードに入るための初期状態に戻します。ここでのリセットは、TWELITE R2/R3 のリセットピン制御によって行います。
  2. シリアルポートのインスタンスを取得する
    • pyserial により、PC 側から TWELITE のシリアル入出力にアクセスするためのインスタンスを取得します。このインスタンスを通じて、後続のコマンド送信やデータの読み出しを実行できます。
  3. +を3回入力する
    • 一定間隔(200〜1000ms)で + を3回送信することで、TWELITE はインタラクティブモードに遷移します。この方法はユーザー手動での操作と同様です。
  4. 保存コマンドの説明 S: まで読み取る
    • インタラクティブモードでは、設定値が並んだあとに S: という保存コマンドの説明行が現れるため、そこまで読み取ることで一連の設定内容をすべて取得できます。
  5. TWELITE をリセットする
    • 読み出しが終わったら、再度リセットしてインタラクティブモードから通常モードに戻します。
with Tweliter(
    type_filter=Tweliter.Type.TWELITE_R2 | Tweliter.Type.TWELITE_R3
) as liter:
    # Reset the device
    liter.reset_device()

    # Get the serial port instance (pyserial)
    ser = liter.get_serial_instance()
    ser.timeout = 1.0

    # Enter to the interactive mode
    for _ in range(3):
        ser.write("+")
        time.sleep(0.3)

    # Read the output
    raw_output = ser.read_until(b"S:").decode("utf-8")

    # Reset the device (Exit interactive mode)
    liter.reset_device()
インタラクティブモードの出力を解釈する流れ
  1. 一行目と --- に挟まれたブロックを抽出する

    • re.search(r"---(.*?)---(.*?)---", raw_output, re.DOTALL) により、インタラクティブモードの出力から設定全体の情報を2つの部分に分けて取り出します。最初のキャプチャグループは、シリアルIDなどが含まれる情報行(information_line)、2つ目は設定項目が並ぶ設定値ブロック(settings_block)です。re.DOTALL により、改行を含む全文検索が可能になります。
  2. 一行目からシリアルIDを抽出する

    • re.search(r"SID=0x([0-9A-Fa-f]+)", information_line) を使って、SID=0x に続く16進数のID値(例:82010079)を取得し、それを 0x82010079 のような文字列に整形します。16進数は大文字小文字を区別せずに抽出されます。
  3. ブロックからコマンドIDと値のペアを抽出する

    • re.findall(r"^\s*(\w):.*?\(([^()]*)\)", settings_block, re.MULTILINE) を使って、設定値の各行から a: ... (値) のような形式を対象に、コマンドID(1文字)と括弧内の値を取り出します。先頭の空白、コロン以降の任意文字列をスキップし、最初に見つかる括弧内の値のみを抽出します。re.MULTILINE により、複数行に対応した検索ができます。
# Find the settings block in the output
filter_output = re.search(r"---(.*?)---(.*?)---", raw_output, re.DOTALL)
if filter_output:
    information_line = filter_output.group(1)
    settings_block = filter_output.group(2)
else:
    print("No settings block found.")
    return None

# Extract serial id from the information line
serial_id_match = re.search(r"SID=0x([0-9A-Fa-f]+)", information_line)
if serial_id_match:
    serial_id = f"0x{serial_id_match.group(1)}"
else:
    print("Serial ID not found.")
    return None

# Extract key-value pairs (str,str) from the settings block
settings_dict = dict(
    re.findall(r"^\s*(\w):.*?\(([^()]*)\)", settings_block, re.MULTILINE)
)

return serial_id, settings_dict

Pythonによるキューアプリの設定値の読み出しと論理デバイスIDの変更

ここでは、キューアプリApp_Cueを書き込んだTWELITEから、TWELITE R2/R3 を通じてシリアルIDと設定値を読み出し、論理デバイスIDを更新するスクリプトを紹介します。

スクリプト

Python 3.12 を使って実装しています。

キューアプリの仕様に沿って、ここではSET ピンを下げることでインタラクティブモードに遷移させています。

# -*- coding: utf-8 -*-

import time
import re

from tweliter import Tweliter  # Mono Wireless module for TWELITE R devices


def revert_all_setttings(liter: Tweliter) -> None:
    """
    Revert all settings

    Args:
        liter (Tweliter): Tweliter instance
    """
    # Get the serial port instance (pyserial)
    ser = liter.get_serial_instance()
    ser.timeout = 1.0

    # Set logical id
    ser.write("R")
    time.sleep(0.3)
    ser.write("S")


def get_serial_id_and_settings(liter: Tweliter) -> tuple[str, dict[str, str]] | None:
    """
    Get the serial ID and all settings

    Args:
        liter (Tweliter): Tweliter instance

    Returns:
        tuple[str, dict[str, str]] | None:
            A tuple containing:
            - str: the serial ID (e.g., "82010079")
            - dict[str, str]: the settings dictionary (e.g., {'a': '0x67720103', ...})
            Returns None if the device cannot be accessed or the output is invalid.
    """
    # Get the serial port instance (pyserial)
    ser = liter.get_serial_instance()
    ser.timeout = 1.0

    # Read the output
    raw_output = ser.read_until(b"S:").decode("utf-8")

    # Find the settings block in the output
    filter_output = re.search(r"---(.*?)---(.*?)---", raw_output, re.DOTALL)
    if filter_output:
        information_line = filter_output.group(1)
        settings_block = filter_output.group(2)
    else:
        print("No settings block found.")
        return None

    # Extract serial id from the information line
    serial_id_match = re.search(r"SID=0x([0-9A-Fa-f]+)", information_line)
    if serial_id_match:
        serial_id = f"0x{serial_id_match.group(1)}"
    else:
        print("Serial ID not found.")
        return None

    # Extract key-value pairs (str,str) from the settings block
    settings_dict = dict(
        re.findall(r"^\s*(\w):.*?\(([^()]*)\)", settings_block, re.MULTILINE)
    )

    return serial_id, settings_dict


def set_logical_id(liter: Tweliter, lid: int) -> None:
    """
    Set new logical id and save it

    Args:
        liter (Tweliter): Tweliter instance
        lid (int): New logical id
    """
    # Get the serial port instance (pyserial)
    ser = liter.get_serial_instance()
    ser.timeout = 1.0

    # Set logical id
    ser.write("i")
    time.sleep(0.3)
    ser.write(f"{lid}\r\n")
    time.sleep(0.3)
    ser.write("S")


def print_settings(settings: dict[str, str], select: list[str] | None = None) -> None:
    """
    Print settings

    Args:
        settings (dict[str, str]): Settings dict
        select (list[str] | None): List of IDs for selected entries. None to select all
    """
    for id, value in settings.items():
        if select is None or id in select:
            match id:
                case "a":
                    print(f"Application ID: {value}")
                case "i":
                    print(f"Logical ID: {value}")
                case "c":
                    print(f"Channel: {value}")
                case "x":
                    print(f"Power / Retry: {value}")
                case "b":
                    print(f"UART Baudrate: {value}")
                case "B":
                    print(f"UART Options: {value}")
                case "k":
                    print(f"Encryption Key: {value}")
                case "o":
                    print(f"Option Bits: {value}")
                case "t":
                    print(f"Transmission Interval: {value}")
                case "p":
                    print(f"Sensor Parameters: {value}")
                case _:
                    print(f"{id}: {value}")


def main() -> None:
    """
    Main function
    """
    lid_to_set = 25
    try:
        with Tweliter(
            type_filter=Tweliter.Type.TWELITE_R2 | Tweliter.Type.TWELITE_R3
        ) as liter:
            # Revert all settings
            print("\nReverting to default settings...")
            liter.enter_interactive_mode()
            revert_all_setttings(liter)

            # Get the serial ID and settings from the device
            liter.enter_interactive_mode()
            result = get_serial_id_and_settings(liter)
            if result is None:
                print("Failed to get serial ID and settings.")
                return
            serial_id, settings = result
            print(f"\nCurrent settings for the device {serial_id}:")
            print_settings(settings)

            # Set logical ID
            print(
                f"\nModifying Logical ID {settings["i"]} to {lid_to_set}=0x{lid_to_set:02x}..."
            )
            set_logical_id(liter, lid_to_set)

            # Get updated setttings
            liter.enter_interactive_mode()
            result = get_serial_id_and_settings(liter)
            if result is None:
                print("Failed to get serial ID and settings.")
                return
            serial_id, settings = result
            print(f"\nUpdated setting(s) for the device {serial_id}:")
            print_settings(settings, select=["i"])

            # Reset the device (Exit interactive mode)
            liter.reset_device()

    except IOError as e:
        print(f"Couldn't open the device {e}")
        return None


if __name__ == "__main__":
    main()

スクリプトを実行すると、例えば以下のようにして論理デバイスIDを 25 に書き換えます。


python modify_app_cue_settings.py
Using TWE-Lite-R R27BESFJ @ ftdi://::R27BESFJ/1

Reverting to default settings...

Current settings for the device 0x8201872b:
Application ID: 0x67720102
Logical ID: --
Channel: 18
Power / Retry: 13
UART Baudrate: 38400
UART Options: 8N1
Encryption Key: 0xA5A5A5A5
Option Bits: 0x00000001
Transmission Interval: 5
Sensor Parameters: 0x00000000

Modifying Logical ID -- to 25=0x19...

Updated setting(s) for the device 0x8201872b:
Logical ID: 25=0x19

解説

設定値を読み出す処理
  1. シリアルポートのインスタンスを取得する
  2. 保存コマンドの説明文のある S: までの文字列をシリアルポートから読み出す
    • インタラクティブモードでは、設定値が並んだあとに S: という保存コマンドの説明が表示されます。そこまでの文字列を読み取ることで設定内容をすべて取得できます。
  3. 一行目と --- に挟まれたブロックを抽出する
    • re.search(r"---(.*?)---(.*?)---", raw_output, re.DOTALL) により、インタラクティブモードの出力を2つの部分に分けて取り出します。最初のキャプチャグループは、シリアルIDなどが含まれる情報行(information_line)、次のグループは設定項目が並ぶブロック(settings_block)です。re.DOTALL により、改行を含む全文検索を行います。
  4. 一行目からシリアルIDを抽出する
    • re.search(r"SID=0x([0-9A-Fa-f]+)", information_line) を使って、SID=0x に続く16進数のID値(例:82010079)を取得し、それを 0x82010079 のような文字列に整形します。16進数は大文字小文字を区別せずに抽出されます。
  5. ブロックからコマンドIDと値のペアを抽出する
    • re.findall(r"^\s*(\w):.*?\(([^()]*)\)", settings_block, re.MULTILINE) を使って、設定値の各行から a: ... (値) のような形式を対象に、コマンドID(1文字)と括弧内の値を取り出します。先頭の空白、コロン以降の任意文字列をスキップし、最初に見つかる括弧内の値のみを抽出します。re.MULTILINE により、複数行に対応した検索を行います。
    # Get the serial port instance (pyserial)
    ser = liter.get_serial_instance()
    ser.timeout = 1.0

    # Read the output
    raw_output = ser.read_until(b"S:").decode("utf-8")

    # Find the settings block in the output
    filter_output = re.search(r"---(.*?)---(.*?)---", raw_output, re.DOTALL)
    if filter_output:
        information_line = filter_output.group(1)
        settings_block = filter_output.group(2)
    else:
        print("No settings block found.")
        return None

    # Extract serial id from the information line
    serial_id_match = re.search(r"SID=0x([0-9A-Fa-f]+)", information_line)
    if serial_id_match:
        serial_id = f"0x{serial_id_match.group(1)}"
    else:
        print("Serial ID not found.")
        return None

    # Extract key-value pairs (str,str) from the settings block
    settings_dict = dict(
        re.findall(r"^\s*(\w):.*?\(([^()]*)\)", settings_block, re.MULTILINE)
    )

    return serial_id, settings_dict

3 - ハードウェア開発

TWELITEのハードウェア開発に関連する細かな情報を集めています。

3.1 - 省電力性能について

TWELITE を電池で長期運用するには

モノをつなぐ無線マイコンモジュールとして低消費電力を実現するためには各処理の消費電流を抑えることが必要ですが、起動時間と処理時間を短縮することも非常に重要です。消費電流が小さくても処理時間が長ければ低消費電力は実現できません。

消費電力(電流)

以下は1パケットを30バイトで送信した時の標準的な消費電流です。

  • 標準出力 BLUE-ブルー
TWELITE BLUEの場合

TWELITE BLUEの場合

  • 高出力 RED-レッド
TWELITE REDの場合

TWELITE REDの場合

高出力 RED-レッドは標準出力 BLUE-ブルーに比べて送信時の消費電流が大きいですが、処理時間が短いので1パケットを送信時の消費電流は同等です。

TWELITE は低消費電流、瞬速起動、高速処理により省電力を実現しています。

消費電力例

TWELITE の消費電力を最小限にした無線タグの例です。この例ではセンサーは使用しておらず、4バイトのIDデータを内蔵タイマーで周期的に送信しています。送信相手からの受信確認(ACK)は行っていません。1パケット送信時の平均消費電流は11.6mA、処理時間は2.5msです。

  • 起床中のみ考えた平均消費電流
11.6[mA] * (2.5/1000)[ms] = 29[uA]
  • スリープ(RAMオン)時間を含めた平均消費電流
29[uA] + 1.5[uA] = 30.5[uA] = 0.0305[mA]

1秒毎に送信した場合の電池寿命はCR2032の容量を220mAhとして、

220/( 0.0305 ) = 約7213[時間] = 300[日] = 10ヶ月

下のグラフはコイン型電池(CR2032)を使用した場合の電池寿命です。30秒毎にデータを送信した場合の電池寿命は10年を超えます。

3.1.1 - 電池運用とバッファ用コンデンサ

TWELITE を小容量の電池で運用する際にはバッファ用のコンデンサを使用します

小容量の電池を使う場合、十分な電流が取れないことがあります。例えば、CR2032 の定格上の電流は 0.2mA 程度で、最大でも 2~3mA 程度しか想定していません。

例えば TWELITEで、無線パケットを送信する場合、瞬間的ですが 20mA 程度消費する事もあり、このとき電流の供給不足、電圧降下などが発生し、システムが正常動作しない事が考えられます。

これを回避するため、バッファ用のコンデンサを VCC-GND 間に接続します。(他にリセットICによる起動制御を行う必要があります)

電源が遮断された場合、電圧3.3V、平均電流が 10mA と仮定して、100uF のバッファーがあれば約10msシステムを動作できます。電源断直後からバッファーからの電流が供給され、無線モジュールが活動不能になる 2V 近傍までは無線モジュールは動作します。

間欠動作・送信時には有効な手段です。注意点として、再送などが発生した場合は送信完了までの時間が大幅に伸びます。1回の再送で数mS消費しますので、再送の回数分を加味したバッファーが必要です。

ただし受信待ちを行うような場合は連続的に大電流 (17.2mA) が消費されることになりますから、上記のようなバッファでの対処は難しく、供給能力の高い電池を利用してください。

コンデンサの容量と動作時間の目安

TWELITEシリーズのモジュールの消費電流は、電源電圧に依存しません。電流一定と言う点から、コンデンサの電荷でどの程度の稼働が見込めるか計算してみます。

静電容量 C のコンデンサに、電圧 v に相当する電荷が蓄積されている場合、一定電流 i で電圧 v から 0 まで降下する時間 tt = Cv/i となります。

電流 i3.3V から 2.1V まで降下するのに必要な時間は、C(3.3-2.1)/i となります。i=10mA, C=100uF とした場合、12ms と計算できます。計算上は 3.3Vで動作していたモジュールの電源が突然断たれた場合、平均電流が 10mA なら 12ms 稼働延長することが期待できることになります。

電流が10mAというのは、あくまでも平均値の仮定です。実際の消費電流の計測値を参照してください。

3.2 - アンテナ実装

お客様設計・実装のRF回路やアンテナの認可適用について

お客様設計の無線回路やアンテナについての認可適用について注意点を記載します。

  • 当社により認可を取得し設計情報をお客様に供給する場合
    • 当社が提出した認可時の技術情報に従って設計並びに生産を行ってください。
    • 当社利用の認可事業者に対してRF回路やアンテナについての技術情報を提出しています。お客様にはこの技術情報に基づいた認可のための必須要件や性能のためのコメントを提示します。
    • 認可事業者の見解と異なる見解が存在する可能性があります。万が一、見解の際によって問題が生じた場合は、当社並びに認可事業者は、認可時の技術情報に基づく情報提示を実施しますが、以下については実施しません。
      • 当該の交渉を行う、または相当の行為。
      • この問題によって生じた補償。
    • 海外認可については、お客様自身によって、適合状況をご確認ください。
      • 海外認可の要件等は更新されている場合があります。その時点で最新の情報を引用してください。
      • お客様の設計・実装について、当社からその是非について最終的な見解を述べることは致しかねます。
  • お客様が独自に設計される場合
    • ほとんどの場合、独自の設計について認可が必要になります。
    • 認可については技術書類等の取り扱いなどをスムーズに行うため原則として当社指定の事業者をご案内します。当社にお問い合わせいただくようお願いいたします。

3.2.1 - 逆F型アンテナの実装

逆F型アンテナの実装に関する注意事項

逆F型パターンアンテナ(TWELITE-SMD-ANT-REVF)の電波認証について注記事項を記載します。

要件

以下の条件を満足すること。

  • 設計データ通りのパターン、スルーホールにより配線すること
    • 設計データ中の変更禁止(配線禁止, DO NOT WIRE)領域を変更しないこと
  • 指定のプリント基板であること
    • プリント基板製造業者へは 1mm 厚を指定してください
    • (1mm 以外の基板厚が必要な場合はこちらを参照下さい)
    • 誘電率の関係でガラスエポキシ(FR-4)を指定します。他の材料は不可です
    • 層構成は両面または4層です
    • レジスト色、シルクの指定要件はありません
  • 設計通りの製造・実装であることを確認していること
    • 一般的に引用される公差を超える設計のずれが無いこと
    • 無線モジュールが実装が適切であること

設計と性能

GND面積

逆F型アンテナは、逆F形状のエレメント部と、モジュール直下のGNDパターンから構成されます。GNDパターンの面積が性能に大きく影響します。最適な大きさは 20x20 ~ 40x40mmです。

配線

逆F型は、外部への配線にも影響を受けやい性質があります。例えば、GND面にコイン電池ホルダーを配置し、外部配線無しといった無線タグ (TWELITE CUEなど) は理想に近い性能が得られます。

GND面に一部配線を行う場合は最小限にとどめてください。例えば1本だけ通す程度であれば、ほとんど影響はありません。

性能評価

認可状況

日本国内

対象モジュール

  • TWE-L-WX
  • MW-R-WX

要件

上記要件を満足すること

北米 (FCC)

※ 海外認可については、お客様自身により適合性について十分ご確認ください。

対象モジュール

  • TWE-L-WX

要件

  • 上記要件を満足すること
  • その他(表示要件)などは FCC の要件を参照すること

欧州 (EU)

※ 海外認可については、お客様自身により適合性について十分ご確認ください。

対象モジュール

  • TWE-L-WX

要件

  • 上記要件を満足すること
  • その他(表示要件)などは CE の要件を参照すること

その他の地域

認可対応無し。

基板厚について

本設計において基板は FR-4 1mm に指定されています。この基板厚は電波認証での認可の根拠であるため、指定外の基板厚の場合、認可外となります。

ただし、日本国内認可に限り以下の基板厚でも認可されています。

  • t=0.5mm (当社で取得済みの海外認可での利用は不可)
  • t=0.8mm (当社で取得済みの海外認可での利用は不可)
  • t=1.6mm (当社で取得済みの海外認可での利用は不可)

アンテナパターンがt=1mmで最適化されているため、僅かながら特性が変化します。ただし変化は多くの場合ごく軽微です。理想GNDサイズに基づく基板上での特性パターンでは 1~3db 程度変化が見られます。

3.2.2 - SMAコネクタの実装

SMAコネクタの実装に関する注意事項

SMAコネクタ(TWELITE-SMD-SMA-CONN)の電波認証について注記事項を記載します。

要件

共通

  • 設計データ通りのパターン、スルーホールにより配線すること
    • 設計データ中の変更禁止(配線禁止, DO NOT WIRE)領域を変更しないこと
  • 指定のプリント基板であること
    • プリント基板製造業者へは 1mm 厚を指定してください
    • 誘電率の関係でガラスエポキシ(FR-4)を指定します。他の材料は不可です
    • 層構成は両面または4層です
    • レジスト色、シルクの指定要件はありません
  • 設計通りの製造・実装であることを確認していること
    • 一般的に引用される公差を超える設計のずれが無いこと
    • 無線モジュールが実装が適切であること
  • 指定コネクタを実装すること

指定コネクタ

認可状況

日本国内

対象モジュール

  • TWE-L-WX
  • MW-R-WX

要件

  • 上記要件を満足すること

北米 (FCC)

認可対応無し。

欧州 (EU)

認可対応無し。

その他の地域

認可対応無し。

3.2.3 - ワイヤアンテナの実装

ワイヤアンテナの実装に関する注意事項

φ=0.8mm 以下の導線を用いて、アンテナを作成することができます。

任意に折り曲げて使用可能ですが、直立に比べ性能が著しく低下する場合があります。アンテナ性能を維持する場合は「ワイヤアンテナの曲げパターン」をご参照ください。(寸法較差は 0.5mm 未満に収めてください。)

3.3 - 信頼性のための検討

TWELITE の実装における信頼性のための検討事項

リセット回路について

始動電圧 (2.05V typ) を超えてからモジュールが起動します。始動電圧から Vhys=38mV 低下したところで再びリセットがかかります。

検討事項は以下の通りです。

  • 外部のリセットICにより、より電圧の高いポイントで始動するようにする
  • 電源ラインに十分な電圧バッファを設ける
回路例

回路例

ウォッチドッグ

TWEモジュール内にはウォッチドッグタイマが機能として含まれていますが、モジュールに対する想定外の電磁ショックを受けた場合、モジュールがハングアップする可能性があります。

検討事項は以下の通りです。

  • 外部ウォッチドッグハードウェアによる強制リセット

定期的なリセット

システムの長期動作が十分確認できていない状況では、無線システムの定期的に強制リセットすることも検討する必要があります。

検討事項は以下の通りです。

  • ソフトウェアにより一定期間ごとにリセットする
  • 外部ハードウェアにより RESETN ピンを制御し強制リセットする

未使用ピンの処理

未使用ピンについては、オープンを推奨していますが、ハードウェア設計の考え方によっては以下を検討してください。

  • ディジタル関連ピンの外部プルアップ
  • アナログ関連ピンのプルダウンまたはプルアップ (半導体データシート中ではオープンを推奨しています)

電源について

よりノイズが少なく安定した電源を推奨します。

  • よりノイズの少ないシリーズレギュレータなどの利用
  • 電源電圧を 2.7V ~ 3.3V とする
  • 乾電池で利用する場合はバッファのキャパシタの利用
  • 電源ラインにパスコンを挿入 (ADC ノイズの低減が見られる場合があります)

アンテナ経由での電磁ノイズ

アンテナ経路から電磁ノイズが流入することがあります。

  • アンテナ経路に対するサージ防護(別途認証が必要になります)
  • 上記外部ウォッチドッグによる強制リセット

各種ノイズ

信号線・マイコン・モータなど周辺デバイスに依存して動作に影響を受ける、または及ぼす場合があります。また無線送信・受信時は、ある程度の電磁ノイズを放射することになりますので他のシステムへの影響も検討することになります。

ホビー等では必要とされる場面は少ないと考えられますが、システム要件によってはこのような検討が必要とされます。

  • 専門的な設計検証・検討が必要になります。

ファームウェア

ファームウェアに信頼性を求める場合に考えられる手法です。一般の用途では検討しない項目も含まれます。

以下に、一般的な手法を一部紹介します。

  • ハードウェアウォッチドッグの利用 (TWELITE NET ではライブラリ内で半導体内のウォッチドッグを利用します)
  • 電圧検出割り込みの利用 (BrownOut 検出)
  • 定期的な強制リセット (標準アプリでは実施していません)
  • メモリー・変数などの定期的なチェック・多重化 (標準アプリでは実施していません)
  • スタックオーバーフローの API の利用
  • 始動時にファームウェアのチェックサム検証 (標準アプリでは実施していません)
  • 通信の暗号化・冗長データによるチェック (App_UART などの暗号化通信はデータの検証を強化します)
  • UART の入出力のチェックサムの強化 (App_UART では xor による 8bit チェックサム)

3.4 - 特殊ピンの取り扱い

TWELITE で特別な振る舞いをするピンについて解説します。

3.4.1 - 特殊ピンの取り扱い (TWELITE BLUE / RED)

TWELITE BLUE / RED で特別な振る舞いをするピンについて解説します。

SPIMISO (別名: DO1, 標準アプリ名: PWM3)

本ピンは出力ピンとして利用されることが多いピンですが、モジュール電源投入やリセット時に入力ピンとして振る舞い、その時 Lo 側の電圧判定をされた場合、モジュールがプログラムモードとして起動します。

本ピンの 始動時の電圧 に気をつけてください。

  • 標準アプリケーションの場合 (PWM3 — 抵抗 — LED —GND) では起動時に GND 側の不定な電圧を持つことになります。全PWMポートを (VCC — 抵抗 — LED — PWM?) にし、オプションビット (00010000, PWM 波形を反転する) を設定します。

SPICLK (別名: DO0, 標準アプリ名: PWM2)

本ピンは出力として利用されるピンです。 外部からの中間的な電圧印加を行う と(ある程度の出力インピーダンスがあったとしても)、TWEモジュールがプログラムモードに遷移しないといった現象が報告されています。

LEDやトランジスタなどの接続では、始動時やスリープ回復時に中間的な状態となり、正常動作しない場合があります。未接続あるいは Vcc 側へプルアップされる回路構成を推奨します。

DIO0 (別名:ADC3), DIO1 (別名: ADC4)

これらのピンはアナログ入力と共用されています。ファームウェア上で注意点としては、AD読み出し時に内部プルアップを無効にしておく必要があります。

ADC2 (別名: Vref)

ADC2 は基準電圧の入力用として利用できます。利用にはソフトウェア上の実装が必要になります。

なお、 基準電圧を出力するピンはありません

GNDピン

SMD 版 28, 30-32 ピンの GND は接続を推奨しますが、未接続での運用も可能です。未接続であっても、無線性能の顕著な変化は観察されていません。

3.5 - UART-USBケーブルでの書き込み

UART-USBケーブルやUSBシリアル変換ICを使った書き込み
市販の 3.3V用 UART-USB ケーブルや USB シリアル変換 IC を使用してファームウェアを書き込むこともできます。

接続方法

接続例

接続例

プログラムモードで起動する方法

  1. プログラム信号ピン(7番ピン)を GND に落としながら電源投入またはリセットします。
  2. プログラム信号ピンを HIGH または OPEN に戻します。

書き込みに使うアプリケーション

一般のシリアル変換IC を使用する場合は、Windows 向けの書き込み専用ソフトウェア TWELITE プログラマtweliter Python 書き込みツールをご利用ください。

TWELITE STAGE アプリは、カスタム設定が適用された FTDI チップを搭載する TWELITE R シリーズの出力を制御して PRGRST, SET を操作する機能を持っているため、一般のシリアル変換ICを使用した書き込みが行えない場合がございます。