How to add simple Servo code from a Tutorial?

No worries - I sure appreciate the help. Full code below.

I'm not sure if the trouble here is with the code, with the way I'm using the object from the new library, with a fundamental incompatibility between the speaker and servo, an electrical mistake on my part, or something else. Here's what I've done to narrow it down:

  • I've confirmed that the servo can move as instructed, since it responds to instructions in setup. For instance, I can do this to watch it move from 'lock' to 'unlock':
  // attach the servo to pin 9
  myServo.attach(9);
 // move the servo to the locked position
  myServo.write(1000);
  delay(2000);
  myServo.write(2000);
  delay(100);

but when I move myServo.write(2000); to the loop, it doesn't respond.

  • I've checked that the conditional code of the loop is being run (turn=Open_CNT, which happens after 4 LED patterns are matched), and I know that because I see the Serial.println messages in the serial monitor.

this plays the 'Cheers' music and sends the messages to the serial monitor, but it doesn't move the servo:

    if (turn==OPEN_CNT) {
      // CODE FOR SERVO OPEN
      Serial.println("\n Simon Says Open the Lock ");
      playCheer();
      delay(100);  // brief pause before unlocking
      myServo.write(2000);  // move the servo to the unlocked position
        delay(10);
   
      // print out status
      Serial.println("The box is unlocked!");
      delay(5000);  // allow time for person to actually Open the door
      
      // move the servo to the locked position
      myServo.write(1200);
      delay(100);
  
      // print out status
      Serial.println("The box is re-locked!");
  
      wait4nextBtn = true;
    }
  • I've confirmed that the problem doesn't come from powering both the speaker and the servo. If I disconnect the speaker, the problem remains.

  • I've swapped in another (100uf) capacitor, in case trouble with the first made the servo is finicky, though I don't know if that even could be an issue. The capacitor is correctly installed, with short to ground.

I wouldn't be surprised if I'm missing something embarrassingly simple, but I don't see what it is, and I don't know how to distinguish it from a more fundamental problem, like the library incompatibility that began this thread.

Here's the full code:

#include "Tone.h"

const int OPEN_CNT = 4;
Tone speaker;
byte speakerPin = 8; // D14 is aka A0, speaker was on pin 13
int starttune[] = {NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_G4, NOTE_F4, NOTE_E4, NOTE_F4, NOTE_G4};
int duration2[] = {100, 200, 100, 200, 100, 400, 100, 100, 100, 100, 200, 100, 500};
int cheer[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_C5, NOTE_G4, NOTE_C5};
int btnNote[] = {NOTE_G3, NOTE_A3, NOTE_B3, NOTE_C4};
int duration[] = {100, 100, 100, 300, 100, 300};
//boolean button[] = {2, 3, 4, 5}; //The four button input pins
//boolean ledpin[] = {8, 9, 10, 11};  // LED pins
int button[] = {15, 16, 17, 18}; //The four button input pins
int ledpin[] = {2, 3, 4, 5};  // LED pins
int turn = 0;  // turn counter
int buttonstate = 0;  // button state checker
int randomArray[100]; //Intentionally long to store up to 100 inputs (doubtful anyone will get this far)
int inputArray[100];
bool wait4nextBtn = true;

// import the library
#include <ServoTimer2.h>
// create an instance of the Servo library
ServoTimer2 myServo;

// ===================================================
void setup()
{
  int note;
  Serial.begin(9600);
  speaker.begin(speakerPin);
  delay(10);
  
  // SERVO SETUP
   // attach the servo to pin 9
  myServo.attach(9);
  // INITIALIZATION SERVO TO CLOSED
 // move the servo to the locked position
  myServo.write(1000);
  delay(100);
  
  // print status to the Serial Monitor
  Serial.println("The box is now locked!");

  for (int x = 0; x < 4; x++) // LED pins are outputs
  {
    pinMode(ledpin[x], OUTPUT);
    pinMode(button[x], INPUT_PULLUP);  // button pins are inputs
  }

  randomSeed(analogRead(0)); //Added to generate "more randomness" with the randomArray for the output function
  for (int thisNote = 6; thisNote < 11; thisNote ++) {
    // play the next note:
    note = starttune[thisNote];
    speaker.play(note);
    if (note == NOTE_C4)      digitalWrite(ledpin[0], HIGH);
    else if (note == NOTE_F4) digitalWrite(ledpin[1], HIGH);
    else if (note == NOTE_G4) digitalWrite(ledpin[2], HIGH);
    else if (note == NOTE_E4) digitalWrite(ledpin[3], HIGH);

    // hold the note:
    delay(duration2[thisNote]);
    // stop for the next note:
    speaker.stop();
    allLEDs(LOW);
    delay(25);
  }
  delay(1000);
}

