Contapezzi con Buzzer

Salve a tutti
ho realizzato un contapezzi dove ad ogni pressione di un pulsante mi va ad aumentare di una unità un contatore e il valore viene visualizzato su un display 7 segment.

Il tutto funziona senonchè ho aggiunto un buzzer che emette un tono ad ogni pressione del pulsante contatore, ed oltre ad emettere il bip c'è sempre un fischio continuo che non riesco a togliere.

Qualcuno può aiutarmi a capire perchè? Grazie.

[code]

 //State change detection (edge detection)
//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/*  The circuit:
 - buttonpin attached to pin 2 from +5V
 - buttonreset attached to pin 4 from +5V
 - 10 kilohm resistor attached to pin 2&4 from ground
*/
// this constant won't change:
const int  buttonPin = 2;// the pin that the pushbutton is attached to
const int  buttonReset = 4;// the pin that the buttonreset is attached to
const int  buzzer = 8;

// Variables will change:
int contatore = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int unita = 0;
int decine = 0;
int centinaia = 0;
int tmp=0;


void setup(){
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);

  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonReset, INPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      contatore++;
      tone (8,800,20);
      
        tmp=contatore;
        unita=tmp%10;
        tmp=tmp/10;
        decine=tmp%10;
        centinaia=tmp/10;

      lc.setDigit(0,2,(byte)centinaia,false);
      lc.setDigit(0,1,(byte)decine,false);
      lc.setDigit(0,0,(byte)unita,false);
    }
      if (buttonState != lastButtonState) {
        if (buttonState == LOW) {
      noTone (8);
       } 
     }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // if the buttonreset is pressed reset the buttonpushcounter
  if  (digitalRead(buttonReset) == HIGH){
      (contatore = 0);
       lc.clearDisplay(0);
    }
  }

[/code]

Poiché l'incremento deve avvenire quando il pulsante viene premuto, puoi scrivere:

if(lastButtonState==0 && buttonState==1)
  {
  lastButtonState=1;
  contatore++;
  tone (8,800,20);
  }

if(buttonState==0 && lastButtonState==1) lastButtonState=0;

Scusami, ma devo andare...

Datman:
Poiché l'incremento deve avvenire quando il pulsante viene premuto, puoi scrivere:

Ok...ma il problema non è l' incremento del contatore, quello lo abbiamo risolto.

il problema è in fischio continuo che fa il Buzzer oltre a fare il Bip previsto, ho provato anche a cambiare Buzzer ma lo fa lo stesso.

Non vedo cose particolari, se non alcune piccole correzioni.
Intanto il noTone(), ossia perché usi noTone() se il comando tone() lo imposti per 20 millisecondi di durata? Mi pare superfluo. Anche la if() dove è contenuto è comunque inutile visto che sei già dentro ad una "if(buttonState != lastButtonState)".
E lastButtonState, sempre per ottimizzare il codice, meglio metterlo dentro la if(), inutile settarla se non è cambiata.
Il pin del buzzer non lo hai definito in setup().
Poi il pin del buzzer lo definisci all'inizio come "const int buzzer = 8;" ma poi non lo usi mai.
Per definire i pin, invece delle variabili (seppur "const") meglio usare i #define.

Insomma, intanto il codice lo cambierei così, vedi tu di provarlo e facci sapere:

//State change detection (edge detection)
//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/*  The circuit:
 - PIN_BUTTON attached to pin 2 from +5V
 - PIN_RESET attached to pin 4 from +5V
 - 10 kilohm resistor attached to pin 2&4 from ground
*/
// this constant won't change:
#define PIN_BUTTON 2 // the pin that the pushbutton is attached to
#define PIN_RESET 4  // the pin that the PIN_RESET is attached to
#define PIN_BUZZER 8 // buzzer pin

// Variables will change:
int contatore = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int unita = 0;
int decine = 0;
int centinaia = 0;
int tmp=0;


void setup(){
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);

  // initialize the button pin as a input:
  pinMode(PIN_BUTTON, INPUT);
  pinMode(PIN_RESET, INPUT);
  pinMode(PIN_BUZZER, OUTPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(PIN_BUTTON);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      contatore++;
      tone (PIN_BUZZER,800,20);
      
      tmp=contatore;
      unita=tmp%10;
      tmp=tmp/10;
      decine=tmp%10;
      centinaia=tmp/10;

      lc.setDigit(0,2,(byte)centinaia,false);
      lc.setDigit(0,1,(byte)decine,false);
      lc.setDigit(0,0,(byte)unita,false);
    }
    // Delay a little bit to avoid bouncing
    delay(50);
    // save the current state as the last state, for next time through the loop
    lastButtonState = buttonState;
  }

  // if the RESET is pressed reset the buttonpushcounter
  if  (digitalRead(PIN_RESET) == HIGH){
      (contatore = 0);
       lc.clearDisplay(0);
    }
  }

