2 заметки с тегом

Music

Электронные клавиши.

26 марта 2013, 23:24

C помощью нескольких резисторов и нескольких кнопок мы собираемся сделать небольшой электро-клавишный инструмент.

В принципе, можно подключить несколько выключателей к цифровым входам и использовать их для воспроизвдения различных нот. Но в этом проекте мы будем конструировать что-то вроде резисторной матрицы.

С помощью этого приёма можно считывать нажатия нескольких клавиш, используя только один аналоговый вход. Это очень полезно, когда обнаруживается недостаток в цифровых входах. Несколько выключателей соединяются параллельно с аналоговым входом Arduino и плюсом, на минус они подключаются через общий резитор. На плюс большая часть выключателей подсоединяется через свой резитор. С таким подключением при нажатии различных кнопок на пине будет разное наряжение. Если нажать несколько кнопок одновременно, на входе получится другое значение, в зависимости от того какие резиторы оказались соединёнными параллельно.

Схема подключения этого всего к Arduino выглядит так:

Первый выключатель подсоединяется к плюсу напрямую без резистора, второй — через резистор на 220 Ом, третий — через резистор на 10кОм, четвёртый — через резистор на 1МОм. Вторые выходы выключателей соединяются с аналоговым входом Arduino и через общий резистор в 10кОм идут на 0. В общем получается схема делителя напряжения, которую мы уже использовали.

Собранный макет:

Программа, с помощью которой вся эта шарманка будет играть:

int notes[]={
  262,294,330,349};//ноты до-фа (массив)
int keys=A0;//клавиши
int speak=8;//пьезоэлемент

void setup(){
  pinMode(speak, OUTPUT);
  Serial.begin(9600);
}

void loop(){
  int keysVal=0;//переменная для хранения значения клавиши
  keysVal=analogRead(keys);
  Serial.println(keysVal); 
  if  (keysVal==1023){
    tone(speak,notes[0]);
  }
  else if ( (keysVal>=990)&&(keysVal<=1010)){
    tone(speak,notes[1]);
  }
  else if ( (keysVal>=505 )&&(keysVal<=515)){
    tone(speak,notes[2]);
  }
  else if( (keysVal>=5)&&(keysVal<=10)){
    tone(speak,notes[3]);
  } 
  else{
    noTone(speak);//если ничего не нажато, замолчать
  }  
}

Для того, чтобы программа могла воспроизвести ноты, она должна где-то хранить список частот, для каждой ноты. Мы будем играть ноты до, ре, ми, фа (262Гц, 294Гц, 330Гц и 349Гц). Для этого в программе мы используем массив.

Массивы используют для хранения списков однотипных элементов, например, частоты нот, используя одно имя переменной. Это достаточно удобный инструмент для быстрого и эффективного доступа к информации.  Массив объявляется так же как и обычная переменная, но после её имени следует пара квадратных скобок []. Если нужно присвоить значения сразу всем элементам массива, то после знака равенства эти значения перечисляются через запятую и обрамляются фигурными скобками {}.

Для того, чтобы прочитать значения из массива, к массиву обращаются по имени и в квадратных скобках указать индекс (номер) конкретного элемента.  Номера элементов в массиве начинаются с нуля. Первый элемент имеет индек 0, второй — 1 и т. д.

Теперь небольшое описание программы:

Сначала мы создаем массив с частотами звуков, которые будем воспроизводить. В функции setup() указываем режим работы выхода, к которому подключен пьезоэлемент и включаем консоль (она нам нужна, чтобы определить какие значения за аналоговом входе будут выдавать нажатия различных кнопок).

В основной программе, сначала мы считываем значение с аналогового входа, затем выводим его на консоль. Этими двумя строчками мы ограничились в первом варианте программы и запустили её, записали значения, кототорые получали на входе при нажатии разных кнопок. Поскольку для каждой кнопки значения немного отличались для разных нажатий, то мы решили использовать не конкретные предпределённые значения, а интервалы. В зависимости от интервала, в котором находится считанное со входа значение, мы выдаем тот или иной тон, частоты берем из нашего массива. Если ни одна из кнопок не нажата, то даем команду «замолчать».

Небольшое видео:

Световой терменвокс.

18 марта 2013, 13:07

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

