Problem using digitalWrite outside the main loop()

I am currently building a handheld data logger. Everything works but I am trying to add a piezo buzzer to provide the user some feedback (will add an RGB led after buzzer). My question, which should be clearer by the end of this post, is why doesnt my digitalWrite() command work outside of my void loop()? Even when my buzzer is turned on and off multiple times within a for loop.

I can successfully buzz the piezo in the main loop():

int piezoPin = 3; 
int piezoStatus = LOW; 
unsigned long previousTime = 0;   // will use millis to pulse piezo. using unsigned long because i read to do so :)
int interval = 1000; // will pulse once per sec. 

void setup() {
 Serial.begin(); 
 pinMode(piezoPin, OUTPUT); 
}

void loop(){
 unsigned long currentTime = millis(); 
 if(currentTime - previousTime > interval) {
  previousTime = currentTime; 
  if(piezoStatus == LOW) {
   piezoStatus = HIGH; 
  }
  else {
   piezoStatus = LOW; 
  } 
  digitalWrite(piezoPin, piezoStatus); 
}

So far so good, this will pulse the piezo once a second and can be changed by changing interval to something else.

However, in my actual sketch, I have data being gather by various functions and when certain criteria are met, say when x, y & z are true, then the data is stored on the sd card.
What I am trying to do is pulse the piezo 20 times if the sd card does not initialize and 3 times if it does initialize and all is good.
I can test this using:

if(!SD.begin(chipSelect)){
  Serial.println("SD card failed or not present");
else {
  Serial.println("SD card ready..")
}

However, I cannot get the piezo to pulse by adding the above code into this SD begin check code:

const int chipSelect = 10; 
int piezoPin = 3; 
int piezoStatus = LOW;
 
void setup(){
 Serial.begin(9600); 
 pinMode(10, OUTPUT); // for sdcard
 getPiezoStatus(); 
}

void loop(){ 
// checking for x, y & z before writing to sd card
}

getPiezoStatus(){
 if(!SD.begin(chipSelect)) {
   Serial.println("SD card failed"); 
     for(int i = 0; i < 20; i++){    // to pulse 20 times if SD is in error
      if(piezoStatus == LOW) {
        piezoStatus = HIGH; 
      }
      else {
      piezoStatus = LOW; 
      } 
      digitalWrite(piezoPin, piezoStatus); 
    }
    else {   // if sd card is there and working correctly
     Serial.println("SD is ready");
     for(int k = 0; k < 3; k++){
      if(piezoStatus == LOW) {
       piezoStatus = HIGH; 
      }
      else {
        piezoStatus = LOW; 
      }
      digitalWrite(piezoPin, piezoStatus); 
    }
}

I can hear a very faint pulse, once. However, with the code outside the main loop(), I cannot get it to buzz loudly (normal) or buzz repeatedly.
I’ve looked into seeing if others can get digitalWrite to work outside the main loop(), however all the examples I’ve found include it in the loop.

I know my code partly works because I get the Serial.println commands (if there are syntax errors in my code above, its because I cant c&p my code right now) when I remove or insert my sd card.

Thanks in advance!

In the code that works, you have a pinMode() call to declare that the piezo pin is an OUTPUT pin. In the code that doesn't. you don't. Coincidence? Not likely.

That'll do it, won't it?
Thank's Paul!

It's fun to reflect upon all the crazy and weird things I imagined could be causing this.. sad to admit that was my Thursday..
At least I'm really good at typing piezo, digitalRead and Serial.println now.. :slight_smile:

Of course setup() is only ever called once, as is anything in it!.

Mark