Hobby Lab 趣味のモノ作り実験のサイトです。
Software Protocol 1Wire 全般
1 概要
2 特徴
2.1 配線が簡素
2.2 遠距離の通信が可能
2.3 複数機器の接続
2.4 デバイス信頼上の注意点
3 64bit ROMコード
3.1 コードの構造
3.2 各コード概要
3.2.1 8bit CRC
3.2.2 48bit 固有コード
3.2.3 8bit ファミリーコード
4 データ並び
4.1 データの格納方法
4.2 シリアル通信のビット順番
5 基本通信手順
5.1 初期化 RESET &
5.2 Write Time Slot
5.3 Read Time Slot
6 その他通信手順
6.1 ROM検索
6.1.1 初期化
6.1.2 コマンド送信1Byte (0X0F)
6.1.3 コマンド受信 :2bit
6.1.4 2bitデータを確認して処理
6.1.5 64bitROMコード完成か確認
6.1.6 具体的なプログラム内容
6.1.7 動作確認

1-Wire関係
プロトコル
 1-Wireについて
スレーブ関係資料
 DS18B20 温度測定
 DS18B20 テスター
マスター関係プログラム
 DS18B20_Arduino
 DS18B20_RaspberryPi
 DS18B20_CH32V

Sf:Pt プロトコル関係
SfPt:MODBUS
Sf:OS関係
SfO:Mint 関係
 PCへMint導入
 アプリ導入
 その他1
 アイコンを作る
SfO:Ubuntu 関係
 PCへUbuntu導入
 アプリ導入
SfO:RaspberryPi 関係
はじめに
 RaspberryPiへOS導入
 アプリ導入
 Programming
シェル・コマンド関係
 LXTerminal
 sed
 i2ctools
I/O・アプリ関係
 RealVNCとViewer
 IO動作確認
 MySQL
 Python
 raspberrypiハード
Sf:Server 関係
SfS:レンタルサーバー
 CORE-X
SfS:Windowsサーバー
 XAMPPの概要と導入
 Note XAMPP
 Note XAMPP Err
 Note Apache
 Note PHP
 Note MyQSL
Sf:Programming関係
C 関係
 C言語でプログラムミング
Python 関係
はじめに
 RaspberryPi開始
 Windows開始
共通事項
 プログラミングNote
 パッケージ導入 pip
 標準ライブラリ
 Serialライブラリ
 SMBusライブラリ
HTML関係
 開始とNote
Sf:IDE 開発環境
SfI:STM32
 STM32CubeIDEでプログラム
 HALと直接レジスター操作の速度
SfI:CH32
 MounRiver Studioでプログラム
SfI:Arduino
各ボード毎の設定
 Uno 設定
 Mega2560 設定
 DUE_CH340 設定
 ESP_WROOM02 設定
 ESP12F_D1mini 設定
 ESP32 設定
 CH32V 設定
ライブラリー
 OneWire使い方
その他
 日本語リファレンス(外部リンク)
 WiFi Macアドレスを調査
Sf:AP アプリ関係
SfA:エディタ
SfA:回路図CAD
SfA:回路シミュレータ
 シミュレーションの設定
 色の設定
 電源設定設定
SfA:リモートソフト
Sf:Otgers その他

1 概要

1-Wireは、Maxim Integrated(現アナログ・デバイセズ)が開発した、1本の信号線と接地線(GND)だけで通信と電力供給の両方を実現する独自の低速シリアル通信規格です。
今回はDS18B20と言うデジタル温度計をRISC-V系のMPUで使用するために調査してみた。





2 特徴


2.1 配線が簡素

信号線とGNDのわずか2本の配線で通信可能。
配線を2本に出来るのは、データラインを通じて通信だけでなく、デバイスの動作に必要な電力も供給できる。
通信線で電源を供給できない場合は、電源供給用の線が1本増え合計3本の線が必要となる。

2.2 遠距離の通信が可能

500メートル程度までの長距離通信をリピーター不要で実現できる。

2.3 複数機器の接続

通信ラインには1つのマスターデバイスに対して、複数のスレーブデバイスを並列に接続できる。

2.4 デバイス信頼上の注意点

スレーブディバイスには64bitの固有の登録番号を持っている。
8bitのファミリーコードと48bitの固有コードを持っているので無限に接続しても識別が可能となっている
現在上記コードの管理は (Dallas Semiconductor→Maxim Integrated→) Analog Devices で行っている。

非正規品のデバイスを購入した場合はこのコードが重複している可能性が有るため、3項で説明した 複数のデバイスが接続できない可能性が発生するので正規品の購入が必要。


私は Analog Devices 社の製品か確認する方法がわからないので、デバイスを使用する場合はコードを必ず確認することにする。




