Subir y bajar volumen de un altavoz

Hola,

Estoy empezando con arduino y me surgen muchas dudas…Os solicito ayuda…

Estoy programando en arduino para que suene un altavoz. Actualmente lo tengo conectado a el pin 3 PWM. Se carga una libreria de notas y usando Tone() suena. La libreria que uso esta definida asi

/*************************************************
 * Public Constants
 *************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58

El codigo que tengo ahora mismo, para modificar, es el siguiente

#include "notas.h"
const int BotonPin = 4;
const int AltavozPin = 3;
byte estadoBoton = LOW;
const int long umbral = 20;
unsigned long previo_ms = 0;

int melody[] = {NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4}; // note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {4, 8, 8, 4, 4, 4, 4, 4};
void suenaMelodia(int AltavozPin){
    for (int thisNote= 0; thisNote< 8; thisNote++) {
      // one second divided by the note type.
      int noteDuration= 1000 / noteDurations[thisNote];
      tone(AltavozPin, melody[thisNote], noteDuration);
      // the note's duration + 30% seems to work well:
      int pauseBetweenNotes= noteDuration* 1.30;
      delay(pauseBetweenNotes);
      noTone(AltavozPin);
    }
}
void setup() {
  pinMode(BotonPin,INPUT);
}
void loop() {
  unsigned long ms = millis();
  estadoBoton = digitalRead(BotonPin);
  if(estadoBoton == HIGH && ms - previo_ms > umbral){
    previo_ms = ms;
    suenaMelodia(AltavozPin);
  }
}

Ahora bien, quiero poder bajar y subir el volumen del altavoz mediante un pulsador. Tone() no lo permite (solo acepta como valores el pin, la nota y la duracion. Creo que para eso, deberia hacerlo mediante PWM, pero no termino de ver como…
Yo supongo que un duty de 50% es el 100% de volumen, pero como relaciono ese duty con la funcion digitalWrite() y la frecuencia?

A ver si alguien me ayuda.
Si conoceis otro metodo… bienvendio sera

Gracias

Un saludo

Buen dia.
Creo que andas un poco perdido, con pwm no puedes bajar ni subir volumen, cuando trabajas con PWM, no cambias la ampitud si no, el ancho de pulso, quiere decir que siempre tendrás 0 o 5 V. a la salida solo con diferente ciclo de trabajo, si tu pones un 50% tendras los mismos 0-5 volts que con el 10% o el 100%.
La función tone(), lo que hace es generar una onda cuadrada de 5V con 50% de ciclo de trabajo con la frecuencia que tu le indicas, si quieres poder controlar el volumen tendrás que hacer un circuito externo para tal cometido

RIG:
Buen dia.
Creo que andas un poco perdido, con pwm no puedes bajar ni subir volumen, cuando trabajas con PWM, no cambias la ampitud si no, el ancho de pulso, quiere decir que siempre tendrás 0 o 5 V. a la salida solo con diferente ciclo de trabajo, si tu pones un 50% tendras los mismos 0-5 volts que con el 10% o el 100%.
La función tone(), lo que hace es generar una onda cuadrada de 5V con 50% de ciclo de trabajo con la frecuencia que tu le indicas, si quieres poder controlar el volumen tendrás que hacer un circuito externo para tal cometido

Hola,

Si, comod ices con PWM no cambio amplitud, pero si cambio el ciclo de trabajo... en un led, se traduce en mayor o menor brillo... en un altavoz se deberia traducir en mayor o menor intensidad de sonido??

Si, comod ices con PWM no cambio amplitud, pero si cambio el ciclo de trabajo

No lo digo yo, lo dice la ciencia

en un led, se traduce en mayor o menor brillo.

Lo que pasa aquí es que apagas y prendes el led tan rápidamente por mayor o menor tiempo dentro de un ciclo de onda, provocando ese efecto de cambiar la intensidad del brillo. Imagina un foco incandescente en tu habitación, cuando tu presionas el interruptor para encender el foco, pasa un tiempo para que el éste llegue a su mayor brillo, imaginemos que dura 1 segundo en llegar a su maximo brillo. Ahora cuando tu enciendes la luz esperas medio segundo y luego la apagas, esperas otro medio segundo y luego la prendes y así repetidamente. eso seria un ciclo de trabajo de 50% a 1Hz. Que resultado tendras? tu foco brillara con media intensidad, pero tu estas aplicando el mismo voltaje de linea(en Mexico 120V) solo que la mitad de tiempo,con esto obtienes el mismo resultado que si encendieras el foco con solo la mitad de voltaje de linea(60V).
Eso es el PWM aplicas todo el voltaje solo cambias el tiempo que aplicas ese voltaje dentro de un ciclo.
En el caso del sonido, es distinto porque un altavoz trabaja diferente a un led o a un foco incandescente.
Necesitas entender bien el concepto de PWM
luego Cómo funciona un altavoz o parlante -
Que es amplitud y frecuencia de una onda, cuando te quede claro el concepto de la amplitud veras que no puedes cambiar el volumen del modo que tu lo quieres hacer

Que es el volumen

Salu2

PWM modifica el ciclo de trabajo a frecuencia constante.
Tone modifica la frecuencia a PWM constante.
Lo que buscas es la combinación de ambas cosas.
Un timer controlado por otro timer.

La sugerencia de un circuito externo podría funcionar usando por ejemplo un potenciometro digital que controlarías con el Arduino como si fuera un potenciometro común.

X9c103
aca tienes otro de microchip Potenciometro Digital MCP4022/

RIG:
No lo digo yo, lo dice la ciencia
Lo que pasa aquí es que apagas y prendes el led tan rápidamente por mayor o menor tiempo dentro de un ciclo de onda, provocando ese efecto de cambiar la intensidad del brillo. Imagina un foco incandescente en tu habitación, cuando tu presionas el interruptor para encender el foco, pasa un tiempo para que el éste llegue a su mayor brillo, imaginemos que dura 1 segundo en llegar a su maximo brillo. Ahora cuando tu enciendes la luz esperas medio segundo y luego la apagas, esperas otro medio segundo y luego la prendes y así repetidamente. eso seria un ciclo de trabajo de 50% a 1Hz. Que resultado tendras? tu foco brillara con media intensidad, pero tu estas aplicando el mismo voltaje de linea(en Mexico 120V) solo que la mitad de tiempo,con esto obtienes el mismo resultado que si encendieras el foco con solo la mitad de voltaje de linea(60V).
Eso es el PWM aplicas todo el voltaje solo cambias el tiempo que aplicas ese voltaje dentro de un ciclo.
En el caso del sonido, es distinto porque un altavoz trabaja diferente a un led o a un foco incandescente.
Necesitas entender bien el concepto de PWM
luego Cómo funciona un altavoz o parlante -
Que es amplitud y frecuencia de una onda, cuando te quede claro el concepto de la amplitud veras que no puedes cambiar el volumen del modo que tu lo quieres hacer

Que es el volumen

Salu2

Gracias, mucho mas claro

surbyte:
PWM modifica el ciclo de trabajo a frecuencia constante.
Tone modifica la frecuencia a PWM constante.
Lo que buscas es la combinación de ambas cosas.
Un timer controlado por otro timer.

La sugerencia de un circuito externo podría funcionar usando por ejemplo un potenciometro digital que controlarías con el Arduino como si fuera un potenciometro común.

X9c103
aca tienes otro de microchip Potenciometro Digital MCP4022/

Si, el problema es que el ejercicio que tengo que hacer dice asi:

"Ejercicio 2. Diseñe un programa que, cuando se pulsa el botón, conmuta el estado de emisión (activado o desactivado) de una melodía por el altavoz controlado por el transistor NPN conectado al pin digital de salida número 3.
Anule el efecto rebote del botón por software, basado en flancos y milisegundos (20 ms).
Vaya incrementando el volumen cada vez que se pulse el botón.

Cuando llegue al máximo, vaya decrementandoel volumen hasta el mínimo."

Sin circuitos externos ni nada... desde la salida de PWM

Asi que no se me ocurre como

Un saludo

Entonces no te compliques.

Simplemente haces lo siguiente.
Frecuencia fija de tono o mejor dicho de PWM, siempre la misma frecuencia, digamos la que este por defecto
Si varias el PWM o ancho de pulso, varias el valor medio o sea el volumen.

Entonces al igual que el led, cambia el ancho de pulso y escucharas un pitido que cambia de volumen o amplitud.
Pero no podrías generar una melodía como lo que pusiste al comienzo.

Gracias @surbyte