① 今日の目標
🏆 Chapter 5 総合作品 — これまでに学んだすべての技術を一つの作品に組み合わせよう!
CdSセンサーで影を検知できる
センサーごとに違う音を鳴らせる
配列でピンと音階をまとめて管理できる
複数センサー+音出力の総合制御ができる
📚 このレッスンで使う技術
Ch1
analogRead()
CdSの光量読み取り
CdSの光量読み取り
Ch2
if/else if
どのセンサーが暗い?
どのセンサーが暗い?
Ch2
配列・for文
4センサーをまとめる
4センサーをまとめる
Ch4
tone()/noTone()
パッシブブザーで音出力
パッシブブザーで音出力
② 必要なもの
Arduino Uno
マイコンボード本体
CdSセル×4個
光センサー(光依存抵抗)
パッシブブザー×1
tone()で音程を出す
10kΩ抵抗×4本
CdSのプルダウン抵抗
LED×4個(オプション)
どのキーが押されたか表示
ブレッドボード+ジャンパー線
部品をつなぐ
③ しくみを学ぼう
☀️ CdSセンサーの仕組み(おさらい)
- 明るい → 抵抗が低い → 電圧が上がる →
analogReadが大きな値(600〜900) - 暗い(影) → 抵抗が高い → 電圧が下がる →
analogReadが小さな値(100〜300) - しきい値(400前後)以下になったら「影が当たった=鍵盤を押した」と判定!
🎵 音階と周波数(おさらい)
| センサー | ピン | 音名 | 周波数 |
|---|---|---|---|
| CdS 1 | A0 | ド (C) | 262 Hz |
| CdS 2 | A1 | レ (D) | 294 Hz |
| CdS 3 | A2 | ミ (E) | 330 Hz |
| CdS 4 | A3 | ファ (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文を変えるだけ!
ピン番号と音階を配列にすることで、センサー数が増えてもfor文を変えるだけ!
breakで同時押し対策
最初に影を検出したセンサーだけ音を鳴らし、
最初に影を検出したセンサーだけ音を鳴らし、
breakでfor文を抜けることで1音ずつ演奏できます。
noTone()で消音
どのセンサーも反応していない時はnoTone()で音を止めます。これで「指を離すと止まる」動作に!
どのセンサーも反応していない時はnoTone()で音を止めます。これで「指を離すと止まる」動作に!
LEDで視覚フィードバック
どのキー(センサー)が押されたか、LEDで光って分かります。オプションで省略もOK!
どのキー(センサー)が押されたか、LEDで光って分かります。オプションで省略もOK!
⑤ 配線図
💡 CdSの接続方法(分圧回路)
CdSと10kΩ抵抗を直列につなぎ、その間をAピンに接続します(プルダウン)。光が当たるとCdSの抵抗が下がり、Aピンの電圧が上がります。
CdSと10kΩ抵抗を直列につなぎ、その間をAピンに接続します(プルダウン)。光が当たるとCdSの抵抗が下がり、Aピンの電圧が上がります。
⑥ チェックリスト
⑦ チャレンジクイズ!
⑧ 🎹 シャドウピアノシミュレーター
CdSセンサーをクリック(タップ)して指の影をかざす感覚で演奏しよう!🖐️
光レベル
—
クリックして演奏!
センサーに触れると音が鳴るよ
🎵 自動演奏で試してみよう
⑨ まとめ
CdS影検知
analogRead < しきい値
で影を判定
analogRead < しきい値
で影を判定
配列でスッキリ
ピン&音階を配列に
for文でまとめて処理
ピン&音階を配列に
for文でまとめて処理
breakで1音ずつ
最初のセンサーで
breakして重複回避
最初のセンサーで
breakして重複回避
Ch1〜4の集大成!
センサー+条件分岐
+配列+音出力を統合
センサー+条件分岐
+配列+音出力を統合