// ========================================================
void loop()  // This 'loop' is automatically run repeatedly
{
  for (int level = 0; level <= 99; level++)
  {
    allLEDs(LOW);
    
    Serial.print("\n Turn: ");   // Some serial output to follow along
    Serial.print(turn);

    if (turn==OPEN_CNT) {
      // CODE FOR SERVO OPEN
      Serial.println("\n Simon Says Open the Lock ");
      playCheer();
      delay(100);  // brief pause before unlocking
      myServo.write(2000);  // move the servo to the unlocked position
        delay(10);
   
      // print out status
      Serial.println("The box is unlocked!");
      delay(5000);  // allow time for person to actually Open the door
      
      // move the servo to the locked position
      myServo.write(1000);
      delay(100);
  
      // print out status
      Serial.println("The box is re-locked!");
  
      wait4nextBtn = true;
    }
    
    if (wait4nextBtn) {
      wait4nextBtn = false;
      bool btnPushed = false;
      while (! btnPushed) { // wait for a key-press before starting all over
        for (int y = 0; y < 4; y++)
        { if (digitalRead(button[y]) == LOW) //Checking for button push
          btnPushed = true; 
        }
      }
      turn = -1; //Reset turn value so the game starts over
      exit;
    }
    
    // fill up the array to be matched by the player
    randomArray[turn] = random(1, 5); //Assigning a random number (1-4) to the randomArray[turn count]
    Serial.print("  Rand#: ");
    Serial.println(randomArray[turn]);

    for (int x = 0; x <= turn; x++)
    {
      Serial.print(randomArray[x]);
      byte btn = randomArray[x];  // logical button/led # (1-4)
      digitalWrite(ledpin[btn - 1], HIGH);
      speaker.play(btnNote[btn - 1], 100);
      delay(400);
      digitalWrite(ledpin[btn - 1], LOW);
      delay(100);
    }
    input();
  }
}

// ===================================================
//            local functions

void input() { //Function for allowing user input and checking input against the generated array
  bool btnPushed;

  for (int x = 0; x <= turn; x++)
  { // for each one in the current sequence wait for a button to be pushed 
    // if it is the correct one we keep looping through the sequence

    btnPushed = false;
    while (! btnPushed) {
      for (int y = 0; y < 4; y++)
      {
        buttonstate = digitalRead(button[y]);
        byte btn = y + 1; // logical button # (1-4)

        if (buttonstate == LOW)  //Checking for button push
        {
          btnPushed = true;
          digitalWrite(ledpin[y], HIGH);
          speaker.play(btnNote[btn - 1], 100);
          delay(100);  // insures minimum LED illumination
          inputArray[x] = btn;
          Serial.print("  btn pushed: ");
          Serial.print(btn);
// was a poor way to allow for button release:         delay(250);
          wait_BtnRelease();  // much better this way
          digitalWrite(ledpin[y], LOW);
          if (inputArray[x] != randomArray[x]) { //Checks value input by user and checks it against
            fail();                              //the value in the same spot on the generated array
            //The fail function is called if it does not match
            exit;
          }
        }
      }
    }  // end while
  }
  delay(500);
  turn++; //Increments the turn count, also the last action before starting the output function over again
}

// ------------------------------------------------------
void playCheer() { //Function used if the player fails to match the sequence
    allLEDs(HIGH);

    for (int thisNote = 0; thisNote < 6; thisNote ++) {
      // play the next note:
      speaker.play(cheer[thisNote]);
      // hold the note:
      delay(duration[thisNote]);
      // stop for the next note:
      speaker.stop();
      delay(25);
    }

    allLEDs(LOW);
    delay(1000);
}

void fail() { //Function used if the player fails to match the sequence

  for (int y = 0; y <= 2; y++)
  { //Flashes lights for failure
    allLEDs(HIGH);
    speaker.play(NOTE_G3, 300);
    delay(200);
    allLEDs(LOW);
    speaker.play(NOTE_C3, 300);
    delay(200);
          // print out status
  }
       Serial.println("\n Oops!");
  delay(500);
  turn = -1; //Resets turn value so the game starts over without need for a reset button
}

// ------------------------------------------------------
void allLEDs(byte state) {
  digitalWrite(ledpin[0], state);
  digitalWrite(ledpin[1], state);
  digitalWrite(ledpin[2], state);
  digitalWrite(ledpin[3], state);
}

void wait_BtnRelease() {
  bool btnStillDown;
  int debounce=0; // need depends on button used. mine caused some double trips
    while (debounce<2) {
      delay(5);
      btnStillDown = false;
      for (int y = 0; y < 4; y++)
      {
        buttonstate = digitalRead(button[y]);
        if (buttonstate == LOW)  //Checking for button push
          btnStillDown = true;
      }
      if (btnStillDown) debounce=0;
      else debounce++;
    }
}