Arduino Uno R4 WiFi で居眠り防止アラートを作ってみた

デスクワーク中や自習中など、「気づいたら少しずつ頭が前に落ちていた」ということは意外とあります。今回も、「エレクトロニクスを簡単に」をテーマとしてtilt switch (傾斜スイッチ)を使って、頭が一定時間うつむいた状態になったらブザーで知らせる簡易な居眠り防止アラートを作ってみました。

仕組みはシンプルで、傾きが一定時間続いたら ALERT とみなし、ブザーとLEDで通知します。なお、これは姿勢変化を使った簡易PoCであり、医学的な眠気判定や安全装置ではありません。特に運転用途や安全クリティカルな用途には使わない前提で試作しています。

目次

はじめに: うつむきに気づきにくい問題

長時間のPC作業や勉強をしていると、眠気そのものより先に、頭が前に傾く・姿勢が崩れるといった変化が出ることがあります。本人は「まだ大丈夫」と思っていても、気づかないうちに集中が切れていることもあり、軽く注意を促してくれる仕組みがあると便利です。

そこで今回は、傾きを検知できるtilt switchを使って、一定角度以上の傾きが続いたら警告するシンプルなアラートを試作してみました。tilt switchは、一定角度になると内部の金属球が接点を切り替える、いわば物理的な仕組みで動くスイッチとして扱えるため、デジタル入力だけで簡単に扱えるのが特徴です。Arduino Tilt Sensor

ローカル警告の基本構成

まずは基本となる、tilt switchで傾きを検知し、ブザーとLEDで警告するシステムを構築しました。

使用した主な部品

・Arduino Uno R4 WiFi
・tilt switch(傾斜スイッチ/ボール型傾斜センサー)
・ 圧電ブザー
・赤色LED/緑色LED
・抵抗
・ブレッドボード
・ジャンパーピン
・取り付け用のクリップやヘッドバンドなど

Arduino Uno R4 WiFiの特徴

マイコンには Arduino Uno R4 WiFiを使用しました。公式ドキュメントによると、このボードはメインMCUとしてRenesas RA4M1を採用しており、48MHz動作のArm Cortex-M4、256KB Flash、32KB S RAM を備えています。また、ESP32-S3 により Wi-Fi / Bluetooth 接続にも対応しています。単純なデジタル入力を使う小さな試作から、将来的な通知・クラウド連携まで広げやすいボードです。
Arduino Documentation
今回の試作では、まずはローカルで姿勢変化に気づけることを重視し、tilt switch LED・ブザーだけの小さな構成から始めます。Uno R4 WiFiには将来的に活かせる無線機能があるので、PoCとして始めてから通知機能に拡張しやすい点も扱いやすいところです。
Arduino Documentation
RA4M1-48MHz Arm Cortex-M4とLCDコントローラおよびHMI用静電容量式タッチセンサ搭載32ビットマイクロコントローラ | Renesas

ローカル警告イメージ

今回の仕組みでは、ヘッドバンドや帽子のつば付近などにセンサーを固定し、通常姿勢では監視状態、前傾姿勢が一定時間続いたら警告状態になるようにします。

・通常時:緑LED点灯
・傾きが短時間だけ発生: まだ警告しない
・傾きが一定時間以上続く: 赤LED点灯+ブザー警告

「一瞬うつむいただけ」で鳴ってしまうと使いにくいため、今回は傾きが連続して続いた時だけ反応するようにしています。

開発環境と実装のポイント

開発環境には Visual Studio Code PlatformIO IDE を使用しました。PlatformIOでは board = uno_r4_wifiplatform = renesas-ra、 framework arduino で設定できます。PlatformIO

傾き判定の考え方

tilt switch は、Arduino公式ドキュメントでも押しボタンに近い感覚で扱えるセンサーとして説明されています。内部の金属球が傾きによって接点をON/OFFするため、ソフトウェア側では「傾いた/ 傾いていない」のデジタル入力として扱えます。今回はこの特徴を使い、次のようなルールで判定します。Arduino Tilt Sensor

・tilt switch が傾きを検知したら、傾斜継続時間の計測を開始
・傾きが1.5秒以上続いたらALERT
・元の姿勢に戻ったら警告解除
・一瞬の揺れで誤判定しにくいよう、簡易デバウンスを入れる

実装上の注意

tilt switch はシンプルで扱いやすい反面、頭の角度そのものを高精度に測るセンサーではありません。取り付け位置やセンサーの向きによって反応角度が変わりやすく、姿勢のクセでも誤反応することがあります。そのため今回は、「眠気そのもの」を測るというより、うつむき姿勢が続いたら軽く注意することを目的にしています。

