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

2023年2月28日

RasberryPi Picoでの水温計作成 その6 完成

Filed under: その他 — pinewell @ 11:25 PM

本日、2月の最終日だが10度を超える気温となったので家の前の舗装をだしてGL400を引っ張りだした。

カフェレーサー化もほぼ終了しあとは若干の塗装と磨きを残す。

3Dプリンタで作った側に装着して搭載。

w=が水温で48.8度。o=が外気温で8.9度。時間は14:21:19。

懸念していたOneWireでの温度取得もほぼ問題ないようできちんと温度が取得できている。大満足。

ちなみに本来のサーモユニットを抜き取り、アマゾンで購入した「グリース継手 ストレート継手 ステンレス製 アクセサリー スレッド 液体用 M16 x 1.5 mm」

を6mmのドリルで貫通させてDS18B20をJ-Bウエルド クイックウェルド 超強力接着剤 KW-20Zで装着している。

GL400Cafe

2023年2月16日

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

Filed under: その他 — pinewell @ 11:24 PM

前回アップしたソースではGC9A01に表示させるフォントが気に入らなかった。

さらにbitmapの表示がどのようにしたらよいものかわからなかったので新たに探してみた。

https://github.com/russhughes/gc9a01_mpy

結果上記のサイトに行きつき、jpgファイル、.pyファイルへ変換してのbitmapファイルの表示方法が分かった。

とりあえず動作はする。実際に車載したときにどうなるか。

from machine import Pin,SPI,I2C,PWM
import gc9a01 # 内包されているfirmwareを使うこと。
import onewire, ds18x20
import time,utime,math

from ds1307 import DS1307 #libフォルダ

from fonts import chango_16 as fontA
from fonts import chango_32 as fontB

import hondaWing #bitmapのpythonスクリプト

