CircuitPython 10行プログラミング (7) 1-Wire
Trinket M0マイコン・ボードとCircuitPythonを使って、1-Wireにつながる温度センサDS18B20を利用します。名前のとおり信号線は1本で、電源とGNDを含めて3本の接続で遠距離通信ができます。いろいろなデバイスがつながりますが、温度センサのDS18B20が最もポピュラです。デフォルトで12ビットの分解能をもっており、測定温度範囲は-55~+125℃です。
●シリアル通信
デバイスには固有の64ビットのROMデータが記録され読み出せるので、複数のデバイスを3本のラインにパラレルに接続できます。
通信は、最初にリセットを、固有のROMデータを問い合わせます(0xf0)。読み出しは0x33です。固有のROMデータを指定した後、温度の変換を要求します。
データシートによれば、温度の変換要求はConverT(0x44)を送ります。温度データはScrachpadの最初の2バイトに収録されています。読み出しは0xbeです。最初のバイトは下位8ビット、次のバイトは上位の3ビットと符号です。符号はbit3~bit7まで同じ値がコピーされています。データは2の補数形式です。
パワーオン・リセット時には下位バイトに0x50、上位バイトに0x05が入っています。85℃です。
Scrachpadの最後の9バイトはCRCです。
●接続
D0に信号を、3VへVdd、GNDにはGNDを接続しました。信号とVddの間には4.7kΩの抵抗をつなぎます。
●Adafruitのライブラリ
前記のように大変複雑な通信手順です。CircuitPythonには1-Wireのライブラリがありますが、ピンの指定と、ビットのタイミングを取るだけのものです。
import busio
import board
onewire = busio.OneWire(board.D0)
print(onewire.read_bit())
もう一つAdafruit OneWire ライブラリがあります。こちらはROMコードを読み出すところまでサポートしています。
import board
from adafruit_onewire.bus import OneWireBus
ow_bus = OneWireBus(board.D0)
devices = ow_bus.scan()
for d in devices:
print("ROM={}\tFamily=0x{:02x}".format(d.rom, d.family_code))
結果は、
ROM=bytearray(b'(\xff\xa4h\x84\x16\x043') Family=0x28 |
でした。
ここで利用する温度センサDS18B20用にもライブラリがあります。1-Wireのライブラリと組み合わせて使います。
# Simple demo of printing the temperature from the first found DS18x20 sensor every second.
# Author: Tony DiCola
import time
import board
from adafruit_onewire.bus import OneWireBus
from adafruit_ds18x20 import DS18X20
# Initialize one-wire bus on board pin D5.
ow_bus = OneWireBus(board.D0)
# Scan for sensors and grab the first one found.
ds18 = DS18X20(ow_bus, ow_bus.scan()[0])
# Main loop to print the temperature every second.
while True:
print('Temperature: {0:0.3f}C'.format(ds18.temperature))
time.sleep(1.0)
実行結果です。
Adafruitのライブラリは、CIRCUIYPYドライブの中のlibへ入れます。ダウンロードは前回と同じです。今回追加したのはadafruit_onewireフォルダとadafruit_ds18x20.mpyの二つです。