また、Arduinoの tilt sensor 解説では、pull-upを使ってactive-low入力として扱う例が紹介されています。今回のコードもその考え方に合わせて INPUT_PULLUP を使用しています。使用するセンサーモジュールによっては出力論理が逆になる場合があるため、その場合は LOW/HIGH の判定を反転してください。Arduino Tilt Sensor

ブザーについては Arduino の tone() を使っています。これは指定したピンに所定周波数の矩形波を出力する関数で、圧電ブザーなどを簡単に鳴らせます。短い警告音を周期的に鳴らすのに向いています。Arduino tone()

配線情報

モジュール

信号

接続先

補足

tilt switch (2ピン)

片側

Arduino Uno R4 WiFiのD2

INPUT_PULLUP で読み取ります。

tilt switch (2ピン)

もう片側

Arduinoの GND

傾いた時に LOW になる想定です。

圧電ブザー

Arduino の D6

tone() で警告音を出します。

圧電ブザー

Arduino の GND

モジュール仕様に応じて接続します。

赤色LED

アノード側

Arduinoの D8

警告状態表示用。抵抗を直列に入れます。

緑色LED

アノード側

Arduinoの D7

通常監視状態表示用。抵抗を直列に入れます。

各LED

カソード側

Arduinoの GND

220Ω程度の抵抗を挟んで配線します。

3ピンの tilt sensor モジュールを使う場合は、DOD2VCC5VGNDGND に接続してください。ただし、モジュールによってはactive-high 出力になることがあります。

実際のプログラム

今回のローカル警告版で使用したプログラムは以下の通りです。
tilt switch の状態を D2 から読み取り、傾きが一定時間続いたらブザーとLEDで警告します。
※本プログラムは、生成AIを用いて作成しております。

#include <Arduino.h>

const int tiltPin = 2;
const int buzzerPin = 6;
const int redLedPin = 7;
const int greenLedPin = 8;

// active-low想定: tilt switchが傾くとLOW
const unsigned long debounceMs = 50;
const unsigned long alertThresholdMs = 1500;
const unsigned long beepIntervalMs = 700;
const unsigned long beepDurationMs = 180;

int lastRawReading = HIGH;
int stableReading = HIGH;
unsigned long lastChangeTime = 0;

bool tiltActive = false;
bool alertState = false;
unsigned long tiltStartTime = 0;
unsigned long lastBeepTime = 0;

bool readTiltDebounced() {
  int raw = digitalRead(tiltPin);
  
   if (raw != lastRawReading) {
    lastChangeTime = millis();
    lastRawReading = raw;
  }
  
   if ((millis() - lastChangeTime) > debounceMs) {
    stableReading = raw;
  }
  
   return (stableReading == LOW);
}

void updateOutputs() {
  digitalWrite(redLedPin, alertState ? HIGH : LOW);
  digitalWrite(greenLedPin, alertState ? LOW : HIGH);
  
  if (alertState) {
    if ((millis() - lastBeepTime) >= beepIntervalMs) {
      tone(buzzerPin, 2000, beepDurationMs);
      lastBeepTime = millis();
    }
  } else {
    noTone(buzzerPin);
  }
}

void setup() {
  Serial.begin(115200);
  
  pinMode(tiltPin, INPUT_PULLUP);
  pinMode(buzzerPin, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, HIGH);
  
  Serial.println("Tilt-based drowsiness alert started.");
}

void loop() {
  unsigned long now = millis();
  bool tilted = readTiltDebounced();

  if (tilted) {
    if (!tiltActive) {
      tiltActive = true;
      tiltStartTime = now;
      Serial.println("Tilt detected.");
    }
    
    if (!alertState && ((now - tiltStartTime) >= alertThresholdMs)) {
      alertState = true;
      Serial.println("ALERT: forward tilt sustained.");
    }
  } else {
    if (tiltActive || alertState) {
      Serial.println("Back to normal posture.");
    }
    
    tiltActive = false;
    alertState = false;
  }
  
  updateOutputs();
  delay(10);
}

ini

[env:uno_r4_wifi]
platform = renesas-ra
board = uno_r4_wifi
framework = arduino
monitor_speed = 115200

プログラムのポイント

pinMode(tiltPin, INPUT_PULLUP) にしているため、通常時はHIGH、傾き検知時はLOW という active-low入力になっています。
readTiltDebounced() で、接点の揺れや細かい振動による誤判定を少し抑えています。
・傾きが発生しても、1.5秒以上継続した時だけ警告するようにしています。
・警告中は tone () を使って2kHzの短い警告音を周期的に鳴らします。tone() は指定ピンに矩形波を出力できるため、圧電ブザーとの相性が良いです。Arduino tone()
・緑LEDは通常監視、赤LEDは警告状態を示します。
Serial.begin(115200) を入れているため、シリアルモニタで姿勢変化や警告状態を確認しながらデバッグできます。
センサーを実際に取り付ける時は、通常姿勢では反応せず、眠くなって前に倒れた時だけ反応する向きになるよう、物理的な角度を調整するのが重要です。