3 64bit ROMコード

3.1 コードの構造

DS18B20のデータシートには

と記載されていた。


3.2 各コード概要

3.2.1 8bit CRC

次以降に説明する56bitの巡回冗長検査 CRC を行いこの8bitに収めます。
多項式関数は CRC = X8 + X5 + X4 + 1

3.2.2 48bit 固有コード

48bitで表すことが出来る10進数値は 280兆 らしいので、280兆個の識別が出来る。

3.2.3 8bit ファミリーコード

ファミリーコード例
コード 品 番 例 用  途
0x01 DS2401, DS1990Aシリコンシリアルナンバー (ROM IDのみ)
0x04 DS2431 1Kb EEPROM
0x06 DS2406, DS2407 I/Oエキスパンダ、スイッチ
0x10 DS18S20, DS1820温度センサー
0x12 DS2438 スマートバッテリーモニター、湿度センサー
0x23 DS2416 デュアルチャンネルアドレサブルスイッチ
0x26 DS2760 バッテリーパックモニター
0x28 DS18B20, MAX31826高分解能温度センサー
0x30 DS2413 デュアルチャンネルPIO
0x81 DS28E01 1Kb ECC EEPROMセキュア認証




4 データ並び

4.1 データの格納方法


1-Wireはリトルエンディアン(Little Endian)を採用していると思われる。


1-WireのEPROMはリトルエンディアンだと言うことをGoogle AIで確認した。
Little EndianBig Endian
格納順位データの最下位バイトが先頭アドレスに格納される。データの最上位バイトが先頭アドレスに格納される。
例 0x12345678メモリ上では 78 56 34 12 の順に格納される。メモリ上では 12 34 56 78 の順に格納される。
採用例 Intel系 (x86) やARM。現在の一般的なPCやサーバーの多く。かつての大型汎用機、ネットワークプロトコル (TCP/IP)。

4.2 シリアル通信のビット順番


ビット順番はLSBファーストと思われる。


データシートなどに記載が無いが、DS18B20のROMコードを読んだ場合は最初にファミリーコードでLSB値が先頭になっていた。
次に送られてきたデータは固有コード、CRC値の順だった。




5 基本通信手順

通信手順は(マスターから見て)
1.初期化
2.コマンド送信
3.データ受信
ここではデータシートを読んで私なりに理解したものを書いているので、間違っていたらお教えください。

5.1初期化

この信号を RESET AND PRESENCE PULSES と言う。

(1)リセット信号 T0 500(us)とする。
 マスターから最初にこの期間 Lo 信号を出力する。
 DS18B20では最小480(us)から余裕をみる。

(2)プレゼンス信号待ち時間
 マスターのリセット復帰からスレーブのプレゼンス信号を送信するまでの待ち時間 15〜60(us)
 この間はバスは Hi 状態。

(3)プレゼンス信号
スレーブ機器が反応して 60〜240(us)の間 Lo 信号を出力する。


(4)プレゼンス信号確認時間 T1 90(us)とする。
マスターがリセット信号を出し終わってから 上記期間後にバス電圧を確認する。
正常なら Lo である。
T1 = tPDHIGH(max) + (tPDLOW(min) / 2) ≒90(us) とした。

(5)次信号までの待ち時間 T3 410(us)とする。
マスターがリセット信号を出し終わってからの時間。
DS18B20では tRSTH > 480(us)になっており、 T3 = tRSTH(480) ー T1(90) + α(20)

5.2コマンド送信 Write Time Slot

この信号を書き込みスロットと言っている。
私は下記のように時間を決めている。

(1)データ送信開始信号 TSO 2(us) とする。
マスターからスレーブに対し書き込むデータを送るということを知らせるための信号だ。
マスターが 1(us) 以上 Lo 信号を出力することになっているので余裕をみた。

(2)スレーブデータ読出し時間
マスターが Lo 信号をだしてから15(us)〜60(us)の間で読み出している。
DS18B20では標準的な読み出し時間は 30(us) と記載があった。

(4)マスターのデータ送信 TS5 60(us) とする。
DS18B20のTS1〜TS3の値から TS5 = TS1 + TS2 + TS3 -TR0 = 58(us)
なおデータとして bit値 0 でバス電圧 Lo 、bit値 1 でバス電圧 Hi の信号となる。

(5)次信号までの待ち時間 TREC 2(us) とする。
TREC は TS0 と同じ考え方で 2(us)とするが、マスターで処理が遅れた場合は最大時間として60(us)とする。
DS18B20には次のデータを送るまでの時間として最大 ∞ と書いている。
しかし私は最大 60(us) としてプログラムする。

5.3データ受信 Read Time Slot

この信号を読み込みスロットと言っている。
私は下記のように時間を決めている。