def main():
    #iniファイルの保存
    def SaveIniFile(filename, dictionary):
        with open(filename, "w") as f:
            for key in dictionary:
                f.write("{},{}\n".format(key, dictionary[key]))
    #iniファイルの読み取り
    def LoadIniFile(filename):
        dictionary = {}
        with open(filename, "r") as f:
            for s in f:
                lst = s.strip().split(",")
                dictionary[lst[0]] = lst[1]
        return dictionary
    #使い方
    #data = {}
    #data["Name"] = "Hippy"
    #data["Year"] = "2021"
    #SaveIniFile("/MyData.ini", data)
    #data = LoadIniFile("/MyData.ini")
    #print(data)
      
  
       
    #arduinoのMAP関数
    def convert(x, in_min, in_max, out_min, out_max):
        return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min

    #円を書いて塗りつぶす
    def circle(x,y,r,c):
       tft.hline(x-r,y,r*2,c)
       for i in range(1,r):
           a = int(math.sqrt(r*r-i*i))#平方根だって
           tft.hline(x-a,y+i,a*2,c)
           tft.hline(x-a,y-i,a*2,c)
    #円を書く
    def ring(x,y,r,c):
        tft.pixel(x-r,y,c)
        tft.pixel(x+r,y,c)
        tft.pixel(x,y-r,c)
        tft.pixel(x,y+r,c)
        #lcd.display()
        #utime.sleep(0.1)
        for i in range(1,r):
            a = int(math.sqrt(r*r-i*i)) # Pythagoras
            tft.pixel(x-a,y-i,c)
            tft.pixel(x+a,y-i,c)
            tft.pixel(x-a,y+i,c)
            tft.pixel(x+a,y+i,c)
            tft.pixel(x-i,y-a,c)
            tft.pixel(x+i,y-a,c)
            tft.pixel(x-i,y+a,c)
            tft.pixel(x+i,y+a,c)
            
    data = LoadIniFile("ini.ini")
    dspMode=data["dspMode"]
    face=("FaceA.jpg","FaceD.jpg")
   
    modePin=21  #時刻合わせモードに移行スイッチ
    upPin=20    #日付・時計あわせのアップスイッチ

    cds = machine.ADC(0) #明るさセンサー GP26がADC0
    # 16bitの数値一単位での電圧値を設定します
    unit = 0.00005035477
    
    kurai = 20000  #暗いとき
    akarui = 65535 #明るいとき
    
    dspMode = 0  #0:アナログ 1:デジタル
    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

    epSec = 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:   #RTCから現在時刻の取得
      i2c_rtc = I2C(0,scl = Pin(17),sda = Pin(16),freq = 100000) #RTCの定義
      result = I2C.scan(i2c_rtc)

      rtc = DS1307(i2c_rtc)
      (year,month,date,day,hour,minute,second,p1)=rtc.datetime()

      #RTCから取得した時間を元に 2021/1/1 00:00:00(RP2040のリセット時間)との差分を作成
      epSec = utime.mktime((year,month,date,hour,minute,second,0,0)) #1970/1/1 00:00:00からの経過秒
      epSec = epSec-1609459200
      
      if year==2000:#RTCからの初取得は2000年となるのでその場合に 2023/2/2 12:00:00にRTCを設定 
          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'(\x07\x83t/!\x01(') #温度計の個体を特定 外気温
    w_ds = bytearray(b'(?\x9b8/!\x01\xd4') #                水温
    
    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(#バックライトはPWMで調整するので指定しない。
        spi,
        240,
        240,
        reset=Pin(12, Pin.OUT),
        cs=Pin(9, Pin.OUT),
        dc=Pin(8, Pin.OUT),
        rotation=0)

    #バックライトはPWMで調整
    pwm = PWM(Pin(25))
    pwm.freq(1000)
    pwm.duty_u16(akarui)
    tft.init()
    
    tft.jpg(face[dspMode], 0, 0, gc9a01.SLOW)
    
    oldx =120
    oldy = 120
    
    
    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 = utime.time()-pushStart
            else:
                flgPush = True #長押し計測スタート
                pushStart = utime.time()
                pushInt = 0
        else:
            if flgPush :# すでに押されていて離した
                flgPush=False
                pushInt=utime.time()-pushStart #押していた時間を取得
                if pushInt > 2: #長押しされた
                    #print("long") 
                    if mode ==0: #時計合わせモードに移行
                        tft.fill(gc9a01.WHITE)
                        (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
                            tft.fill(gc9a01.WHITE)
                            tft.jpg(face[dspMode], 0, 0, gc9a01.SLOW)
                            oldx=120
                            oldy=120
                        else:#次のセクションへ移行
                            sec=sec+1
                else:
                    print("short") #短押しは表示モード切り替え
        #調整用UPボタンの処理
        if swUp.value() == 1:
            #print("up")
            if tokei : #時計表示ができる。 
                if mode == 1: #時刻調整モード
                    utime.sleep_ms(200)        
                    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
                else :
                    #時刻設定モードじゃ無い場合は表示モード切り替え
                    if dspMode==0:
                        dspMode=1
                        tft.jpg(face[dspMode], 0, 0, gc9a01.SLOW)
                        data["dspMode"] = dspMode
                        SaveIniFile("/ini.ini", data)
                    else:
                        dspMode=0
                        data["dspMode"] = dspMode
                        SaveIniFile("/ini.ini", data)
                        tft.jpg(face[dspMode], 0, 0, gc9a01.SLOW)
                        oldx=120
                        oldy=120
                        
                #print(str(uYear)+"/"+str(uMonth)+"/"+str(uDate) + "  " + str(uHour)+":"+str(uMinute)+":00")

        
        if mode ==0: #通常表示
            #温度の取得
            oTemp = 999.99
            wTemp = 999.99
            oReadErr=""
            wReadErr=""
            if dsCnt > 0 :#温度計の数が0以上だったら
                flgSuc=True
                try:
                    ds_sensor.convert_temp()
                    utime.sleep_ms(750)
                except:
                    flgSuc=False
                if flgSuc:
                    for rom in roms:
                        if rom == o_ds :
                            buf = oTemp
                            try:
                                oTemp = ds_sensor.read_temp(rom)
                                oReadErr="O"
                            except:
                                oReadErr="X"
                                oTemp=buf
                        else :
                            buf = wTemp
                            try:
                                wTemp = ds_sensor.read_temp(rom)
                                wReadErr="O"
                            except:
                                wReadErr="X"
                                wTemp=buf
            
            if dspMode==0:
                wwTemp = 20 #最小温度            
                if wTemp <=120 or wTemp > 20: #読み取れている?
                    wwTemp = wTemp
        
                kakudo = convert(wwTemp,20,120,40,320) #角度を取得
                rad = 3.14*kakudo/180 #ラジアン値に変換
                r=90  #針の長さ
                x = int(r*(math.cos(rad))) + 120 #座標を求める
                y = int(r*(math.sin(rad))) + 120 

                c=gc9a01.BLACK
                if wTemp >80:
                    c=gc9a01.RED
                elif wTemp<40:
                    c=gc9a01.BLUE
            
                tft.write(fontA, "w={:.1f}  ".format(wTemp),150,105,c,gc9a01.WHITE)
                tft.write(fontA, "o={:.1f}  ".format(oTemp),155,120,gc9a01.BLACK,gc9a01.WHITE)
        
                if (x != oldx) or (y !=oldy) :
                  tft.line(122, 120 ,oldx ,oldy, gc9a01.WHITE)
                  tft.line(121, 121 ,oldx ,oldy, gc9a01.WHITE)
                  tft.line(120, 120, oldx, oldy, gc9a01.WHITE)
                  tft.line(120, 119 ,oldx ,oldy, gc9a01.WHITE)
                  tft.line(120, 121, oldx, oldy, gc9a01.WHITE)
                  tft.line(119, 119 ,oldx ,oldy, gc9a01.WHITE)
                  tft.line(119, 120 ,oldx ,oldy, gc9a01.WHITE)
                  tft.line(118, 120 ,oldx ,oldy, gc9a01.WHITE)
                  tft.line(120, 118 ,oldx ,oldy, gc9a01.WHITE)

                  tft.write(fontA, "20",175, 162,gc9a01.BLACK,gc9a01.WHITE)
                  tft.write(fontA, "40",94, 190,gc9a01.BLACK,gc9a01.WHITE)
                  tft.write(fontA, "60",40, 148,gc9a01.BLACK,gc9a01.WHITE)
                  tft.write(fontA, "80",40, 77,gc9a01.BLACK,gc9a01.WHITE)
                  tft.write(fontA, "100",94, 31,gc9a01.BLACK,gc9a01.WHITE)
                  tft.write(fontA, "120",175, 61,gc9a01.BLACK,gc9a01.WHITE)
                  tft.bitmap(hondaWing,120-int(hondaWing.WIDTH/2),50)
          
                  tft.line(122, 120 ,x ,y, gc9a01.RED)
                  tft.line(121, 121 ,x ,y, gc9a01.RED)
                  tft.line(120, 120, x, y, gc9a01.RED)
                  tft.line(120, 119 ,x ,y, gc9a01.RED)
                  tft.line(120, 121, x, y, gc9a01.RED)
                  tft.line(119, 119 ,x ,y, gc9a01.RED)
                  tft.line(119, 120 ,x ,y, gc9a01.RED)
                  tft.line(118, 120 ,x ,y, gc9a01.RED)
                  tft.line(120, 118 ,x ,y, gc9a01.RED)
        
                  oldx = x
                  oldy = y

                circle(120,120,10,gc9a01.BLACK)
            else :
                # 温度の表示 右寄せ
                tft.write(fontA, "WaterTemp",40,68,gc9a01.BLACK,gc9a01.WHITE)
                w = tft.write_len(fontB,"    {:.2f}".format(wTemp))
                tft.write(fontB, "    {:.2f}".format(wTemp),210-w,86,gc9a01.BLACK,gc9a01.WHITE)
                tft.write(fontA,wReadErr,40,90,gc9a01.BLACK,gc9a01.WHITE)
                tft.write(fontA, "OutTemp",40,128,gc9a01.BLACK,gc9a01.WHITE)
                w = tft.write_len(fontB,"    {:.2f}".format(oTemp))
                tft.write(fontB, "    {:.2f}".format(oTemp),210-w,146,gc9a01.BLACK,gc9a01.WHITE)
                tft.write(fontA,oReadErr,40,150,gc9a01.BLACK,gc9a01.WHITE)

            if tokei :
                it = utime.mktime(utime.localtime()) #ローカルでは 2021/1/1 00:00:00として起動した1970/1/1 00:00:00からの経過秒
                it = it+epSec                        #RTC差分の値とあわせて
                time =   utime.localtime(it)         #本当の現在時刻を生成
                year=time[0]
                month=time[1]
                date=time[2]
                hour=time[3]
                minute=time[4]
                second=time[5]
                if dspMode==1:
                    dateStr = "{0:04d}/ {1:02d}/ {2:02d}  ".format(year,month,date)
                    tft.write(fontA, dateStr,56, 195,gc9a01.BLACK,gc9a01.WHITE)
                    tft.write(fontA, "                ",85, 178,gc9a01.BLACK,gc9a01.WHITE)
                timeStr = "{0:02d}:{1:02d}:{2:02d}  ".format(hour,minute,second)
                tft.write(fontA, timeStr,80, 213,gc9a01.BLACK,gc9a01.WHITE)
                
                
        else: #時計合わせ
            
            dateStr = "{0:04d}/ {1:02d}/ {2:02d}  ".format(uYear,uMonth,uDate)
            tft.write(fontA, dateStr,60, 195,gc9a01.BLACK,gc9a01.WHITE)
            timeStr = "{0:02d}:{1:02d}:00      ".format(uHour,uMinute)
            tft.write(fontA, timeStr,82, 213,gc9a01.BLACK,gc9a01.WHITE)
            if sec ==0:
                tft.write(fontA,"year       ",85, 178,gc9a01.BLACK,gc9a01.WHITE)
            elif sec ==1:
                tft.write(fontA,"month      ",85, 178,gc9a01.BLACK,gc9a01.WHITE)
            elif sec ==2:
                tft.write(fontA,"date       ",85, 178,gc9a01.BLACK,gc9a01.WHITE)
            elif sec ==3:
                tft.write(fontA,"hour       ",85, 178,gc9a01.BLACK,gc9a01.WHITE)
            elif sec ==4:
                tft.write(fontA,"minute ",85, 178,gc9a01.BLACK,gc9a01.WHITE)
        utime.sleep_ms(10)        
main()

2023年2月15日

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

Filed under: その他 — pinewell @ 11:38 PM

実際にはPicoでは無いのだが。

画面

さてなんやかんやあって上記画像通り、アナログでの表示に成功。

sinとかcosとかラジアンとか高校のころ以来。

w=で水温 o=外気温となる。

水温は40℃以下は青色表示、80℃以上は赤表示とする。

ただ問題ががが。実際にエンジンをかけるとノイズなのかまともに動かない。

とりあえずRTCからの時間取得で失敗していたのでRTCから取得はエンジン始動前の1回にしてみた。

その後寒くてエンジン始動も倉庫内の作業も困難で試してない。

2023年2月7日

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

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

Fritzingを改めて使ってみる。

パーツを作るのが面倒・・・。

必要な情報を貼っていく。

RP2040-LCD-1.28

2つあるヘッダのうち、H2のみを使う。

PICO

本来のPicoとはすこーし違うよう。

PiRTC

Pi用のRTC。DS1307は5V駆動なので3.3Vへのロジックレベル変換が内蔵されている。が、3.3Vも繋ぐ必要があるのは誤算だった。

ブレッドボードで再現

これを収めるケースを作らねば。

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

2023年1月26日

RasberryPi Picoでのメーター作成

Filed under: その他 — pinewell @ 2:01 PM

バイクの水温計を作成したい。

ついては以下の要件

1.水温

2.外気温

3.時計

4.振動センサーによる盗難防止ブザー

Waveshare RP2040-LCD-1.28 というものを購入した。

温度計のために GPIO 2つ

時計合わせのためのボタンに2つ。

RTCのI2Cに2つ。

6つの空きGPIOが必要。

2016年2月23日

Fedora23でのポインターの速度

Filed under: その他 — pinewell @ 6:07 PM

随分久しぶりの更新である。
まぁ、おっくうで。

ワシはFedoraをサーバーにしてKVMで仮想化Windowsサーバーを走らせている。
過去の開発環境なんかもまとめてつっこんで運用している。

昨年12月頃のこと。それまで使用していたFedora21がEndOfLifeとなり、Fedora23に更新した。
クリーンインストールして再び環境構築となるのでそれなりに時間がかかる。
インストール後、特に困ったのがポインターの速度。Wireless Trackball M570tを使用しているのだが、
これまでGnomeで速いにしておけば特に不満が無かったのだが、Fedora23からは最速に設定しても遅い。

xinputで調べてみると、最速の1に設定されていて、これ以上上げられない。

$xinput
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Logitech M570 id=9 [slave pointer (2)]
⎜ ↳ Logitech K270 id=10 [slave pointer (2)]

$xinput list-props 9
Device ‘Logitech M570’:
Device Enabled (148): 1
Coordinate Transformation Matrix (150): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
libinput Accel Speed (282): 1.000000

悩んだね〜。
もう3ヶ月も前のことなのだが。
結果的に、libinputをSRPMで持ってきてソースを改変。ビルドしなおして目的を果たした。
変更箇所は以下。

— libinput-1.1.8/src/filter.c 2016-02-18 10:39:30.000000000 +0900
+++ libinput-1.1.7/src/filter.c 2016-02-14 08:11:33.057512464 +0900
@@ -112,10 +112,10 @@ filter_get_type(struct motion_filter *fi
* Default parameters for pointer acceleration profiles.
*/

-#define DEFAULT_THRESHOLD v_ms2us(0.4) /* in units/us */
-#define MINIMUM_THRESHOLD v_ms2us(0.2) /* in units/us */
-#define DEFAULT_ACCELERATION 2.0 /* unitless factor */
-#define DEFAULT_INCLINE 1.1 /* unitless factor */
+#define DEFAULT_THRESHOLD v_ms2us(0.1) /* in units/us */
+#define MINIMUM_THRESHOLD v_ms2us(0.05) /* in units/us */
+#define DEFAULT_ACCELERATION 500.0 /* unitless factor */
+#define DEFAULT_INCLINE 8.8 /* unitless factor */

ところがこのlibinput、まぁ良く更新してくれるもんだからそのたびに作業が必要。
これまでpatchファイルは作っていなかったのだが、さすがに面倒になったのでpatchを作成。
SPECファイルをいじるだけで良いようした。

4Kモニタ3枚の移動+synergyでのWindows環境への移動もボールを少しだけ動かすだけで移動できるようになる。
ソースがあるLinuxだから改変できる。Windowsだとフリーウェア?があるか?

2015年3月6日

UPSのバッテリー その3

Filed under: その他,育苗管理システム — pinewell @ 11:44 AM

オークションで落札した OMRON BY35S、サンケン SCU-A501 ともに
容量/サイズとも 秋月のこれと同じ。
しかも縦置きなんだな、双方とも。
ついつい安くて買ってしまったが、小さいUPSが5つとなった。もう要らない。

2015年1月16日

サーバーの更新

Filed under: その他,副業 — pinewell @ 7:00 PM

本業である農業がヒマなこの時期に毎年更新をしているLinuxサーバー。
今年はFedoraが変則でFedora20からFedora21への更新となった。

お金があればCPUをHaswell-Eにして、DDR4メモリなども構想したのだが、円安となったためか
べらぼうに高いような気がしてやめにする。

骨董となったcore i7 980Xにもう少し頑張ってもらうこととして、HDDの入れ替えと
OSをSSDにいれて折角だからましなRAIDボードに接続することにする。
OS用に128GBのSSD。SanDisk SDSSDHP128G。アマゾン専用品?で比較的安く購入できた。
データ用には4TBのHDD。HGST HMS5C4040ALE640。これを4基でRAID5を組んで使う。
12TBの広大なデータ域は/home としてマウント、移行が終わった段階で4.6TBを使用している。
仮想OSのデータや、開発でのソース、ISOイメージや2002年ごろから撮り貯めている写真のデータなど、増える一方で減ることはない。
仮想OSのデータ用のバックアップとして3TBのHDD。ST3000NM0033-9ZM178。
/homeのバックアップとして2TBのHDD HDS723020BLA642 をRAID0で組んでいる。
さらに仕事のデータは国内/海外に借りているVPSにバックアップをし、
日毎、週毎、月毎のデータをdebian化したLinkStation6台に分散してバックアップしている。

RAIDカードはIBM ServeRaid M1015。これをSATAへのケーブル2組こみで某オークションで入手。
RAID自体はlinuxのsoftwareRAIDを使うので使い勝手考えて、9210-8iのファームウェアに載せ換えて使用しています。

で、更新前のhdparam
# hddtemp /dev/sd[abcdefgh]
/dev/sda: ST3000NM0033-9ZM178: 35°C
/dev/sdb: HGST HMS5C4040ALE640: 31°C
/dev/sdc: HGST HMS5C4040ALE640: 29°C
/dev/sdd: SanDisk SDSSDHP128G: 27°C
/dev/sde: HGST HMS5C4040ALE640: 31°C
/dev/sdf: HGST HMS5C4040ALE640: 32°C
/dev/sdg: Hitachi HDS723020BLA642: 31°C
/dev/sdh: Hitachi HDS723020BLA642: 31°C

ICH10R
#hdparm -t /dev/sd[abcdefgh]
/dev/sda:
Timing buffered disk reads: 548 MB in 3.01 seconds = 182.04 MB/sec
/dev/sdb:
Timing buffered disk reads: 374 MB in 3.00 seconds = 124.47 MB/sec
/dev/sdc:
Timing buffered disk reads: 360 MB in 3.01 seconds = 119.53 MB/sec
/dev/sdd:
Timing buffered disk reads: 706 MB in 3.00 seconds = 235.27 MB/sec
/dev/sde:
Timing buffered disk reads: 396 MB in 3.01 seconds = 131.66 MB/sec
/dev/sdf:
Timing buffered disk reads: 366 MB in 3.01 seconds = 121.57 MB/sec
JMB363
/dev/sdg:
Timing buffered disk reads: 476 MB in 3.01 seconds = 158.19 MB/sec
/dev/sdh:
Timing buffered disk reads: 472 MB in 3.01 seconds = 156.98 MB/sec

折角のSSDも235.27MB/secと勿体無い結果。ICH10RではSSDを使い切れていない。

# hddtemp /dev/sd[abcdefghijk]
/dev/sda: Hitachi HDS723020BLA642: 30°C
/dev/sdb: Hitachi HDS723020BLA642: 30°C
/dev/sdc: HGST HMS5C4040ALE640: 29°C
/dev/sdd: HGST HMS5C4040ALE640: 28°C
/dev/sde: HGST HMS5C4040ALE640: 28°C
/dev/sdf: ST3000NM0033-9ZM178: 33°C
/dev/sdg: HGST HMS5C4040ALE640: 28°C
/dev/sdh: SanDisk SDSSDHP128G: 27°C
9210-8i
# hdparm -t /dev/sd[abcdefgh]
/dev/sda:
Timing buffered disk reads: 472 MB in 3.01 seconds = 156.75 MB/sec
/dev/sdb:
Timing buffered disk reads: 476 MB in 3.00 seconds = 158.44 MB/sec
/dev/sdc:
Timing buffered disk reads: 378 MB in 3.00 seconds = 125.96 MB/sec
/dev/sdd:
Timing buffered disk reads: 376 MB in 3.00 seconds = 125.22 MB/sec
/dev/sde:
Timing buffered disk reads: 388 MB in 3.01 seconds = 128.78 MB/sec
/dev/sdf:
Timing buffered disk reads: 536 MB in 3.00 seconds = 178.59 MB/sec
/dev/sdg:
Timing buffered disk reads: 384 MB in 3.00 seconds = 127.85 MB/sec
/dev/sdh:
Timing buffered disk reads: 1372 MB in 3.00 seconds = 456.98 MB/sec

さすがPCI Express 8x接続。8台でいっぱいいっぱいの帯域使用でもしっかりSSDの性能を生かしている。
456.98MB/secなら充分な速さ。カタログ値で530MB/secなのでしっかり使えているでしょう。
HDDに関しては誤差レベルの変化なのでHDDの性能限界なのでしょう。

これでまだまだ戦える。LGA1366は息の長いプラットフォームとなっています。
こうなったらサーバー用のマザーボードで980X2つ積んでみるのもよいかも。メモリにECC以外が使えれば良いのだが。

2015年1月12日

4K環境更新。CDU2150A+T221+P2415Q

Filed under: その他,副業 — pinewell @ 6:39 PM

去年の年末に驚くニュースを発見。
DELLから実売5万円程度の4Kモニタが発売されると言うもの。
某掲示板ではその話題で盛り上がっており、アマゾンやらヨドバシやらで予約注文するも発売延期やらで入手困難なのではないか?とか。
DELLからメールもチェックするも、確かに発売日には入手できないようだ。

スレをチェックしていると「Amazonで予約復活」を発見。即注文すると目出度く発送された。どうやら入手困難なのは27インチモデルで
私が欲しかった24インチモデルはその後も比較的入手可能だった。
メールを見返してみると12月16日には届いたようだ。

無事セットアップが完了しているのでメモしておく。
あ、ちなみにマザーボード、CPU、メモリも入れ替えている。
現在の環境
CPU core i7 4790K (殻割り)
MB Z97X-UD3H-BK
Memory Panram W3U1866HPS-8G x4
VG MSI R7 260X 2G x2
モニターの接続には DVIx2本でCDU2150A,DVIx2本でT221、DisplayPortx1本でP2415Q。
マザーにオンボードのHD4600でHDMI1本。

モニター4K 3枚。FHD 1枚。
CDU2150A 3840x2400x33Hz SingleDVI-D を2本。EDIDオーバーライドケーブル。
T221 3840x2400x48Hz DualDVI-D を2本。EDIDオーバーライドケーブル。
P2415Q 3840x2160x60Hz DisplayPort を1本。
E2210HDS 1920x1080x60Hz HD4600でHDMI を1本。

実際のところP2415QをメインとしてT221をサブに、CDU2150Aを撤去してまおうかとも思ったのだが、
縦2400の解像度に慣れてしまった身としては2160は耐えられそうもなかったので、4K3枚並べることに。
これまでどおりT221がWindows機での開発用メインモニタとなる。

Linux側ではP2415QをメインにE2210HDSをサブとして使用している。
P2415Q 3840x2160x30Hz HDMIケーブル
E2210HDS 1920x1080x60Hz DVIケーブル。
30Hzが気になるが、DisplayPortの仕様で下記記載のじつに許せないことがあり仕方無し。
_
/ \
| ○ <-私
実際はもっとなだらか
CDU2150A T221 P2415Q E2210HDS

良い点
開発中(と、いうか書斎にこもっている時)にはE2210HDS では監視カメラの画像が並べられる(3列x2行)
linux側でも4Kとなったので作業領域が広がった。
P2415Q 24インチなのでT221よりは字が大きい。
P2415Q 軽い。T221から比べるとホントに軽いし薄い。

不満点
DisplayPortの仕様らしいのだが、入力切替(mDP HDMI)でモニタが切り離される(ケーブルを抜いたのと同じ状態)。
そのため、P2415Qに置いておいたウィンドウが違うモニタに移動されてしまう。復帰後自分で再配置しないといけない。
モニタの配置は記憶してくれるので再度設定する必要はないのだが、ウィンドウの再配置はがっかり。
有効な対策は高価なDisplayPort用のEDID保持機。この解像度に対応したものがあるか不明。
DVIケーブルと違ってEDIDのオーバーライドは(簡単には)できそうにない。
linux機にHDMIを使用しているのはこのため。HDMI接続なら入力切替でも保持できている(オーバーライドケーブルも作ったのだが)。

gamen

 

 

 

 

 

5番のモニターが1920×1080でFHDなのだが、小さく見える。
一番右の3は某掲示板でHDMIポートにP2415Qを接続するとDisplayPortの問題がなくなるという情報をもとに
P2415QのEDIDROMをのっけたHDMIケーブルを挿してみたのだが解決に至らなかった名残。まだ外していなかった。

gamen2

 

 

 

 

 

 

 

Eyefinityでディスプレイグループを作成している。
2番がCDU2150Aで1920x2400x33Hzを2つ。1番がT221で1920x2400x48Hzを2つ。

スケーリングはすべてのモニターで100%。目が良いのでせっかくの作業領域を無駄にしたくない。

Older Posts »

Powered by WordPress