稼働中

Raspberry Pi Pico(s_02)DS18B20 用モジュール (1wire)

DS18B20 DS18B20c.py

DS18B20は1-Wireディジタル温度計です。
1本の信号線のみで双方向通信かつ電源供給可能な方式です。※詳細はデータシートを参照ください。
DS18B20センサーモジュールで使う自作の’DS18B20c.py’を記事d_05を元に作成しました。’DS18B20c.py’は末尾にあります。
※開発環境はThonnyです。ThonnyでMicroPythonをRaspberry Pi Pico with RP2040にインストールして使っています。

使い方

■ファイル転送
Raspberry Pi Picoへ’DS18B20c.py’を送った後でimportして使います。
※DS18B20c.pyの末尾に、使用例(DS3231T_ex.py)の## example以降をコピペ追加しても動作確認できます。
■メソッド
‘DS18B20c.py’をimportすると「select_rom, Convert_T, Read_SPAD, disp_SPAD, ds_Temp, Write_SPAD, Recall_E2, Read_PS, Read_Rom, Convert_S, Copy_SPAD」のメソッドが使えるようになります。
DS18B20(Pin(num))で初期化します。
Pin(num)はDS18B20のDQピンと接続するGPIOの番号です。

(01)select_rom(d_scan,num=0)
バス上の1wireデバイスをスキャンして得たrom-codeリスト(d_scan)からnumのrom-codeを得ます。
(02)Read_Rom()
バス上に1wireデバイスが1つしかない場合にrom-codeを取得できます。
(03)Convert_S()
温度データをSCRATCHPADの温度レジスタに保存します。rom-codeを送信しないのでバス上に1wireデバイスが1つしかない場合などに使います。
(04)Convert_T(r_code)
温度データをSCRATCHPADの温度レジスタに保存します。
(05)Read_SPAD(r_code)
SCRATCHPADを読みます。bytearray(9)を返します。
(06)Write_SPAD(r_code, TH=0x4b, TL=0x46, Cfg=0x7f)
SCRATCHPADのTH、TL、Configレジスタに書込みます。
(07)disp_SPAD(buf)
SCRATCHPADのデータbytearray(9)を表示します。
(08)ds_Temp(buf)
符号付きで温度を返します。bufはSCRATCHPADのデータbytearray(9)を与えます。
(09)Copy_SPAD(r_code)
SCRATCHPADのTH、TL、Configレジスタの値をEEPROMにコピーします。
(10)Recall_E2(r_code) # RECALL E2
EEPROMの値をSCRATCHPADのTH、TL、Configレジスタに書込みます。
(11)Read_PS(r_code)
Power SupplyをParasite(0)/Externally(1)で返します。
通信線で供給Parasite(0)/外部電源Externally(1)で返します。
※r_codeはrom-codeです。rom-codeはデバイス固有の8bytes(64bit)データです。

使用例

以下は温度測定、SCRATCHPADデータの読書き、リコールなどを確認しています。


DS18B20_ex.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
from machine import Pin
import onewire
import time
from DS18B20c import DS18B20
## # DS18B20 Programmable Resolution 1-Wire Digital Thermometer
## example
a=DS18B20(Pin(12)) #instance

s_dat=a.ow.scan() # GPIO 12のデバイスROM

## ROM_CODE GET
rom_code=a.select_rom(s_dat,0)
print(rom_code,rom_code[0])
print('')

# rom_code=a.Read_Rom()
# print(rom_code,rom_code[0])
# print('')

#a.Convert_S()           # CONVERT T(SKIP_ROM)
a.Convert_T(rom_code)    # CONVERT T(MATCH_ROM)
 
#Read_SPAD >> print
print('Current SPAD')
buf=a.Read_SPAD(rom_code)
a.disp_SPAD(buf)
print('')

#Temperature cirius 
temp=a.ds_Temp(buf)
print('TEMP=%4.2fc' %temp)
print('')
 
#Write_SPAD(TH,TL,Config)
#a.Write_SPAD(rom_code)
a.Write_SPAD(rom_code,0x30,0x20,0x7f)
print('Write_SPAD')
buf=a.Read_SPAD(rom_code)
a.disp_SPAD(buf)
print('')
 
#a.Copy_SPAD(rom_code) 
a.Recall_E2(rom_code)
print('SPAD_DATA')
buf=a.Read_SPAD(rom_code)
a.disp_SPAD(buf)
print('')

# Read Power Supply 通信線(0)外部(1)
print(a.Read_PS(rom_code))

実行結果 
実行すると以下のようになりました。※Thonnyのshellに表示されます。


DS18B20_ex.py
>>> %Run -c $EDITOR_CONTENT
bytearray(b'(\xffe\xf8\x93\x16\x05S') 40

Current SPAD        #SCRATCHPADデータ
bytearray(9)= bytearray(b'\xe4\x01KF\x7f\xff\x7f\x10p')
0  228  0xe4
1    1  0x1
2   75  0x4b
3   70  0x46
4  127  0x7f
5  255  0xff
6  127  0x7f
7   16  0x10
8  112  0x70

TEMP=30.25c         #温度測定の結果

Write_SPAD          #SCRATCHPADデータ書込み
bytearray(9)= bytearray(b'\xe4\x010 \x7f\xff\x7f\x10\x9d')
0  228  0xe4
1    1  0x1
2   48  0x30        #write data
3   32  0x20        #write data
4  127  0x7f        #write data
5  255  0xff
6  127  0x7f
7   16  0x10
8  157  0x9d

