no tone

I’ve written the following code to count incoming pulses for an experiment. It’s supposed to take 20 averaged readings then then print something in the serial monitor and repeat. It does this 60 times. The frequency counter works fine but the tone isn’t being produced between sessions. I tried taking it out of the while loop but then I was getting a reading of 0Hz for the frequency (should have been ~15Hz). The speaker is fine because just putting the tone command into a separate program works.

////////////////////////////////////// ON THE BOARD ///////////////////////////////////////////

// BNC to pin 2 (BNCpin)
// Connect the buzzer to pin 4 (tonepin)
// Connect the button to pin A2 (buttonpin)
// tone(pin, frequency, duration)              it will interfere with PWM output on pins 3 and 11

/////////////////////////////////////////////////////////////////////////////////////////////////////

const int buttonpin = A2; // Setting the pin for the button
const int BNCpin = 2; // Setting which pin to watch for the pulses
const int tonepin = 4; // Setting the pin for the buzzer
volatile int fc = 0; // Interrupt frequency counter, transfered to fmon
int buttonstate = 0; // Current state of the button
int fmon = 0; // Transfer counter 
int sc = 0; // Session counter (to differentiate sessions in the serial monitor)
int tc = 0; // Tone counter (for marking session changes)
int freak = 0; // Printing frequency in the serial monitor 
const int inttime = 1000; // Integration time for the frequency, 1000 means it will average over a second (1000ms)
unsigned long seshstart; // For ensuring sessions last for 20 seconds 
unsigned long seshend = 0; // Ditto
unsigned long secintA = 0; // For averaging readings over a second
unsigned long secintB = 0; // Ditto



// Setup baud rate & interrupt
void setup() {
  Serial.begin(57600);
  cli(); // Stop interrupts
  attachInterrupt(digitalPinToInterrupt(BNCpin), pulse, RISING);
}


          
void loop() {

    fc = 0;

    
  if (sc%2 == 0){
// Wait for participant to start expt
    buttonstate = digitalRead(buttonpin);
    while (digitalRead(buttonpin) == buttonstate){
    }
  }


// Provide 3 tones then begin 
//Add this into above if st8mt to exclude tones during control session
  while (tc < 3){
    tone(tonepin, 300, 1000);
    noTone(tonepin);
    delay(1000);
    tc = tc + 1; 
  }


    sei(); //Start interrupt counter

// Show if it is an attn towards/away session
  if (sc%2 == 0){
    Serial.println("Attention towards session");
  }
  else if (sc%2 == 1){
    Serial.println("Attention away session");
  }


  seshstart = millis(); // Time when readings are first being taken 


  // This loop is the frequency counter. It averages pulses over a second
  while (seshend <= 20021){

    if (secintA == 0){
      secintA = millis();
    }
    

    secintB = millis() - secintA; 

    
    if (secintB >= inttime){
      cli(); // Stop interrupts
      fmon = fc;
      fc = 0;
      sei(); //Start interrupt
      freak = fmon/(secintB/1000); // fmon is no of pulses, secintB/1000 should be ~1
      Serial.println(freak);
      secintA = 0;
    }

    seshend = millis() - seshstart;
  }

  
  cli(); // Stop interrupts

  
  // Resetting the counters
  tc = 0;
  sc = sc + 1;
  seshend = 0;
  secintA = 0;
  tone(tonepin, 1000, 3000);
  
// End experiment
  if (sc == 60){
    detachInterrupt(digitalPinToInterrupt(BNCpin));
    tone(tonepin, 700, 3000);
    noTone(tonepin);
    tone(tonepin, 700, 3000);
    noTone(tonepin);
    tone(tonepin, 700, 3000);
    noTone(tonepin);
    buttonstate = digitalRead(buttonpin);
    while (digitalRead(buttonpin) == buttonstate){
    }
  }
  
}


// Interrupt for when a pulse is registered
void pulse() {
  fc = fc + 1;
}
  cli(); // Stop interrupts
  attachInterrupt(digitalPinToInterrupt(BNCpin), pulse, RISING);

Seems like you forgot to re-enabe the interrupts.

There is NO reason to disable/enable interrupts when adding another handler.

No I re enable the interrupts later on. I didn't want the counter starting until it was supposed to

    tc = tc + 1; 
  }


    sei(); //Start interrupt counter

// Show if it is an attn towards/away session
  if (sc%2 == 0){
  while (tc < 3){
    tone(tonepin, 300, 1000);
    noTone(tonepin);
    delay(1000);
    tc = tc + 1;
  }

The tone() function relies on interrupts, which you have, as of yet, failed to re-enable.

The tone() function just starts the noise happening. You IMMEDIATELY stop the tone, and then stick your thumb up your * for a second.

I’m not surprised that you don’t hear anything.

  cli(); // Stop interrupts

 
  // Resetting the counters
  tc = 0;
  sc = sc + 1;
  seshend = 0;
  secintA = 0;
  tone(tonepin, 1000, 3000);

Again with the tone() call with interrupts disabled…

Ahh ok, thanks I'll give that a try.

For the

    tone(tonepin, 300, 1000);
    noTone(tonepin);

though I assumed it would play the tone for a second before cancelling it

tone() is not a blocking function. It starts making noise, and returns immediately. If you do nothing, the noise will end 1 second later. If you call noTone() before the specified time is up, the noise will be shut off immediately.