Lesson 21

🎹 光センサーで弾くデジタルピアノ!
影でド・レ・ミ・ファ!

CdSセンサーに指の影をかざすと音が鳴る魔法のピアノを作ろう!センサー読取り・条件分岐・配列・音出力、これまでの全技術を組み合わせるChapter 5 総合作品だよ!

⏱ 90分 🤖 Arduino ☀️ CdS×4 🔊 ブザー 🏆 総合作品
🎹

今日の目標

🏆 Chapter 5 総合作品 — これまでに学んだすべての技術を一つの作品に組み合わせよう!
☀️
CdSセンサーで影を検知できる
🎵
センサーごとに違う音を鳴らせる
📚
配列でピンと音階をまとめて管理できる
🔗
複数センサー+音出力の総合制御ができる

📚 このレッスンで使う技術

Ch1
analogRead()
CdSの光量読み取り
Ch2
if/else if
どのセンサーが暗い?
Ch2
配列・for文
4センサーをまとめる
Ch4
tone()/noTone()
パッシブブザーで音出力

必要なもの

🔵

Arduino Uno

マイコンボード本体

☀️

CdSセル×4個

光センサー(光依存抵抗)

🔊

パッシブブザー×1

tone()で音程を出す

10kΩ抵抗×4本

CdSのプルダウン抵抗

💡

LED×4個(オプション)

どのキーが押されたか表示

🔌

ブレッドボード+ジャンパー線

部品をつなぐ

しくみを学ぼう

☀️ CdSセンサーの仕組み(おさらい)

  • 明るい → 抵抗が低い → 電圧が上がる → analogRead大きな値(600〜900)
  • 暗い(影) → 抵抗が高い → 電圧が下がる → analogRead小さな値(100〜300)
  • しきい値(400前後)以下になったら「影が当たった=鍵盤を押した」と判定!

🎵 音階と周波数(おさらい)

センサー ピン 音名 周波数
CdS 1A0ド (C)262 Hz
CdS 2A1レ (D)294 Hz
CdS 3A2ミ (E)330 Hz
CdS 4A3ファ (F)349 Hz

📚 配列で複数センサーを管理しよう

4つのCdSを個別に書くと長くなります。配列を使えばスッキリ!

❌ 配列なし(長い…)
if (analogRead(A0) < 400) tone(8, 262);
if (analogRead(A1) < 400) tone(8, 294);
if (analogRead(A2) < 400) tone(8, 330);
if (analogRead(A3) < 400) tone(8, 349);
✅ 配列+for文(スッキリ!)
int pins[]  = {A0, A1, A2, A3};
int notes[] = {262, 294, 330, 349};
for (int i = 0; i < 4; i++) {
  if (analogRead(pins[i]) < 400) {
    tone(8, notes[i]); break;
  }
}

Arduinoコード

shadow_piano.ino
// ── ピン定義 ──
const int BUZZER    = 8;      // パッシブブザー
const int THRESHOLD = 400;    // 影判定しきい値

// CdSセンサーのピンと対応する音階(配列)
int cdsPins[]  = {A0, A1, A2, A3};          // センサーピン
int noteFreqs[] = {262, 294, 330, 349};       // ド・レ・ミ・ファ
const int NUM_KEYS = 4;

// オプション:LEDピン(各センサーに1つ)
int ledPins[] = {2, 3, 4, 5};

void setup() {
  pinMode(BUZZER, OUTPUT);
  for (int i = 0; i < NUM_KEYS; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
  Serial.begin(9600);
  Serial.println("Shadow Piano Ready! ♪");
}

void loop() {
  bool anyShadow = false;

  // 4つのセンサーを順番にチェック
  for (int i = 0; i < NUM_KEYS; i++) {
    int val = analogRead(cdsPins[i]);

    if (val < THRESHOLD) {
      // 影が検出された → 音を鳴らす
      tone(BUZZER, noteFreqs[i]);
      digitalWrite(ledPins[i], HIGH);
      anyShadow = true;

      // 最初のキーだけ鳴らす(同時押し対策)
      break;
    } else {
      digitalWrite(ledPins[i], LOW);
    }
  }

  // どこにも影がなければ音を止める
  if (!anyShadow) {
    noTone(BUZZER);
    for (int i = 0; i < NUM_KEYS; i++) {
      digitalWrite(ledPins[i], LOW);
    }
  }
}
📚
配列でまとめる
ピン番号と音階を配列にすることで、センサー数が増えてもfor文を変えるだけ!
breakで同時押し対策
最初に影を検出したセンサーだけ音を鳴らし、breakでfor文を抜けることで1音ずつ演奏できます。
🔇
noTone()で消音
どのセンサーも反応していない時はnoTone()で音を止めます。これで「指を離すと止まる」動作に!
💡
LEDで視覚フィードバック
どのキー(センサー)が押されたか、LEDで光って分かります。オプションで省略もOK!

配線図

Arduino Uno 5V GND A0 A1 A2 A3 D8 D2 D3 D4 D5 CdS CdS CdS CdS 各10kΩ プルダウン ブザー パッシブ D8 GND LED ×4(オプション) 5V/電源 GND A0〜A3 D8ブザー D2〜D5 LED
💡 CdSの接続方法(分圧回路)
CdSと10kΩ抵抗を直列につなぎ、その間をAピンに接続します(プルダウン)。光が当たるとCdSの抵抗が下がり、Aピンの電圧が上がります。

チェックリスト

チャレンジクイズ!

🎹 シャドウピアノシミュレーター

CdSセンサーをクリック(タップ)して指の影をかざす感覚で演奏しよう!🖐️

光レベル
クリックして演奏!
センサーに触れると音が鳴るよ
🎵 自動演奏で試してみよう
analogRead(A0): 720  A1: 715  A2: 718  A3: 722

まとめ

☀️
CdS影検知
analogRead < しきい値
で影を判定
📚
配列でスッキリ
ピン&音階を配列に
for文でまとめて処理
breakで1音ずつ
最初のセンサーで
breakして重複回避
🏆
Ch1〜4の集大成!
センサー+条件分岐
+配列+音出力を統合
🚗
次のレッスン
Lesson 22: 動くロボットカー!障害物を自動で避けよう
DCモーター2個+超音波センサーで、自動で障害物を避けるロボットカーを作ろう!