SPAD_DATA          #RECALL EEPROMからSCRATCHPADに書込み
bytearray(9)= bytearray(b'\xe4\x01KF\x7f\xff\x7f\x10p')
0  228  0xe4
1    1  0x1
2   75  0x4b        #write data
3   70  0x46        #write data
4  127  0x7f        #write data
5  255  0xff
6  127  0x7f
7   16  0x10
8  112  0x70

1                   #Power Supply externally(1)
>>> 

DS18B20用モジュール


DS18B20c.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
from machine import Pin
import onewire
import time

## # DS18B20 Programmable Resolution 1-Wire Digital Thermometer
## ROM COMMANDS 
# SEARCH_ROM = 0xF0     # 240
READ_ROM = 0x33
MATCH_ROM = 0x55        # 85
SKIP_ROM = 0xCC         # 204
# ALARM_SEARCH = 0xEC   # 236

## DEVICE COMMANDS
CONVERT = 0x44      #CONVERT T [44h] 
RD_SCRATCH = 0xBE   #READ SCRATCHPAD [BEh]  
WR_SCRATCH = 0x4E   #WRITE SCRATCHPAD [4Eh]
CP_SCRATCH = 0x48   #COPY SCRATCHPAD [48h]
RECALL_E2 = 0xB8    #RECALL E2 [B8h]
RD_POWER = 0xB4   #READ POWER SUPPLY[B4h]

class DS18B20:
    def __init__(self,o_pin=Pin(12)):      
        self.ow = onewire.OneWire(o_pin)  # GPIO 12 で OneWire バスを作成

    def select_rom(self,d_scan,num=0):
        self.rom_code = d_scan[num] # ここではデバイスは1つだけなのでs[0] 2つ目ならs[1]
        self.family_code=d_scan[num][0] # FAMILY CODEはs[0][0] bytearray(8)no[0]
        return self.rom_code

    # READ_ROM 1wire device がひとつだけ
    def Read_Rom(self):
        self.buf = bytearray(8)
        self.ow.reset(True)
        self.ow.writebyte(READ_ROM)     #READ_ROM = 0x33
        self.ow.readinto(self.buf)      #buf=rom_code
        #print('READ_ROM=',self.buf)
        return self.buf

    ## CONVERT T(SKIP_ROM)
    def Convert_S(self):
        self.ow.reset(True)
        self.ow.writebyte(SKIP_ROM)     #ow.SEARCH_ROMでも可
        self.ow.writebyte(CONVERT)
        time.sleep_ms(750)

    ## CONVERT T(MATCH_ROM)
    def Convert_T(self,r_code):
        self.ow.reset(True)
        self.ow.writebyte(MATCH_ROM)    #ow.MATCH_ROMでも可
        self.ow.write(r_code)           #8bytes
        self.ow.writebyte(CONVERT)      #温度データをSCRATCHPADに書込む
        time.sleep_ms(750)

    ## READ SCRATCHPAD  レジスタデータ読出し 9bytes
    def Read_SPAD(self,r_code):    
        self.buf = bytearray(9)
        #self.ow.select_rom(rom_code) 
        self.ow.reset(True)          #select_romはreset~writeと同じ
        self.ow.writebyte(MATCH_ROM)
        self.ow.write(r_code)
        self.ow.writebyte(RD_SCRATCH) #RD_SCRATCH=0xBE READ SCRATCHPAD
        self.ow.readinto(self.buf)
        print('bytearray(9)=',self.buf)
        return self.buf

    ## WRITE SCRATCHPAD byte 2,3,4 TH,TL,config レジスタ書込み
    def Write_SPAD(self, r_code, TH=0x4b, TL=0x46, Cfg=0x7f):
        ##TH,TL,config レジスタ書込みデータ
        buf = bytearray(3)
        buf[0]=TH  # TH Register 0x4b =78.0deg 0x20>32c
        buf[1]=TL  # TL Register 0x46 =70.0deg 0x14>20c
        buf[2]=Cfg  # Configuration Register 0x7fb  12bit
        #
        self.ow.reset(True)
        self.ow.select_rom(r_code)
        self.ow.writebyte(0x4e) #_WRITE SCRATCHPAD [4Eh]
        self.ow.write(buf)

    ## temperature変換
    def ds_Temp(self, buf):    
        # SCRATCHPADのbyte0,byte1が温度データ 2bytesを符号付き10bitにする
        dat=(buf[1] & 0x0f)<<8 | buf[0]
        # Singned data
        bit_num=12
        if dat >= (2**(bit_num-1)):
            dat=dat-(2**bit_num)
        self.temp=dat*0.0625   # config 12bit >> 0.0625/bit
        #print('temp=',temp)
        return self.temp

    ## COPY SCRATCHPAD
    def Copy_SPAD(self, r_code):
        self.ow.reset(True)
        self.ow.writebyte(MATCH_ROM)
        self.ow.write(r_code)          #8bytes
        self.ow.writebyte(CP_SCRATCH)    #COPY SCRATCHPAD [48h]
        time.sleep_ms(10)

    ## RECALL E2
    def Recall_E2(self, r_code):
        self.ow.reset(True)
        self.ow.writebyte(MATCH_ROM)
        self.ow.write(r_code)            #8bytes
        self.ow.writebyte(RECALL_E2)     #COPY SCRATCHPAD [48h]

    ## Read Power Supply readbit parasite(0)externally(1)
    def Read_PS(self, r_code):
        self.ow.reset(True)
        self.ow.writebyte(MATCH_ROM)
        self.ow.write(r_code)      #8bytes
        self.ow.writebyte(RD_POWER)  #Read Power Supply[B4h] 
        #print(ow.readbit())
        return self.ow.readbit()

    # SCRATCHPAD data-list  データの確認
    def disp_SPAD(self, buf):
        for i in range(9):
            print(i,'%4d '%buf[i],hex(buf[i]))