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]))