Терменвокс

В этом эксперименте мы имитируем действие музыкального инструмента терменвокс: изменяем высоту звучания бесконтактным путем, больше или меньше закрывая от света фоторезистор.

Оригинальный инструмент был изобретён ещё в 1920 году, Львом Сергеевичем Терменом, человеком с непростой и насыщенной судьбой. А сейчас мы имеем возможность воспроизвести изобретение с помощью нехитрой электроники.

1. Список деталей для эксперимента

  • 1 плата Arduino Uno

  • 1 беспаечная макетная плата

  • 1 пьезопищалка

  • 6 проводов «папа-папа»

  • 1 резистор номиналом 10 кОм

  • 1 фоторезистор

2. Схема на макетке

Схема подключения терменвокса на Arduino

Схема подключения терменвокса на Arduino

Обратите внимание:

  • В данной схеме мы используем резистор нового номинала, посмотрите таблицу маркировки, чтобы найти резистор на 10 кОм или воспользуйтесь мультиметром

  • Полярность фоторезистора, как и обычного резистора, не играет роли. Его можно устанавливать любой стороной

  • В данном упражнении мы собираем простой вариант схемы включения пьезодинамика

  • Полярность пьезопищалки роли не играет: вы можете подключать любую из ее ножек к земле, любую к порту микроконтроллера

  • На Arduino Uno использование функции tone мешает использованию ШИМ на 3-м и 11-м портах. Зато можно подключить её к одному из них

  • Вспомните, как устроен делитель напряжения: фоторезистор помещается в позицию R2 — между аналоговым входом и землей. Так мы получаем резистивный фотосенсор.

3. Скетч

#define BUZZER_PIN  3 // даём имена для пинов с пьезопищалкой (англ. buzzer) и фоторезистором (англ. Light Dependent Resistor или просто LDR)
#define LDR_PIN     A0
void setup()
{
  // пин с пьезопищалкой — выход...
  pinMode(BUZZER_PIN, OUTPUT);
  // ...а все остальные пины являются входами изначально, всякий раз при подаче питания или сбросе микроконтроллера. Поэтому, на самом деле, нам совершенно необязательно настраивать LDR_PIN в режим входа: он и так им является
}
void loop()
{
  int val, frequency;
  // считываем уровень освещённости так же, как для потенциометра: в виде значения от 0 до 1023.
  val = analogRead(LDR_PIN);
  // рассчитываем частоту звучания пищалки в герцах (ноту), используя функцию проекции (англ. map). Она отображает значение из одного диапазона на другой, строя пропорцию. В нашем случае [0; 1023] -> [3500; 4500]. Так мы получим частоту от 3,5 до 4,5 кГц.
  frequency = map(val, 0, 1023, 3500, 4500);
  // заставляем пин с пищалкой «вибрировать», т.е. звучать (англ. tone) на заданной частоте 20 миллисекунд. При следующих проходах loop, tone будет вызван снова и снова, и на деле мы услышим непрерывный звук тональностью, которая зависит от количества света, попадающего на фоторезистор
  tone(BUZZER_PIN, frequency, 20);
}

4. Пояснения к коду

  • Функция map(value, fromLow, fromHigh, toLow, toHigh) возвращает целочисленное значение из интервала [toLow, toHigh], которое является пропорциональным отображением содержимого value из интервала [fromLow, fromHigh]

  • Верхние границы map не обязательно должны быть больше нижних и могут быть отрицательными. К примеру, значение из интервала [1, 10] можно отобразить в интервал [10, -5]

  • Если при вычислении значения map образуется дробное значение, оно будет отброшено, а не округлено

  • Функция map не будет отбрасывать значения за пределами указанных диапазонов, а также масштабирует их по заданному правилу

  • Если вам нужно ограничить множество допустимых значений, используйте функцию constrain(value, from, to), которая вернёт: - value, если это значение попадает в диапазон [from, to] - from, если value меньше него - to, если value больше него

  • Функция tone(pin, frequency, duration) заставляет пьезопищалку, подключённую к порту pin, издавать звук высотой frequency герц на протяжении duration миллисекунд

  • Параметр duration не является обязательным. Если его не передать, звук включится навсегда. Чтобы его выключить, вам понадобится функция noTone(pin). Ей нужно передать номер порта с пищалкой, которую нужно выключить

  • Одновременно можно управлять только одной пищалкой. Если во время звучания вызвать tone для другого порта, ничего не произойдёт

  • Вызов tone для уже звучащего порта обновит частоту и длительность звучания