Esempio: Giochi di luce e suoni (natalizi) con Arduino

Schema da realizzare:

giochi_di_luce_e_suoni_semplice_bb.png

Firmware da caricare:

/*************************************************
 * Frequenza delle note
 *************************************************/
#define N_REST 0
#define N_B0  31
#define N_C1  33
#define N_CS1 35
#define N_D1  37
#define N_DS1 39
#define N_E1  41
#define N_F1  44
#define N_FS1 46
#define N_G1  49
#define N_GS1 52
#define N_A1  55
#define N_AS1 58
#define N_B1  62
#define N_C2  65
#define N_CS2 69
#define N_D2  73
#define N_DS2 78
#define N_E2  82
#define N_F2  87
#define N_FS2 93
#define N_G2  98
#define N_GS2 104
#define N_A2  110
#define N_AS2 117
#define N_B2  123
#define N_C3  131
#define N_CS3 139
#define N_D3  147
#define N_DS3 156
#define N_E3  165
#define N_F3  175
#define N_FS3 185
#define N_G3  196
#define N_GS3 208
#define N_A3  220
#define N_AS3 233
#define N_B3  247
#define N_C4  262
#define N_CS4 277
#define N_D4  294
#define N_DS4 311
#define N_E4  330
#define N_F4  349
#define N_FS4 370
#define N_G4  392
#define N_GS4 415
#define N_A4  440
#define N_AS4 466
#define N_B4  494
#define N_C5  523
#define N_CS5 554
#define N_D5  587
#define N_DS5 622
#define N_E5  659
#define N_F5  698
#define N_FS5 740
#define N_G5  784
#define N_GS5 831
#define N_A5  880
#define N_AS5 932
#define N_B5  988
#define N_C6  1047
#define N_CS6 1109
#define N_D6  1175
#define N_DS6 1245
#define N_E6  1319
#define N_F6  1397
#define N_FS6 1480
#define N_G6  1568
#define N_GS6 1661
#define N_A6  1760
#define N_AS6 1865
#define N_B6  1976
#define N_C7  2093
#define N_CS7 2217
#define N_D7  2349
#define N_DS7 2489
#define N_E7  2637
#define N_F7  2794
#define N_FS7 2960
#define N_G7  3136
#define N_GS7 3322
#define N_A7  3520
#define N_AS7 3729
#define N_B7  3951
#define N_C8  4186
#define N_CS8 4435
#define N_D8  4699
#define N_DS8 4978

/*************************************************
 * Melodie
 *************************************************/
typedef struct {
   int *melody;
   int *durations;
   int numCount;
   int tempo;
   int low, high;
} tune;

tune tunes[5];

// Jingle Bells
int jingleBells[] = { N_E5, N_E5, N_E5, N_E5, N_E5, N_E5, N_E5, N_G5, N_C5, N_D5, N_E5,
                      N_F5, N_F5, N_F5, N_F5, N_F5, N_E5, N_E5, N_E5, N_E5, N_D5, N_D5, N_E5, N_D5, N_G5,
                      N_E5, N_E5, N_E5, N_E5, N_E5, N_E5, N_E5, N_G5, N_C5, N_D5, N_E5,
                      N_F5, N_F5, N_F5, N_F5, N_F5, N_E5, N_E5, N_E5, N_G5, N_G5, N_F5, N_D5, N_C5};
int jingleBellsDurations[] = { 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 16,
                               4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8,
                               4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 16,
                               4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16 };
                               
// The first noel
// http://www.music-for-music-teachers.com/support-files/first-noel-broken-chord-stretch-key-of-c.pdf

