Arduino:Примеры/RTTTL

Материал из Онлайн справочника
Перейти к навигации Перейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Перевел 364226 статей для сайта.</br>Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


RTTTL[1]

Это скетч для библиотеки Tone, который при помощи платы Arduino демонстрирует, как проигрывать на динамике различные рингтоны (или RTTTL; от «Ring Tone Text Transfer Language»): темы к мультфильму «Симпсоны», сериалу «Секретные материалы», песню «Take on me» группы A-HA и т.д.

Код

  1 //  RTTTL
  2 
  3 // Забавный скетч, демонстрирующий использование библиотеки Tone.
  4 
  5 // Чтобы совместить выходные данные для сигналов и выходные данные 
  6 // от маленького динамика (например, на 8 ом и выше), воспользуйтесь 
  7 // резисторами на 1 кОм. Подключите их к каждому выходному контакту, 
  8 // а затем соедините вместе на динамике. Не забудьте подключить другую 
  9 // сторону динамика к «земле»!
 10 
 11 // Больше рингтонов можно скачать тут:
 12 // http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation
 13 
 14 #include <Tone.h>
 15 
 16 Tone tone1;
 17 
 18 #define OCTAVE_OFFSET 0
 19 
 20 int notes[] = { 0,
 21 NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
 22 NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
 23 NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
 24 NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
 25 };
 26 
 27 //char *song = "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6";  //  «Симпсоны»
 28 //char *song = "Indiana:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6";  //  «Индиана Джонс»
 29 //char *song = "TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5";  //  «Take on me» - A-HA
 30 //char *song = "Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6";  //  «The Entertainer» - Scott Joplin
 31 //char *song = "Muppets:d=4,o=5,b=250:c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,8a,8p,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,8e,8p,8e,g,2p,c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,a,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,d,8d,c";  //  «Маппеты»
 32 //char *song = "Xfiles:d=4,o=5,b=125:e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,g6,f#6,e6,d6,e6,2b.,1p,g6,f#6,e6,d6,f#6,2b.,1p,e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,e6,2b.";  //  «Секретные материалы»
 33 //char *song = "Looney:d=4,o=5,b=140:32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f";
 34 //char *song = "20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b";  //  «20 век FOX»
 35 //char *song = "Bond:d=4,o=5,b=80:32p,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d#6,16d#6,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d6,16c#6,16c#7,c.7,16g#6,16f#6,g#.6";  //  «Джеймс Бонд»
 36 //char *song = "MASH:d=8,o=5,b=140:4a,4g,f#,g,p,f#,p,g,p,f#,p,2e.,p,f#,e,4f#,e,f#,p,e,p,4d.,p,f#,4e,d,e,p,d,p,e,p,d,p,2c#.,p,d,c#,4d,c#,d,p,e,p,4f#,p,a,p,4b,a,b,p,a,p,b,p,2a.,4p,a,b,a,4b,a,b,p,2a.,a,4f#,a,b,p,d6,p,4e.6,d6,b,p,a,p,2b";  //  «МЭШ»
 37 //char *song = "StarWars:d=4,o=5,b=45:32p,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#.6,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#6";  //  «Звездные войны»
 38 //char *song = "GoodBad:d=4,o=5,b=56:32p,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,d#,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,c#6,32a#,32d#6,32a#,32d#6,8a#.,16f#.,32f.,32d#.,c#,32a#,32d#6,32a#,32d#6,8a#.,16g#.,d#";
 39 //char *song = "TopGun:d=4,o=4,b=31:32p,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,16f,d#,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,g#";  //  «Лучший стрелок»
 40 //char *song = "A-Team:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#";  //  «Команда A»
 41 //char *song = "Flinstones:d=4,o=5,b=40:32p,16f6,16a#,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,d6,16f6,16a#.,16a#6,32g6,16f6,16a#.,32f6,32f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,a#,16a6,16d.6,16a#6,32a6,32a6,32g6,32f#6,32a6,8g6,16g6,16c.6,32a6,32a6,32g6,32g6,32f6,32e6,32g6,8f6,16f6,16a#.,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#6,16c7,8a#.6";  //  «Флинстоуны»
 42 //char *song = "Jeopardy:d=4,o=6,b=125:c,f,c,f5,c,f,2c,c,f,c,f,a.,8g,8f,8e,8d,8c#,c,f,c,f5,c,f,2c,f.,8d,c,a#5,a5,g5,f5,p,d#,g#,d#,g#5,d#,g#,2d#,d#,g#,d#,g#,c.7,8a#,8g#,8g,8f,8e,d#,g#,d#,g#5,d#,g#,2d#,g#.,8f,d#,c#,c,p,a#5,p,g#.5,d#,g#";
 43 //char *song = "Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#";
 44 //char *song = "Smurfs:d=32,o=5,b=200:4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8f#,p,8a#,p,4g#,4p,g#,p,a#,p,b,p,c6,p,4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8b,p,8f,p,4f#";  //  «Смурфики»
 45 //char *song = "MahnaMahna:d=16,o=6,b=125:c#,c.,b5,8a#.5,8f.,4g#,a#,g.,4d#,8p,c#,c.,b5,8a#.5,8f.,g#.,8a#.,4g,8p,c#,c.,b5,8a#.5,8f.,4g#,f,g.,8d#.,f,g.,8d#.,f,8g,8d#.,f,8g,d#,8c,a#5,8d#.,8d#.,4d#,8d#.";  //  «Мана-мана»
 46 //char *song = "LeisureSuit:d=16,o=6,b=56:f.5,f#.5,g.5,g#5,32a#5,f5,g#.5,a#.5,32f5,g#5,32a#5,g#5,8c#.,a#5,32c#,a5,a#.5,c#.,32a5,a#5,32c#,d#,8e,c#.,f.,f.,f.,f.,f,32e,d#,8d,a#.5,e,32f,e,32f,c#,d#.,c#";
 47 char *song = "MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d";  //  «Миссия невыполнима»
 48 
 49 void setup(void)
 50 {
 51   Serial.begin(9600);
 52   tone1.begin(13);
 53 }
 54 
 55 #define isdigit(n) (n >= '0' && n <= '9')
 56 
 57 void play_rtttl(char *p)
 58 {
 59   // никаких ошибок здесь не проверяется:
 60 
 61   byte default_dur = 4;
 62   byte default_oct = 6;
 63   int bpm = 63;
 64   int num;
 65   long wholenote;
 66   long duration;
 67   byte note;
 68   byte scale;
 69 
 70   // формат: d=N,o=N,b=NNN:
 71   // находим начало (пропускаем название и т.д.)
 72 
 73   while(*p != ':') p++;    // игнорируем название:
 74   p++;                     // пропускаем «:»
 75 
 76   // считываем продолжительность, заданную по умолчанию:
 77   if(*p == 'd')
 78   {
 79     p++; p++;              // пропускаем "d="
 80     num = 0;
 81     while(isdigit(*p))
 82     {
 83       num = (num * 10) + (*p++ - '0');
 84     }
 85     if(num > 0) default_dur = num;
 86     p++;                   // пропускаем запятую
 87   }
 88 
 89   Serial.print("ddur: "); Serial.println(default_dur, 10);
 90 
 91   // считываем октаву, заданную по умолчанию:
 92   if(*p == 'o')
 93   {
 94     p++; p++;              // пропускаем "o="
 95     num = *p++ - '0';
 96     if(num >= 3 && num <=7) default_oct = num;
 97     p++;                   // пропускаем запятую
 98   }
 99 
100   Serial.print("doct: "); Serial.println(default_oct, 10);
101 
102   // считываем количество ударов в минуту:
103   if(*p == 'b')
104   {
105     p++; p++;              // пропускаем "b="
106     num = 0;
107     while(isdigit(*p))
108     {
109       num = (num * 10) + (*p++ - '0');
110     }
111     bpm = num;
112     p++;                   // пропускаем двоеточие
113   }
114 
115   Serial.print("bpm: "); 
116   Serial.println(bpm, 10);
117 
118   // BPM (beats per minute), как правило, выражает 
119   // количество четвертных нот в минуту:
120   wholenote = (60 * 1000L / bpm) * 4;  // это время проигрывания ноты (в миллисекундах)
121 
122   Serial.print("wn: "); Serial.println(wholenote, 10);
123 
124 
125   // теперь начинаем цикл для ноты:
126   while(*p)
127   {
128     // сначала считываем продолжительность ноты (если задана):
129     num = 0;
130     while(isdigit(*p))
131     {
132       num = (num * 10) + (*p++ - '0');
133     }
134     
135     if(num) duration = wholenote / num;
136     else duration = wholenote / default_dur;  // далее нужно будет проверить, нет ли дальше ноты с точкой
137 
138     // теперь считываем ноту:
139     note = 0;
140 
141     switch(*p)
142     {
143       case 'c':
144         note = 1;
145         break;
146       case 'd':
147         note = 3;
148         break;
149       case 'e':
150         note = 5;
151         break;
152       case 'f':
153         note = 6;
154         break;
155       case 'g':
156         note = 8;
157         break;
158       case 'a':
159         note = 10;
160         break;
161       case 'b':
162         note = 12;
163         break;
164       case 'p':
165       default:
166         note = 0;
167     }
168     p++;
169 
170     // считываем опциональный символ «#» (диез):
171     if(*p == '#')
172     {
173       note++;
174       p++;
175     }
176 
177     // считываем опциональный символ «.» (нота с точкой):
178     if(*p == '.')
179     {
180       duration += duration/2;
181       p++;
182     }
183   
184     // считываем гамму:
185     if(isdigit(*p))
186     {
187       scale = *p - '0';
188       p++;
189     }
190     else
191     {
192       scale = default_oct;
193     }
194 
195     scale += OCTAVE_OFFSET;
196 
197     if(*p == ',')
198       p++;       // пропускаем запятую для следующей ноты (или, возможно, мы уже в конце)
199 
200     // теперь проигрываем ноту:
201 
202     if(note)
203     {
204       Serial.print("Playing: ");  //  "Проигрывание: "
205       Serial.print(scale, 10); Serial.print(' ');
206       Serial.print(note, 10); Serial.print(" (");
207       Serial.print(notes[(scale - 4) * 12 + note], 10);
208       Serial.print(") ");
209       Serial.println(duration, 10);
210       tone1.play(notes[(scale - 4) * 12 + note]);
211       delay(duration);
212       tone1.stop();
213     }
214     else
215     {
216       Serial.print("Pausing: ");  //  "Пауза:" 
217       Serial.println(duration, 10);
218       delay(duration);
219     }
220   }
221 }
222 
223 void loop(void)
224 {
225   play_rtttl(song);
226   Serial.println("Done.");  //  "Готово."
227   while(1);
228 }

См.также

Внешние ссылки