Arduino: Buzzer con zumbido extraño

Me ha pasado un par de veces que he dejado enchufado el cautín (una vez toda la noche), así que estoy proyectando un enchufe-temporizador de manera que a los 30 minutos corta la corriente (un pulsador permite reiniciar el temporizador otros 30 minutos.
El problema es con el buzzer:

7tfIz61s.jpg

A los 30 minutos suena como está programado, pero desde el principio hace un zumbido contínuo muy tenue y no sé como hacer para que esté en silencio (inicialmente lo alimentaba con 5v y ahora lo conecto a los 3.3v pero igualmente hace ese zumbido molesto)

Los componentes del temporizador son:
Arduino Nano, Relé optoacoplado, pulsador, display de 8 segmentos, un led bicolor y el buzzer.
Un esquema de conexiones:

YbTFAIjl.png

El sketch es este:

Código:
#include "TM1637.h"

#define DIO 2
#define CLK 3
#define LedRojo 6
#define Buzzer 9
#define Pulsador 10
#define Relay 11

int segundos = 0;  
int minutos = 0;
int contador = 1800; // 30 minutos (30x60)
int T_Transcurrido=0;  //temporizacion
int T_comienzo=0;

TM1637 Display(CLK,DIO);
int8_t Digits[] = {1,8,0,0}; //Contador descendente desde 30'

void setup() 
{
  //Serial.begin(9600);//Solo para ver monitor serie
  pinMode(Buzzer,OUTPUT);
  pinMode(Relay,OUTPUT);
  pinMode(Pulsador,INPUT);
  pinMode(LedRojo, OUTPUT);
  digitalWrite(Pulsador, 0 );
  digitalWrite(Buzzer, 0 );
  digitalWrite(Relay, 0 );
  digitalWrite(LedRojo, 0 );
  Display.set();  Display.init();   
}

void loop() 
{
  if (minutos <= 31) //Mantiene el Relé encendido 1' más
    {digitalWrite(Relay, 1 );}   //Relé encendido
  else
    {digitalWrite(Relay, 0 );  //Relé apagado
      digitalWrite(LedRojo, 1 );
      CalculaDigitos(0);
      if (digitalRead(Pulsador) == 1)
        { analogWrite(Buzzer, 0 );
          digitalWrite(LedRojo, 0 );
          segundos = 0; minutos = 0;  contador = 1801;
          T_Transcurrido = 0; T_comienzo = 0;}
      return;}
  
  if (segundos<60)
    {segundos++; delay(1000);}    //Contador de segundos
  else
    {segundos=0;minutos++;}
  //En caso de querer controlar por el monitor serie:
  //Serial.print(segundos);Serial.print("-");Serial.println(minutos);

  if (digitalRead(Pulsador) == 0 && minutos >= 30)
    { Alarma();
      digitalWrite(LedRojo, 1 );
      CalculaDigitos(0);return;
     }
  
  if (digitalRead(Pulsador) == 1)
    { analogWrite(Buzzer, 0 );
      digitalWrite(LedRojo, 0 );
      segundos = 0; minutos = 0;  contador = 1801;
      T_Transcurrido = 0; T_comienzo = 0;}
  
  for (contador>=0 ; contador--;)
    {CalculaDigitos(contador);return;}
}

void Alarma()
{ 
  for ( int contador = 0; contador<10 ; contador++)
  {
    analogWrite(Buzzer, 1); delay(50);
    analogWrite(Buzzer, 0); delay(10);
  }
}

void CalculaDigitos( int Num)
{
   int8_t Digit0 = Num %10 ;
   int8_t Digit1 = (Num % 100) / 10 ;
   int8_t Digit2 = (Num % 1000) / 100 ;
   int8_t Digit3 = Num  / 1000  ;
   Digits[3] = Digit0 ;
   Digits[2] = Digit1 ;
   Digits[1] = Digit2 ;
   Digits[0] = Digit3 ;
   Display.display(Digits);
}
 
Última edición:
Holaaa AlbertoG :D Antes de nada aclaremos dos conecptos que sino será un lio :v Un buzzer activo suena a una frecuencia determinada porque lleva un circuito oscilador, por lo que solo es necesario mandar un pulso (con digitalWrite) para encenderlo o apagarlo. El buzzer pasivo por el contrario necesita una onda senoidal para generar el sonido. La ventaja es que puedes generar una amplia gama de frecuencias. Para generar esa senoidal puedes emplear PWM a través de AnalogWrite pero es aconsejable emplear las funciones tone() y noTone() para evitar ruidos molestos o problemas con otras partes el código. Te recomendaria que cambiaras el buzzer a otro pin PWM que no sea el 9 para probar ya que en determinadas ocasiones el pwm del pin 9 se deshabilita o hace ruido cuando se emplean timers u otras configuraciones.

En conclusión si tu buzzer es activo debes mandarle un pulso HIGH o LOW y si tu buzzer es pasivo emplear la función tone() y noTone(). En otras circunstancias lo que suceda es indeterminado.
 
Última edición:
Tone genera onda cuadrada
Analog write genera onda cuadrada de amplitud variable de 1kHz mas o menos, para generar una senoidal en el rango del audio a partir de esto haría falta una de 30kHz o mas, bastante mas. Al menos se pone el foble de la frecuencia a imitar, y luego haría falta un filtro.

En el programa solo hay analogwritew (buzzer, 0) y analog write(buzzer, 1), lo segundo no pone la salida "a 1", tan solo lo pone al "1%", en realidad al 1/256.

Tiene toooooda la pinta de que el buzzer es pasivo y por eso no suena con digitalwrite.

Quita los analog write o y sustituyelos por digital write 0, es probable que aunque le pongas cero de un pequeño pico.

Puedes poner dos cosas
digitalWrite(buzzer,0) para apagarlo
y
analogWrite(buzzer, 128) para hacer una onda cuadrada de 1kHz mas o menos
o
notone(buzzer) para apagar
tone(buzzer,1000) para una onda cuadrada de 1kHz
 
Última edición:
Ante todo gracias por las respuestas, se aprende mucho de las explicaciones tan buenas que ponen.
Según me comentaron en el foro de Arduino, el módulo ese tiene un oscilador incorporado.
He probado en lugar de analogWrite utilizar digitalWrite pero apenas produce sonido con digitalWrite.
En cuanto a cambiar de pin, el problema es que ya monté todo en una PCB con sodaduras, no es que no podría pero claro, es un poco de lío.
Ahora mismo el problema lo llevo resuelto con una resistencia de 1000K al GND, y con eso no hace ese ruido por el que consulté.
Me plantearé reconectar el módulo y utilizar las funciones Tone y noTone.
 
No se, una resistencia de 1M es lo mas parecido a no poner nada. Mucho sentido no tiene.
Prueba a "callar" la salida con digitalwrite (buzzer,0)

En todo caso para la próxima compras un buzzer pasivo que es mas barato, si total vas a usar tone lo mismo te da.
 
Atrás
Arriba