int firstNoel[] = { N_E4, N_D4, N_C4, N_D4, N_E4, N_F4, N_G4, N_A4, N_B4, N_C5, N_B4, N_A4,
                    N_G4, N_A4, N_B4, N_C5, N_B4, N_A4, N_G4, N_A4, N_B4, N_C5, N_G4, N_F4,
                    N_E4, N_E4, N_D4, N_C4, N_D4, N_E4, N_F4, N_G4, N_A4, N_B4, N_C5, N_B4, N_A4,
                    N_G4, N_A4, N_B4, N_C5, N_B4, N_A4, N_G4, N_A4, N_B4, N_C5, N_G4, N_F4,
                    N_E4, N_E4, N_D4, N_C4, N_D4, N_E4, N_F4, N_G4, N_C5, N_B4, N_A4, N_A4,
                    N_G4, N_C5, N_B4, N_A4, N_G4, N_A4, N_B4, N_C5, N_G4, N_F4, N_E4
                  };

int firstNoelDurations[] = { 2, 2, 6, 2, 2, 2, 8, 2, 2, 4, 4, 4,
                             8, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4,
                             8, 2, 2, 6, 2, 2, 2, 8, 2, 2, 4, 4, 4,
                             8, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4,                             
                             8, 2, 2, 6, 2, 2, 2, 8, 2, 2, 8, 4,
                             12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8  };
                             
// O Holy Night
// http://www.music-for-music-teachers.com/support-files/o-holy-night-lead-sheet-c.pdf

int oHolyNight[] = { N_E4, N_E4, N_E4, N_G4, N_REST, N_G4, N_A4, N_A4, N_F4, N_A4, N_C5,
                     N_G4, N_G4, N_E4, N_D4, N_C4, N_E4, N_F4, N_G4, N_F4, N_D4, N_C4,
                     N_E4, N_E4, N_E4, N_G4, N_REST, N_G4, N_A4, N_A4, N_F4, N_A4, N_C5,
                     N_G4, N_G4, N_FS4, N_E4, N_B4, N_G4, N_A4, N_B4, N_C5, N_B4, N_E4, N_REST, N_G4,
                     N_G4, N_A4, N_D4, N_G4, N_A4, N_G4, N_C5, N_E4, N_A4, N_G4, N_G4, N_G4, N_A4,
                     N_D4, N_G4, N_A4, N_G4, N_C5, N_E4, N_G4, N_C5, N_C5, N_B4, N_A4,
                     N_B4, N_A4, N_REST, N_A4, N_D5, N_D5, N_A4, N_A4, N_A4, N_C5,
                     N_C5, N_REST, N_C5, N_E5, N_D5, N_D5, N_G4, N_C5, N_C5, N_B4, N_A4,
                     N_G4, N_G4, N_G4, N_A4, N_G4, N_G4, N_G4, N_C5, N_D5,
                     N_D5, N_G4, N_E5, N_E5, N_D5, N_C5, N_B4, N_C5, N_D5,
                     N_C5 };

int oHolyNightDurations[] = { 6, 4, 2, 8, 2, 2 , 4, 2, 4, 2, 12,
                              4, 2, 4, 2, 6, 4, 2, 6, 4, 2, 24,
                              6, 4, 2, 8, 2, 2 , 4, 2, 4, 2, 12,
                              4, 2, 4, 2, 6, 4, 2, 6, 4, 2, 20, 2, 2,
                              6, 6, 6, 6, 4, 2, 4, 2, 6, 4, 2, 6, 6,
                              6, 6, 4, 2, 4, 2, 12, 12, 6, 4, 2,
                              12, 8, 2, 2, 12, 4, 2, 4, 2, 12,
                              8, 2, 2, 12, 8, 2, 2, 12, 6, 4, 2,
                              12, 4, 2, 4, 2, 12, 6, 6, 12,
                              6, 6, 12, 6, 6, 12, 6, 4, 2,
                              24 };

// http://www.christmas-carol-music.org/Lead_Sheets/WeThreeKings.html

