Caja musical Arduino Uno + libreria playtune [SOLUCIONADO]

Buenas tardes desde España!

Este es mi primer post en el foro de Arduino, lo primero que quisiera es dar las gracias a toda la comunidad de arduino.cc, llevo casi 6 meses trasteando con este invento y cada día disfruto mas, empece con proyectos simples pero cada vez intento adentrarme mas en proyectos mas complejos, lo malo es que sufro muchas carencias tanto a nivel de programación como de electronica, pero intento mejorar día a día! De nuevo, GRACIAS!

Actualmente estoy con un proyecto de una caja musical (el aniversario de bodas con mi mujer es el mes que viene y quiero darla un regalo emotivo), estoy usando un arduino uno junto con la librería arduino-playtune de Len Shustek (LenShustek (Len Shustek) · GitHub) la cual reproduce tonos con usando los 3 generadores del atmega328 (6 en el caso del Mega2560). El proyecto que trae la propia librería como ejemplo ya lo tengo funcionando, pero no consigo hacerlo funcionar como yo quiero, que seria de la siguiente manera:

Tengo un boton al pin 2, los pines de los generadores son 10,11 y 12.
Tengo una caja de madera con un interruptor instalado a una pila de 9v, al encender el interruptor se enciende el arduino. En la tapa de la caja tengo un boton, que al estar la caja cerrada esta siempre pulsado (con el arduino encendido). Al abrir la caja el botón se suelta y esta en su estado normal. Lo que estoy intentando hacer es que al encender el arduino lo primero que haga sea verificar si el botón esta pulsado, en tal caso paro la reproducción, y si el botón esta suelto empiezo la reproducción desde el principio. Con idea de que al cerrar la caja el botón quede pulsado y la música detenida, el código que tengo ahora mismo es este:

tune_playscore(score) para empezar a reproducir el score anteriormente definido
tune_stopscore para parar la reproducción
tune_playing es true siempre y cuando se este reproduciendo la canción.

Actualmente la canción no empieza a reproducirse hasta que la tapa se abre y el botón se suelta, pero no consigo que la canción pare al pulsar el botón.

void loop () {

buttonState = digitalRead(buttonPin);

if (buttonState == LOW){
pt.tune_playscore(score);
while (pt.tune_playing){ ;
if (buttonState == HIGH) {
pt.tune_stopscore();
}
}
}

Alguien ve el error? Pido disculpas por mi falta de conocimientos respecto a la programación de arduino, intento aprender todos los días algo nuevo. Muchas gracias de antemano por su atención.

Sobra el ; de despes del while si lo pones se queda dentro de ese while sin hacer nada no entra dentro de lo que hay entre {}

void loop () {
  
  buttonState = digitalRead(buttonPin);
  
  if (buttonState == LOW){
      pt.tune_playscore(score);
      while (pt.tune_playing){ 
      if (buttonState == HIGH) {
      pt.tune_stopscore();
   }   
  }
}

de todas formas yo haria:
.

void loop () {
  
  buttonState = digitalRead(buttonPin);
  
  if (buttonState == LOW){
      pt.tune_playscore(score);

  else pt.tune_stopscore();
  
 }   
  }
}

Así no detienes la ejecución del loop y puedes hacer otras cosas mientras, no se si tu proyecto incluye algo mas (una muñeca bailarina que gire mientras la tapa este abierta por ejemplo jajaj)

Prueba de este modo.
buttonState = LOW inicia la melodía.
Luego entras en el while mientras no se detenga pero dentro del while debes esperar que se cierre la tapa

void loop () {
  
  buttonState = digitalRead(buttonPin);
  
  if (buttonState == LOW){
      pt.tune_playscore(score);
  }
 
  while (pt.tune_playing) {
          if (buttonState == HIGH) 
            pt.tune_stopscore();
   }   
}

Buenas tardes de nuevo y gracias por una respuesta tan rápida! GRACIAS!

Pero aun así no consigo hacer que la música pare, efectivamente la música no empieza a reproducir hasta que se abre la tapa y el botón queda suelto, pero al cerrar la tapa la música sigue sonando. He probado vuestras dos soluciones GO_zalo y surbyte pero nada, al cerrar la caja y pulsar el botón sigue reproduciendo la música.

Podia ser a causa de la libreria arduino-playtune? Mirando la documentación poca opción mas tengo para parar la música aparte de usar tune_stopchans (), pero esto pararía los timers y desactivaría los pines, así que tendría que apagar y encender de nuevo el arduino.

El código lo tengo ahora mismo como me ha recomendado surbyte:

void loop () {
 
 buttonState = digitalRead(buttonPin);
 
 if (buttonState == LOW){
     pt.tune_playscore(score);
 }

 while (pt.tune_playing) {
         if (buttonState == HIGH) 
           pt.tune_stopscore();
  }   
}

GO_zalo: Había pensado efectivamente en hacer algo con un microservo SG90 que tengo por aquí, pero esto seria si me diese tiempo, ya que me quedan 20 días para el aniversario, la caja esta lista, solo me falta hacer funcionar el software ;D Si me da tiempo intentare añadirle un poco de "movimiento" al proyecto.

Mil gracias de nuevo!

puedes comprobar si el boton funciona haciendo:

int led = 13;


void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
}

