I'll put the whole code below. I thought it would be easier if I posted the parts giving me trouble, but in case I missed something, it's all below.
As I read Chris' code, using the map function as listed converts to microseconds, but in case there was something there I misunderstood, I tried doing it with your figures (though other threads suggest 1000 and 2000 for 0 and 180?). Now the servo moves for the first step to 'lock.' Thanks!
So where I'm stuck is the second servo movement, to 'unlock.' Is there a mistake in my code?
if (turn==OPEN_CNT) {
// CODE FOR SERVO OPEN
Serial.println("\n Simon Says Open the Lock ");
playCheer();
// move the servo to the unlocked position
myServo.write(2000);
delay(4000); // allow time for person to actually Open the door
// print out status
Serial.println("the box is unlocked!");
// CODE FOR SERVO RETURN TO NORMAL STATE
// move the servo to the locked position
myServo.write(1000);
delay(500);
// print out status
Serial.println("the box is locked!");
Serial.println(" Re-Close ");
wait4nextBtn = true;
}
Full code here:
#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);
// 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(500);
// print status to the Serial Monitor
Serial.println("the box is locked!");
for (int x = 0; x < 4; x++) // LED pins are outputs
{
pinMode(ledpin[x], OUTPUT);
pinMode(button[x], INPUT); // button pins are inputs
digitalWrite(button[x], HIGH); // enable internal pullup; buttons start in high position; logic reversed
}
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(500); // brief pause before unlocking
// move the servo to the unlocked position
myServo.write(1800);
delay(10);
// print out status
Serial.println("The box is unlocked!");
delay(5000); // allow time for person to actually Open the door
// CODE FOR SERVO RETURN TO NORMAL STATE
// move the servo to the locked position
myServo.write(1000);
// print out status
Serial.println("The box is 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++;
}
}