viernes, 1 de diciembre de 2017

Hacer sonar "Jingle Bells" y "Happy Birthday To you" con Arduino, un LDR y un speaker cuando se abre una caja metálica




Les presento un nuevo proyecto con Arduino: una caja metálica que cuando se abre y recibe luz e incide sobre el fotosensor LDR hace sonar la melodía "cumpleaños feliz" al menos una vez  gracias al buzzer pasivo (speaker)  y cuando se cierra la caja, después de acabar la melodía deja de sonar. Ideal como regalo y sorpresa para tus seres queridos. El fotosensor LDR y el buzzer pasivo están conectados a Arduino mediante cables protoboard.

Lista de componentes:
  • 1 placa PCB perforada.
  • 1 resistencia de 100 Kohm.
  • 1 fotorresistencia LDR.
  • 1 speaker (buzzer pasivo).
  • 1 microcontrolador Arduino Rev UNO.
  • 1 caja metálica de galletas vacía.
  • 1 pila de 9 V
  • Cinta aislante para sujetar la pila a la base de la caja metálica
  • 1 Portapilas Batería Botón Clip Cable Soporte Pila 9V con conector DC 5.5x2.1mm
  • 3 Piezas 2 Pin 5 mm Conector PCB de Bloqueo de Terminal de Tornillo de Montaje 300V 10A
  • varias tuercas y tornillos (arandelas si también lo deseas)
  • varios cables de protoboard
Lista de herramientas:
  • 1 soldador tipo lapiz
  • 1 bobina de estaño para soldar
  • 1 taladro para hacer perforaciones en la placa PCB y en la caja metálica
  • 1 alicates para apretar las tuercas
  • 1 Destornillador para electrónica

Aquí tienen un esquema elaborado con Fritzing y que indica como se conectan los componentes y los cables a la placa de Arduino.


Hice el montaje del circuito usando como base una caja metálica de galletas comprada en un supermercado de LIDL. Perforé la base con una broca para metal de 3 con un taladro. Usé tuercas y tornillos del mismo calibre para sujetar la placa PCB perforada y la placa del controlador Arduino a la caja.

Debería hacer lo mismo con la pila de 9 V pero no tenía una chapa metálica por casa, así que improvisé con una cinta adhesiva. En este caso, lo mejor es una cinta aislante o colocar una chapa metálica encima de la pila y atornillarla a la base de la caja metálica. Eso se lo dejo a ustedes.




Les dejo 2 códigos que han sido tomados de Internet y que he adaptado para satisfacer mis necesidades para este proyecto.

Uso un pin analógico para el fotosensor LDR y mapeo los valores que toma la fotorresistencia y oscilan entre 0 (ausencia total de luz) y 1024 (presencia total de luz).

Comprobé que luces del microcontrolador Arduino afectaban al fotosensor LDR y por lo tanto al funcionamiento del circuito. Por esa razón, he tenido que tomar un valor relativamente alto (850) para que funcione correctamente, este valor es modificable en cualquier momento. 

Tengan en cuenta que si abren la caja metálica en un lugar oscuro, podría no sonar la melodía. Configuren el codigo según sus necesidades. Ustedes pueden observar los valores de luminosidad que toma el fotosensor LDR a través del Serial Monitor.

Código de la melodía "Cumpleaños Feliz" ("Happy Birthday to You")

/ * Happy Birthday to You
// * Original Composition :
// * Composed by :
// * Coded By - http://forum.arduino.cc/index.php?topic=178460.0
// * Use BSD Clause 2 License for Distribution
// * Collection by GitHub User @abhishekghosh - https://github.com/AbhishekGhosh/Arduino-Buzzer-Tone-Codes
#define LDRPin A0
int BuzzerPin = 10;
// Variable donde se almacena el valor del LDR
int LDRValue = 0;
int length = 28; // the number of notes
char notes[] = "GGAGcB GGAGdc GGxecBA yyecdc";
int beats[] = { 2, 2, 8, 8, 8, 16, 1, 2, 2, 8, 8, 8, 16, 1, 2, 2, 8, 8, 8, 8, 16, 1, 2, 2, 8, 8, 8, 16 };
int tempo = 150;
void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(BuzzerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(BuzzerPin, LOW);
    delayMicroseconds(tone);
  }
}
void playNote(char note, int duration) {
  char names[] = {'C', 'D', 'E', 'F', 'G', 'A', 'B',
                  'c', 'd', 'e', 'f', 'g', 'a', 'b',
                  'x', 'y'
                 };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014,
                  956,  834,  765,  593,  468,  346,  224,
                  655 , 715
                };
  int SPEE = 5;
  // play the tone corresponding to the note name
  for (int i = 0; i < 17; i++) {
    if (names[i] == note) {
      int newduration = duration / SPEE;
      playTone(tones[i], newduration);
    }
  }
}
void setup() {
  Serial.begin(9600);
  pinMode(LDRPin, INPUT);
  pinMode(BuzzerPin, OUTPUT);
}
void loop() {

LDRValue= analogRead(LDRPin);
Serial.println (LDRValue);
  if (LDRValue > 850)
   {
    pinMode(BuzzerPin, HIGH);
    for (int i = 0; i < length; i++) {
      if (notes[i] == ' ') {
        delay(beats[i] * tempo); // rest
      } else {
        playNote(notes[i], beats[i] * tempo);
      }
      // pause between notes
      delay(tempo);
    }
  }
  if (LDRValue < 850)
  {
    pinMode(BuzzerPin, LOW);
  }
  delay (1000);
}

Código de la melodía del villancico navideño "Jingle Bells"

// * Jingle Bells
// * Collection by GitHub User @elubow - https://gist.github.com/elubow/7844436
#define LDRPin A0
int BuzzerPin = 10;
// Variable donde se almacena el valor del LDR
int LDRValue = 0;
int length = 26;
char notes[] = "eeeeeeegcde fffffeeeeddedg";
int beats[] = { 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
int tempo = 300;
void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(BuzzerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(BuzzerPin, LOW);
    delayMicroseconds(tone);
  }
}
void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };

  // play the tone corresponding to the note name
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}
void setup() {
pinMode(LDRPin, INPUT);
pinMode(BuzzerPin, OUTPUT);
}
void loop() {
LDRValue= analogRead(LDRPin);
Serial.println (LDRValue);
  if(LDRValue > 850)
  { 
   pinMode(BuzzerPin,HIGH);
       for (int i = 0; i < length; i++) {
          if (notes[i] == ' ') {
            delay(beats[i] * tempo); // rest
          } else {
            playNote(notes[i], beats[i] * tempo);
          }
       
          // pause between notes
          delay(tempo / 2);
         }
  }

  if(LDRValue < 850)
        {
        pinMode(BuzzerPin,LOW);
        }
delay (1000);
}