DS18B20の取得はOneWireを使うと1つのGPIOで取得できる。
周りの明るさで輝度を調整したかったので、いつ買ったのかもわからないセンサーを接続した。
I2CでRTC。DS1307を用いた。
from machine import Pin, SPI,I2C,PWM
import gc9a01py as gc9a01
import onewire, ds18x20
import time,utime
from ds1307 import DS1307
# from fonts import vga1_8x8 as font
# from fonts import vga2_8x8 as font
# from fonts import vga1_8x16 as font
# from fonts import vga2_8x16 as font
# from fonts import vga1_16x16 as font
# from fonts import vga1_bold_16x16 as font
# from fonts import vga2_16x16 as font
# from fonts import vga2_bold_16x16 as font
# from fonts import vga1_16x32 as font
# from fonts import vga1_bold_16x32 as font
# from fonts import vga2_16x32 as font
# from fonts import vga2_bold_16x32 as font
# from fonts import vga2_bold_16x32 as fontB
# from truetype import NotoSerif_32 as fontC
from fonts import vga2_8x16 as fontA
from fonts import vga2_16x32 as fontB
def main():
modePin=21 #時刻合わせモードに移行スイッチ
upPin=20 #日付・時計あわせのアップスイッチ
cds = machine.ADC(0) #明るさセンサー
# 16bitの数値一単位での電圧値を設定します
unit = 0.00005035477
kurai = 20000 #暗いとき
akarui = 65535 #明るいとき
mode = 0 #0:通常 1:時計合わせ
sec = 0 #時計合わせの時のセクション 0:Year 1:month 2 day 3 hour 4 minute
uYear = 0 #時計あわせようの値
uMonth = 0
uDate = 0
uHour = 0
uMinute = 0
swMode = machine.Pin(modePin,machine.Pin.IN,machine.Pin.PULL_DOWN) #スイッチの定義
swUp = machine.Pin(upPin,machine.Pin.IN,machine.Pin.PULL_DOWN) #スイッチの定義
pushStart =0 #押し始めた時間
flgPush = False #押しているか
pushInt = 0 #押されていた時間
DSPIN = 19 #温度計のPin。onewire
dsCnt = 0 #温度計の数
ds_pin = machine.Pin(DSPIN)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin)) #温度計を定義
pw33 = machine.Pin(18,machine.Pin.OUT) #RTCの3.3Vを得るため
pw33.value(1)
tokei=True #RTCが取得できたか?
try:
i2c_rtc = I2C(0,scl = Pin(17),sda = Pin(16),freq = 100000) #RTCの定義
result = I2C.scan(i2c_rtc)
#print(result)
rtc = DS1307(i2c_rtc)
#print(rtc.datetime())
(year,month,date,day,hour,minute,second,p1)=rtc.datetime()
if year==2000:#初期時は2000年となるのでその場合に 2023/2/2 12:00:00に設定
year = 2023
month = 2
date = 2
day = 4
hour = 12
minute = 0
second = 0
now = (year,month,date,day,hour,minute,second,0)
rtc.datetime(now)
except:
#print("not Tokei") #RTCが取得できなかったら tokei非表示
tokei=False
o_ds = bytearray(b'(?\x9b8/!\x01\xd4') #温度計の個体を特定 外気温
w_ds = bytearray(b'(\x07\x83t/!\x01(') # 水温
try:
roms = ds_sensor.scan() #センサーを取得
dsCnt=len(roms) #センサー数を得る
for rom in roms:
print('Found DS devices: ', rom)
except:
dsCnt = 0
#液晶ディスプレイの定義
spi = SPI(1, baudrate=60000000, sck=Pin(10), mosi=Pin(11))
#tft = gc9a01.GC9A01(
# spi,
# dc=Pin(8, Pin.OUT),
# cs=Pin(9, Pin.OUT),
# reset=Pin(12, Pin.OUT),
# backlight=Pin(25, Pin.OUT),
# rotation=0)
tft = gc9a01.GC9A01(#バックライトはPWMで調整するので指定しない。
spi,
dc=Pin(8, Pin.OUT),
cs=Pin(9, Pin.OUT),
reset=Pin(12, Pin.OUT),
rotation=0)
#バックライトはPWMで調整
pwm = PWM(Pin(25))
pwm.freq(1000)
pwm.duty_u16(akarui)
#pwm.duty_u16(20000)
tft.fill(gc9a01.WHITE)
tft.fill_rect(0,0,240,60,gc9a01.RED)
tft.text(fontB,"HONDA",80,20,gc9a01.WHITE,gc9a01.RED)
while True:
for i in range(100): #バックライトの明るさ調整
# ADCの値を読み込みます(16bitの生の数値)
voltRaw = cds.read_u16()
#print("voltRaw:" + str(voltRaw))
volt = voltRaw * unit
#print( "volt:" + "{:.3f}".format(volt))
if volt > 2:
pwm.duty_u16(kurai)
else:
pwm.duty_u16(akarui)
#モードスイッチが押されているか?
if swMode.value() == 1:
if flgPush :
pushInt = time.time()-pushStart
else:
flgPush = True
pushStart = time.time()
pushInt = 0
else:
if flgPush :# すでに押されていて離した
flgPush=False
pushInt=time.time()-pushStart
if pushInt > 2: #長押しされた
#print("long")
if mode ==0: #時計合わせモードに移行
(uYear,uMonth,uDate,day,uHour,uMinute,second,p1)=rtc.datetime() #
mode=1
sec=0
else: #時計合わせモードで長押し
if sec == 4:#分まで設定してたら時計合わせ終了
now = (uYear,uMonth,uDate,0,uHour,uMinute,0,0)
rtc.datetime(now)
sec=0
mode=0
else:#次のセクションへ移行
sec=sec+1
else:
print("short") #短押しはなにもしない
if swUp.value() == 1:
if mode == 0:
(year,month,date,day,hour,minute,second,p1)=rtc.datetime()
print(str(year)+"/"+str(month)+"/"+str(date) + " " + str(hour)+":"+str(minute)+":"+str(second))
else:
if sec ==0:
uYear=uYear+1
if uYear>2100:
uYear=2023
elif sec ==1:
uMonth=uMonth+1
if uMonth>12:
uMonth=1
elif sec ==2:
uDate=uDate+1
if uDate>31:
uDate=1
elif sec ==3:
uHour=uHour+1
if uHour>23:
uHour=0
elif sec ==4:
uMinute=uMinute+1
if uMinute>59:
uMinute=0
#print(str(uYear)+"/"+str(uMonth)+"/"+str(uDate) + " " + str(uHour)+":"+str(uMinute)+":00")
#温度の取得
oTemp = 999.99
wTemp = 999.99
if dsCnt > 0 :
ds_sensor.convert_temp()
for rom in roms:
if rom == o_ds :
oTemp = ds_sensor.read_temp(rom)
else :
wTemp = ds_sensor.read_temp(rom)
# 温度の表示
tft.text(fontA,"WaterTemp",50,62,gc9a01.BLACK,gc9a01.WHITE)
tft.text(fontB,"{:.2f}".format(wTemp),100,80,gc9a01.BLACK,gc9a01.WHITE)
tft.text(fontA,"OutTemp",50,122,gc9a01.BLACK,gc9a01.WHITE)
tft.text(fontB,"{:.2f}".format(oTemp),100,140,gc9a01.BLACK,gc9a01.WHITE)
if mode ==0: #通常表示
if tokei :
(year,month,date,day,hour,minute,second,p1)=rtc.datetime()
dateStr = "{0:04d}/ {1:02d}/ {2:02d}".format(year,month,date)
tft.text(fontA,dateStr,85,190,gc9a01.BLACK,gc9a01.WHITE)
timeStr = "{0:02d}:{1:02d}:{2:02d}".format(hour,minute,second)
tft.text(fontA,timeStr,92 ,208,gc9a01.BLACK,gc9a01.WHITE)
tft.text(fontA," ",85 ,174,gc9a01.BLACK,gc9a01.WHITE)
else: #時計合わせ
dateStr = "{0:04d}/ {1:02d}/ {2:02d}".format(uYear,uMonth,uDate)
tft.text(fontA,dateStr,85,190,gc9a01.BLACK,gc9a01.WHITE)
timeStr = "{0:02d}:{1:02d}:00".format(uHour,uMinute)
tft.text(fontA,timeStr,92 ,208,gc9a01.BLACK,gc9a01.WHITE)
if sec ==0:
tft.text(fontA,"year ",85 ,174,gc9a01.BLACK,gc9a01.WHITE)
elif sec ==1:
tft.text(fontA,"month ",85 ,174,gc9a01.BLACK,gc9a01.WHITE)
elif sec ==2:
tft.text(fontA,"date ",85 ,174,gc9a01.BLACK,gc9a01.WHITE)
elif sec ==3:
tft.text(fontA,"hour ",85 ,174,gc9a01.BLACK,gc9a01.WHITE)
elif sec ==4:
tft.text(fontA,"minute",85 ,174,gc9a01.BLACK,gc9a01.WHITE)
main()
これでスイッチ2個で外気温、水温、時計と照度計を用いた水温計が実現できる。