Really basic/stupid question about routines for a simple Jack-in-the-box.

I really can't get my head around routines or timing in Wiring. I was corrupted by BASIC in my formative years.

I am making a Jack-in-the-Box pinhole camera. When the tilt switch is activated a speaker plays "Pop goes the Weasel" the servo then opens the lid for 2 seconds. Then closes. At least it should. At the moment it happens at the same time and I can't seem to change it without braking it. Ideally I would like it to open when the word "Pop" is said in the tune. If it could be split into 2 routines I would be able to play with the timings easier.

So could someone please look over my Frankenstein code and point me in the right direction. Thanks:

#include "pitches.h"
#include <Wire.h>
#include <Servo.h>

Servo myservo;
int switchPin = 10;
int melody[] = {
 NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4, NOTE_G4, NOTE_E4, NOTE_C4, 0, 0,
 NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4,NOTE_C4, 0, 0,
 NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4, NOTE_G4, NOTE_E4,NOTE_C4, 0, 0,
 NOTE_A4, 0, 0, NOTE_D4,        NOTE_F4, NOTE_E4,            NOTE_C4
 };
 
int noteDurations[] = {
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 2,       4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 2, 4, 2, 2
};

void setup() 
{
  pinMode(switchPin, INPUT);  // set digital pin 10 as input (Tilt Switch)
  pinMode(13, OUTPUT);  // set digital pin 13 as LED output
  myservo.attach(9); // Servo attached to Pin 9
  myservo.write(0);
}

void loop() 
{
  if (digitalRead(switchPin) == HIGH){
       digitalWrite(13, HIGH);   
       delay(500);  
   for (int thisNote = 0; thisNote < 41; thisNote++) 
     {
       int noteDuration = 500/noteDurations[thisNote];
       tone(8, melody[thisNote],noteDuration);
       int pauseBetweenNotes = noteDuration * 1.30;
       delay(pauseBetweenNotes);
       noTone(8);
           myservo.write(90);}
     }else{
    digitalWrite(13, LOW); 
   myservo.write(0);
  }
}

Your indentation is all random - sort it out if you want to be able to read the code!!

I think you've put the servo call inside the note playing loop rather than after it. That doesn't seem right.

Fair call.

I fixed it up and sorted out how routines work. I just need to be able to make both routines run at the same time, so that I can program the servo to run at "pop".

#include "pitches.h"
#include <Wire.h>
#include <Servo.h>

Servo myservo;
int switchPin = 10;
int melody[] = {
  NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4, NOTE_G4, NOTE_E4, NOTE_C4, 0, 0,
  NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4,NOTE_C4, 0, 0,
  NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4, NOTE_G4, NOTE_E4,NOTE_C4, 0, 0,
  NOTE_A4, 0, 0, NOTE_D4, NOTE_F4, NOTE_E4, NOTE_C4
};

int noteDurations[] = {
  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  4, 4, 4, 4, 4, 4, 2,       4, 4, 4,
  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  4, 4, 4, 2, 4, 2, 2
};

void setup() 
{
  pinMode(switchPin, INPUT);  // set digital pin 10 as input (Tilt Switch)
  pinMode(13, OUTPUT);  // set digital pin 13 as LED output
  myservo.attach(9); // Servo attached to Pin 9
  myservo.write(0);
}

void loop() 
{
  if (digitalRead(switchPin) == HIGH){
    digitalWrite(13, HIGH);   
    delay(500);  
    playtune();
    servomove();
  }
  else{
    digitalWrite(13, LOW); 
  }
}

void servomove()
{
  myservo.write(90);
  delay(2000);
  myservo.write(0);
}

void playtune()
{
  for (int thisNote = 0; thisNote < 41; thisNote++) 
  {
    int noteDuration = 500/noteDurations[thisNote];
    tone(8, melody[thisNote],noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(8);
  }
}

Don't use delays. Instead loop without them and check (eg. via a call to millis() ) whether it is time to do something else.

Thanks all, I worked it out with a friend:

#include "pitches.h"
#include <Wire.h>
#include <Servo.h>

Servo myservo;
int switchPin = 10;
int timer = 0;
int melody[] = {
  NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4, NOTE_G4, NOTE_E4, NOTE_C4, 0, 0,
  NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4,NOTE_C4, 0, 0,
  NOTE_C4, 0, NOTE_C4, NOTE_D4, 0, NOTE_D4, NOTE_E4, NOTE_G4, NOTE_E4,NOTE_C4, 0, 0,
  NOTE_A4, 0, 0, NOTE_D4, NOTE_F4, NOTE_E4, NOTE_C4
};

int noteDurations[] = {
  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  4, 4, 4, 4, 4, 4, 2,       4, 4, 4,
  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  4, 4, 4, 2, 4, 2, 2
};

void setup() 
{
  pinMode(switchPin, INPUT);  // set digital pin 10 as input (Tilt Switch)
  pinMode(13, OUTPUT);  // set digital pin 13 as LED output
  myservo.attach(9); // Servo attached to Pin 9
  myservo.write(0);
}

void loop() 
{
  if (digitalRead(switchPin) == HIGH){
    digitalWrite(13, HIGH);   
    delay(500);  
    playtune();
    //servomove();
  }
  else{
    digitalWrite(13, LOW); 
  }
}

void servomove()
{
  myservo.write(90);
  delay(2000);
  myservo.write(0);
}

void playtune()
{
  for (int thisNote = 0; thisNote < 41; thisNote++) 
  {
    int noteDuration = 500/noteDurations[thisNote];
    tone(8, melody[thisNote],noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    timer += pauseBetweenNotes;
    if (timer >= 5600){
       myservo.write(90);
    }
    delay(pauseBetweenNotes);
    noTone(8);
  }
  timer = 0;
  delay(2000);
  myservo.write(0);
}