|
|
View previous topic :: View next topic |
Author |
Message |
lcs87
Joined: 07 Jul 2010 Posts: 6
|
assistance required in magnetic reed switch and push button |
Posted: Wed Jul 07, 2010 8:37 am |
|
|
Hi, recently I build a security system which involves locking, unlocking, and password changing with the use of PIC16F877A. The code for the software goes quite well, until when I try to add in a magnetic reed switch to detect intruders and a push button to bypass the password entry to unlock.
The problems that I am facing is, the switch kept on detecting a breach even when I get the magnet close to the switch. The push button is not behaving normally as well, sometimes words from other function just come out when I press it. I believe it has something to do with the bouncing of the switch, in which I could not solve.
Below is the picture of how I attach the switch and button.
Below is the code that I have written, it is quite messy and redundant, because my knowledge in C is very very limited.
Code: |
#include <16F877a.h> //PIC utilizado
#fuses HS,NOWDT,NOPROTECT,NOLVP //Configuramos los fuses
#use delay (clock=4000000) //Oscilador a 4Mhz
#INCLUDE "lcd.c" //Incluyo LCD.C
#define use_portb_kbd TRUE
#INCLUDE "kbd.c"
#include "switch.h"
#include "switch.c"
void menu(void);
void unlock(void);
void lock(void);
void change(void);
void security(void);
void solelock(void);
int counter=0;
char c=0;
char keyin[5];
char stored[5]= "1234";
int lock_state=1;
void main(void)
{
set_tris_C(0b00001010);
port_b_pullups(TRUE);
kbd_init();
lcd_init();
menu();
}
void menu(void)
{
while(TRUE){
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("1. lock door");
lcd_gotoxy(1,2);
lcd_putc("2. unlock door");
delay_ms(2000);
lcd_putc('\f');
lcd_putc("3. change PW");
delay_ms(2000);
//while(TRUE){
do{
if(lock_state==0){
if(input(PIN_C1)==1){
//delay_ms(500);
security();
break;
}
}
else{
if(input(PIN_C3)==0){
solelock();
break;
}
}
c=kbd_getc();
}while(c==0);
if(c=='1'){
lock();
}
else if(c=='2'){
unlock();
}
else if(c=='3'){
change();
}
}
}
//}
void lock(void)
{
lcd_putc('\f');
//if(input(PIN_C1)==0){
if(lock_state==0){
//if(input(PIN_C1)==0){
if(input(PIN_C3)==1){
lcd_gotoxy(1,1);
lcd_putc("already locked");
delay_ms(2000);
//security();
}
}
//}
//else{
if(lock_state==1){
//if(input(PIN_C1)==0){
//if(input(PIN_C3)==1){
lcd_gotoxy(1,1);
lcd_putc("locked");
output_low(PIN_C4);
delay_ms(2000);
lock_state = 0;
//security();
}
//}
//}
//}
}
void security(void){
if(lock_state==0){
if(input(PIN_C1)==1){
//if(input(PIN_C3)==1){
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("intruder!!");
lcd_gotoxy(1,2);
lcd_putc("2. disable??");
while(TRUE){
do{
c=kbd_getc();
}while(c==0);
if(c=='2'){
unlock();
break;
}
}
}
}
}
//}
void unlock(void)
{
lcd_putc('\f');
if(lock_state==1){
//if(input(PIN_C1==0)){
if(input(PIN_C3==1)){
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("already unlock");
delay_ms(2000);
}
}
//}
//if(input(PIN_C3)==0){
//if(input(PIN_C1)==0){
//if(lock_state==0){
//delay_ms(1000);
//lcd_putc('\f');
//lcd_putc("unlocked11");
//output_high(PIN_C4);
//lock_state = 1;
//delay_ms(2000);
//}
//}
//}
if(input(PIN_C3)==1){
//if(input(PIN_C1)==1){
if(lock_state==0){
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("password:");
lcd_gotoxy(1,2);
while(TRUE)
{
do{
c=kbd_getc();
}while(c==0);
if(c=='0'){
lcd_putc("*");
keyin[counter]='0';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='1'){
lcd_putc("*");
keyin[counter]='1';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='2'){
lcd_putc("*");
keyin[counter]='2';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='3'){
lcd_putc("*");
keyin[counter]='3';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='4'){
lcd_putc("*");
keyin[counter]='4';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='5'){
lcd_putc("*");
keyin[counter]='5';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='6'){
lcd_putc("*");
keyin[counter]='6';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='7'){
lcd_putc("*");
keyin[counter]='7';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='8'){
lcd_putc("*");
keyin[counter]='8';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='9'){
lcd_putc("*");
keyin[counter]='9';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
}
if(keyin[1]==stored[1]&&keyin[2]==stored[2]&&keyin[3]==stored[3]&&keyin[4]==stored[4]){
solelock();
}
else{
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("wrong");
delay_ms(2000);
}
}
}
//}
//}
}
void change(void){
lcd_putc('\f');
lcd_gotoxy(1,1);
if(input(PIN_C3)==1){
if(input(PIN_C1)==0){
if(lock_state==0){
lcd_putc("unlock first!");
delay_ms(2000);
}
//}
//if(input(PIN_C1)==0){
else if(lock_state==1){
lcd_putc("new password:");
lcd_gotoxy(1,2);
while(TRUE)
{
do{
c=kbd_getc();
}while(c==0);
if(c==0){
lcd_putc("*");
stored[counter]='0';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='1'){
lcd_putc("*");
stored[counter]='1';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='2'){
lcd_putc("*");
stored[counter]='2';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='3'){
lcd_putc("*");
stored[counter]='3';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='4'){
lcd_putc("*");
stored[counter]='4';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='5'){
lcd_putc("*");
stored[counter]='5';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='6'){
lcd_putc("*");
stored[counter]='6';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='7'){
lcd_putc("*");
stored[counter]='7';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='8'){
lcd_putc("*");
stored[counter]='8';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='9'){
lcd_putc("*");
stored[counter]='9';
counter=counter+1;
if (counter==4){
counter = 0;
break;
}
}
}
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("new password");
lcd_gotoxy(1,2);
lcd_putc("changed");
delay_ms(2000);
lock_state = 1;
}
}
}
}
void solelock(void){
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("unlocked");
lock_state = 1;
output_high(PIN_C4);
delay_ms(2000);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 07, 2010 12:52 pm |
|
|
Quote: |
I believe it has something to do with the bouncing of the switch, in which
I could not solve.
|
Strip the program down in size, so it's easier to debug. Just have it do
a small number of things (1 or 2 features). Get rid of 90% of the code.
For example, just put the code to detect if the switch is open or closed.
Then maybe turn on an LED, or display a message to show the status
of the switch. Get that code working reliably.
If you still have problems, then post the complete (small) program.
Also post your compiler version. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Jul 07, 2010 1:34 pm |
|
|
Try putting a 0.1uF cap from Pin 0 to 0V for each of your switches. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
lcs87
Joined: 07 Jul 2010 Posts: 6
|
|
Posted: Wed Jul 07, 2010 5:12 pm |
|
|
First off, I would like to thank you all for the reply, I will try to isolate the switch part. I will update with the latest result later.
edit:i think my compiler is ver4.068 |
|
|
lcs87
Joined: 07 Jul 2010 Posts: 6
|
|
Posted: Wed Jul 07, 2010 5:42 pm |
|
|
update: I tried the push button. It worked inconsistenly, sometimes it just run off to another function, displaying other output from other functions, but the magnetic reed is still having some problem. I have a input high even when I have the magnet to close the reed switch. I'm also having a problem in the unlock part, the asking for password sometimes does not appear. It seem there might be bouncing issue too. Advices please.
Code: |
#include <16F877a.h> //PIC utilizado
#fuses HS,NOWDT,NOPROTECT,NOLVP //Configuramos los fuses
#use delay (clock=4000000) //Oscilador a 4Mhz
#INCLUDE "lcd.c" //Incluyo LCD.C
#define use_portb_kbd TRUE
#INCLUDE "kbd.c"
#include "switch.h"
#include "switch.c"
void menu(void);
void unlock(void);
//void lock(void);
//void change(void);
void security(void);
void solelock(void);
int counter=0;
char c=0;
char keyin[5];
char stored[5]= "1234";
int lock_state=1;
void main(void)
{
set_tris_C(0b00001010);
port_b_pullups(TRUE);
kbd_init();
lcd_init();
menu();
}
void menu(void)
{
while(TRUE){
lock_state=0; //always in lock state.
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("1. lock door");
lcd_gotoxy(1,2);
lcd_putc("2. unlock door");
delay_ms(2000);
lcd_putc('\f');
lcd_putc("3. change PW");
delay_ms(2000);
//while(TRUE){
do{
if(lock_state==0){
if(input(PIN_C1)==1){ //pin_c1 is the input port listening to reed switch
//delay_ms(500);
security();
break;
}
else{
if(input(PIN_C3)==0){ //pin_c3 is the push button input.
solelock();
break;
}
}
}
c=kbd_getc(); //ignore this, this is for the keypad.
}while(c==0);
}
}
void security(void){ //always go to this line when i reattach the magnetic
if(lock_state==0){ //reed switch, even when the switch is closed.
if(input(PIN_C1)==1){
//if(input(PIN_C3)==1){
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("intruder!!");
lcd_gotoxy(1,2);
lcd_putc("2. disable??");
while(TRUE){
do{
c=kbd_getc();
}while(c==0);
if(c=='2'){
unlock();
break;
}
}
}
}
}
//}
void solelock(void){ //initiate locking mechanism
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("unlocked");
lock_state = 1;
output_high(PIN_C4);
delay_ms(2000);
}
void unlock(void)
{
lcd_putc('\f');
if(lock_state==1){
//if(input(PIN_C1==0)){
if(input(PIN_C3==1)){
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("already unlock");
delay_ms(2000);
}
}
if(input(PIN_C3)==1){
//if(input(PIN_C1)==1){
if(lock_state==0){
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("password:");
lcd_gotoxy(1,2);
while(TRUE)
{
do{
c=kbd_getc();
}while(c==0);
if(c=='0'){
lcd_putc("*");
keyin[counter]='0';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='1'){
lcd_putc("*");
keyin[counter]='1';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='2'){
lcd_putc("*");
keyin[counter]='2';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='3'){
lcd_putc("*");
keyin[counter]='3';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='4'){
lcd_putc("*");
keyin[counter]='4';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='5'){
lcd_putc("*");
keyin[counter]='5';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='6'){
lcd_putc("*");
keyin[counter]='6';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='7'){
lcd_putc("*");
keyin[counter]='7';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='8'){
lcd_putc("*");
keyin[counter]='8';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='9'){
lcd_putc("*");
keyin[counter]='9';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
}
if(keyin[1]==stored[1]&&keyin[2]==stored[2]&&keyin[3]==stored[3]&&keyin[4]==stored[4]){
solelock();
}
else{
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("wrong");
delay_ms(2000);
}
}
}
//}
//}
}
|
|
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu Jul 08, 2010 1:58 am |
|
|
if(keyin[1]==stored[1]&&keyin[2]==stored[2]&&keyin[3]==stored[3]&&keyin[4]==stored[4])
char stored[5]= "1234";
You do know that arrays in C are zero based indexed, this means the first item is stored at [0] so:-
char stored[5]= "1234";
stored[0] == '1'
stored[1] == '2'
stored[2] == '3'
stored[3] == '4'
stored[4] == '\0'
Your conditional (if) statement above is wrong.
Also counter used to index keyin starts at 0 which is correct but doesn't match your if statement. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu Jul 08, 2010 2:05 am |
|
|
Also just to help you out the following:-
Code: |
if(c=='0'){
lcd_putc("*");
keyin[counter]='0';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='1'){
lcd_putc("*");
keyin[counter]='1';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='2'){
lcd_putc("*");
keyin[counter]='2';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='3'){
lcd_putc("*");
keyin[counter]='3';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='4'){
lcd_putc("*");
keyin[counter]='4';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='5'){
lcd_putc("*");
keyin[counter]='5';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='6'){
lcd_putc("*");
keyin[counter]='6';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='7'){
lcd_putc("*");
keyin[counter]='7';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='8'){
lcd_putc("*");
keyin[counter]='8';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
}
else if (c=='9'){
lcd_putc("*");
keyin[counter]='9';
counter = counter+1;
if (counter==4){
counter = 0;
break;
}
|
In your code can be reduced to
Code: |
if ((c >= '0') && (c <= '9'))
{
lcd_putc('*'); // Note the single quote.
keyin[counter++] = c;
if (counter == 4)
{
counter = 0;
break;
}
}
|
You can also simplify the code in change()
PS. Please post code which is indented as something like this is a major pain to read. |
|
|
lcs87
Joined: 07 Jul 2010 Posts: 6
|
|
Posted: Thu Jul 08, 2010 2:54 am |
|
|
thank for all the inputs, . it seems that after some checking, i found out that my reed switch is dead, and that is what been causing the problems. However, with the old issue solved, i now have a newer problem, it seem that when the reed switch is "on"(LOW input to the PIN_C1), the program is not responding to my keypad input, until i release it. 1 more question, does adding the one second delay before running "solelock()" function helps with the bounce of the switch?
Code: |
#include <16F877a.h> //PIC utilizado
#fuses HS,NOWDT,NOPROTECT,NOLVP //Configuramos los fuses
#use delay (clock=4000000) //Oscilador a 4Mhz
#INCLUDE "lcd.c" //Incluyo LCD.C
#define use_portb_kbd TRUE
#INCLUDE "kbd.c"
void menu(void);
void unlock(void);
void lock(void);
void change(void);
void security(void);
void solelock(void);
int counter=0;
char c=0;
char keyin[5];
char stored[5]= "1234";
int lock_state=1;
void main(void)
{
set_tris_C(0b00001010);
port_b_pullups(TRUE);
output_high(PIN_C4);
kbd_init();
lcd_init();
menu();
}
void menu(void)
{
while(TRUE){
//lock_state=0;
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("1. lock door");
lcd_gotoxy(1,2);
lcd_putc("2. unlock door");
delay_ms(2000);
lcd_putc('\f');
lcd_putc("3. change PW");
delay_ms(2000);
//while(TRUE){
do{
if((lock_state==0)&&(input(PIN_C1)==1)){
//if(input(PIN_C1)==1){
//delay_ms(1000);
security();
break;
}
//else{
if((lock_state==0)&&(input(PIN_C3)==0)){
delay_ms(1000); //one second delay before running the function
solelock();
break;
//}
}
//}
c=kbd_getc();
}while(c==0);
if(c=='1'){
lock();
}
else if(c=='2'){
unlock();
}
else if(c=='3'){
change();
}
}
}
//}
|
p/s: thanks Wayne_ your method definitely make my program shorter and easier to read.
Last edited by lcs87 on Thu Jul 08, 2010 4:18 am; edited 1 time in total |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu Jul 08, 2010 4:03 am |
|
|
It is still very dificult to read with no indentation and lots of commented lines.
Please tidy it up so we can have a look at it properly
Cheers. |
|
|
lcs87
Joined: 07 Jul 2010 Posts: 6
|
|
Posted: Thu Jul 08, 2010 4:20 am |
|
|
i edited the code above, i believe it was something to do with the 1st infinite loop. do i have to add a "else{" after the code below? or it will automatically go to the lower part when the condition are not fulfilled
Code: | //else{
if((lock_state==0)&&(input(PIN_C3)==0)){
delay_ms(1000); //one second delay before running the function
solelock();
break;
//}
}
//} |
edit: hmm, i found that when i completely rip off the reed switch only the program can accept input from the keypad.. weird. holding the magnet to the switch makes it hang at the part waiting for keypad to be pressed. |
|
|
lcs87
Joined: 07 Jul 2010 Posts: 6
|
|
Posted: Thu Jul 08, 2010 5:26 am |
|
|
latest update: it seem that there is a problem with the switch or something, i change the way the switch connect to the pin(5V-->10k resistor-->pin C1) and it magically worked. I do not know why, but it just work. I also substitute the broken magnetic switch with another push button, i think the magnetic reed switch and push button behave similiarly. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|