Hello! I have used all the analog and digital pins on my arduino. Is it okay to use digital pins 0 and 1 for the D4 and D5 of the LCD? And also can I just tie RW to the ground so that I can conserve one pin and therefore the code will be lcd {rs,en,d4,d5,d6,d7} = {5,4,0,1,2,3} instead of lcd {rs,rw,en,d4,d5,d6,d7}={5,6,4,0,1,2,3}?? Will it affect the behavior and functionality of the LCD? TIA!
D0 and D1 are used for serial communication. So if you sketch does not need serial communication with the computer you can use these pins like any other digital pin.
The standard lcd library does not use the RW pin, so you can ground it and save a pin with no adverse effects. You can use pins 0 and 1 as outputs to the LCD data pins if you don't need serial communications, but I wouldn't use them for the EN line because then the lcd would be receiving commands when the bootloader runs.
btw if you're short of pins, it's often possible use the LCD control pins (except EN) for other outputs at the same time; for example, driving a second lcd display, or driving the columns of a keypad matrix. This is because the lcd ignores the values on these pins until you pulse the EN pin.
Thanks for the information guys! I freed some analog pins but all digital pins are still used up! I still have questions though. By the way, I'm currently working on a project which is an password protected electronic vault that will use:
a. 16x2 lcd (used pins are: 5,4,0,1,2,3)
b. 4x3 keypad matrix(used pins are for rows: 11,6,7,9 and for columns: 10,12,8)
c. servo motor (cannot rotate 360 degrees.)
So here's my questions.
-
Is it okay to connect rs,en,d4,d5,d6 and d7 to analog pins a0,a1,a2,a3 and a4?
-
Should I connect the servo motor only to digital pins or analog pins or PWM? I have problem with this. I have it connected to A0 (pin 14), and whenever the sketch is done uploading to the board, the servo continuously rotating ( I mean like a knob) and the arduino keeps on restarting.
PLEASE somebody help me out. This is the code I got:
#include <Password.h>
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Servo.h>
Servo myservo;
int pos = 0;
LiquidCrystal lcd(5,4,3,2,1,0);
Password password = Password( "4321" );
const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3',},
{'4','5','6',},
{'7','8','9',},
{'*','0',' ',}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = {
11,6,7,9}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
10,12,8}; //connect to the column pinouts of the keypad
const int buttonPin = 7;
int buttonState = 0;
// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
#define ledPin 13
void setup(){
pinMode(buttonPin, INPUT);
lcd.begin(16, 2); //Enter password is not working either
lcd.print("Enter password"); //and I don't know why.
digitalWrite(ledPin, LOW); // sets the LED on
keypad.addEventListener(keypadEvent); //add an event listener for this keypad
keypad.setDebounceTime(250);
myservo.attach(14); //wtf!
}
void loop(){
keypad.getKey();
if(keypad.getKey()==NO_KEY)
{
lcd.setCursor(1,0);
lcd.print("Enter Password");
}
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
lcd.clear();
}
}
//take care of some special events
void keypadEvent(KeypadEvent eKey){
switch (keypad.getState()){
case PRESSED:
lcd.setCursor(0,1);
lcd.print(eKey);
switch (eKey){
case ' ':
guessPassword();
break;
default:
password.append(eKey);
}
}
}
void guessPassword(){
if (password.evaluate()){
digitalWrite(ledPin,HIGH); //activates garaged door relay
delay(500);
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(3); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=50; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(3); // waits 15ms for the servo to reach the position
}
digitalWrite(ledPin,LOW); //turns off door relay after .5 sec
lcd.setCursor(1,0);
lcd.print("VALID PASSWORD ");
password.reset(); //resets password after correct entry
delay(600);
lcd.clear();
lcd.setCursor(4,0);
lcd.print("Welcome!");
delay(2000);
lcd.clear();
}
else{
digitalWrite(ledPin,LOW);
lcd.setCursor(0,0);
lcd.print("INVALID PASSWORD ");
password.reset(); //resets password after INCORRECT entry
delay(600);
lcd.clear();
}
}
brutal_magnet:
- Is it okay to connect rs,en,d4,d5,d6 and d7 to analog pins a0,a1,a2,a3 and a4?
How are you proposing to connect 6 LCD pins to 5 Arduino pins? Yes you can use analog pins as digital outputs, so if you meant to include a5 as well, the answer is yes.
brutal_magnet:
2. Should I connect the servo motor only to digital pins or analog pins or PWM? I have problem with this. I have it connected to A0 (pin 14), and whenever the sketch is done uploading to the board, the servo continuously rotating ( I mean like a knob) and the arduino keeps on restarting.
I don't think it should matter what sort of pin you use. Try following this tutorial http://www.arduino.cc/en/Tutorial/knob then once you have got it working, change the pin to the one you want to use. If the Arduino keeps restarting, my guess is that you are running it from the +5v supplied by the Arduino and it is taking too much current.
How are you proposing to connect 6 LCD pins to 5 Arduino pins? Yes you can use analog pins as digital outputs, so if you meant to include a5 as well, the answer is yes.
Oops typo, a5 is included though.
I don't think it should matter what sort of pin you use. Try following this tutorial http://www.arduino.cc/en/Tutorial/knob then once you have got it working, change the pin to the one you want to use.
The knob example is working, having the servo connected to +5V.
If the Arduino keeps restarting, my guess is that you are running it from the +5v supplied by the Arduino and it is taking too much current.
In my project, both lcd and servo are connected to +5V. Do you mean I should only use +3.3V?
brutal_magnet:
In my project, both lcd and servo are connected to +5V. Do you mean I should only use +3.3V?
No, I mean that it might be better to power the servo from a different +5v supply. However, first you need to establish whether or not the Arduino keeps resetting if the servo is not connected to the Arduino. If it still does, then the problem is not caused by the servo taking too much current.
No, I mean that it might be better to power the servo from a different +5v supply. However, first you need to establish whether or not the Arduino keeps resetting if the servo is not connected to the Arduino. If it still does, then the problem is not caused by the servo taking too much current.
whenever I disconnect the servo, the arduino is not resetting, but when I put back the servo, it will keep resetting again and again. I've tried connecting the positive and negative of servo to an external source which is 6.28V having the other pin connected to A0 but it doesn't rotate even if I entered the correct password.
Regarding the password, I want to set a limitation for it wherein only 3 attempts can only be made. If the password entered is still incorrect after third attempt, the buzzer will be activated (yeah I'm going to add a buzzer). I'm thinking how am I going to code that?
delay(3); // waits 15ms for the servo to reach the position
If you are going to have comments that state the obvious, they should do so correctly.
keypad.getKey();
if(keypad.getKey()==NO_KEY)
{
Get a key that was pressed, but throw it away. Well, OK.
Regarding the password, I want to set a limitation for it wherein only 3 attempts can only be made. If the password entered is still incorrect after third attempt, the buzzer will be activated (yeah I'm going to add a buzzer). I'm thinking how am I going to code that?
You've got a block of code that checks whether the password was valid, and does one thing if it is, and something else if it isn't. It isn't rocket science to count how many times that something else is done.
brutal_magnet:
whenever I disconnect the servo, the arduino is not resetting, but when I put back the servo, it will keep resetting again and again. I've tried connecting the positive and negative of servo to an external source which is 6.28V having the other pin connected to A0 but it doesn't rotate even if I entered the correct password.
Did you remember to connect the negative side of that external 6.28v supply to Arduino ground?
Whew I'm done coding the "attempt" part and seems to be working fine. Thanks for reminding me about the comments, I always forgot change it everytime I change values. Oh well, I didn't connect the negative to the arduino, my fault. I'll try it now and see what happens.
Yey it is now working! Now I'd like to have a password for reset so the buzzer will be deactivated after entering a wrong password for the third attempt.
Is it possible to do this?
Password password = Password ("4321");
Password resetPass = Password ("1234");
//take care of some special events
void keypadEvent(KeypadEvent eKey){
switch (keypad.getState()){
case PRESSED:
lcd.setCursor(0,1);
lcd.print(eKey);
switch (eKey){
case ' ': guessPassword(); break;
default:
password.append(eKey);
resetPass.append(eKey);
}
}
}
Is it possible to do this?
Yes.
I'm having a hard time getting the 'reset' code working. Don't know what is wrong and I'm sleepy now. Be right back after I get some sleep.
void keypadEvent(KeypadEvent eKey){
switch (keypad.getState()){
case PRESSED:
lcd.setCursor(0,1);
lcd.print(eKey);
switch (eKey){
case ' ': guessPassword(); break;
default:
password.append(eKey);
resetPass.append(eKey);
}
}
}
void guessPassword(){
if (password.evaluate()){
digitalWrite(ledPin,HIGH); //activates garaged door relay
delay(500);
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(3); // waits 3ms for the servo to reach the position
}
for(pos = 180; pos>=50; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(3); // waits 3ms for the servo to reach the position
}
digitalWrite(ledPin,LOW); //turns off door relay after .5 sec
lcd.setCursor(0,0);
lcd.print(" VALID PASSWORD ");
password.reset(); //resets password after correct entry
delay(600);
lcd.clear();
lcd.setCursor(4,0);
lcd.print("Welcome!");
delay(1000);
lcd.clear();
counter=0;
}
else{
digitalWrite(ledPin,LOW);
lcd.setCursor(0,0);
lcd.print("INVALID PASSWORD ");
password.reset(); //resets password after INCORRECT entry
delay(600);
lcd.clear();
counter++;
if (counter==3)
{
lcd.clear();
digitalWrite(buzzerPin,HIGH);
lcd.setCursor(0,0);
lcd.print("Warning:Intruder");
delay(2000);
if (resetPass.evaluate()) // this should deactivate the buzzer
{
digitalWrite(buzzerPin,LOW);
counter = 0;
password.reset();
resetPass.reset();
}
}
}
}
If you were to put each { on a new line, and use Tools + Auto format, you would make your code a lot more readable, and see that you have a problem.
When password.evaluate() is called, in guessPassword() it returns either true or false. If the password entered was incorrect, counter is incremented, from 0 to 1.
Another incorrect password, and counter is incremented, from 1 to 2.
Another incorrect password, and counter is incremented, from 2 to 3. At 3, the buzzer is started, and the reset password tested. It contains the same value as the password that was entered, presumably the one to open the box, not the one to reset the system.
When the buzzer starts, you enter the reset password, which is not the enter password. So, password is not the enter password, so counter is incremented, from 3 to 4.
Since 4 is not 3, the reset password is not checked...
The if(counter == 3) statement needs to be if(counter >= 3), so that the reset password IS checked.
PaulS:
The if(counter == 3) statement needs to be if(counter >= 3), so that the reset password IS checked.
ok so I've made some changes to the code but it still the resetPass.evaluate() is not working :
if (counter>=3)
{
lcd.clear();
digitalWrite(buzzerPin,HIGH);
lcd.setCursor(0,0);
lcd.print("Warning:Intruder");
delay(2000);
password.reset(); //also tried without these
resetPass.reset(); // but still not working
delay(600);
if (resetPass.evaluate())
{
digitalWrite(buzzerPin,LOW);
counter = 0;
password.reset();
resetPass.reset();
}
}
Really have no idea why such a simple task for comparing password with strcmp() requires a class but take a look at this:
I can upload a new video with the buzzer and reset code in action tomorrow. Too late tonight.
You will need a phi-panel to do this though. If you have an LCD all you need is the back pack and the panel is on sale
Code:
char in_char[16]; // Buffer to store incoming characters
int response; // Stores whether the password is a match to the key
boolean auth=false; // Whether a user has passed the authencation with the right password
void setup()
{
Serial.begin(19600);
delay(500); // Make sure the panel is up and running.
}
void loop()
{
for (int i=3;i>0;i--)
{
Serial.print("Password:("); // Print the question
Serial.print(i); // Print number of trials left
Serial.println(")");
get_passwd(in_char); // Get password from user, which will be stored in in_char[].
response=strcmp(in_char, "072811"); // Compare the input with key "072811". 0 means match.
if (response==0)
{
auth=true;
break;
}
}
if (auth)
{
Serial.println("Correct!");
Serial.print("Opening door..");
delay(3000);
}
else
{
Serial.println("Incorrect!");
delay(1000);
Serial.print("Intruder alert");
while (1)
{
while (!Serial.available()) // wait for a key press
{
Serial.print("\eP~"); // just beeps a few times and repeat!
delay(125);
Serial.print("\eP~");
delay(125);
Serial.print("\eP~");
delay(125);
Serial.print("\eP~");
delay(250);
}
Serial.println("Reset alarm:");
get_passwd(in_char); // Get password from user, which will be stored in in_char[].
response=strcmp(in_char, "118207"); // Compare the input with alarm reset password. 0 means match.
if (response==0) return; // Restart the password process
else
{
Serial.println("Incorrect!");
delay(1000);
Serial.print("Intruder alert");
}
}
}
}
void get_passwd(char in_char[])
{
int i=0;
while(1) {
if (Serial.available()) {
in_char[i]=Serial.read(); // Read in one character
if (in_char[i]=='\n') { // The \n represents enter key.
in_char[i]=0; // Terminate the string with 0.
Serial.write('\n'); // New line
break; // This breaks out of the while(1) loop.
}
Serial.write('*'); // Echo * to hide user input
i++;
}
}
}
Only took 15 minutes to make the above program
resetPass.reset(); // but still not working
delay(600);
if (resetPass.evaluate())
{
Reset the contents of the object, then see if it contains what you expect. I can't imagine why that doesn't work.