Третий опыт с Arduino. В данной мини-лекции мы узнаем, как проигрывать при помощи Arduino простейшие мелодии, а также закрепим материал предыдущих двух уроков.    
Для опытов была создана экспериментальная платформа под кодовым названием “Щячло”. Это игрушка Furby из Макдональдса с кое-какими принципиальными доработками. В глаза ей были вставлены два мощных светодиода (пожалуй, слишком мощных, не жадничайте, как я и не покупайте светодиоды на 30000 мКд, а то в глазах после опытов будут плясать зайчики) . В щячло к Щячлу был вмонтирован фоторезистор, а в хвостовой части – стоит динамик (впрочем, он находился там и в прошлой инкарнации Furby).
Итак, суть опыта такова: имеется некоторый уровень освещенности от настольной лампы, и если мы её выключим – сработает фотодатчик и игрушка начнёт играть мелодию, а также в такт “мигать” глазами.
Мелодия выбрана с намёком на “Космическую Одиссею” Стэнли Кубрика и Артура Кларка. Да и 2010 год в конце-то концов. Кстати знаете ли вы, почему HAL-9000 пел именно Daisy Daisy, когда Дэйв вытаскивал из него один за другим модули памяти? [узнайте]
Мне очень важны ваши комментарии, так что не стесняйтесь, пишите.
Исходный код для данного примера. Прокомментированный и даже разукрашенный.
int speakerPin = 9; // выход для динамика         
int leftEye= 10; // левый светодиод         
int rightEye=11; // правый светодиод         
int photoPin = 0; // аналоговый вход для фоторезистора         
int val = 0; // переменная для значения считанного с аналогового входа         
        
// ноты мелодии         
char notes[] = "GECgabCaCg DGECabCDED EFEDGEDC CECaCag gCEDgCEDEFGECDgC "; // пробел - это пауза         
// длительность для каждой ноты и паузы         
int beats[] = { 4, 4, 4, 4, 1, 1, 1, 2, 1, 4,         
        2, 4, 4, 4, 4, 1, 1, 1, 2, 1,         
        4, 2, 1, 1, 1, 1, 2, 1, 1, 4,         
        2, 1, 2, 1, 2, 1, 1, 4, 2, 1,         
        2, 1, 2, 1, 2, 1, 2, 1, 1, 1,         
        1, 1, 2, 1, 4, 4, 4} ;         
        
int tempo = 200; // темп исполнения         
int length = sizeof(notes); // количество нот         
        
        
void playTone(int tone, int duration) {         
digitalWrite(leftEye,HIGH); // зажигаем оба глаза         
digitalWrite(rightEye,HIGH);  
 // проигрываем требуемую ноту с нужной частотой и длительностью         
 for (long i = 0; i < duration * 1000L; i += tone * 2) {         
  digitalWrite(speakerPin, HIGH);         
  delayMicroseconds(tone);         
  digitalWrite(speakerPin, LOW);         
  delayMicroseconds(tone);         
}         
digitalWrite(leftEye,LOW); // гасим оба глаза         
digitalWrite(rightEye,LOW);   
  
}         
        
void playNote(char note, int duration) {         
 // массив для наименований нот (до ре ми ... и т.д. в пределах двух октав)         
 char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C','D','E','F','G','A','B' };         
 // соответствующие нотам частоты         
 int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956, 850, 759, 716, 638, 568, 507 };         
        
 // выбор частоты по наименованию ноты         
 for (int i = 0; i < 15; i++) {         
  if (names[i] == note) {         
   playTone(tones[i], duration);         
  }         
}         
}         
        
void setup() {         
pinMode(speakerPin, OUTPUT);// цифровые выводы на динамик         
pinMode(leftEye, OUTPUT);  // и оба светодиода         
pinMode(rightEye, OUTPUT); // конфигурируем как выходы         
pinMode(photoPin, INPUT);  // а с фоторезистором - как вход         
}         
        
void loop() {         
// считываем значение с фотодатчика         
val = analogRead(photoPin);   
// небольшая задержка для регенерации АЦП         
delay(10);         
if (val>1020) { // если значение превысило предел (стало темно) - запускаем цикл проигрывания мелодии         
 for (int i = 0; i < length; i++) { //         
   if (notes[i] == ' ') {         
    delay(beats[i] * tempo); // пауза         
   } else {         
    playNote(notes[i], beats[i] * tempo); // либо проигрываем соответствующую ноту         
   }         
  // небольшая пауза между нотами         
  delay(tempo / 2);         
  }         
}         
}       
      
* This source code was highlighted with Source Code Highlighter.  
 







