CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

assistance required in magnetic reed switch and push button

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
lcs87



Joined: 07 Jul 2010
Posts: 6

View user's profile Send private message

assistance required in magnetic reed switch and push button
PostPosted: Wed Jul 07, 2010 8:37 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 07, 2010 12:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 07, 2010 1:34 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 07, 2010 5:12 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jul 07, 2010 5:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 1:58 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 2:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 2:54 am     Reply with quote

thank for all the inputs, Very Happy . 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

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 4:03 am     Reply with quote

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 Smile

Cheers.
lcs87



Joined: 07 Jul 2010
Posts: 6

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 4:20 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jul 08, 2010 5:26 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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