У терменвокса две антенны, при изменении положения рук исполнителя относительно них  изменяется ёмкость колебательного контура антенн. Эти антенны подключены к аналоговой схеме, которая создает звук. Одна антенна отвечает за частоту звука, а вторая за его громкость. Arduino, конечно же, не может воспроизвести загадочные звуки этого инструмента, но можно эмулировать их с помощью функции tone(). На рисунках ниже можно увидеть разницу между модуляциями произведёнными функцией analogWrite() и функцией tone(). Эти модуляции заставляют воспроизводящие устройства (такие как наушники, колонки или пьезоэлементы) издавать различые звуки.

Большую часть времени сигнал равен нулю, но частота такая же как и в ШИМ 150 PWM 50: analogWrite(50)
Большую часть времени сигнал равен единице, но частота такая же как и в ШИМ 50 PWM 150: analogWrite(50)
Рабочий цикл составляет 50% (половину времени сигнал есть, половину времени нет), но частота изменилась. TONE 440: tone(9,440)
Рабочий цикл такой же как и в Tone 440, но частота больше вдвое. TONE 880: tone(9,440)

Вместо определения ёмкости с помощью Arduino, мы будем использовать фоторезистор, чтобы определять количество света. Двигая руки над фоторезистором, мы будем менять количество света, которое на него попадает, так же как проекте «Лампа хамелеон». Изменение напряжения на аналоговом входе будет определять ноту какой частоты играть.

Фоторезистор к Arduino мы подключим используя схему делителя напряжения. Ранее мы уже заметили, что когда считываем напряжение с этой схемы используя функцию analogRead(), получаемые значения не всегда полностью покрывают диапазон от 0 до 1023 (максимальный диапазон, который может быть считан с аналогового входа). Резистор фиксированного сопротивления, подсоединённый к «земле», ограничивает считываемые значения снизу, а максимальная яркость освещения — сверху. Вместо того, чтобы ограничивать диапазон возможных значений, можно откалибровать сенсор, получив максимальное и минимальное значения, и соотнести их с частотой извлекаемого звука с помощью функции map() (как мы уже делали), таким образом, диапазон частот, которые будет издавать наш терменвокс, станет максимально возможным. Так же к нашему сенсору добавится дополнительная «фича»: куда бы мы не перенесли схему, например, в более темное помещение, она будет автоматически подстраиваться.

Итак , вот схема, которую мы будем собирать:

Собранный макет:

Пишем программу, для управления терменвоксом:

int sVal;//Значение на фоторезисторе
int sLow=1023; //минимальное значение фоторезистора
int sHigh=0;//максимальное значение фоторезистора
int ledPin=13;//встроенный светодиод

void setup(){
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,HIGH); //начало калибровки
  while(millis()<5000) { //калибруем в течении 5 секунд
    sVal=analogRead(A0);
    if (sVal>sHigh){
      sHigh=sVal;
    }
    if(sVal<sLow){
      sLow=sVal;
    }
  }
  digitalWrite(ledPin,LOW);//окончание калибровки
}

void loop(){
  int freq;
  sVal=analogRead(A0);//считываем значение с фоторезистора
  freq=map(sVal,sLow,sHigh,50,4000);//приводим значение
  tone(8,freq,20);//извлекаем звук
  delay(10);
}

Небольшой комментарий к программе:

Объявления переменных:

sVal — сюда будем считывать значение с фоторезистора;

sLow и sHigh — максимальное и минимальное значения, которые можно прочитать с фоторезистора. В начале программы они соответственно равны 1023 (минимальное) и 0 (максимальное). В процессе калибровки в этих переменных появятся реальные значения минимума и максимума.

ledPin — пин со светодиодом, при начале калибровки включим его, по окончании выключим.

Инициализация:

Включаем светодиод. Втечении первых пяти секунд, в цикле считывается значение с фоторезистора, если оно меньше уже зафиксированного минимального значения (первоначально 1023), то записываем его в минимальное, если оно больше уже зафиксированного максимального значения (первоначально 0), то записываем его в максимальное. Используем функцию mills(), для определения времени, прошедшего с момента включения Arduino.

Основная программа: вобщем довольно простая, функция tone() используется для воспроизведения звука, первый её параметр — пин, на который выводить звук, второй — частота звука, третий — длительность.

Вот что вышло:

Настоящий терменвокс позволяет управлять не только частотой звука, но и его громкостью. В этом примере мы можем менять только частоту. Если подсоединить потенциоментр последовательно с пьезоэлементом, то звук можно будет регулировать с помощью его ручки или можно поставить второй фоторезистор. Мы решили подключить потенциометр.

Схема и фото макета ниже, а вот видео: