Arduino - hrá melódiu v pozadí cez timer2
<syntaxhiglight lang="C" line="line"> //these are for Aruino pin D12, change to any other pin as desired
- define SIRENE_PORT PORTB
- define SIRENE_DDR DDRB
- define SIRENE_PIN 4
- define FIS3 2960
- define G3 3136
void setup() {
Serial.begin(9600); init_tone2();
}
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 };
//popcorn uint16_t dlzka_melodia[] = {0, 386, 26, 281, 217}; const uint8_t melodia1[] PROGMEM = { 252, 50, 149, 49, 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, 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, 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, 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, 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, 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, 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, 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 , 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, 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, 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 , 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 };
//kohutik jarabi 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 };
// kankán const uint8_t melodia3[] PROGMEM = { 252, 100, 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, 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, 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, 135,131,128,126,75,76,78,80,81,76,80,76,81,76,80,76,81,76,80,76,81,76,80,76, 251,2,11,3,16,19,251,1,4,3,16,19, 251,1,4,3,16,19,251,1,4,3,16,19, 251,1,4,3,16,19,251,1,4,3,16,19, 251,1,4,3,16,19,251,1,4,3,16,19, 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, 174,88,91,90,88,143,143,93,95,90,91,138,138,88,91,90,88,86,93,89,90,136, 64,71,71,73,71,69,69,73,74,78,81,78,78,76,251,1,184,1,32,126, 78,76,126,78,76,126,78,76,126,78,76,126,78,76,126,78,76,126, 78,76,78,76,78,76,78,76, 131,119,119,119,169 };
//labutie jazero const uint8_t melodia4[] PROGMEM = { 252, 220, 66, 69, 73, 69, 66, 69, 73, 69, 66, 69, 73, 69, 66, 69, 73, 69, 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, 99, 83, 81, 80, 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, 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, 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, 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, 99, 83, 81, 80, 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 };
volatile int16_t music_speed = 800 / 16;
volatile PGM_P current_note ; volatile uint16_t notes_remaining;
void zahraj_melodiu2(uint8_t cislo) {
if (cislo == 1) current_note = melodia1; else if (cislo == 2) current_note = melodia2; else if (cislo == 3) current_note = melodia3; else if (cislo == 4) current_note = melodia4; notes_remaining = dlzka_melodia[cislo]; next_note();
}
void next_note() {
uint16_t freq, dur; if (!notes_remaining) return; otto_translate_tone_flash(&freq, &dur); tone2(freq, dur);
}
void otto_translate_tone_flash(uint16_t *freq, uint16_t *del) {
do { uint8_t n = pgm_read_byte(current_note); if (n == 251) { current_note++; uint8_t f1 = pgm_read_byte(current_note); current_note++; uint8_t f2 = pgm_read_byte(current_note); current_note++; uint8_t d1 = pgm_read_byte(current_note); current_note++; uint8_t d2 = pgm_read_byte(current_note); *freq = (f1 << 8) + f2; *del = (music_speed * 16 * (long)d1) / d2; notes_remaining -= 4; } else if (n == 252) { current_note++; music_speed = pgm_read_byte(current_note); current_note++; notes_remaining -= 2; continue; } else if (n == 254) { *freq = FIS3; *del = music_speed; } else if (n == 255) { *freq = G3; *del = music_speed; } else { uint8_t len = n / 50; *del = music_speed; while (len--) *del *= 2; n = n % 50; if (n != 49) { uint8_t octave = (n + 5) / 12; n = (n + 5) % 12; float ffreq = octave_4[n]; octave = 4 - octave; while (octave > 0) { ffreq /= 2.0; octave--; } *freq = (uint16_t)ffreq; } else *freq = 0; } notes_remaining--; current_note++; break; } while(1);
}
void loop() {
zahraj_melodiu2(1);
int counter = 0; do { Serial.print("music playing in the background... "); Serial.println(counter); delay(100); } while (notes_remaining);
delay(2000); zahraj_melodiu2(2); while (notes_remaining); delay(2000); zahraj_melodiu2(3); while (notes_remaining); delay(2000); zahraj_melodiu2(4); while (notes_remaining); delay(2000);
// sending direct tones for (int i = 0; i < 2; i++) { tone2(262, 200); delay(200); tone2(330, 200); delay(200); tone2(262, 200); delay(200); tone2(330, 200); delay(200); tone2(392, 400); delay(400); tone2(392, 400); delay(400); }
delay(2000);
}
static volatile uint8_t tone2_state; static volatile uint8_t tone2_pause; static volatile uint32_t tone2_len;
void init_tone2() {
notes_remaining = 0; tone2_pause = 0; TCCR2A = 2; TCCR2B = 0; TIMSK2 = 2; SIRENE_DDR |= (1 << SIRENE_PIN);
}
ISR(TIMER2_COMPA_vect)
{
if (!tone2_pause) { if (tone2_state) { SIRENE_PORT |= (1 << SIRENE_PIN); tone2_state = 0; } else { SIRENE_PORT &= ~(1 << SIRENE_PIN); tone2_state = 1; } } if ((--tone2_len) == 0) { TCCR2B = 0; tone2_pause = 0; next_note(); }
}
void tone2(uint16_t freq, uint16_t duration) {
uint32_t period = 1000000 / freq;
if (freq >= 977) // prescaler 32 { tone2_state = 0; tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period; TCNT2 = 0; OCR2A = (uint8_t) (250000 / (uint32_t)freq); TCCR2B = 3; } else if (freq >= 488) // prescaler 64 { tone2_state = 0; tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period; TCNT2 = 0; OCR2A = (uint8_t) (125000 / (uint32_t)freq); TCCR2B = 4; } else if (freq >= 244) // prescaler 128 { tone2_state = 0; tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period; TCNT2 = 0; OCR2A = (uint8_t) (62500 / (uint32_t)freq); TCCR2B = 5; } else if (freq >= 122) //prescaler 256 { tone2_state = 0; tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period; TCNT2 = 0; OCR2A = (uint8_t) (31250 / (uint32_t)freq); TCCR2B = 6; } else if (freq >= 30) //prescaler 1024 { tone2_state = 0; tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period; TCNT2 = 0; OCR2A = (uint8_t) (7813 / (uint32_t)freq); TCCR2B = 7; } else if (freq == 0) { tone2_pause = 1; tone2_state = 0; period = 1000000 / 500; tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period; TCNT2 = 0; OCR2A = (uint8_t) (125000 / (uint32_t)500); TCCR2B = 4; }
} </syntaxhighlight>