int weThreeKings[] = { N_B4, N_A4, N_G4, N_E4, N_FS4, N_G4, N_FS4, N_E4,
                       N_B4, N_A4, N_G4, N_E4, N_FS4, N_G4, N_FS4, N_E4,
                       N_G4, N_G4, N_G4, N_A4, N_A4, N_B4, N_B4, N_D5, N_C5, N_B4,
                       N_A4, N_B4, N_A4, N_G4, N_FS4, N_E4,
                       N_FS4, N_A4, N_G4, N_G4, N_G4, N_D4, N_G4, N_E4, N_G4, N_G4, N_G4, N_G4, N_D4, N_G4, N_E4, N_G4,
                       N_G4, N_G4, N_A4, N_B4, N_C5, N_B4, N_A4, N_B4, N_G4, N_G4, N_G4, N_D4, N_G4, N_E4, N_G4 };
                       
int weThreeKingsDurations[] = { 4, 2, 4, 2, 2, 2, 2, 6,
                                4, 2, 4, 2, 2, 2, 2, 6,
                                2, 2, 2, 4, 2, 4, 2, 2, 2, 2,
                                2, 2, 2, 4, 2, 6,
                                6, 6, 4, 2, 4, 2, 4, 2, 6, 4, 2, 4, 2, 4, 2, 6,
                                4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 6  };
  
// What child is this
// http://www.free-scores.com/PDF_EN/traditional-what-child-is-this-39593.pdf

int whatChild[] = { N_E4, N_G4, N_A4, N_B4, N_C5, N_B4, N_A4, N_FS4, N_D4, N_E4, N_FS4, N_G4, N_E4, N_E4, N_DS4, N_E4, N_FS4, N_B3, N_REST,  N_E4,
                    N_G4, N_A4, N_B4, N_C4, N_B4, N_A4, N_FS4, N_D4, N_E4, N_FS4, N_G4, N_FS4, N_E4, N_DS4, N_CS4, N_D4, N_E4, N_E4, N_REST,
                    N_D5, N_D5, N_C5, N_B4, N_A4, N_FS4, N_D4, N_E4, N_FS4, N_G4, N_E4, N_E4, N_DS4, N_E4, N_FS4, N_DS4, N_B3, N_REST, 
                    N_D5, N_D5, N_C5, N_B4, N_A4, N_FS4, N_D4, N_E4, N_FS4, N_G4, N_FS4, N_E4, N_DS4, N_CS4, N_D4, N_E4, N_E4} ;

int whatChildDurations[] = { 2, 4, 2, 3, 1, 2, 4, 2, 3, 1, 2, 4, 2, 3, 1, 2, 6, 2, 2, 2,
                             4, 2, 3, 1, 2, 4, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 6, 4, 2,
                             6, 3, 1, 2, 4, 2, 3, 1, 2, 4, 2, 3, 1, 2, 4, 2, 4, 2,
                             6, 3, 1, 2, 4, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 6, 4};

/*************************************************
 * Controllo della riproduzione
 *************************************************/
  
const int buttonPin = 2;     // the number of the pushbutton pin
int buttonState = 0;
int toneNum = 0;  
int randomOffset = 0;
int outputStartPin = 3;
int continuousMode = 1;   // sa vale 0 la melodia parte alla pressione del tasto sul pin 2, se vale 1 parte in automatico

void play(int tuneNum) {
  
  randomOffset = random(32);
    
  int numNotes = tunes[tuneNum].numCount;
  int tempo = tunes[tuneNum].tempo;
  for (int thisNote = 0; thisNote < numNotes; thisNote++) {
    
    int freq = tunes[tuneNum].melody[thisNote]*2;
    int noteDuration = tempo*tunes[tuneNum].durations[thisNote];
    
    if (freq > 0) {
       int n = (map(freq, tunes[tuneNum].low, tunes[tuneNum].high, 1, 31) + randomOffset)%31 + 1; 
       lightsUp(n);
       tone(8, freq, noteDuration);
       
    } else {
       // REST
       delay(noteDuration);
    }

    delay(noteDuration);
    blankLights();
    
    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 0.30;    
    delay(pauseBetweenNotes);    
    
    noTone(8);
     
  }  
}

