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

From DT^2
Revision as of 08:25, 10 August 2018 by Admin (talk | contribs) (Created page with "<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_PI...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

<syntaxhiglight lang="C" line="line"> //these are for Aruino pin D12, change to any other pin as desired

  1. define SIRENE_PORT PORTB
  2. define SIRENE_DDR DDRB
  3. define SIRENE_PIN 4
  1. define FIS3 2960
  2. 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>