Arduino - hrá melódiu v pozadí cez timer2

From DT^2
Jump to: navigation, search
  1 //these are for Aruino pin D12, change to any other pin as desired
  2 #define SIRENE_PORT  PORTB
  3 #define SIRENE_DDR   DDRB
  4 #define SIRENE_PIN   4
  5 
  6 #define FIS3 2960
  7 #define G3 3136
  8 
  9 void setup() {
 10   Serial.begin(9600);
 11   init_tone2();
 12 }
 13 
 14 float octave_4[] = { 2093.00, 2217.46, 2349.32, 2489.02, 2637.02, 2793.83, 2959.96, 3135.96, 3322.44, 3520.00, 3729.31, 3951.07 };
 15 
 16 //popcorn
 17 uint16_t dlzka_melodia[] = {0, 386, 26, 281, 217};
 18 const uint8_t melodia1[] PROGMEM = { 252, 50, 149,  49, 
 19 28, 31, 35, 40, 49, 99, 38, 49, 99, 40, 49, 99, 35, 49, 99, 31, 49, 99, 35, 49, 99, 28, 49, 99, 49,
 20 28, 31, 35, 40, 49, 99, 38, 49, 99, 40, 49, 99, 35, 49, 99, 31, 49, 99, 35, 49, 99, 28, 49, 99, 149,
 21 40, 49, 99, 42, 49, 99, 43, 49, 99, 42, 49, 99, 43, 49, 99, 40, 49, 99, 42, 49, 99, 40, 49, 99, 42, 49, 99, 38, 49, 99, 40, 49, 99, 38, 49, 99, 40, 49, 99, 36, 49, 99, 40, 49, 99, 
 22 28, 31, 35, 40, 49, 99, 38, 49, 99, 40, 49, 99, 35, 49, 99, 31, 49, 99, 35, 49, 99, 28, 49, 99, 49,
 23 28, 31, 35, 40, 49, 99, 38, 49, 99, 40, 49, 99, 35, 49, 99, 31, 49, 99, 35, 49, 99, 28, 49, 99, 149,
 24 40, 49, 99, 42, 49, 99, 43, 49, 99, 42, 49, 99, 43, 49, 99, 40, 49, 99, 42, 49, 99, 40, 49, 99, 42, 49, 99, 38, 49, 99, 40, 49, 99, 38, 49, 99, 40, 49, 99, 42, 49, 99, 43, 49, 99,
 25 49, 35, 38, 43, 47, 49, 99, 45, 49, 99, 47, 49, 99, 43, 49, 99, 38, 49, 99, 43, 49, 99, 35, 49, 99, 
 26 49, 35, 38, 43, 47, 49, 99, 45, 49, 99, 47, 49, 99, 43, 49, 99, 38, 49, 99, 43, 49, 99, 35, 49, 99, 149 ,
 27 47, 49, 99, 254, 49, 99, 255, 49, 99, 254, 49, 99, 255, 49, 99, 47, 49, 99, 254, 49, 99, 47, 49, 99, 254, 49, 99, 45, 49, 99, 47, 49, 99, 45, 49, 99, 47, 49, 99, 43, 49, 99, 47, 49, 99, 
 28 49, 35, 38, 43, 47, 49, 99, 45, 49, 99, 47, 49, 99, 43, 49, 99, 38, 49, 99, 43, 49, 99, 35, 49, 99, 
 29 49, 35, 38, 43, 47, 49, 99, 45, 49, 99, 47, 49, 99, 43, 49, 99, 38, 49, 99, 43, 49, 99, 35, 49, 99, 149 ,
 30 47, 49, 99, 254, 49, 99, 255, 49, 99, 254, 49, 99, 255, 49, 99, 47, 49, 99, 254, 49, 99, 47, 49, 99, 254, 49, 99, 45, 49, 99, 47, 49, 99, 45, 49, 99, 47, 49, 99, 254, 49, 99, 255, 49, 99
 31 };
 32 
 33 //kohutik jarabi
 34 const uint8_t melodia2[] PROGMEM = { 252, 150, 119, 121, 173, 174, 124, 124, 124, 123, 171, 173, 123, 123, 123, 121, 169, 171, 121, 121, 121, 123, 171, 169, 119, 119 };
 35 
 36 // kankán
 37 const uint8_t melodia3[] PROGMEM = { 252, 100,
 38 251,1,184,1,32,126,149,251,1,184,1,32,126,149,251,1,184,1,32,126,251,1,184,1,32,126,251,1,184,1,32,126,251,1,184,1,32,126,
 39 64,71,71,73,71,69,69,73,74,78,81,78,78,76,251,1,184,1,32,126,78,68,68,78,76,69,69,73,73,71,73,71,85,83,85,83,
 40 64,71,71,73,71,69,69,73,74,78,81,78,78,76,251,1,184,1,32,126,78,68,68,78,76,69,69,73,73,71,73,71,71,69,119,
 41 135,131,128,126,75,76,78,80,81,76,80,76,81,76,80,76,81,76,80,76,81,76,80,76,
 42 251,2,11,3,16,19,251,1,4,3,16,19,
 43 251,1,4,3,16,19,251,1,4,3,16,19,
 44 251,1,4,3,16,19,251,1,4,3,16,19,
 45 251,1,4,3,16,19,251,1,4,3,16,19,
 46 174,88,91,90,88,143,143,93,95,90,91,138,138,88,91,90,88,86,86,85,83,81,79,78,76,
 47 174,88,91,90,88,143,143,93,95,90,91,138,138,88,91,90,88,86,93,89,90,136,
 48 64,71,71,73,71,69,69,73,74,78,81,78,78,76,251,1,184,1,32,126,
 49 78,76,126,78,76,126,78,76,126,78,76,126,78,76,126,78,76,126,
 50 78,76,78,76,78,76,78,76,
 51 131,119,119,119,169 };
 52 
 53 //labutie jazero
 54 const uint8_t melodia4[] PROGMEM = {
 55 252, 220, 66, 69, 73, 69, 66, 69, 73, 69, 66, 69, 73, 69, 66, 69, 73, 69,
 56 185, 78, 80, 81, 83, 251, 5, 39, 3, 8, 81, 251, 5, 39, 3, 8, 81, 251, 5, 39, 3, 8, 78, 81, 78, 73, 81, 178,
 57 99, 83, 81, 80, 
 58 185, 78, 80, 81, 83, 251, 5, 39, 3, 8, 81, 251, 5, 39, 3, 8, 81, 251, 5, 39, 3, 8, 78, 81, 78, 73, 81, 178,
 59 149, 128, 130, 131, 133, 85, 86, 251, 6, 32, 3, 8, 86, 135, 86, 88, 251, 6, 224, 3, 8, 88, 136, 88, 90, 251, 7, 184, 3, 8, 90, 85, 81, 80, 78, 
 60 130, 131, 133, 85, 86, 251, 6, 32, 3, 8, 86, 135, 86, 88, 251, 6, 224, 3, 8, 88, 136, 88, 90, 251, 7, 73, 3, 8, 86, 133, 86, 91, 251, 7, 184, 3, 8, 87, 251, 7, 184, 3, 8, 85,
 61 185, 78, 80, 81, 83, 251, 5, 39, 3, 8, 81, 251, 5, 39, 3, 8, 81, 251, 5, 39, 3, 8, 78, 81, 78, 73, 81, 178,
 62 99, 83, 81, 80, 
 63 185, 78, 80, 81, 83, 251, 5, 39, 3, 8, 81, 251, 5, 39, 3, 8, 81, 251, 5, 39, 3, 8, 78, 81, 78, 73, 81, 178 };
 64 
 65 volatile int16_t music_speed = 800 / 16;
 66 
 67 volatile PGM_P current_note ;
 68 volatile uint16_t notes_remaining;
 69 
 70 void zahraj_melodiu2(uint8_t cislo)
 71 {
 72   if (cislo == 1) current_note = melodia1;
 73   else if (cislo == 2) current_note = melodia2;
 74   else if (cislo == 3) current_note = melodia3;
 75   else if (cislo == 4) current_note = melodia4;
 76   notes_remaining = dlzka_melodia[cislo];
 77   
 78   next_note();
 79 }
 80  
 81 void next_note()
 82 {
 83   uint16_t freq, dur;
 84   if (!notes_remaining) return;
 85   otto_translate_tone_flash(&freq, &dur);  
 86   tone2(freq, dur);
 87 }
 88 
 89 void otto_translate_tone_flash(uint16_t *freq, uint16_t *del)
 90 {
 91   do {
 92   uint8_t n = pgm_read_byte(current_note);  
 93   if (n == 251)
 94   {
 95     current_note++;
 96     uint8_t f1 = pgm_read_byte(current_note);
 97     current_note++;
 98     uint8_t f2 = pgm_read_byte(current_note);
 99     current_note++;
100     uint8_t d1 = pgm_read_byte(current_note);
101     current_note++;
102     uint8_t d2 = pgm_read_byte(current_note);    
103     *freq = (f1 << 8) + f2;
104     *del = (music_speed * 16 * (long)d1) / d2;
105     notes_remaining -= 4;
106   }
107   else if (n == 252)
108   {
109     current_note++;
110     music_speed = pgm_read_byte(current_note);
111     current_note++;
112     notes_remaining -= 2;
113     continue;
114   }
115   else if (n == 254)
116   {
117     *freq = FIS3;
118     *del = music_speed;
119   }
120   else if (n == 255)
121   {
122     *freq = G3;
123     *del = music_speed;
124   }
125   else
126   {
127     uint8_t len = n / 50; 
128     *del = music_speed;
129     while (len--) *del *= 2;
130     n = n % 50;
131     if (n != 49)
132     {
133       uint8_t octave = (n + 5) / 12;
134       n = (n + 5) % 12;
135       float ffreq = octave_4[n];
136       octave = 4 - octave;
137       while (octave > 0)
138       {
139         ffreq /= 2.0;
140         octave--;  
141       }
142     *freq = (uint16_t)ffreq;
143     }
144   else *freq = 0;
145   }
146   notes_remaining--;
147   current_note++;
148   break;
149   } while(1);
150 }
151 
152 void loop() {
153   
154   zahraj_melodiu2(1);
155 
156   int counter = 0;
157   do {
158     Serial.print("music playing in the background... ");
159     Serial.println(counter); 
160     delay(100);
161   } while (notes_remaining);
162 
163   delay(2000);
164   
165   zahraj_melodiu2(2);
166   while (notes_remaining);
167   
168   delay(2000);
169   
170   zahraj_melodiu2(3);
171   while (notes_remaining);
172   
173   delay(2000);
174   
175   zahraj_melodiu2(4);   
176   while (notes_remaining);
177   
178   delay(2000);
179 
180   // sending direct tones
181   for (int i = 0; i < 2; i++)
182   {
183     tone2(262, 200);
184     delay(200);
185     tone2(330, 200);
186     delay(200);
187   
188     tone2(262, 200);
189     delay(200);
190     tone2(330, 200);
191     delay(200);
192   
193     tone2(392, 400);
194     delay(400);
195   
196     tone2(392, 400);
197     delay(400);
198   }
199 
200   delay(2000);
201 }
202 
203 static volatile uint8_t tone2_state;
204 static volatile uint8_t tone2_pause;
205 static volatile uint32_t tone2_len;
206 
207 void init_tone2()
208 {
209   notes_remaining = 0;
210   tone2_pause = 0;
211   TCCR2A = 2;
212   TCCR2B = 0;
213   TIMSK2 = 2;
214   SIRENE_DDR |= (1 << SIRENE_PIN);  
215 }
216 
217 
218 ISR(TIMER2_COMPA_vect)
219 {
220   if (!tone2_pause)
221   {
222     if (tone2_state) 
223     {
224       SIRENE_PORT |= (1 << SIRENE_PIN);
225       tone2_state = 0;
226     }
227     else 
228     {
229       SIRENE_PORT &= ~(1 << SIRENE_PIN);
230       tone2_state = 1;
231     }
232   }
233   if ((--tone2_len) == 0) 
234   {
235     TCCR2B = 0;
236     tone2_pause = 0;
237     next_note();
238   }
239 }
240 
241 void tone2(uint16_t freq, uint16_t duration)
242 {
243   uint32_t period = 1000000 / freq;
244 
245   if (freq >= 977)  // prescaler 32
246   {
247     tone2_state = 0;
248     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
249     TCNT2 = 0;
250     OCR2A = (uint8_t) (250000 / (uint32_t)freq);
251     TCCR2B = 3;
252   }
253   else if (freq >= 488) // prescaler 64
254   {
255     tone2_state = 0;
256     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
257     TCNT2 = 0;
258     OCR2A = (uint8_t) (125000 / (uint32_t)freq);
259     TCCR2B = 4;    
260   }
261   else if (freq >= 244) // prescaler 128
262   {
263     tone2_state = 0;
264     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
265     TCNT2 = 0;
266     OCR2A = (uint8_t) (62500 / (uint32_t)freq);
267     TCCR2B = 5;
268   }
269   else if (freq >= 122) //prescaler 256
270   {
271     tone2_state = 0;
272     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
273     TCNT2 = 0;
274     OCR2A = (uint8_t) (31250 / (uint32_t)freq);
275     TCCR2B = 6;
276   }
277   else if (freq >= 30) //prescaler 1024
278   {
279     tone2_state = 0;
280     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
281     TCNT2 = 0;
282     OCR2A = (uint8_t) (7813 / (uint32_t)freq);
283     TCCR2B = 7;
284   }
285   else if (freq == 0)
286   {
287     tone2_pause = 1;
288     tone2_state = 0;
289     period = 1000000 / 500;
290     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
291     TCNT2 = 0;
292     OCR2A = (uint8_t) (125000 / (uint32_t)500);
293     TCCR2B = 4;
294   }
295 }