Arduino Nanoで自動化するガレージスライドドア:OLED表示・安全センサ・リモコン連携
必要な部品と材料
| Arduino Nano R3 | ×1 |
| OLEDディスプレイ 0.96インチ 128×64(SPI接続、SSD1306) | ×1 |
| リレーモジュール 4ch(3ch使用) | ×1 |
| ブレッドボード電源モジュール 5V/3.3V(または220V→5V小型電源) | ×1 |
| タクトスイッチ 12mm(リセット/故障解除用) | ×1 |
| ブレッドボード & ジャンパーワイヤー | 各1 |
| 市販の無線リモコン受信機(リレー出力タイプ) | ×1 |
| フォトセル(安全センサ、赤外線遮断検知) | ×1 |
| リミットスイッチ 2個(全開・全閉検知) | ×2 |
| 220Vモータ・既存ドア機構(流用) | ×1式 |
プロジェクトの背景
自宅のスライドドアのリモコンが効かなくなり、モータカバーを開けるとトカゲが基板上でショート死しており、制御基板が焼損していました。これを機にArduinoで制御ユニットを自作・高機能化することにしました。
⚠️ 安全に関する警告
このプロジェクトは220V(または100V)商用電源を直接扱います。 感電・火災のリスクがあります。電気工事の知識・経験がない方は実施しないでください。必ず事前にシミュレーション・ベンチテストを行い、実機接続は慎重に行ってください。
システム構成
本プロジェクトの核心は、Arduino Nanoベースのメイン制御ユニットです。以下の機能を統合しています。
- モータ正転(開)/ 逆転(閉)制御:リレー2chで220Vモータの極性切替
- 表示灯(信号灯)制御:リレー1chで点滅パターン制御
- リミットスイッチ監視:全開(OBERT)、全閉(TANCAT)
- 安全フォトセル監視:閉鎖中に障害物検知で即座に開放動作へ切替
- 無線リモコン「開」コマンド受信(リレー接点入力)
- OLEDディスプレイによる状態監視(デバッグ・調整用)
- 故障検知(走行タイムアウト)とアラーム表示
ピンアサイン(Nano基準)
| 機能 | ピン | 備考 |
|---|---|---|
| フォトセル入力 | D2 | INPUT_PULLUP、遮断でHIGH |
| 表示灯リレー | D5 | LOWアクティブ |
| 全閉リミット | D7 | INPUT_PULLUP、押下でHIGH |
| 全開リミット | D3 | INPUT_PULLUP、押下でHIGH |
| モータ開リレー | D6 | LOWアクティブ |
| モータ閉リレー | D12 | LOWアクティブ |
| リモコン「開」入力 | D4 | INPUT_PULLUP、受信でLOW |
| OLED (SPI) | D11(MOSI), D13(SCK), D9(DC), D10(CS), D8(RST) | Adafruit_SSD1306ライブラリ使用 |
| リセットボタン | (別途割当推奨) | 故障フラグクリア用 |
OLED表示内容
制御ボックス内部に設置し、調整時に蓋を開けて確認する用途です。以下をリアルタイム表示。
- 現在のフェーズ(メインループ、開動作、待機、閉動作、故障等)
- 主要動作の経過時間(秒)
- 各センサ状態(フォトセル、全閉、全開、リモコン入力)
- 故障フラグ(AVARIA)
ステートマシン(フローチャート概要)
- BUCLE_PRINCIPAL(メインループ):リモコン「開」コマンド待ち。センサ状態をOLED表示。故障時は表示灯点滅で警告。
- SEQUENCIA_OBERTURA(開シーケンス):モータ正転開始、表示灯低速点滅。全開リミット到達で「PORTA_OBERTA」へ。タイムアウト(28秒)で故障。リモコン「開」再受信で即座に閉シーケンスへ移行(キャンセル機能)。
- PORTA_OBERTA(全開待機):モータ停止、表示灯特殊点滅(短点滅+長消灯)。30秒経過、またはリモコン「開」受信で閉シーケンスへ。
- SEQUENCIA_TANCAMENT(閉シーケンス):モータ逆転開始、表示灯高速点滅。全閉リミット到達でメインループへ。フォトセル遮断検知で即座に開シーケンスへ(安全機能)。リモコン「開」受信で開シーケンスへ。タイムアウト(28秒)で故障。
コード全文(英語コメント版・抜粋)
完全版はGitHubまたはプロジェクトページからダウンロード可能です。ここでは主要構造を抜粋。
/*********************************************************************
* Automated Sliding Door Controller for Arduino Nano
* Based on original Catalan code by M. B. R.
*********************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// ピン定義
#define FOTOCELULA 2
#define BOMBETA 5
#define TANCAT 7
#define OBERT 3
#define MOTOR_OBRIR 6
#define MOTOR_TANCAR 12
#define OBRIR 4
// OLED SPIピン
#define OLED_MOSI 11
#define OLED_CLK 13
#define OLED_DC 9
#define OLED_CS 10
#define OLED_RESET 8
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
// タイミング定数
unsigned long TEMPS_PORTA_OBERTA = 30000; // 全開待機 30秒
unsigned long TEMPS_MAXIM_RECORREGUT = 28000; // 走行タイムアウト 28秒
unsigned long previousMillis = 0, currentMillis = 0;
int TEMPS_DISPLAY = 0;
int DURADA = 300; // 点滅周期制御用
unsigned long TEMPS_LLUM = 0;
bool LLUM = false;
bool AVARIA = false;
void setup() {
// 出力初期化(リレーはLOWアクティブ)
digitalWrite(MOTOR_OBRIR, HIGH); digitalWrite(MOTOR_TANCAR, HIGH); digitalWrite(BOMBETA, HIGH);
pinMode(FOTOCELULA, INPUT_PULLUP);
pinMode(TANCAT, INPUT_PULLUP);
pinMode(OBERT, INPUT_PULLUP);
pinMode(OBRIR, INPUT_PULLUP);
pinMode(BOMBETA, OUTPUT);
pinMode(MOTOR_OBRIR, OUTPUT);
pinMode(MOTOR_TANCAR, OUTPUT);
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC);
display.display(); delay(1000);
display.clearDisplay(); display.display();
display.setTextSize(1); display.setTextColor(WHITE);
}
void loop() {
// === メインループ:リモコン「開」待ち ===
BUCLE_PRINCIPAL:
delay(2000); previousMillis = millis();
while (digitalRead(OBRIR) == HIGH) { // LOWでコマンド受信
updateDisplay("BUCLE PRINCIPAL");
if (AVARIA && (millis() - previousMillis < 60000)) digitalWrite(BOMBETA, LOW);
else digitalWrite(BOMBETA, HIGH);
}
goto SEQUENCIA_OBERTURA;
// === 開シーケンス ===
SEQUENCIA_OBERTURA:
previousMillis = millis();
digitalWrite(MOTOR_OBRIR, LOW); digitalWrite(BOMBETA, LOW); delay(1000);
A:
if (digitalRead(OBERT) == HIGH) goto PORTA_OBERTA;
if (digitalRead(OBRIR) == LOW) { // キャンセル:閉シーケンスへ
digitalWrite(MOTOR_OBRIR, HIGH); digitalWrite(BOMBETA, HIGH); delay(1000);
while (digitalRead(OBRIR) == HIGH) {}; goto SEQUENCIA_TANCAMENT;
}
updateTimingAndDisplay("Obrint porta");
if (millis() - previousMillis >= 28000) { digitalWrite(MOTOR_OBRIR, HIGH); AVARIA = true; }
controlBlink(1000); // 低速点滅
goto A;
// === 全開待機 ===
PORTA_OBERTA:
previousMillis = millis();
digitalWrite(MOTOR_OBRIR, HIGH); delay(500);
C:
if (digitalRead(OBRIR) == LOW) goto SEQUENCIA_TANCAMENT;
updateTimingAndDisplay("Porta Oberta completament");
if (millis() - previousMillis >= 30000) goto SEQUENCIA_TANCAMENT;
controlSpecialBlink(); // 短点滅+長消灯
goto C;
// === 閉シーケンス ===
SEQUENCIA_TANCAMENT:
previousMillis = millis();
digitalWrite(MOTOR_TANCAR, LOW); digitalWrite(BOMBETA, LOW);
if (digitalRead(TANCAT) == LOW) delay(1000);
B:
if (digitalRead(TANCAT) == HIGH) { digitalWrite(MOTOR_TANCAR, HIGH); digitalWrite(BOMBETA, HIGH); goto BUCLE_PRINCIPAL; }
if (digitalRead(OBRIR) == LOW) { digitalWrite(MOTOR_TANCAR, HIGH); digitalWrite(BOMBETA, HIGH); delay(1000); while (digitalRead(OBRIR) == HIGH) {}; goto SEQUENCIA_OBERTURA; }
if (digitalRead(FOTOCELULA) == HIGH) { digitalWrite(MOTOR_TANCAR, HIGH); delay(1000); goto SEQUENCIA_OBERTURA; }
updateTimingAndDisplay("Tancant porta");
if (millis() - previousMillis >= 28000) { digitalWrite(MOTOR_TANCAR, HIGH); AVARIA = true; goto BUCLE_PRINCIPAL; }
controlBlink(300); // 高速点滅
goto B;
}
// ヘルパー関数群(表示更新、点滅制御等)は省略
void updateDisplay(const char* phase) { /* OLEDへ多行表示 */ }
void updateTimingAndDisplay(const char* phase) { /* 経過時間計算・表示 */ }
void controlBlink(int period) { /* 表示灯PWM制御 */ }
void controlSpecialBlink() { /* 待機時の特殊パターン */ }
配線図・回路図
Fritzing回路図とピンアサイン表を参照してください。リレーモジュールはLOWアクティブ前提です。220V側は必ず適切な絶縁・クリアランスを確保し、リレー定格(10A以上推奨)を確認してください。
改良ポイント・拡張案
- 元の市販品にはなかった「フォトセル安全機能」「走行タイムアウト故障検知」「OLEDによる可視化」を追加
- ショックセンサや電流センサ(ACS712等)を追加すれば、障害物検知・過負荷保護がより確実に
- ESP32等へ移植すれば、Wi-Fi経由でスマホから開閉・状態確認・ログ記録が可能
- ソーラー充電+バッテリーで停電時も動作する冗長化
まとめ
実用的な家電制御をArduinoで置き換え、安全機能と可視化を追加した好例です。goto文を多用したステートマシン実装は賛否ありますが、組み込み制御の現場では「状態遷移が明確で、割り込み不要な単純制御ならあり」とされるパターンです。よりモダンに書くならenum class Stateとswitch(state)、関数分割を推奨します。高電圧扱いには十分注意し、自己責任でチャレンジしてください。
製造プロセス
- Raspberry Pi向けコンパクトDHT温湿度ブレークアウト – ATtiny85 & DHT22/DHT11
- Raspberry Piの可能性を最大限に引き出す必須アクセサリー
- SIGHT:視覚障害者を支援するスマートグラス
- Raspberry Pi で水中ドローンを自作:設計、開発、組み立てガイド
- 車両用トップクオリティショックアブソーバーの選び方
- 手動バンドソー:あらゆるプロジェクトに対応する耐久・携帯性に優れた切断ソリューション
- 自動パワープレスとは? - 究極の板金成形機
- 自動化が中小企業の成長を加速する:明るい未来への道筋
- 心からの別れ:出版業界40年の歩みを終えて
- 五極管:管性能向上の第5要素
- スイス型・量産旋削向け精密スライディングヘッドストック自動化