ドアセンサーが1日に数回レポートを送信し、農地センサーが10分ごとに1パケットをアップロードし、スマートロックがユーザーの接近に応じて即座に応答する。これらすべてを「低消費電力 IoT」と呼べるが、必要とされるネットワークや受信戦略は異なる。プロトコル名を見る前に、有効ペイロード、送信周期、ダウンリンクの遅延要件、電源供給、インフラストラクチャの有無を確認するべきであり、距離、消費電力、転送速度を条件なしの固定ランキングとして埋め込むべきではない。
技術 システム内での位置 先に評価すべき制約条件
Zigbee 802.15.4 などを基盤とした完全なアドホックネットワーク/アプリケーション体系 ノードの役割、ルーティングカバレッジ、デバイス機能の相互運用性
Thread IPv6 対応低消費電力メッシュネットワーク パレントノード、ボーダールーティング、IP 接続性
Matter IP ベースのアプリケーション相互運用性とセキュリティ体系 デバイスタイプ、コントローラー、ファブリックと認可
Z-Wave 従来型メッシュや LR などのモードを含むデバイス制御エコシステム 地域/デバイスモードおよびコントローラーのサポート
LoRa / LoRaWAN 変調/物理層技術と広域ネットワークプロトコル 空中時間、ゲートウェイ、ダウンリンクウィンドウとネットワーク容量
NB-IoT / LTE-M セルラー IoT アクセス 通信事業者ネットワーク、カバレッジ、消費電力状態と料金/運用管理
NFC / RFID 近接インタラクション、タグ識別など リーダー/ライター、給電、タグの種類とセキュリティ機能
UWB 広帯域測距/測位および関連通信 測距プロトコル、アンカーの幾何配置、遮蔽と消費電力サイクル
メッシュは到達可能なパスを広げるものであり、すべてのバッテリー駆動ノードを常時受信状態にするものではない
Zigbee では通常、コーディネーター、ルーター、エンドデバイスが区別される。コーディネーターはネットワークを確立し、対応する管理責任を負い、ルーターは転送を行い、エンドデバイスは親ノードに依存する。スリープ状態のエンドデバイスは他のノードのリレーとして機能できない。ルーティングノードは到達可能である必要があるため、通常は継続的な電源で供給されるが、「コンセントに挿されたデバイス」だからといって必ずしもルーターとして動作するとは限らない。Silicon Labs:Zigbee ノードタイプ
親ノードはスリープ中の子デバイスに対してダウンリンクデータをキャッシュし、子デバイスがウェイクアップすると取得する。この省電力化はリスニングの削減によるものであり、ダウンリンクがいつでも到達可能ではないことを意味する。マルチホップは一部の失敗したパスを回避できるが、他の利用可能なルート、リソース、カバレッジが存在する場合にのみ意味を持つ。家中のルーター付き電球が壁のスイッチで電源を切られた場合、バッテリー駆動のドアセンサーが自動的にそれらのメッシュ幹線を引き受けるわけではない。
コーディネーターはアプリケーションゲートウェイとは異なる:同じハードウェアボックスがコーディネーター、プロトコル変換、自動化サービスを同時に提供する場合もあるが、これら3つの役割は個別に分析する必要がある。Zigbee 製品の相互運用性には、デバイスタイプ、クラスタ、拡張機能、コントローラーのサポートも関与しており、「同じプロトコルなら完全に汎用的」または「すべてのベンダーがロックインされる」と単純に一般化できるものではない。
Z-Wave も単一のメッシュとして列挙できるものではない:従来の Z-Wave と Z-Wave Long Range ではトポロジーが異なり、LR はデバイスから中央コントローラーへのスター型接続を使用する。互換性のあるコントローラーで対応するネットワークを管理できるが、デバイスモードと地域での対応能力を確認する必要がある。Z-Wave Alliance:Long Range
Thread と Matter:ネットワークの相互接続後、アプリケーションは互いを認識する必要がある
Thread の一般的なデプロイメントは 2.4 GHz IEEE 802.15.4 を基盤としており、6LoWPAN などのメカニズムを使用して IPv6 を伝送する。802.15.4 ファミリーに他の周波数帯が含まれているからといって、すべての Thread 製品にサブギガヘルツを統一して割り当てることはできない。Thread のルーティング役割、スリープエンドデバイス、ボーダールーティングの役割分担も、「ネイティブ IPv6」だからといってネットワーク上のすべてのノードが Wi-Fi に直接接続できるとは推論できない。
ボーダールーティングは Thread と他の IP ネットワーク間でルーティングを行い、関連する発見/ネットワークサービスも担当する。通常、すべてのアプリケーションコマンドをプライベートプロトコルに変換する必要はないが、任意の透過的なレイヤー2ブリッジではない。分離された Thread ネットワーク内では通信可能だが、外部 IP ネットワークにアクセスするには対応する境界パスが必要である。Thread Group:ボーダールーティング
休止中のドアセンサー Matter over Thread Thread 親ノード 上り受信・下り保持 ボーダールーティング Thread と他の IP ネットワーク間 Matter コントローラー 購読・権限・自動化 IP 1つの物理ボックスが複数の役割を担う場合がある 境界ルータとアプリ制御は別の役割 ドアセンサーから自動化へ:無線転送、IP ルーティング、Matter コントロールが それぞれ一段を担当 ドアセンサーは他のノードに対して転送を行わない;唯一のボーダールーティングが失われると外部アクセスに影響し、複 数の役割を1つに統合すると共通障害点となる可能性がある。
Thread には再選挙可能なリーダーなどのメカニズムがあるが、役割がないわけでも、あらゆるデプロイメントに単一障害点がないわけでもない。ボーダールーティングが1つのみの場合、その障害は対応する外部パスを遮断する。自動化が1つのコントローラーでのみ実行されている場合、ネットワークルーティングが正常であっても、そのコントローラーがロジックを実行するのを代替することはできない。複数のボーダールーティングを設定するには、適切な共通ネットワークとして構成する必要がある。複数のボックスを購入しただけで自動的に同じメッシュが形成されるわけではない。Thread Group:一般的なネットワークトポロジー
Matter はアプリケーションレイヤーのデバイスモデル、インタラクション、セキュリティなどを定義しており、Thread、Wi-Fi、または Ethernet 上で実行されることが多い。BLE は発見/プロビジョニングに一般的に使用されるが、通常の Matter コントロールデータの一般的な伝送媒体ではない。Matter コントローラー、プロビジョニングコミッショナー、Thread ボーダールーティング、旧式デバイスをブリッジする Matter ブリッジは異なる役割であり、1つのボックスが複数の役割を担うことができる。CSA:Matter
ドアセンサーのイベントが自動化に到達するまでの一連の流れ
ドアセンサーがウェイクアップして開封を検出すると、属性/イベントを Matter インタラクションとして送信し、Thread 親ノードとルーティングを介してコントローラーに到達する。コントローラーが Wi-Fi/Ethernet ネットワーク上にある場合、中間にボーダールーティングを経由する。コントローラーは確立されたサブスクリプションと認可に基づいて更新を受信し、電灯を点灯するかどうかを決定する。物理的な無線応答、IP 到達、Matter インタラクションの成功、電灯の実際の点灯は、それぞれ異なる完了ポイントである。
Matter のマルチ管理者メカニズムにより、複数のファブリックで認可管理が可能だが、購入した時点ですべてのエコシステムが自動的に権限を得るわけではない。デバイスタイプ、オプション機能、プラットフォームのサポートは、利用可能な制御に影響を与える。ネットワーク暗号化は伝送を保護するが、アプリケーションの権限が誰が解錠/設定変更を行うかを決定する。ブランド間の相互運用性は、認可を省略することを意味するものではない。
LoRa と LoRaWAN:無線パケットとネットワークサービスをまず区別する
LoRa は Semtech が推進するスペクトラム拡散変調技術体系である。LoRaWAN はデバイスのアクセス、メッセージ、セキュリティ、ネットワーク動作を定義する。LoRa 変調を使用してプライベートなピアツーピアパケットを送信しても、LoRaWAN ネットワークによって管理されるデバイスになるわけではない。周波数帯、チャネル、送信制限は地域の仕様とデバイスの実装によって決定され、433/868/915 MHz をどこでも自由に交換できるメニューとして扱うことはできない。
一般的な LoRaWAN はスター・オブ・スターズである:同じアップリンクは複数のゲートウェイで受信され、IP を介して Network Server にバックホールされ、ネットワーク側で重複排除と対応するネットワーク管理を調整する。ゲートウェイは依然として RF 受信、パケット転送、ダウンリンクスケジューリングなどのタスクを実行しており、「プロトコルを実行しない」ステートレスな電線ではない。アプリケーションデータはアプリケーション側のサービスによって処理され、ネットワークキーとアプリケーションキーには異なる役割があり、すべてのアプリケーションペイロードが Network Server によって復号されると一概に記述することはできない。LoRa Alliance:LoRaWAN アーキテクチャ
OTAA は接続プロセスを通じてセッション関係を確立する。セッションキー、カウンター、再起動後の状態保持は適切に処理する必要がある。無線 ACK またはネットワークサーバーがアップリンクを受信しても、業務データベースにすでに保存されていることを意味するものではなく、アプリケーションは依然としてメッセージ番号を使用して確認、重複排除、障害復旧を行うことができる。
SF が増加すると、同じパケットが空中で占有する時間が長くなる
従来の LoRa モデルでは、シンボル時間は Tsym=2^SF/BW である。帯域幅 125 kHz の場合、SF7 はシンボルあたり 1.024 ms、SF12 は 32.768 ms である。高い SF は検波能力と空中時間(ToA)を変更するが、必ずしもより遠く、より信頼性が高いとは限らない。より長い占有時間は衝突の機会と送信エネルギー消費を増加させる。Semtech:LoRa FAQ
明確な変調の教育条件を採用する:物理ペイロード 20 バイト、明示ヘッダー、CRC 有効、符号化率 4/5、プリアンブル 8 シンボル、SF12 で低データレート最適化を有効にする。従来の LoRa パケット長式によると、SF7 の空中時間は約 56.576 ms、SF12 は約 1318.912 ms となる。ここでの 20 バイトは変調器のペイロードであり、LoRaWAN のアプリケーションデータ 20 バイトではない。後者にはプロトコルフィールドを加える必要がある。Semtech:SX1276 データシート、LoRa time-on-air
100 ノードがすべて後者を使用し、600 秒ごとに1パケットを送信し、同じチャネル/SF に集中していると仮定すると、送信時間の合計のみで約 21.98% の時間を占有する。ランダムな重複、再送、ダウンリンクにより、容量はさらに変化する。これは負荷の見積もりであり、ある地域で許可されているデューティサイクルではなく、成功率を保証するものでもない。実際のデプロイメントでは、地域の仕様、法規、ネットワークポリシーに基づいて再予算化する必要がある。
ダウンリンクの遅延は受信ウィンドウによって決定される
TX 上り RX1 RX1 RX2 RX2 待機 待機 スリープに戻る LoRaWAN Class A:ダウンリンクの機会はアップリンクに続き、いつでも到達可能 ではない RX1 で対応する有効なダウンリンクを受信した場合、RX2 はこのアップリンクのために開かれない ウィンドウの時刻とパラメータは仕様と設定による;利用可能なウィンドウを見逃したコマンドは、次のアップリンクま で待つ可能性がある。図は時間比率で描画されていない。
カテゴリ 受信スケジュール ダウンリンク/消費電力の境界
Class A アップリンク後に RX1/RX2 をスケジュール ウィンドウを見逃すと次のアップリンクまで待つ必要がある;低デューティサイクルに適している
Class B 同期ビーコンを使用して追加の受信スロットをスケジュール より予測可能な機会だが、同期とリスニングのコストが必要
Class C 送信待機条件なしで可能な限り継続的に受信 待機時間を短縮するが、ゼロ遅延ではない;依然としてスケジューリングと空中時間の制約を受ける
Class C は「必ずコンセントに挿す必要がある」という物理法則ではなく、継続的な受信は通常、電力が豊富なシナリオにより適していることを意味する。すべてのノードが頻繁に確認を要求すると、ダウンリンクの負荷が増加する。LoRaWAN は少量の周期性データに適しており、キロ単位の到達距離から、頻繁な低遅延制御や大容量ファイルのアップグレードに適していると推論することはできない。
一バイトでシンボル群が増える理由は?
SFを固定し一バイトずつ増やすと段差が見える。20 BをSF7からSF12にすると56.576 msから1318.912 msへ変わる。縦軸固定で時間を比較し、距離や成功率は予測しない。
図を準備しています 再読み込み
一バイトでシンボル群が増える理由は? シンボル時間は2^SFで増え、ペイロード符号化は群単位で切上げるためバイト数に対して階段状となる。
{"id":"lora-airtime-staircase","title":"一バイトでシンボル群が増える理由は?","summary":"シンボル時間は2^SFで増え、ペイロード符号化は群単位で切上げるためバイト数に対して階段状となる。","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"control\"><label for=\"payload\" data-i18n=\"payload\"></label><output for=\"payload\" id=\"payload-value\"></output><input id=\"payload\" type=\"range\" min=\"1\" max=\"64\" value=\"20\" step=\"1\"></div><div class=\"control\"><label for=\"sf\" data-i18n=\"sf\"></label><output for=\"sf\" id=\"sf-value\"></output><input id=\"sf\" type=\"range\" min=\"7\" max=\"12\" value=\"7\" step=\"1\"></div><div class=\"chart-wrap\"><div class=\"chart-label\" data-i18n=\"packing\"></div><svg id=\"stairs\" class=\"curve\" viewBox=\"0 0 360 210\" role=\"img\" data-i18n-label=\"packing\"></svg></div><div class=\"chart-wrap\"><div class=\"chart-label\" data-i18n=\"plot\"></div><svg id=\"plot\" class=\"curve\" viewBox=\"0 0 360 210\" role=\"img\" data-i18n-label=\"plot\"></svg></div><div class=\"metrics\"><div><span data-i18n=\"symbols\"></span><strong id=\"symbols\"></strong></div><div><span data-i18n=\"symbol\"></span><strong id=\"symbol\"></strong></div><div><span data-i18n=\"time\"></span><strong id=\"time\"></strong></div></div><p id=\"eq\" class=\"formula\"></p><details class=\"scope\"><summary data-i18n=\"scopeLabel\"></summary><p data-i18n=\"scope\"></p></details>","css":".intro{margin:8px 0 18px;color:var(--muted);font-size:14px}.caption,.hint{font-size:12px;color:var(--muted);margin-top:12px}.control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;align-items:center;margin:14px 0;font-size:13px}.control label{font-size:13px}.control output{color:var(--accent);min-width:5em;text-align:right;font-variant-numeric:tabular-nums}.control input{grid-column:1/-1;width:100%;margin:0}.presets{display:flex;gap:4px;align-items:stretch}.presets button{flex:1 1 0;min-width:0;overflow-wrap:anywhere;font-size:13px}.actions{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}.actions button{flex:1;min-width:0;font-size:13px;min-height:42px}.copy{display:grid;font-size:14px;margin:16px 0}.copy>*{grid-area:1/1;margin:0}.reserve{visibility:hidden}.scope{margin-top:14px;color:var(--muted);font-size:12px}.scope summary{padding:8px 0;cursor:pointer}.scope p{margin-top:10px}.two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.card{border:1px solid var(--rule);border-radius:9px;padding:14px;min-width:0}.card header{font-size:14px;font-weight:600;margin-bottom:10px}.card button{font-size:12px;width:100%;min-width:0}.card small{display:block;font-size:12px;color:var(--muted)}.card code{font-size:12px;overflow-wrap:anywhere}.metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.metrics>div{border-left:2px solid var(--accent);padding-left:10px;min-width:0}.metrics span{display:block;min-height:3.2em;color:var(--muted);font-size:12px}.metrics strong{font-size:23px;display:block;font-weight:550;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.formula{border-top:1px solid var(--rule);padding-top:12px;margin-top:14px;font-size:13px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.value{font:550 20px ui-monospace,monospace}.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:12px;color:var(--muted);margin:12px 0}.legend span:before{content:'';display:inline-block;width:8px;height:8px;border-radius:2px;background:var(--accent);margin-right:6px}.legend .second:before{background:var(--second)}.check{display:flex;align-items:center;gap:8px;font-size:13px;margin:12px 0}.check input{width:16px;height:16px;flex-shrink:0;accent-color:var(--accent)}select,input[type=text],input[type=number]{background:var(--paper);color:var(--ink);font:inherit;font-size:13px;padding:10px;border:1px solid var(--rule);border-radius:7px;max-width:100%;min-width:0}select{width:100%;min-height:42px}.band{height:20px;display:flex;background:var(--surface);border-radius:4px;overflow:hidden}.band i{height:100%;display:block;background:var(--accent);transition:width .25s}.band i.second{background:var(--second)}button:disabled{cursor:default}.status{font-size:13px;min-height:4.8em}.mono{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums}.muted{color:var(--muted)}\n@media(max-width:480px){.two{gap:8px}.card{padding:12px 9px}.actions button,.presets button{font-size:12px}.metrics strong{font-size:20px}.metrics{gap:8px}}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n.track-row{margin:16px 0}.track-row>span{display:block;font-size:12px;color:var(--muted);margin-bottom:7px}.track{display:flex;gap:5px;min-width:0}.cell{flex:1;min-width:0;min-height:48px;border:1px solid var(--rule);border-radius:5px;background:var(--surface);display:flex;align-items:center;justify-content:center;text-align:center;padding:5px 3px;font-size:12px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.cell.on{background:var(--accent-soft);border-color:var(--accent)}.cell.gold{background:var(--second-soft);border-color:var(--second)}.cell.empty{border-style:dashed;color:var(--muted)}.cell.error{border-color:var(--second);text-decoration:line-through}.choices{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin:14px 0}.choices button{min-width:0;padding:10px 4px;font-size:12px;overflow-wrap:anywhere}.choices button[aria-current=true]{border-color:var(--accent);background:var(--accent-soft)}.relation{display:grid;grid-template-columns:minmax(0,1fr) 28px minmax(0,1fr);align-items:center;gap:6px;margin:12px 0}.relation .cell{min-height:72px}.relation>i{text-align:center;font-style:normal;color:var(--accent)}.readout{font-size:13px;white-space:pre-line;min-height:6.4em;overflow-wrap:anywhere}.plot{position:relative;border-left:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:8px 0;margin:18px 0}.plot-row{height:28px;position:relative;margin:4px 0;background:var(--surface)}.plot-row i{position:absolute;inset-block:5px;background:var(--accent);min-width:2px;transition:width .2s,left .2s}.plot-row b{position:relative;padding:4px 6px;font:11px/28px ui-monospace,monospace;background:var(--paper);border-radius:3px}.axis{display:flex;justify-content:space-between;font-size:11px;color:var(--muted)}\n\n/* Action labels must remain readable across locales and narrow embeds. */\n.actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}\n.actions button{overflow-wrap:anywhere;white-space:normal;min-height:58px;padding:8px}\nbutton{overflow-wrap:anywhere}\n@media(min-width:640px){.actions{grid-template-columns:repeat(3,minmax(0,1fr))}}\n\n.metrics span{overflow-wrap:anywhere}\n.panel{border:1px solid var(--rule);border-radius:9px;padding:12px;margin:14px 0;min-width:0}.panel h3{font-size:13px;margin:0 0 10px;color:var(--muted)}.source{font:13px/1.8 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;margin:12px 0}.source mark{background:var(--accent-soft);color:var(--ink);border-bottom:2px solid var(--accent)}.source .fault{background:var(--second-soft);border-color:var(--second)}.diagram{display:block;width:100%;height:auto;max-height:320px;margin:14px 0;overflow:visible}.diagram text{fill:var(--ink);font:12px ui-monospace,monospace}.diagram .edge{stroke:var(--muted);stroke-width:1.5;fill:none}.diagram .edge.on{stroke:var(--accent);stroke-width:3}.diagram .node{fill:var(--surface);stroke:var(--rule);stroke-width:1.5}.diagram .node.on{fill:var(--accent-soft);stroke:var(--accent)}.diagram .node.gold{fill:var(--second-soft);stroke:var(--second)}.log{font:12px/1.8 ui-monospace,monospace;white-space:pre-line;overflow-wrap:anywhere;min-height:7.2em}.table{display:grid;gap:5px;margin:14px 0}.table .tr{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}.table .tr>*{padding:8px 5px;background:var(--surface);border-radius:4px;min-width:0;overflow-wrap:anywhere;font-size:12px}.table .tr .on{background:var(--accent-soft)}.table .tr .gold{background:var(--second-soft)}.choices button{min-height:44px}.metrics strong{min-height:1.6em}.code-line{display:block}.code-line.on{background:var(--accent-soft);border-left:2px solid var(--accent);padding-left:6px}.status-badge{font-size:12px;color:var(--accent)}.tile-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}.tile-grid .cell{min-height:40px}.actions button{min-height:48px}.form-field{display:grid;gap:8px;margin:14px 0;font-size:13px}.form-field input{width:100%;font-family:ui-monospace,monospace}.metrics.three{grid-template-columns:repeat(3,minmax(0,1fr))}.formula{min-height:3.2em}.presets{flex-wrap:wrap}.presets button{flex-basis:25%;min-height:44px}\n\n.budget{display:flex;height:28px;margin:16px 0;background:var(--surface);border-radius:5px;overflow:hidden}.budget i{display:block;background:var(--accent);transition:width .2s}.budget i.gold{background:var(--second)}.intervals{margin:16px 0}.interval{position:relative;height:36px;background:var(--surface);margin:6px 0;border-radius:4px;overflow:hidden}.interval i{position:absolute;height:100%;background:var(--accent-soft);border-left:2px solid var(--accent)}.interval i.gold{background:var(--second-soft);border-color:var(--second)}.interval span{position:relative;z-index:1;font:12px/36px ui-monospace,monospace;padding-left:7px}.table .tr>*{min-height:4.8em}.formula{white-space:pre-line;min-height:7.2em}.actions:has(>button:only-child){grid-template-columns:1fr}.metrics strong{min-height:3.2em}.rangegrid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:3px;margin:14px 0}.rangegrid .cell{min-height:30px;padding:3px 1px;font-size:10px}.message{min-height:7.2em;white-space:pre-line;font:13px/1.8 ui-monospace,monospace;overflow-wrap:anywhere}\n/* Allow CJK hanging punctuation without overflowing a metric's border box. */\n.metrics>div{padding-right:4px}.metrics span{line-break:anywhere}\n\n.chart-wrap{margin:18px 0}.chart-label{font-size:12px;color:var(--muted);min-height:3.2em}.curve{display:block;width:100%;height:auto;max-height:320px;overflow:visible}.curve text{font:11px ui-monospace,monospace;fill:var(--muted)}.gridline{stroke:var(--rule);stroke-width:1}.metrics strong{font-size:20px;min-height:3.2em}.formula{font:12px/1.8 ui-monospace,monospace;min-height:9em}.readout{min-height:8em}.presets button{flex-basis:30%}.scope p{overflow-wrap:anywhere} .unit-note{font-size:12px;color:var(--muted);margin:10px 0}\n\n.metrics span{word-break:break-all;line-break:strict}.metrics>div{padding-right:6px}\n\n","js":"const $=s=>document.querySelector(s);const set=(id,v)=>$('#'+id).textContent=v;const t=k=>viz.t(k);function cells(id,values){$('#'+id).replaceChildren(...values.map(v=>{const e=document.createElement('div');e.className='cell '+(v.cls||'');e.textContent=v.text;e.title=v.title||v.text;return e;}));}function pressed(mode){document.querySelectorAll('[data-mode]').forEach(e=>e.setAttribute('aria-pressed',String(e.dataset.mode===mode)));}const esc=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const fmt=s=>'{'+[...s].sort().join(', ')+'}';function graph(id,nodes,edges){const el=$('#'+id);el.setAttribute('viewBox','0 0 360 200');el.innerHTML='<defs><marker id=\"arrow-'+id+'\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"var(--muted)\"/></marker></defs>'+edges.map(e=>{const a=nodes[e[0]],b=nodes[e[1]],dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1;if(edges.some(r=>r[0]===e[1]&&r[1]===e[0])){const nx=-dy/d,ny=dx/d;return '<path class=\"edge '+(e[2]?'on':'')+'\" d=\"M '+(a.x+dx/d*22+nx*12)+' '+(a.y+dy/d*22+ny*12)+' Q '+((a.x+b.x)/2+nx*38)+' '+((a.y+b.y)/2+ny*38)+' '+(b.x-dx/d*25+nx*12)+' '+(b.y-dy/d*25+ny*12)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}return '<line class=\"edge '+(e[2]?'on':'')+'\" x1=\"'+(a.x+dx/d*25)+'\" y1=\"'+(a.y+dy/d*25)+'\" x2=\"'+(b.x-dx/d*28)+'\" y2=\"'+(b.y-dy/d*28)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}).join('')+nodes.map(n=>'<g><circle class=\"node '+(n.cls||'')+'\" cx=\"'+n.x+'\" cy=\"'+n.y+'\" r=\"25\"/><text x=\"'+n.x+'\" y=\"'+(n.y+4)+'\" text-anchor=\"middle\">'+esc(n.name)+'</text>'+(n.sub?'<text x=\"'+n.x+'\" y=\"'+(n.y+43)+'\" text-anchor=\"middle\">'+esc(n.sub)+'</text>':'')+'</g>').join('');}function table(id,rows){$('#'+id).classList.add('table');$('#'+id).replaceChildren(...rows.map(r=>{const row=document.createElement('div');row.className='tr';row.style.gridTemplateColumns='repeat('+r.length+',minmax(0,1fr))';r.forEach(x=>{const c=document.createElement('div');if(typeof x==='object'){c.textContent=x.text;c.className=x.cls||'';}else c.textContent=x;row.append(c)});return row;}));}function band(id,parts,total){$('#'+id).replaceChildren(...parts.map((p,i)=>{const e=document.createElement('i');e.style.width=(100*p.value/total)+'%';e.className=i%2?'gold':'on';e.title=p.name+': '+p.value;return e}));}function intervals(id,items,total){$('#'+id).replaceChildren(...items.map(p=>{const row=document.createElement('div');row.className='interval';const bar=document.createElement('i');bar.style.left=(100*p.start/total)+'%';bar.style.width=(100*(p.end-p.start)/total)+'%';bar.className=p.cls||'';const label=document.createElement('span');label.textContent=p.label;row.append(bar,label);return row;}));}function plot(id,series,xr,yr,opts={}){const e=$('#'+id),X=x=>42+(x-xr[0])/(xr[1]-xr[0])*298,Y=y=>175-(y-yr[0])/(yr[1]-yr[0])*148;let out='<defs><clipPath id=\"clip-'+id+'\"><rect x=\"42\" y=\"27\" width=\"298\" height=\"148\"/></clipPath></defs>';for(let i=0;i<3;i++){let x=xr[0]+i*(xr[1]-xr[0])/2,y=yr[0]+i*(yr[1]-yr[0])/2;out+='<path class=\"gridline\" d=\"M '+X(x)+' 27V175M42 '+Y(y)+'H340\"/><text x=\"'+X(x)+'\" y=\"194\" text-anchor=\"middle\">'+esc(opts.xfmt?opts.xfmt(x):Number(x.toFixed(2)))+'</text><text x=\"36\" y=\"'+(Y(y)+4)+'\" text-anchor=\"end\">'+esc(opts.yfmt?opts.yfmt(y):Number(y.toFixed(2)))+'</text>';}out+='<g clip-path=\"url(#clip-'+id+')\">';for(const s of series){out+='<path fill=\"none\" stroke=\"'+(s.color||'var(--accent)')+'\" stroke-width=\"2.5\" '+(s.dash?'stroke-dasharray=\"5 4\"':'')+' d=\"'+s.pts.map((p,i)=>(i?'L':'M')+X(p[0]).toFixed(2)+','+Y(p[1]).toFixed(2)).join(' ')+'\"/>';}for(const p of opts.points||[])out+='<circle cx=\"'+X(p[0])+'\" cy=\"'+Y(p[1])+'\" r=\"4\" fill=\"var(--second)\" stroke=\"var(--paper)\" stroke-width=\"1.5\"/>';if(opts.cursor!==undefined)out+='<path d=\"M'+X(opts.cursor)+' 27V175\" stroke=\"var(--muted)\" stroke-dasharray=\"3 3\"/>';e.innerHTML=out+'</g>';e.dataset.curves=JSON.stringify(series.map(s=>s.pts));}const curve=(fn,lo,hi,n=120)=>Array.from({length:n+1},(_,i)=>{const x=lo+(hi-lo)*i/n;return[x,fn(x)]});function inputs(draw){document.querySelectorAll('input,select').forEach(e=>{e.addEventListener('input',draw);e.addEventListener('change',draw)});draw()}const n=id=>+$('#'+id).value;const show=(id,v,d=3)=>set(id,Number(v.toFixed(d)));function draw(){let p=n('payload'),sf=n('sf'),de=sf>=11?1:0,ts=2**sf/125,raw=x=>(8*x-4*sf+28+16)/(4*(sf-2*de)),sy=x=>8+Math.max(Math.ceil(raw(x))*5,0),time=x=>(12.25+sy(x))*ts,pts=[];for(let i=1;i<=64;i++)pts.push([i,time(i)],[i+1,time(i)]);show('payload-value',p);show('sf-value',sf);plot('stairs',[{pts:pts.map(([x,y])=>[x,y/ts-12.25])}],[1,65],[0,128],{points:[[p,sy(p)]]});plot('plot',[{pts}],[1,65],[0,3000],{points:[[p,time(p)]]});show('symbols',sy(p));show('symbol',ts,3);show('time',time(p),3);set('eq','DE = '+de+'; Tsym = 2^SF / BW\\nceil((8PL − 4SF + 44)/(4(SF−2DE))) = '+Math.ceil(raw(p))+'\\nNpayload = 8 + 5 × max(ceil(…), 0)\\nT = (8 + 4.25 + Npayload)Tsym');}inputs(draw);","audio":false,"strings":{"heading":"一バイトでシンボル群が増える理由は?","intro":"ペイロードとSFを変え、丸め前後と空中時間を見る。","packing":"横軸 ペイロード B、縦軸 ペイロードのシンボル数","payload":"PHYペイロード(B)","plot":"横軸ペイロードB、縦軸空中時間ms","reset":"リセット","scope":"従来LoRa:BW=125 kHz、CR=4/5、明示ヘッダー、CRC、前置8シンボル。SF11/12で低データレート最適化。PHYペイロードでLoRaWANアプリバイトではない。","scopeLabel":"モデルの範囲と前提","sf":"SF","symbol":"一シンボル(ms)","symbols":"ペイロードシンボル数","time":"空中時間(ms)"}}
セルラー IoT:ゲートウェイを自前で構築しない場合でも、ネットワークとウェイクアップを管理する必要がある
NB-IoT/LTE-M はセルラーインフラストラクチャを活用し、現場での LPWAN ゲートウェイの自前構築の一部の作業を省略するが、依然として互換性のあるモジュール、SIM/eSIM、ネットワークカバレッジ、サービス管理が必要である。デプロイメントごとのモバイル性、転送速度、ローミング、カバレッジ強化機能は異なり、「NB-IoT は固定 250 kbit/s」としてすべてのバージョンや現場の動作を表すものではない。
PSM はデバイスをより深い省電力状態にさせる。この間、ネットワークからいつでもページングされることは通常ない。eDRX はページングリスニング周期を延長し、その代わりにより長いダウンリンク待機時間を引き換える。アタッチ、弱カバレッジでの再試行、カバレッジ強化のための重複送信は、アプリケーションの小さなパケット自体よりもはるかに多くのエネルギーを消費する可能性がある。ネットワークがダウンリンクをキャッシュするかどうか、そしてどの程度キャッシュするかはデプロイメントに依存し、クラウドコマンドがすでに送信されたからといって、デバイスがすぐに受信するとは限らない。GSMA:Mobile IoT デプロイメントガイド
NFC/RFID:距離が短いからといって、身元が信頼できるわけではない
NFC は 13.56 MHz の近接インタラクションに基づいており、一般的な用途にはタグの読み書きとカードの模擬が含まれる。パッシブタグはリーダー/ライターのフィールドからエネルギーを取得するため、タグ自体には電池が必要ないが、システム全体がゼロ消費電力であるわけではない。読み取り範囲はコイル、マッチング、金属環境、デバイス能力の影響を受け、特定のタグが1メートルの読み取りを常に保証するものではない。NFC Forum:テクノロジー概要
NFC Forum Tag Type はプロトコルとデータマッピングなどを記述するものであり、製品ブランド、固定容量、またはセキュリティレベルの同義語ではない。Type 4 が自動的にすべてのタグに同じセキュリティメカニズムがあることを意味するものではなく、Type 5 が ISO 15693 と関連しているからといって、スマートフォンが産業用遠距離リーダーとして使用できるわけではない。実際のチップの認証、ストレージアクセス、キーの能力を確認する必要がある。NFC Forum:仕様
RFID の範囲はより広く、LF/HF は通常近接結合を利用し、UHF タグは通常バックスクラッターを使用する。UID を読み取っただけでは、識別子を受信しただけであることを示すに過ぎない。アクセス制御に使用する場合、具体的なプロトコルの認証とリプレイ攻撃防止設計に基づいて判断する必要があり、UID 自体を複製不可能な秘密として扱うことはできない。
UWB:ToF は距離であり、測位には幾何学とキャリブレーションが必要
UWB の広帯域時間領域特性は、到達時間の正確な推定に役立つ。応答処理時間を正しく差し引いた後、往路伝播の残り時間が 20 ns の場合、d=c×20ns/2≈3.0 m となる。往路測定誤差がわずか 1 ns であっても、約 15 cm の距離誤差に対応する。処理遅延、両端のクロック、アンテナ遅延は無視できない。FiRa:UWB テクノロジー FAQ
単一の距離は円/球面を1つ制約するだけであり、完全な位置は複数のアンカー、角度、または運動情報と組み合わせる必要がある。非視界、人体による遮蔽、マルチパス、アンカーの幾何配置はバイアスをもたらす可能性があり、「センチメートルレベル」にはテスト条件を付記する必要がある。セキュリティ測距には、対応するプロトコルとアイデンティティのバインディングが必要であり、すべての UWB パルスが天然に完全なスマートロックセキュリティを備えているわけではない。
UWB は BLE と連携できる:BLE は低消費電力の発見と制御に使用され、精密な測距が必要な場合に UWB をウェイクアップさせる。全体の消費電力は測距頻度と送受信スケジュールに依存し、技術名を直接「中程度消費電力」に置き換えることはできない。
要件を計算可能な選択条件として記述する
要件の例 優先して検証すべき質問 考えられる技術的方向
家庭用ドアセンサー、バッテリー駆動、イベントレポート ルーターの常時オンライン、コントローラーの相互運用性、イベントの遅延要件 Thread/Matter、Zigbee など
農地用、10分ごとに1パケット リンク予算、ゲートウェイバックホール、空中時間とダウンリンク待機 LoRaWAN またはカバレッジのあるセルラー IoT
都市部の分散型検針 現場カバレッジ、運用保守、ディープスリープからのウェイクアップコスト NB-IoT/LTE-M など
接近時のプロビジョニングまたはタグ読み取り 操作距離、スマートフォン API、タグ認証 NFC
ドアロック付近での精密測距 アイデンティティバインディング、NLOS、消費電力とキャリブレーション 発見リンクと連携する UWB
これらは評価の方向性であり、地域、デバイス、ビジネス条件を無視した固定推薦ではない。
LoRa 空中時間と ToF の再計算
from math import ceil , isclose
def airtime ( sf , payload_bytes = 20 , bw = 125000 ) :
de = int ( sf >= 11 ) tsym = 2 * * sf / bw
numerator = 8 * payload_bytes - 4 * sf + 28 + 16
payload_symbols = 8 + max ( ceil ( numerator / ( 4 * ( sf - 2 * de ) ) ) * 5 , 0 )
return ( 8 + 4. 25 + payload_symbols ) * tsym
assert isclose ( airtime ( 7 ) , 0. 056576 )
assert isclose ( airtime ( 12 ) , 1. 318912 )
assert isclose ( 100 * airtime ( 12 ) / 600 , 0. 2198186666666667 )
c = 299792458
assert isclose ( c * 20e-9 / 2 , 2. 99792458 )
assert isclose ( c * 1e-9 / 2 , 0. 149896229 )
print ( ' LoRa パケット時間、集約負荷および往路 ToF 変換チェック通過' )
ここではモデルによる予算見積もりであり、無線パケットは送信されておらず、現場のカバレッジや測位精度も測定されていない。
継続的な参照