麦わら帽子に取り付けてみました。

前に傾くと、赤色LEDが光り、ブザーが鳴ります。

発展編:Wi-Fi通知やログ記録への拡張

ローカルで警告できるようになったら、次は「記録する」「離れた場所へ通知する」 方向にも広げられます。

Arduino Uno R4 WiFiESP32-S3を搭載しており、Wi-Fi / Bluetooth 接続に対応しています。そのため、今回のような姿勢変化PoCを起点に、警告発生時刻をMQTTで送信する、Webダッシュボードに回数を表示する、一定回数を超えたら通知するといった拡張がしやすい構成です。
Arduino Documentation

例えば、以下のような使い方が考えられます。

・一日の警告回数を記録する
・長時間作業中に姿勢崩れが増える時間帯を可視化する
・勉強・作業セッションごとの集中状態をざっくり振り返る
・PC側やスマホ側に通知を飛ばす

ローカルのブザーだけでもPoCとしては十分ですが、無線連携まで進めると、「その場で気づく」から「あとで振り返れる」 へ価値を広げられます。

今後の展望(改善案)

今回の試作は「前傾姿勢が続いたら注意する」ことを目的にしたシンプルな構成ですが、実際に使いやすくするなら改善したい点もあります。

判定精度の向上
tilt switch だけだと、単なる前かがみや物理振動でも反応することがあります。加速度センサーやジャイロセンサーと組み合わせると、姿勢変化をより滑らかに取れるようになります。

取り付け方法の改善
センサーの向きが少し変わるだけで判定条件が変わるため、帽子・ヘッドセット・メガネなど、固定方法を工夫すると安定しやすくなります。

警告方法の最適化
いきなり大きな音を鳴らすのではなく、最初はLEDだけ、次に短い音、さらに続いたら強めの警告、というように段階制御しても良さそうです。

ログの蓄積
何時ごろに警告が多いのかを記録すると、集中が切れやすい時間帯の把握にも使えます。

筐体化
ブレッドボード試作のままだと使い続けにくいため、小型ケースやクリップで装着しやすくすると実用性が上がります。

関連技術・参考トピック

今回の実装はかなりシンプルですが、発展させるならいくつか面白い方向があります。

まず、tilt switch は Arduino公式でも押しボタンに近いデジタル入力部品として扱われており、最初のPoCには向いています。一方で、角度や姿勢を連続値として見たい場合は、加速度センサーやIMUの方が適しています。今回のような試作は、まずは閾値を超えたら反応するところから始める、という意味で分かりやすい題材です。

Arduino Tilt Sensor

また、Arduino Uno R4 WiFi はWi-Fi/Bluetoothだけでなく、32ビットMCUや各種周辺機能を備えているため、ローカルの電子工作から通知・可視化まで段階的に広げやすいのも魅力です。

Arduino Documentation

開発環境としての PlatformIOも、ボード設定を明示しやすく、ビルドやシリアル確認をまとめて進められるので、Arduino IDE以外で整然と管理したい場合に便利です。

PlatformIO

無線という観点では、Renesasは近年 Wi-Fi 6/ Bluetooth LE対応MCU (RA6シリーズ) やコンボモジュール(RRQ61051) も展開しています。今回の作例でそこまで踏み込んでいるわけではありませんが、IoT機器が「つながること」を前提に設計される流れの中で、より低消費電力・高機能な常時接続デバイスへ広げていく方向性を考える参考になります。

WiFi/BLE-MCU (RA6シリーズ)
WiFi/BLEモジュール (RRQ61051)

まとめ

今回は、Arduino Uno R4 WiFitilt switchを使って、うつむき姿勢が一定時間続いたら警告する簡易な居眠り防止アラートを作ってみました。

構成自体はシンプルですが、

・傾きを検知する
・一瞬の揺れではなく継続時間で判定する
・ブザーとLEDでその場で気づけるようにする
・将来的にはログや通知に広げる

という流れを通して、小さなセンサー入力から実用寄りのフィードバック装置を作る面白さを体験できる題材でした。

まずはローカル警告の小さな仕組みから始めて、そこから通知、記録、姿勢分析へと広げていける点も、このテーマの面白さだと思います。

参考リンク

Arduino UNO R4 WiFi 公式ドキュメント
PlatformIO: Arduino Uno R4 WiFi ボード情報
Arduino公式:Tilt Sensor
Arduino公式:tone() Reference
RA4M1-48MHz Arm Cortex-M4とLCDコントローラおよびHMI用静電容量式タッチセンサ搭載32ビットマイクロコントローラ | Renesas
WiFi/BLE-MCU (RA6シリーズ)
WiFi/BLEモジュール (RRQ61051)