(1)データ受信開始信号 TRO 2(us) とする。
マスターからスレーブに対し読み込むデータを送ってくれということを知らせるための信号だ。
マスターが 1(us) 以上 Lo 信号を出力することになっているので余裕をみた。

(2)スレーブデータ送信
スレーブはデータbit値が 0 の場合、マスターの開始信号(Lo)を1(us)程度で確認しすぐ、バスの Lo 状態に途切れなくデータ信号(Lo)を出している。
これはDS18B20の信号により確認ができた。

この後スレーブのデータ信号が復帰する時間はマスターがLo信号を出してから 15(us)〜60(us)となっている。
なおスレーブのデータとしてマスターと同じ bit値 0 は Lo、bit値 1 は Hi の信号となる。

(3)スレーブデータ信号確認時間 TR3 6(ns)とする
スレーブのデータ最小復帰時間の前に検出する必要がある。
TR3 = (TR1 / 2) ー TR0 = 5(us)とする。

(4)読み込みデータ待ち時間 TR4 56(ns)とする。
マスターがスレーブデータを読み込んだ後、スレーブがデータ送信復帰最大時間を待つ時間。
TR4 = TR1 + TR2 ー TR0 ー TR3 = 52(us)から余裕をとる。

(5)次信号までの待ち時間 TREC 2(us) とする。
TREC は TS0 と同じ考え方で 2(us)とするが、マスターで処理が遅れた場合は最大時間として60(us)とする。
DS18B20には次のデータを送るまでの時間として最大 ∞ と書いている。
しかし私は最大 60(us) としてプログラムする。




6 その他通信手順

6.1 ROM検索

DS18B20の場合:SEARCH ROM [0xF0] となっているが、全ての1-Wireスレーブが当てはまるか確認していない。
参考URLは1-Wire 検索アルゴリズム
私が解釈した概略フローは
[1]マスターから初期化コマンドを送信(6.1.1参照)
      ↓
[2]マスターから検索コード[0xF0]を送信(6.1.2参照)
      ↓
[3]各スレーブから自分のRomCodeのLSB+N(N=繰返し数で最初は0)値を送信
 ※[5]から来た場合は[4]のRomCodeと同じ場合にLSB+Nのコード値を送信する。
  1回目は各スレーブから自分のコードを送信
  2回目は各スレーブから自分のコードを反転して送信
 この2回の信号により先の4種類を検出する。(6.1.3項参照)
      ↓
[4]マスター側で決定したLSB+N(N=繰返し数で最初は0)の値を送信(6.1.4参照)
      ↓
[5]最後のROM Code bit(64)まで[3]へ繰り返す(6.1.5参照)

6.1.1 初期化

 5.1 RESET AND PRESENCE PULSES
(1)マスター:リセット信号
(2)全スレーブ:PRESENCE信号
 返答がない場合は:検索コマンド終了処理

6.1.2 コマンド送信1Byte (0X0F)

 5.2 コマンド送信 Write Time Slot × 8bit を使用して送信

6.1.3 コマンド受信 :2bit

 5.3 データ受信 Read Time Slot × 2nbit を使用して受信

BUSに接続されている各スレーブから自分のRomCodeが同時にファミリーコードのLSBから順に最後のCRC MSBまで送信されるが
各スレーブには4種類の状態があり1回の答えでは判らないため2回=2bitの信号送ることにしている。
1回目
スレーブの値Bus電圧マスターが取得する値
全て0 Lo0
全て1 Hi1
0と1が混在Lo0
対象なし Hi1

しかし、信号には2値(電圧Loと電圧Hi)しか無いので、4種類を区別することができない。 このため2回目には各スレーブから自分のコードを反転して送信
スレーブの値Bus電圧マスターが取得する値
全て0 Hi1
全て1 Lo0
0と1が混在Lo0
対象なし Hi1

1回目の値と2回目の値を組み合わせることにより4種類に別ける事ができるようになる。
スレーブの値マスターが取得する値
1回目2回目
全て0 01
全て1 10
0と1が混在00
対象なし 11

これをbit値として判りやすく順に並べた表にすると
Bit(1)Bit(2)内容
00関係するROM番号の現在のビット位置には0と1の両方があります。
01参加する ROM 番号のビットには 0 のみがあります。
10参加する ROM 番号のビットには 1 のみが含まれます。
11検索に参加しているデバイスはありません。

6.1.4 6.1.3項の2bitデータを確認して処理

11なら
最初の64bitROMコードのLSBなら:検索コマンド終了処理[正常終了]
以外なら:検索コマンド終了処理 [異常(途中でスレーブが消えた)処理]

