simple program (that I can't seem to make)

I (a hopelessly new arduino user) am attempting to make a program that will activate a continuously rotating servo once a password is inputted via keypad. After using the software serial monitor I have verified that my keypad is working and so is the servo, I just can't seem to get a program together that will open after entering a password. Here's my feeble attempt (be nice), and what's wrong?

#include <Password.h>

#include <Keypad.h>

Password password = Password( "1204" );

const byte rows = 4; //four rows
const byte cols = 3; //four columns
char keys[rows][cols] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[rows] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[cols] = {6, 7, 8}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );

const byte servoPin = 9;

int pulseWidth;

int myAngle;

void setup(){
pinMode(servoPin, OUTPUT); // sets the digital pin as output
Serial.begin(9600);
keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}

void servoPulse(int servoPin, int myAngle)
{
pulseWidth = (myAngle * 10) + 600;
digitalWrite(servoPin, HIGH);
delayMicroseconds(pulseWidth);
digitalWrite(servoPin, LOW);
}

void loop(){
keypad.getKey();
delay(50);
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
switch (eKey){
case '*': guessPassword(); break;
case '#': password.reset(); break;
default:
password.append(eKey);
}
}

void guessPassword(){
if (password.evaluate()){
Serial.println("success");
for (myAngle=10; myAngle<=170; myAngle++)
{
servoPulse(servoPin, myAngle);
delay(20);
}
}
}

You showed some code. Great, but next time, please use the button with the # when posting code.

You also said that you verified that the keypad is working. How?

Finally, you said "It doesn't work!". Or, words to that effect. But, you didn't explain what is being written to the serial monitor, and what parts do, and do not work.

Do you see "success" in the serial monitor?

I'd start with adding Serial.print statements to keypadEvent, to see what key was pressed, and to guessPassword (that's a lousy name, by the way - the function does not guess the password) to show when it is called, and to show what password.evaluate() returned.

I verified that the keypad is functional using just a printserial code and the serial monitor. The program I posted above didn't return "success" or anything. The closest thing I have to functional is this:

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char key = keypad.getKey();

int servoPin = 9;

int myAngle;

int pulseWidth;

void setup()
{
  pinMode(9, OUTPUT);
}

void servoPulse(int servoPin, int myAngle)
{
  pulseWidth = (myAngle *10) + 600;
  digitalWrite(servoPin, HIGH);
  delayMicroseconds(pulseWidth);
  digitalWrite(servoPin, LOW);
}

void loop()
{
 if(keypad.getKey() != NO_KEY)
 {
   for (myAngle=10; myAngle<=170; myAngle++)
   {
     servoPulse(servoPin, myAngle);
     delay(20);
   }
 }
}

That program successfully makes the servo rotate and return (which would pull a door handle) when any key on the keypad is pressed. What I can't figure out is how to make the "if" statement (currently if(keypad.getKey() != NO_KEY) into an "if" statement that is counted as true when the correct password is inputted. Any Idea how I would go about changing this into a password based activation? I'm sorry if I'm somewhat thick when I comes to this, this is literally the first day I've worked with microcontrollers or programming of any kind.

You had the keypadEvent function. Was that function called? Using a Serial.print statement, echo the key that was entered.

You had a guessPassword function. Was that function called?

What does password.evaluate() return?

It appears that your code is pretty close. I've never used the Password class, so I can't help you with that class. But, I'd add Serial.print statements in the first code you posted, to see what is being called, and what is being passed in. It should become obvious quickly what is wrong. If not, post the code, and output, again, after adding the print statements.

We can suggest other statements to add, or point out why you are getting the results you are, if they don't seem reasonable.

So, after fiddling more with the password library, I got frustrated and tried a new approach, and it works!

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char key = keypad.getKey();

int servoPin = 9;

int myAngle;

int pulseWidth;

void setup()
{
  pinMode(9, OUTPUT);
  Serial.begin(9600);
  Serial.println(keypad.getKey());
}

void servoPulse(int servoPin, int myAngle)
{
  pulseWidth = (myAngle *10) + 600;
  digitalWrite(servoPin, HIGH);
  delayMicroseconds(pulseWidth);
  digitalWrite(servoPin, LOW);
}

void loop()
{ 
 if(keypad.getKey() == '1')
 {
  while(keypad.getKey() != '2')
  {loop;}
  {
     while(keypad.getKey() != '0')
     {loop;}
     {
       while(keypad.getKey() != '4')
       {loop;}
       {
  for (myAngle=0; myAngle<=170; myAngle++)
   {
     servoPulse(servoPin, myAngle);
     delay(20);
     Serial.println(key);
   }
 }
}
}
}
}

With the password being 1204. Yes I realize that if someone were to start pushing all the buttons systematically it would let them in under this code, but It's for a dorm room, and nobody will expect anything other than the correct code to work (nobody around here anyway :P)

  {loop;}

Can you explain what that's supposed to be doing?

Can you explain what that's supposed to be doing

That's actually quite a neat harmless reminder! ;D

(Evaluate "loop", a pointer to void function, and discard the result. It is probably optimised-out, but actually serves a useful purpose)

Not really recommended, though.

but actually serves a useful purpose

That's the part I'm missing, I guess. What is the useful purpose?

I don't think that it's doing what OP intended, since it formed the body of the while loop.

My intention with the

{loop;}

was to make it wait for the next imput. It may not be the right way to do it, but it does indeed wait for the next keypad input, and without the loop being in there, it starts spinning the servo nonstop as soon as I press "1".

The { and } define the range of instructions to execute. Under some circumstances, you want to do nothing in the body of the while loop. Your situation is a case in point.

So, what you want is:

while(keypad.getKey() != 2)
{
}

The loop; statement is not doing what you think it is doing, and should be removed, for all your while bodies.

Just updated to the format quoted above, and it works just the same. I'll be sure to use that form in the future rather than loop, like I said I've only been at this a couple of days :smiley:

@Bindrelie

So, after fiddling more with the password library, I got frustrated

What kind of problems were you having with the password library? I haven't used it, but it certainly seems like it ought to work.

So when you entered a correct code in a separate program it printed success.

And in another separate program you tested your servo.

But when put together they don't work.

If you're still having trouble, try this:
modify your code so when password is entered correctly it moves the servo.

In other words forget about trying to angle the servo correctly or tell it when to stop.

I say this because i recently found out continuous rotation servos cannot be controlled by angle, only speed and direction.

If you search "questions about servos" in the forum you would get more info. (Continuous rotation servos are NOT servos). :-[

Use Servo.h library to clean up your code a bit. It can be found on the Arduino website. For information on using that library with continuous servos see the forum I mentioned.