void lightSweep(int k, int nBits) {
  for (int i=0; i<5; i++) {
    lightsUp(k);
    delay(50);
    k = k<<1;
    blankLights();
    delay(20);
  }
  
  k = k>>nBits;
  
  for (int i=0; i<5; i++) {
    lightsUp(k);
    delay(50);
    k = k>>1;
    blankLights();
    delay(20);
  }  
}

void fromCenter() {
  for (int i=0; i<2; i++) {
    lightsUp(4);
    delay(50);
    blankLights();
    delay(50);
  }
  
  for (int i=0; i<4; i++) {
    lightsUp(10);
    delay(50);
    blankLights();
    delay(50);
  }
  
  lightsUp(31);
  delay(100);
  blankLights();
}

void lightEffect(int n) {
  switch(n) {
     case 0: for (int i=0; i<2; i++) { lightSweep(1, 1); }
             break;        
             
     case 1: for (int i=0; i<2; i++) { lightSweep(7, 2); }
             break;        
          
     case 2: for (int i=0; i<2; i++) { lightSweep(5, 2); }
             break;   
             
     case 3: for (int i=0; i<2; i++) { fromCenter(); }
             break;               
  }
}

void lightsUp(int n) {
  int i = 0;
  while (n>0 && i<5) {
    if (n%2 == 1) {
      digitalWrite(outputStartPin+i, HIGH);            
    } else {
      digitalWrite(outputStartPin+i, LOW);
    }
    n = n>>1; 
    i++;
  }
}

void blankLights() {
  for (int i=0; i<5; i++) {
    digitalWrite(i+outputStartPin, LOW); 
  }
}

void setup() {
  
  int numTunes = 5;
  
  tunes[0].melody = jingleBells;
  tunes[0].durations = jingleBellsDurations;
  tunes[0].numCount = sizeof(jingleBells)/sizeof(int);
  tunes[0].tempo = 60;
  
  tunes[1].melody = firstNoel;
  tunes[1].durations = firstNoelDurations;
  tunes[1].numCount = sizeof(firstNoel)/sizeof(int);  
  tunes[1].tempo = 60;
  
  tunes[2].melody = oHolyNight;
  tunes[2].durations = oHolyNightDurations;
  tunes[2].numCount = sizeof(oHolyNight)/sizeof(int);    
  tunes[2].tempo = 100;
  
  tunes[3].melody = weThreeKings;
  tunes[3].durations = weThreeKingsDurations;
  tunes[3].numCount = sizeof(weThreeKings)/sizeof(int);      
  tunes[3].tempo = 100;
  
  tunes[4].melody = whatChild;
  tunes[4].durations = whatChildDurations;
  tunes[4].numCount = sizeof(whatChild)/sizeof(int);      
  tunes[4].tempo = 100;  
  
  for (int i=0; i<numTunes; i++) {
    int low = N_DS8;
    int high = 0;
    for (int j=0; j<tunes[i].numCount; j++) {
      int freq = tunes[i].melody[j];
      if (freq != 0 && freq<low) low = freq;
      if (freq>high) high = freq;
    }
    tunes[i].high = high;
    tunes[i].low = low;
  }
   
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);     
  
  for (int i=0; i<5; i++) {
     pinMode(outputStartPin + i, OUTPUT);
  } 
  
}

void playTune() {
  int effectNum = random(4);
  lightEffect(effectNum);
  play(toneNum);
  toneNum = (toneNum+1)%5;
  lightEffect(effectNum);  
}

void loop() {
  
  if (continuousMode) {
    playTune();
    delay(2000);
    
  } else {
  
    // read the state of the pushbutton value:
    buttonState = digitalRead(buttonPin);

    // check if the pushbutton is pressed.
    // if it is, the buttonState is HIGH:
    if (buttonState == HIGH) {    
      playTune();
    }
  } 

}



Ultime modifiche: sabato, 18 marzo 2023, 16:55