void loop () {
 
 buttonState = digitalRead(buttonPin);
 digitalWrite(led,buttonState);
 
 if (buttonState == LOW){
     pt.tune_playscore(score);
 }

 while (pt.tune_playing) {
         digitalWrite(led,buttonState);
         if (buttonState == HIGH) 
           pt.tune_stopscore();
  }   
}
}

Y observando el led llamado L que esta en la placa conectado al pin 13

También puedes comprobar si es problema de la libreria haciedo

void loop () {

pt.tune_playscore(score);
delay (50000);

pt.tune_stopscore();
delay(5000);  
}

También es posible que los rebotes presentes en el pulsadores estén volviendo un poco loco al pt.tune prueba a añadir un delay de 50 ms después de cada lectura del pin

Coméntanos que resultado has tenido con las tres opciones!

Buenas GO_zalo, he probado primero con el ejemplo del arduino IDE del botón y funciona, el led de la placa se enciende al pulsar y se apaga al soltarlo. Sin embargo con el código del playtune no responde en absoluto, siempre apagada.

Probando la librería dándole el delay la música empieza y efectivamente para, pero no vuelve reproducir tras el delay del playtune_stopscore.

Poniendo un Delay(50) después de leer el estado del botón tampoco parece funcionar, debería ponerlo después de salir del while tal vez?

No entiendo que puede estar pasando, pero agradezco tu ayuda!

Pues yo creo que tu primer código debería funcionar, pero no lo hace por un pequeño detalle. Prueba así:

void loop () {
  
  if (digitalRead(buttonPin)== LOW){
      pt.tune_playscore(score);
      while (pt.tune_playing){ ;
      if (digitalRead(buttonPin) == HIGH) { // ¡¡¡¡No estabas leyendo aquí el pin digital, así que butonState no cambiaba
      pt.tune_stopscore();
   }   
  }
}

Buena observación Serafín, evidentemente no la vimos.

Sigue sobrando el ; de la línea del while, pero es verdad que nos habíamos tragado el fallo de leer el pin.

void loop () {
  
  if (digitalRead(buttonPin)== LOW){
      pt.tune_playscore(score);
      while (pt.tune_playing){ 
      if (digitalRead(buttonPin) == HIGH) { // ¡¡¡¡No estabas leyendo aquí el pin digital, así que butonState no cambiaba
      pt.tune_stopscore();
   }   
  }
}

De todas formas si en el que haces play y al cabo de 5 segundos pause y luego play otra vez no funciona, nunca funcionará con el botón. Debe ser problema de la librería tendrías que buscar una versión más actual

GO_zalo. El delay no funciona porque la librería se ha tomado control del timer0, dejando sin servicio delay, millis, etc.
Si miras el .cpp de la librería lo comenta, y además provee de una función delay alternativa.

Buenos dias!

Ya lo tengo funcionando, efectivamente el codigo entraba dentro del while y solo miraba el valor de la variable del boton, en vez de su estado, ahora funciona a las mil maravillas, muchisimas gracias!

Ahora igual le hago caso a la idea de GO_zalo y le añado algo de movimiento con el microservo que tengo por aqui tirado.

Intentare documentar durante la semana que viene el proceso de montaje de la caja, el diseño del circuito con fritzing y el uso del miditone y la libreria play-tune para reproducir .mid usando el arduino, eso ya lo pondre en zona de proyectos.

Muchisimas gracias noter, GO_zalo y surbyte por la ayuda! Ahora pongo el hilo como funcionando.

GRACIAS!