Ciao doc, il noTone () l' avevo usato per fare anche quella prova (non sapendo più che pesci pigliare!)...
comunque ho provato il tuo codice ma il fischio permane, il beep lo fa, ma il fischio non se ne va!
Ho anche provato a inteporre una resistenza da 10 ohm tra il contatto del buzzer e il pin 8 ma non cambia nulla.

:slight_smile: non è che hai usato un buzzer attivo al posto di uno passivo.... :slight_smile:

Patrick_M:
:slight_smile: non è che hai usato un buzzer attivo al posto di uno passivo.... :slight_smile:

No Patrick_M...è il piezo dello starter Kit.

ok allora fai una prova, collega il negativo al gnd di arduino e il positivo al pin 3,3V di arduino.... meglio con la resistenza da 10-100 Ohm in mezzo, e vedi se con l'alimentazione diretta in CC suona o se ne sta muto... poi ne parliamo :wink:

Patrick_M:
ok allora fai una prova, collega il negativo al gnd di arduino e il positivo al pin 3,3V di arduino.... meglio con la resistenza da 10-100 Ohm in mezzo, e vedi se con l'alimentazione diretta in CC suona o se ne sta muto... poi ne parliamo :wink:

Se ne sta muto! :cold_sweat:

boh.... fai ancora una prova... come suggerito qui aumenta la resistenza a 1K Ohm ... altro nin zo

o meglio prova a cambiare anche il buzzer a questo punto

Patrick_M:
boh.... fai ancora una prova... come suggerito qui aumenta la resistenza a 1K Ohm ... altro nin zo

o meglio prova a cambiare anche il buzzer a questo punto

Ok farò anche questa prova...certo che usare una libreria per far fare un beep a un piezo!!
Ho già provato a cambiare buzzer.

Così che succede?

#include "LedControl.h"
LedControl lc=LedControl(12,11,10,1);
#define PIN_BUTTON 2 // the pin that the pushbutton is attached to
#define PIN_RESET 4  // the pin that the PIN_RESET is attached to
#define PIN_BUZZER 8 // buzzer pin

int contatore = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int unita = 0;
int decine = 0;
int centinaia = 0;
int tmp=0;

void setup()
{
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);

  pinMode(PIN_BUTTON, INPUT);
  pinMode(PIN_RESET, INPUT);
  pinMode(PIN_BUZZER, OUTPUT);

  tone(PIN_BUZZER,1000,1000);
}

Comunque pinMode(PIN_BUZZER, OUTPUT); non è necessario per usare tone().

Flavi71:
Ok farò anche questa prova...certo che usare una libreria per far fare un beep a un piezo!!
Ho già provato a cambiare buzzer.

:smiley: no, io intendevo solo di usare una resistenza da 1K :smiley:

Flavi71:
Ok farò anche questa prova...certo che usare una libreria per far fare un beep a un piezo!!

Una libreria???...

La resistenza in serie serve solo per non sovraccaricare le uscite usando altoparlanti dinamici da 4...32 ohm. Non serve per i cicalini piezoelettrici. Tanto meno può fare qualcosa per risolvere il problema in oggetto.

Flavi71:
No Patrick_M...è il piezo dello starter Kit.

Così per qualche altro test, prova intanto a cambiare il pin del buzzer da 8 a 9 (ovviamente cambiando anche il valore nella #define).

Però un dubbio: nel reference della tone() leggo:
Use of the tone() function will interfere with PWM output on pins 3 and 11
Ed io vedo che la LedControl usa il Pin 11 (CLK), non avendo mai usato quella libreria non so se all'interno usi qualche interrupt, quindi magari il pin del buzzer "risente" del clock, non so dirti.
Prova a fare uno sketch dove gestisci con un pulsante SOLO il buzzer, senza led e vedi se fa la stessa cosa.
Se lo fa ugualmente, non so darti risposte. Se non lo fa, è un qualche conflitto tra tone() e LedControl (in tal caso prova a cambiare il pin da 11 ad un altro).

docdoc:
... Però un dubbio: nel reference della tone() leggo:
Use of the tone() function will interfere with PWM output on pins 3 and 11

Ovviamnete visto che, su Arduno UNO ... usano lo stesso Timer ...

Timer2
Usato per il PWM sui pin 3 e 11
Usato dalla tone()
8-bit phase correct pwm mode
(default 488.28125 Hz)

Guglielmo

Avevo sospettato qualcosa del genere, ma l'I/O8 non è usato dalla libreria. Comunque usare un I/O diverso è una prova da fare.

... c'è però sempre la possibilità di scaricare ed installare QUESTA libreria che offre i seguenti vantaggi:

  • Doesn't use timers which frees up conflicts with other libraries.
  • Compatible with all ATmega, ATtiny and ARM-based microcontrollers.
  • About 1,500 bytes smaller binary sketch size than the standard tone library.
  • Exclusive use of port registers for AVR-based microcontrollers for fastest and smallest code.
  • Optional volume parameter.
  • Close to a plug-in replacement for the standard Tone library.

Guglielmo

Quella libreria, però, blocca l'esecuzione del programma.

... allora cercatene un'altra con Google, ci sono varie alternative che permettono di usare timers differenti :wink:

Guglielmo