Arduino UNOで1つの割り込みを使って10個のボタンを効率的に制御する方法
概要
Arduino UNO(ATmega328P)には外部割り込みピンが2つ(INT0、INT1)しかありませんが、このプロジェクトでは1つの割り込みピンだけで最大20個のボタンを検出する独自の手法を紹介します。ダイオードや外部部品を一切使わず、ソフトウェアのみで「共通モード」と「個別モード」を動的に切り替えることで実現しています。
必要な部品
- Arduino UNO(または互換ボード)×1
- ブレッドボード ×1
- ジャンパーワイヤー ×21本
- タクトスイッチ(任意のサイズ) ×10個
- Arduino IDE
回路図
全ボタンの片側をそれぞれ別のデジタルピン(例:D4〜D13)に接続し、もう片側を全てまとめて割り込み対応ピン(D2)に接続します。追加の抵抗やダイオードは不要です。
仕組み:2つのモードを高速切り替え
1. 共通モード(待機時)
- 共通ピン(D2):
INPUT_PULLUP - ボタン側ピン(D4〜D13):
OUTPUT+LOW
この状態では、どのボタンを押しても共通ピンがLOWになり、割り込みが発生します。
2. 個別モード(割り込み発生直後)
- 共通ピン(D2):
OUTPUT+LOW - ボタン側ピン(D4〜D13):
INPUT_PULLUP
割り込みサービスルーチン(ISR)内で瞬時にこのモードに切り替え、全ボタンピンをスキャンしてどのボタンが押されているかを特定します。処理完了後、再び共通モードに戻ります。
サンプルコード(シリアル出力版)
const int commonPin = 2;
const int buttonPins[] = {4,5,6,7,8,9,10,11,12,13};
unsigned long lastFire = 0;
void setup() {
configureCommon();
attachInterrupt(digitalPinToInterrupt(commonPin), pressInterrupt, FALLING);
Serial.begin(9600);
}
void loop() { /* 空 */ }
void pressInterrupt() {
if (millis() - lastFire < 200) return; // デバウンス
lastFire = millis();
configureDistinct();
for (int i = 0; i < 10; i++) {
if (!digitalRead(buttonPins[i])) press(i);
}
configureCommon();
}
void configureCommon() {
pinMode(commonPin, INPUT_PULLUP);
for (int p : buttonPins) {
pinMode(p, OUTPUT);
digitalWrite(p, LOW);
}
}
void configureDistinct() {
pinMode(commonPin, OUTPUT);
digitalWrite(commonPin, LOW);
for (int p : buttonPins) pinMode(p, INPUT_PULLUP);
}
void press(int btn) { Serial.println(btn + 1); }
応用例:サーボ制御+スリープモード
ボタン操作でサーボ角度を変更し、5秒無操作でパワーダウンスリープに移行する省電力版も提供されています。トランジスタでサーボ電源を遮断し、消費電流を最小限に抑えます。
メリット・デメリット
| メリット | デメリット |
|---|---|
| 外部部品ゼロ(ダイオード不要) | ISR内でピンモード変更を行うため、わずかなレイテンシ発生 |
| ピン数の節約(UNOで最大20ボタン) | 同時押し検出には工夫が必要 |
| スリープ復帰に最適 | メカニカルスイッチのチャタリング対策必須 |
まとめ
この「動的ピンモード切り替え」テクニックは、バッテリー駆動のリモコンやUIデバイスなど、割り込みピンが限られる場面で極めて有効です。ピンチェンジ割り込みライブラリを使わず、標準の外部割り込みのみで実装できる点も魅力です。
製造プロセス
- ArduinoだけでDTMFデコーダーを構築 – 外付けIC不要
- Arduinoで作るモニター用Ambilightシステム:没入感アップの自作ガイド
- Arduinoで超音波レベーション(浮遊)装置を自作:ステップバイステップガイド
- Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
- ArduinoとMAX30100で作るリアルタイムIoT心拍数モニター
- Arduino UNO WiFi Webサーバー:ブラウザからLEDをON/OFF制御
- スマート駐車場カウンター:Arduino、Processing、PHPでリアルタイム車両管理
- Arduinoで自動化するChrome恐竜ゲーム – LDRとPythonで障害物を検知してジャンプ
- Arduino NanoとRDA5807Mで作るコンパクトFMラジオ
- ワイヤレスArduinoプログラミングシールド – HC-05 BluetoothでUSBケーブル不要に
- Arduinoで作るデジタル腕時計 - 有限状態マシンによる実装