MsTimer2をつかってMelodyのテンポを調整できるようにしてみた。
Arduino付属のサンプル"Melody"*1を改造してテンポ調整できるようにしました。
アナログ入力0番につながった可変抵抗の値によって曲のテンポが変化します。
発音中に可変抵抗の値が変化した場合にも滑らかにテンポが変わるようにタイマ割り込みを使って発音のタイミングを得ています。
Arduinoの標準のライブラリではタイマは使用できませんがContributed LibraryとしてMsTimer2*2があります。
これを利用することでシンプルにタイマ割り込み処理が実現できました。
以下ソース。
#include <MsTimer2.h> int speakerPin = 9; int length = 15; // the number of notes char notes[] = "ccggaagffeeddc"; // a space represents a rest int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4, 1 }; volatile int tempo = 127; volatile int prevtempo = 0; volatile int idx = 0; volatile int cancel_note = 0; void playTone(int tone, int duration) { for (long i = 0; i < duration * 1000L; i += tone * 2) { if (cancel_note == 1){ //発音をキャンセルしたときはインデックスを一個戻す cancel_note = 0; idx--; if (idx < 0){ idx = 0; } break; } digitalWrite(speakerPin, HIGH); delayMicroseconds(tone); digitalWrite(speakerPin, LOW); delayMicroseconds(tone); } } void play() { if (notes[idx] == ' ') { delay(beats[idx] * tempo); // rest } else { playNote(notes[idx], beats[idx] * tempo); } idx++; if (idx > length) { idx = 0; } } void playNote(char note, int duration) { char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'D' }; int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956, 850 }; // play the tone corresponding to the note name for (int i = 0; i < 9; i++) { if (names[i] == note) { playTone(tones[i]*4, duration); } } } void setup() { pinMode(speakerPin, OUTPUT); MsTimer2::set(10, play); // 10ms period MsTimer2::start(); } void loop() { tempo = analogRead(0); if (abs(tempo - prevtempo) > 10){ //可変抵抗の値が変わったとき cancel_note = 1; //発音をキャンセル } prevtempo = tempo; }
MsTimer2は「Arduinoをはじめよう」に収録されている言語リファレンスの中でも紹介されています。*3
- 作者: Massimo Banzi,船田巧
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/03/27
- メディア: 単行本(ソフトカバー)
- 購入: 26人 クリック: 235回
- この商品を含むブログ (63件) を見る