Digispark ATtiny85 にスイッチを付ける場合のコツ

# 1. はじめに

まだまだ現役で使っている、↓こちらの`Digispark ATtiny85`ですが、このIO端子にスイッチを付ける場合に、ちょっとしたハマりポイント（コツ）があるので、まとめておきます。

[<img width="200" alt="digispark_attiny85.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/8d7fb206-6b53-20db-6cb0-2a3ebebaa02b.jpeg" />](http://digistump.com/products/1)

# 2. 「スイッチ」とは、

↓こちらの様なタクトスイッチやキースイッチのことで、いわゆる「押しボタン」スイッチです。

<img width="80" alt="tact_switch.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/75caad12-d94e-21ba-473c-c6d1b93f7c0a.png" />
<img width="120" alt="keyswitch.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/f8687f7c-babc-83cf-b3ff-30b8b02535a8.jpeg" />


# 3. どこのIO端子にスイッチを付ける？

`ATtiny85`は`PB0`から`PB5`までの6個のIO端子がありますが、下記の回路図から分かるように、`PB3`と`PB4`は、USBの信号線（D-/+）として使われているので、USBデバイスとして使う場合には、このIO端子にはスイッチは付けられません。
また、PB5は標準ではRESET端子のため、ここにもスイッチは付けられません（FUSEを変更すれば IO端子として使用することができますが）。

よって、普通にスイッチを付けて入力端子として使用できるのは、`PB0`から`PB2`の3ポートということになります。

[<img width="500" alt="Digispark_Schematic.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/118fa402-648f-f57d-828d-2afce1af3753.png" />](https://s3.amazonaws.com/digistump-resources/files/97a1bb28_DigisparkSchematic.pdf)

# 4. 「スイッチ」を付ける場合

一般には、プルアップ抵抗を入れてIO端子をVCCに引き上げ、スイッチが押されたらGNDに落とす回路（下図左側）がよく使われます。

<img width="300" alt="pullup" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/3773d388-2ff9-c57b-e347-c50c2a75eaf2.png" />


内部プルアップ機能を有しているIOポート（マイコン）であれば、回路上の外部プルアップ抵抗を省略することができます（上図右側）。この場合、Arduino環境であれば、
`pinMode(IO0, INPUT_PULLUP)`の様に指定します。マイコンの内部でプルアップしてくれます。


どちらの場合も、プログラムからは、
・スイッチを`押していない`状態：`HIGH`
・スイッチを`押している`状態：`LOW`
 で、判定します。

# 5. しかし、`PB1`にはLEDが．．．

そうなんです。先ほどの回路図にも書いてありましたが、`PB1`にはLEDが接続されています。プログラムからこの端子を`HIGH`にすると、LEDを点灯できますね。

この`PB1`にスイッチを付けるときは、ちょっとしたコツがあります。

# 6. `Digispark ATtiny85`の`PB1`にスイッチを付ける場合、

下記の回路図の様に、`PB1`に付けたスイッチは`Vcc`に接続します。

<img width="300" alt="a" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/f8b00694-2de4-e9c6-1457-bc09ec7829ef.png" />

_（当然のことながら、SW1を押すとLEDが点灯します。）_

そして、プログラムからは、
・スイッチを`押していない`状態：`LOW`
・スイッチを`押している`状態：`HIGH`
 で、判定します。

`PB0`と`PB2`に付けたスイッチはGNDに接続するため、`PB1`とは、判定の仕方が`HIGH`/`LOW`逆になります。


:::note warn
ATtiny85の内部プルアップ機能を使う前提での話です。。。

もし、外部抵抗を付けるのであれば、`PB0`と`PB2`にプルダウン抵抗を付けてVccに接続すれば、3ポートとも判定方法を統一できます。
:::

# 7. Arduino環境でのプログラムの書き方

`PB0`と`PB2`は<ins>`内部プルアップ`</ins>、`PB1`は<ins>`外部プルダウン`</ins>として扱います。


```c:スケッチ例
//各スイッチのピン番号
#define SW0 0 //PB0
#define SW1 1 //PB1
#define SW2 2 //PB2

//各スイッチの判定関数（マクロ）
#define isSwicthOn(sw, val) (digitalRead(sw) == val)
#define isSw0On() isSwicthOn(SW0, LOW)
#define isSw1On() isSwicthOn(SW1, HIGH)
#define isSw2On() isSwicthOn(SW2, LOW)

void setup() {
  //ピン設定
  pinMode(SW0, INPUT_PULLUP); //internal pull-up
  pinMode(SW1, INPUT);        //external pull-down
  pinMode(SW2, INPUT_PULLUP); //internal pull-up
}

void loop() {
  //各スイッチの判定
  if (isSw0On()) {  ...  }
  if (isSw1On()) {  ...  }
  if (isSw2On()) {  ...  }

  delay(10);
}
```

この扱いを間違うと、「スイッチを押しても反応しない」、「押してないのに勝手に反応する」現象に悩まされます。

自分でも忘れていて、ハマることがあったので、ここにまとめておきました。
以上、ご参考まで。

<hr>

数年前にオリジナル基板を作成したミニキーボードは、現在も活躍しています。

<img alt="IMG_7654w.png" width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/295b7413-78be-cd89-f34c-8e05eae9cb09.png">

<hr>

関連記事

https://qiita.com/nak435/items/67aca33ca49b6f328faa

https://qiita.com/nak435/items/d8caed1cd29f5e67dcd7