Pitch follower: управление тоном через tone() и фоторезистор
Превратите Arduino в световой терменвокс: фоторезистор управляет высотой тона динамика через функцию tone().
В этом уроке мы научим Arduino менять высоту звука в зависимости от освещённости. Фоторезистор считывает уровень света, а функция tone() преобразует эти данные в звуковой сигнал. Получается простой аналог терменвокса — инструмента, которым управляют движением руки, не касаясь его.
Необходимые компоненты
- Динамик 8 Ом
- Фоторезистор
- Резистор 4,7 кОм
- Резистор 100 Ом
- Провода для соединения
- Макетная плата
Схема подключения

Схема подключения: Arduino UNO соединён с макетной платой, на которой установлены динамик, фоторезистор и резистор.
Один вывод динамика подключите к цифровому пину 9 через резистор 100 Ом, второй — к GND. Фоторезистор питается от 5V; его второй вывод идёт на аналоговый вход A0 и одновременно через резистор 4,7 кОм на GND. Резистор 100 Ом защищает динамик от перегрузки по току.
Принципиальная схема

Принципиальная схема: фоторезистор и резистор 4,7 кОм подключены к аналоговому входу A0 Arduino UNO; динамик 8 Ом через резистор 10 кОм подключён к цифровому выводу ~9.
Компоненты на схеме: ФОТОРЕЗИСТОР, РЕЗИСТОР 4,7 кОм, РЕЗИСТОР 10 кОм, ДИНАМИК 8 Ом.
Как это работает
Фоторезистор — это компонент, чьё сопротивление падает при увеличении освещённости. Вместе с резистором 4,7 кОм он образует делитель напряжения. Чем ярче свет, тем выше напряжение на A0, тем большее число возвращает analogRead(), и тем выше тон, который генерирует tone().
Человек слышит звуки в диапазоне примерно 20–20 000 Гц. Для данного проекта диапазон 120–1500 Гц звучит наиболее выразительно и хорошо воспроизводится небольшим динамиком.
Код
Логика проста: читаем аналоговый вход, преобразуем значение в частоту с помощью map() и передаём её в tone(). Главное — правильно задать границы map() под реальный диапазон вашего фоторезистора.
Прежде чем загружать скетч, откройте Serial Monitor и посмотрите, какие значения выдаёт analogRead(A0) при минимальной и максимальной освещённости в вашем помещении. В типичных условиях диапазон составляет примерно 400–1000, но у вас он может отличаться. Подставьте свои числа в вызов map().
/*
Pitch follower
Воспроизводит тон, высота которого изменяется в зависимости от аналогового входа
Схема:
- Динамик 8 Ом на цифровом пине 9
- Фоторезистор на analog 0, подключён к 5V
- Резистор 4.7 kilohm на analog 0, подключён к ground
Создан 21 Jan 2010
Изменён 31 May 2012
Автор: Tom Igoe, с предложением от Michael Flynn
Этот пример кода находится в открытом доступе.
https://www.arduino.cc/en/Tutorial/Tone2
*/
void setup() {
// Инициализация последовательной связи (только для отладки):
Serial.begin(9600);
}
void loop() {
// Считываем значение датчика:
int sensorReading = analogRead(A0);
// Выводим показание датчика, чтобы знать его диапазон
Serial.println(sensorReading);
// Преобразуем диапазон аналогового входа (в данном случае 400–1000 от фоторезистора)
// в диапазон выходной высоты тона (120–1500Hz)
// Измените минимальное и максимальное значения входа ниже в зависимости от диапазона,
// который выдаёт ваш датчик:
int thisPitch = map(sensorReading, 400, 1000, 120, 1500);
// Воспроизводим тон:
tone(9, thisPitch, 10);
delay(1); // Задержка между считываниями для стабильности
}
Типичные ошибки
- Нет звука. Проверьте полярность динамика и надёжность соединений. Убедитесь, что резистор 100 Ом стоит именно в цепи динамика, а не перепутан с 4,7 кОм.
- Тон не меняется. Скорее всего, диапазон
map()не соответствует реальным показаниямanalogRead(). Добавьте вloop()строкуSerial.println(analogRead(A0));и откройте Serial Monitor — вы сразу увидите актуальные значения. - Звук монотонный или «зависает». Фоторезистор может быть слишком медленным при резких изменениях освещённости. Попробуйте поднести руку ближе или использовать фонарик для более контрастного управления.
- Писк вместо тона. Слишком высокие значения частоты. Уменьшите верхнюю границу второго диапазона в
map().
Как проверить результат
- Загрузите скетч и поднесите руку к фоторезистору — тон должен понижаться по мере затенения.
- Посветите фонариком — тон поднимается.
- Плавно перемещая руку, можно «играть» простые мелодии.
Где пригодится
- Интерактивные инсталляции и световые музыкальные игрушки.
- Обучающие демонстрации работы АЦП и функции
map(). - Основа для более сложных терменвоксов с несколькими датчиками.
Дополнительные материалы
Больше базовых примеров вы найдёте в разделе built-in examples.
Подробное описание всех функций языка Arduino доступно в language reference.
Последнее обновление: 11.08.2015, SM