while statement help!

Hello,

There is a small part of my code that im stuck with. i am using a while statement to execute a command to a piece of hardware (mp3 trigger)
To trigger the mp3 track it seems the trigger likes a HIGH followed by LOW signal ie the track is played on the signal changing back from HIGH to LOW. the trouble i am having is that if i send HIGH, delay(x) then LOW delay(x) the mp3 track is either, if the delay is very short (100-500) constantly restarted at the end of the delay, or if the delay is too long (500+) the response to the next if statement is far too slow.

Is there a simple way of sending a brief HIGH then a LOW once only without it looping? Any suggestions are very much appreciated :slight_smile:

this is the code:

  while (digitalRead(switchPin)==LOW) {
      digitalWrite(tracktwo, HIGH); // trigger track two - ringtone
      delay (300);
      digitalWrite(tracktwo, LOW);
      delay(1200);

if it helps this is the rest of the code to put it in context

void ring (){
  if (hookState==HIGH) {
    ringAction.setInterval(30*1000); //check again in 30 sec because the phone was already lifted
  } 
  else { // start ringing
    Serial.println("2 hookval LOW. start ringing: tracktwo HIGH, relay LOW - START VOID RING LOOP ");
    digitalWrite(relayswitch, LOW); //relay switch is LOW - main speaker
    while (digitalRead(switchPin)==LOW) {
      digitalWrite(tracktwo, HIGH); // trigger track two - ringtone
      delay (300);
      digitalWrite(tracktwo, LOW);
      delay(1200);
     
      
      
      //TODO add a timeout to this endless loop, calls until pickup
    }
    //phone is ringing and is picked up
    Serial.println("3 hookval - trackthree HIGH, relayswitch HIGH - PHONE PICKED UP PLAYING MESSAGE ");
    digitalWrite(relayswitch, HIGH);               //relay switch is high - plays through earpiece
    digitalWrite(trackthree, HIGH); // play track 3 answer message
    delay(1000);
    digitalWrite(trackthree, LOW);
    while (digitalRead(switchPin)==HIGH) {/*wait*/
    }
    Serial.print("4 hookval- trackstop HIGH, relayswitch LOW - PHONE PUT DOWN STOP MESSAGE PLAYING ");
    digitalWrite(trackstop, HIGH);
    delay(400);
    digitalWrite(trackstop, LOW);
    digitalWrite(relayswitch, LOW);               //relay switch is LOW - main speaker
    Serial.println("END OF VOID RING LOOP ");

    ringAction.setInterval(INTERVAL); //schedule next call
  }
}

I also tried this:

  while (digitalRead(switchPin)==LOW) {
      digitalWrite(tracktwo, HIGH); // trigger track two - ringtone
      delay (300);
      digitalWrite(tracktwo, LOW);

and it didn't trigger the mp3 track to play. it seems to just leave the pin on HIGH.

Check out this tutorial: Blink without Delay

It illustrates the basic technique you need to resolve your problem quite well.

Korman

Thanks, i just checked it out. it looks like it would be useful but i dont want the led to blink repeatedly i just want it to turn on and off once. maybe i could add a counter to the blinks...

I'm also certain, you don't have a led attached either, but that was beside the point. The important part is the use of variables and the millis() function. Understand the concept behind this tutorial and then the application to you problem will be obvious. If it doesn't become obvious, consider that as a sign that your understanding of the concept isn't solid yet and work some more on it.

Korman

while (digitalRead(switchPin)==LOW) {
digitalWrite(tracktwo, HIGH); // trigger track two - ringtone
delay (300);
digitalWrite(tracktwo, LOW);
delay(1200);

@chopeone1: Assuming there's meant to be a closing brace there, you're only examining the state of "switchPin" every 1.5 seconds.
Maybe you've misunderstood how a while loop works.

Got it working! thanks for your pointers Korman.

  while (digitalRead(switchPin)==LOW) {
      //digitalWrite(tracktwo, HIGH); // trigger track two - ringtone
      //delay (300);
      //digitalWrite(tracktwo, LOW);
      //delay(200);
     unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if ((ledState == LOW) && (blinks <1))
      ledState = HIGH;
    else
      ledState = LOW;
      blinks ++;

    // set the LED with the ledState of the variable:
    digitalWrite(tracktwo, ledState);
  }

At some point, you need to reset blinks to 0.