00,01,10なら
00の場合は種類のスレーブがいるので、どれでも選択しても良いがここではb0 値とする
 b1のスレーブは次の初期化まで沈黙する。
該当する最初のbit値を64bitROMコードのデータに加える。

上記bit値をコマンド送信 マスター:1bit bx値

 5.2 コマンド送信 Write Time Slot × 1 を使用して送信

6.1.5 64bitROMコード完成か確認

未完なら63bit分は3項へループ処理
64bit分終わったら
64bitROMコードをEEPROMの配列へ記録する。
スレーブの接続制限個数内なら

 1項 初期化へ戻る

 スレーブの接続個数制限値なら検索コマンド終了処理[制限値である処理]

6.1.6 具体的なプログラム内容

(1)プログラム変数
型名変数名初期値説明
uint8_tFamilyCode0x28DS18B20のファミリーコード
uint8_tdfSlaveMax8スレーブの最大接続数
uint8_tSearchRomSlaveNo0サーチromCodeしているスレーブNo(No=最大dfSlaveMax)
uint8_tbitPos[SearchRomSlaveNo]0ROM Codeが決まっているbit位置0~63 LSB=0
uint64_tRomCode64[SearchRomSlaveNo]0スレーブのRomCode
uint8_tSlaveValue0サーチしたスレーブ数-1
uint64_tRomCodeD01次RomCode
uint64_tbit10First受信データ 最大64bitシフトをするためuint64_t
uint8_tbit30Second受信データ
uint8_tbit20LSB+1=bit1、LSB=bit3 6.1.3参照
uint8_terrcode0エラーコード

(2)エラーコード
エラーコード説明
0b00000001接続が無い
0b00000010bit2=3 検索に参加しているデバイスが無い

(3)プログラム説明
SlaveValue = 0 ; //スレーブ数クリア:初期値
RomCode64[0 ~ dfSlaveMax-1] = 0; //全スレーブROM Codeのクリア
RomCode64[0]=FamilyCode;//最初のスレーブ検索にファミリーコード条件を入力
bitPos[0]=7;//最初のスレーブROMCodeの決定しているbitポジション(ファミリーコード 8Bit-1= 7 )設定

while ( SearchRomSlaveNo < dfSlaveMax )
//以下内容をスレーブ最大数まで繰り返す
●RESET AND PRESENCE PULSE
RomCodeD = 0;
●Write Time Slot 0xF0 (SearchROM)
for( i1 = 0 ; i1 < 64 ; ++i1 )
// 以下内容を64回繰り返す:最初のbitはLSBから始まる。
●Read Time Slot bit1
●Read Time Slot bit3
bit2 = bit1➡LBS+1、bit3➡LSB
if ( bitPos[SearchRomSlaveNo] >= i1)
bit1 = (RomCode64[SearchRomSlaveNo] >> i1) & 0x01;
//決まっているbitポジションならマスターが送信するbitを決まっているコードにする。
else
switch(bit2)
//決まってないなら、スレーブのデータを解析する。
case 0x00: //他にCodeが有り:
if ( SlaveValue < dfSlaveMax - 1 )
//スレーブが制限1個前を超えない(追加しても良い)場合の処理
++SlaveValue; //RomCodeスレーブ数を+1(検索スレーブを追加)
RomCode64[SlaveValue] = RomCodeD ; //今までのRomCodeを追加するスレーブにコピー
RomCode64[SlaveValue] |= 1UUL << i1 ;//マスターが決定する値と反対の値を入れる
bitPos[SlaveValue] = i1 ; //追加したスレーブの決定したbil数を入れる

case 0x03: //対象がいなくなった処理
RomCode64[SearchRomSlaveNo] = 0;
errcode = 0x02;
goto end_loop;


RomCodeD |= bit1 << i1; //bitデータを64bitデータへ入力
●Write Time Slot bit1
RomCode64[SearchRomSlaveNo]=RomCodeD;
if( SearchRomSlaveNo == SlaveValue ){ break; }
++SearchRomSlaveNo;
end_loop:
return errcode;

6.1.7 動作確認

テスト状況















右図はオシロ波形 ➡
水色線が 1-Wire (DS18B20)の信号
赤色線が1-Wire の 1bit信号で 値が1 のときにHiになる。
青色線が1-Wire の 1bit分の信号でその間はHiになっている。
全8スレーブの検索で 133(ms) かかっている。

1スレーブ分の拡大オシロ波形

水色線について(左側から)
・RESET AND PRESENCE PULSE
・Write Time Slot 0xF0
・下記信号が64
 ・スレーブ信号 2
 ・マスター決定信号 1







もう少し拡大信号
以上です!(続きは CH32V test_ModBusで応用例を記載する。





































更新日 2026/01/17 08:45  管理者 平林 剛Hirabayashi Takeshi