pinewell's farmer blog 農業と電子工作、ソフトウェア、バイク、車

2023年2月5日

RasberryPi Picoでの水温計作成 その2

Filed under: その他 — pinewell @ 9:44 PM

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個で外気温、水温、時計と照度計を用いた水温計が実現できる。

コメントはまだありません »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress