Piano Hat (CAP1188) を使ってみる

## はじめに
スイッチサイエンスさんのブースで見かけて、[Pimoroni](https://shop.pimoroni.com/)というメーカの[PianoHat](https://shop.pimoroni.com/products/piano-hat) というボードを購入しました。見た目の通り、ピアノの鍵盤のような形をしているので、このボード一つで音がでるのかと思っていました。

![alt](https://cdn.shopify.com/s/files/1/0174/1800/products/Piano_HAT_4_of_4_512x512.JPG?v=1438331603)

しかし、<b>このボードは音源が搭載されていません。</b>Raspberry Pi などの母艦があって、PianoHatでタッチイベントを検出して、母艦で音を出さないとなりません。ですので、音を出すことは横へ置いておいて、まずはこのボードの仕組みを勉強してみたいと思います。

## PianoHat 仕様
- 16個の静電タッチパッド（13個のピアノ鍵盤、Octarve up/down、Instrument ）
- 2x Microchip CAP1188 capacitive touch driver chips

CAP1188(http://www.microchip.com/wwwproducts/en/CAP1188) は8ch の静電タッチパッド入力のチップなので、PianoHatの16個の静電パッドを２個のCAP1188で取り込んでいます。

ピン配置は[こちらのページ](https://pinout.xyz/pinout/piano_hat)を参照してください。

## CAP1188の初期化
レジスターは[取説](http://ww1.microchip.com/downloads/en/DeviceDoc/CAP1188%20.pdf)を見ながら調べます。また、Arduinoの[サンプルプログラム](https://github.com/adafruit/Adafruit_CAP1188_Library)がありましたのでこちらを見ながら勉強してみます。

```CAP1188.ino
#define CAP1188_PRODID 0xFD
#define CAP1188_MANUID 0xFE
#define CAP1188_REV 0xFF

#define CAP1188_MTBLK 0x2A
#define CAP1188_LEDLINK 0x72
#define CAP1188_STANDBYCFG 0x41

void setup() {
  // put your setup code here, to run once:
  uint8_t i2c_addr = slaveAddress;
  Wire.begin();

  Serial.begin(9600);
  Serial.println("CAP1188 test!");

  //接続テスト
  Serial.print("Product ID: 0x");
  Serial.println(readRegister(CAP1188_PRODID), HEX);
  Serial.print("Manuf. ID: 0x");
  Serial.println(readRegister(CAP1188_MANUID), HEX);
  Serial.print("Revision: 0x");
  Serial.println(readRegister(CAP1188_REV), HEX);

  //初期設定
  // allow multiple touches
  writeRegister(CAP1188_MTBLK, 0); 
  // Have LEDs follow touches
  writeRegister(CAP1188_LEDLINK, 0xFF);
  // speed up a bit
  writeRegister(CAP1188_STANDBYCFG, 0x30);
}
```

### 接続チェック
最初に、ちゃんとつながっているかどうかチェックするためにいくつかのレジスターを読み込んでみます。

|REGISTER ADDRESS| R/W |FUNCTION|REGISTER NAME|DEFAULT VALUE|
|:---------------|:----|:-------|:------------|:--------------|
|FDh |R |Product ID |Stores a fixed value that identifies each product |50h|
|FEh |R |Manufacturer ID |Stores a fixed value that identifies SMSC |5Dh|
|FFh |R |Revision |Stores a fixed value that represents the revision number |83h|

### 初期設定

|REGISTER ADDRESS| R/W |FUNCTION|REGISTER NAME|DEFAULT VALUE|
|:---------------|:----|:-------|:------------|:--------------|
|2Ah |R/W |Multiple Touch Configuration |Determines the number of simultaneous touches to flag a multiple touch condition| 80h |

00H を設定。最上位ビットをクリアします。multipleタッチ回路が無効になります。 デバイスはmultipleタッチをブロックしません。（毎回反応するってことだと思われます。）

|REGISTER ADDRESS| R/W |FUNCTION|REGISTER NAME|DEFAULT VALUE|
|:---------------|:----|:-------|:------------|:--------------|
|72h |R/W |Sensor Input LED Linking |Controls linking of sensor inputs to LED channels| 00h |

FFHを設定。静電タッチパッドのセンサーをLED入力にリンクします。（タッチするとLEDが光るってことだと思います。）

|REGISTER ADDRESS| R/W |FUNCTION|REGISTER NAME|DEFAULT VALUE|
|:---------------|:----|:-------|:------------|:--------------|
|41h |R/W |Standby Configuration |Controls averaging and cycle time while in standby | 39h| 

30Hを設定。Standby Configurationは、それらのセンサ入力の平均化とサイクル時間を制御します。多少チャタリングがあっても、素早く反応する設定になっています。

- STBY_CY_TIME[B0:B1] NUMBER OF SAMPLES TAKEN PER MEASUREMENT [0,0]=1
- STBY_SAMP_TIME[B2:B3] SAMPLING TIME [0,0]=320usec

## Loopのプログラム

```CAP1188.ino
#define CAP1188_SENINPUTSTATUS 0x3
#define CAP1188_MAIN 0x00
#define CAP1188_MAIN_INT 0x01

uint8_t status=0;

void loop() {
  uint8_t t = readRegister(CAP1188_SENINPUTSTATUS,slaveAddress2);
  if (t) {
    writeRegister(CAP1188_MAIN, readRegister(CAP1188_MAIN) & ~CAP1188_MAIN_INT);
  }
  if(status!=t){
     status=t;
     Serial.println(status, HEX);
  }
}
```
|REGISTER ADDRESS| R/W |FUNCTION|REGISTER NAME|DEFAULT VALUE|
|:---------------|:----|:-------|:------------|:--------------|
|03h |R |Sensor Input Status |Returns the state of the sampled　capacitive touch sensor inputs |00h|
|00h |R/W |Main Control |Controls general power states and power dissipation| 00h|

Sensor Input Statusはタッチされていると１に、されていないとゼロになる８ビットのレジスタです。

Main ControlのLSBは、割り込みがあることを示します。 このビットがセットされると、ALERT＃ピンがアサートされます。ということなので、タッチセンサーの入力があった時にはこのビットをクリアします。