Waveshare Pico-CapTouch-ePaper-2.9 をCircuitpythonで使う (タッチスクリーン)

前回の続きです。

Waveshare Pico-CapTouch-ePaper-2.9 はタッチディスプレイなので表示だけじゃなくてタッチも取得したいです。

www.waveshare.com

タッチスクリーンドライバ

Wikiによると、タッチパネルはI2Cで接続されています。さらにサンプルコードを見るとICNT86というコントローラだと推測されます。

CircuitPythonのライブラリを調べるとTouchscreenというクラスがありましたが、どうやら抵抗膜式のタッチスクリーンを想定したクラスのようで利用は出来なさそうです。

docs.circuitpython.org

さらに、ICNT86のデータシートが見つからないのでサンプルコードをCircuitPythonで動くように書き換える方針が一番手っ取り早いですね。

github.com

実装

サンプルコードを参考にして実装したスクリプトです。

サンプル通りにINT信号を利用すると押しっぱなしの処理がややこしかったので都度レジスタを読んで座標を取得しています。

class ICNT86:
  def __init__(self, rotation):
    self.rotation = rotation
    self.address = 0x48
    self.i2c = busio.I2C(board.GP7, board.GP6)
    self.trst = digitalio.DigitalInOut(board.GP16)
    self.trst.direction = digitalio.Direction.OUTPUT

  def init(self, reset):
    while not self.i2c.try_lock():
      pass

    if reset:
      self.trst.value = 1
      time.sleep(0.1)
      self.trst.value = 0
      time.sleep(0.1)
      self.trst.value = 1
      time.sleep(0.1)

  def is_touch(self):
      def convert(x, y):
        if self.rotation == 0:
          return (x, y)
        if self.rotation == 90:
          return (y, 128 - x)
        if self.rotation == 180:
          return (128- x, 296 - y)
        if self.rotation == 270:
          return (296 - y, x)
        raise Exception

      b = self.readbytes(0x1001, 1)
      if b[0] > 0x00:
        t = b[0]
        b = self.readbytes(0x1002, t * 7)
        i = 0
        for i in range(0, t, 1):
          if b[5 + 7*i] > 0:
            x = 127 - ((b[4 + 7*i] << 8) + b[3 + 7*i])
            y = ((b[2 + 7*i] << 8) + b[1 + 7*i])
            yield convert(x, y)
      self.writebyte(0x1001, 0)
      time.sleep(0.01)

  def writebyte(self, reg, value):
    b = [(reg>>8) & 0xff, reg & 0xff, value]
    self.i2c.writeto(self.address, bytearray(b))

  def write(self, reg):
    b = [(reg>>8) & 0xff, reg & 0xff]
    self.i2c.writeto(self.address, bytearray(b))

  def readbytes(self, reg, len):
    self.write(reg)
    b = bytearray(len)
    self.i2c.readfrom_into(self.address, b)
    return b

これでHIDキーボードと組み合わせれば左手デバイスの完成は目前ですね!