TM1630のライブラリっぽいものを作りたかった

TM1630

こう、なんていうか、誰かが作ったライブラリを使う時って、importして、インスタンス作って、メソッド使うみたいな感じだと思うんだけど、そういうのを自分も作れたらいいなーと思って。で、そういうのはクラスを作ったりするオブジェクト指向プログラミングが必要みたいなことはなんとなく分かる。ただ、イマイチちゃんと分かってないので書けたとしても、それが果たして正しいのかという。でもまぁとりあえずやってみてダメなところを気付けるようにしたい、みたいな。っぽいってつけるのは、ライブラリ作りました!って言えるほどのことは出来てる自信ないし、おこがましいしみたいなことで。ダラダラつらつら。

https://dalomo.net/blog/2019/10/25/739/

この記事の手続型?逐次型?のプログラムをオブジェクト指向型っぽく書き直していってみる。

ソース

import pigpio

class TM1630:

    #0-9, " ", %L, %R, degL, degR
    DISP_HEX = [0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x27, 0x7f, 0x6f, 0x0, 0x6b, 0x5d, 0x63, 0x39]

    def __init__(self, pi, DATA_PIN, CLK_PIN, STB_PIN):
        self.pi = pi
        self.DATA_PIN = DATA_PIN
        self.CLK_PIN = CLK_PIN
        self.STB_PIN = STB_PIN

        self.pi.set_mode(DATA_PIN, pigpio.OUTPUT)
        self.pi.set_mode(CLK_PIN, pigpio.OUTPUT)
        self.pi.set_mode(STB_PIN, pigpio.OUTPUT)

        self.pi.write(DATA_PIN,0)
        self.pi.write(CLK_PIN,1)
        self.pi.write(STB_PIN,1)

    def breakSTB(self):
        self.pi.write(self.STB_PIN,1)
        self.pi.write(self.STB_PIN,0)

    def write_databit(self, bin):
        if bin == 0:
            self.pi.write(self.DATA_PIN,0)
        elif bin == 1:
            self.pi.write(self.DATA_PIN,1)

    def write_byte(self, hex):
        for i in range(8):
            shiftb = hex >> i & 0b1
            self.pi.write(self.CLK_PIN,0)
            self.write_databit(shiftb)
            self.pi.write(self.CLK_PIN,1)
            self.pi.write(self.CLK_PIN,0)

        self.pi.write(self.CLK_PIN,1)

    def begin(self):
        self.pi.write(self.STB_PIN,0)

    def end(self):
        self.pi.write(self.STB_PIN,1)

    def set_displaymode(self, hex):
        self.write_byte(hex)
        self.breakSTB()

    def set_datacommand(self, hex):
        self.write_byte(hex)
        self.breakSTB()

    def set_displayaddress(self, hex):
        self.write_byte(hex)

    def set_displaycontrol(self, hex):
        self.write_byte(hex)

    def str2segdata(self, str):
        arr = []
        for i in range(4):
            arr.insert(i, self.DISP_HEX[int(str[i])])

        return arr

    def write_data(self, str):
        ADDR_BASE = 192
        data = self.str2segdata(str)

        for j in range(4):
            self.set_displayaddress(int(ADDR_BASE + j * 2))
            self.write_byte(int(data[j]))
            self.breakSTB()

    def display(self, str):
        self.begin()
        self.set_displaymode(0x0)
        self.set_datacommand(0x44)
        self.write_data(str)
        self.set_displaycontrol(0x8f)
        self.end()

ということでとりあえず書いてみた。意識してクラス書いたの初めてかもしんない。取りあえず動くは動く。TM1630はいろんな機能があるし、もっとそういう設定もできるように作りたかったけど、途中で力尽きてしまった。

改善点・疑問点

  • selfってこんなに使うもんなの。61個もあるんだけど省略したいよ。
  • スコープが分からん。どこにでもアクセスできるガバガバクラスになってると思う。インスタンス変数とメンバ変数とpublicメソッドとprivateメソッドとちゃんと考えて書いてない。
  • 前のプログラムを関数に切り分けていった、みたいな感じなので、クラス使ってるけどオブジェクト指向になってるかというとなってないんじゃないか。
  • 外部から使う関数って.displayだけなので他の関数は外から使えないようにしないといけないと思うんだけどやり方がわからない。
  • 肝心の.displayも4桁で0-9までしか対応してない。例えば123とか12345とかを引数にするとエラーになる。バリデーションとかもしてない。
  • %と℃を表示できるようにしたかったけど、力尽きたしまだどうすればいいか思いつかない。DISP_HEXのインデックス11-14はその名残。
  • など

でも、とりあえず形になったので、それはやっぱり嬉しいなぁ。

BME280の表示で使ってみる

BME280のサンプルプログラムの一番下

if __name__ == "__main__":

   import time
   import BME280
   import pigpio

   pi = pigpio.pi()

   if not pi.connected:
      exit(0)

   s = BME280.sensor(pi)

   stop = time.time() + 60

   while stop > time.time():
      t, p, h = s.read_data()
      print("h={:.2f} p={:.1f} t={:.2f}".format(h, p/100.0, t))
      time.sleep(0.9)

   s.cancel()

   pi.stop()

を、恐れ多くも

if __name__ == "__main__":

   import time
   import BME280
   import pigpio
   import TM1630

   pi = pigpio.pi()

   if not pi.connected:
      exit(0)

   s = BME280.sensor(pi)
   tm1630 = TM1630.TM1630(pi, 17, 27, 22)

   t, p, h = s.read_data()
   tm1630.display(str(int(round(h))).zfill(4))
   time.sleep(1)
   tm1630.display(str(int(round(p/100.0))).zfill(4))
   time.sleep(1)
   tm1630.display(str(int(round(t))).zfill(4))
   time.sleep(1)

   s.cancel()

   pi.stop()

て書き換えて、実行すると

こんな感じ。動くは動くでしょ。湿度→気圧→温度の順。

使ってみたい人用

https://dalomo.net/app/TM1630_for_Rpi_python.zip

そんな人いるかどうかわかんないけど、使ってみたい人いれば。直してくれたらもっと嬉しい。1から書き直しってレベルになるだろうけど。

参考

http://www.tohoho-web.com/python/class.html

https://note.nkmk.me/python-keyword-reserved-word/

https://teratail.com/questions/157952

https://note.nkmk.me/python-function-return-multiple-values/

https://www.itbook.info/network/python14.html

https://note.nkmk.me/python-str-extract/

https://qiita.com/Usek/items/a206b8e49c02f756d636

https://udemy.benesse.co.jp/development/web/python-list.html

https://note.nkmk.me/python-str-num-conversion/

https://note.nkmk.me/python-range-usage/

https://hacknote.jp/archives/23200/

https://note.nkmk.me/python-round-decimal-quantize/

https://qiita.com/soutarrr7/items/84e529d87aa3b3a9adcb

https://teratail.com/questions/143957

https://qiita.com/beatdown0514/items/361d6c213c2a1f2f5767

https://teratail.com/questions/162831

https://www.javadrive.jp/python/string/index9.html

https://yukun.info/python-typeerror-module-object-is-not-callable/

https://note.nkmk.me/python-format-zero-hex/

https://gammasoft.jp/blog/python-string-format/

https://note.nkmk.me/python-int-max-value/

https://e-tec-memo.herokuapp.com/article/191/

https://heppoko.hatenadiary.jp/entry/2013/11/20/043850

https://python.ms/object/class/method/self/

https://teratail.com/questions/146350

カテゴリー: したい, できた タグ: , , , , , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です