Mấy ngày trước mình đã đăng bài này nhưng có thay đổi về thiết kế sau khi làm phần cứng nên mình đã xóa đi và thiết kế lại. Thay đổi các vấn đề như sau:
Khóa điện mình tưởng là có lò xo. Nhưng khi lắp mới biết nó có hai hành trình đóng mở (thò ra thụt vào) khi đổi chiều dòng điện. Vậy nên bài hôm trc dùng 1 relay để đóng ngắt là k thể làm được. Mình đã thiết kế lại cầu H để điểu khiển chiều dòng điện. Mình dùng 4 con relay để làm cầu H cho nó đơn giản và dễ hiểu. Khóa điện này mua ở ngoài Minh Hà, chạy điện 9-12VDC. Bên Minh Hà có treo cái khóa này ở trên tường, nhưng họ đóng mở bằng RF điều khiển 4 con relays.
Mạch nguồn hôm trước dùng 7805 rất là nóng vì mạch này chạy liên tục 24/24h. Mình đã thay bằng 7805 bằng Lm2576 cho dòng lớn hơn, ổn định hơn và ít nóng hơn 7805
Tính năng:
Không reset password về mặc định ban đầu (1111) khi bị mất nguồn. Vì dữ liệu được lưu vào eeprom.
Có thể change pass bất kì lúc nào. Sau khi nhập pass từ keypad , ấn phím A để changepass, ấn phím 'Ok' ( * ). khi changepass, nhập hai lần password mới để xác nhận
Mật khẩu là một số tự nhiên từ 1-9999. Nếu nhập số quá 4 chữ số sẽ báo "Invalid Pass"
Tự động đóng băng hệ thống trong 1 khoảng thời gian sau khi nhập sai pass 4 lần.
Nhập số giống như trên điện thoại. Nhập sai 1 ký tự ấn phím 'Del' (#) để xóa kí tự vừa nhập. Ấn phím 'D' để xóa kí tự vừa nhập. Trong chế độ changepass có thể bấm phím 'B' để hủy change pass, thoát ra ngoài
Khi phím được ấn thì còi chip kêu 1 tiếng. Ngoài ra còn kêu 2 tiếng, 3 tiếng hoặc 4 tiếng tùy vào chức năng đang sử dụng
Mạch Nguyên lý:
Mạch nguồn:
Mạch cầu H (4 relays):
Mạch điều khiển:
Code: mình viết bằng avrstudio, các bạn xem file đính kèm bên dưới, nếu file project không mở được thì các bạn tạo project mới rồi add các file .c .h của mình vào là đc.
Hàm quét Keypad 4x4:
/*
* keypad.h
*
* Created: 15/05/2014 4:10:46 SA
* Author: LeThanhTung
*/
#ifndef KEYPAD_H_
#define KEYPAD_H_
#include <avr/io.h>
#include <util/delay.h>
#define KEYPAD_DDR DDRD
#define KEYPAD_PORT PORTD
#define KEYPAD_PIN PIND
uint8_t scan_code[4]={0x0E,0x0D,0x0B,0x07};
uint8_t ascii_code[4][4]={ {'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'},};
uint8_t GetKeyPressed()
{
//---khai bao huong cho cac chan ket noi keypad
KEYPAD_PORT=0x0F; //*
KEYPAD_DDR=0xF0; //*
//*********************************************
uint8_t i,j,keyin;
for(i=0;i<4;i++)
{
KEYPAD_PORT=0xFF-(1<<(i+4));
_delay_ms(40);
keyin=KEYPAD_PIN & 0x0F;
if(keyin!=0x0F)
for(j=0;j<4;j++)
if(keyin==scan_code[j]) return ascii_code[j];
}
return 0;
}
#endif /* KEYPAD_H_ */
Hàm đóng mở relays để bật tắt và đổi chiều dòng điện:
/*
* relay.h
*
* Created: 21/05/2014 9:41:14 CH
* Author: LeThanhTung
*/
#ifndef RELAY_H_
#define RELAY_H_
#include <avr/io.h>
#define Relay_PORT PORTC
#define Relay_DDR DDRC
//mo
void open()
{ Relay_PORT =0x21; //treo cao pin 0 va 5
_delay_ms(500);
Relay_DDR =0x21; //pin pC0 pc5 set la input
lcd_clrscr();
lcd_gotoxy(0,0);
lcd_puts("Open the door");
_delay_ms(50);
}
// dong cua (khoa day ra)
void close()
{ Relay_PORT =0x12; //treo cao pin 1 va 4
_delay_ms(500);
Relay_DDR =0x12; // pin pC4 pc1 set la output
lcd_clrscr();
lcd_gotoxy(0,0);
lcd_puts("Close the door");
_delay_ms(2000); // thoi gian du dai de khoa kip day ra
Relay_DDR =0x00;
Relay_PORT = 0x00; // off tat ca cac relay. de tiet kiem dien
}
#endif /* RELAY_H_ */
Xem thêm...
Khai báo giá trị mặc định ban đầu của pass:
uint16_t EEMEM pass1 = 1111;
Chương trình chính:
#include <avr/io.h>
#define F_CPU 12000000UL
#include <util/delay.h>
#include <avr/eeprom.h>
#include "lcd.h"
#include "keypad.h"
#include "relay.h"
#include "buzzer.h"
#include "user.h"
#include "changepass.h"
int main(){
uint16_t key2;
uint16_t number=0, i =0,l=0;
lcd_init(LCD_DISP_ON);
lcd_clrscr();
while(1)
{
lcd_gotoxy(0,0);
lcd_puts("Enter password: ");
key2=GetKeyPressed(); //doc keypad
//neu mot trong cac phim tu 0-9 dc bam thi giatri = giatri*10 +(key-48)
//vi du: gia tri =123. sau khi bam phim 1 (ma ascii la 49). giatri moi se la 123*10 +(49-48) =1231
if((key2=='0')||(key2=='1')||(key2=='2')||(key2=='3')||(key2=='4')||(key2=='5')||(key2=='6')||(key2=='7')||(key2=='8')||(key2=='9'))
{
_1beep();
number = ((number*10) + (key2-48));
i++;
if((i>4)||(i<0))
{
_delay_ms(300);
i=0;
number=0;
lcd_clrscr();
lcd_gotoxy(0,0);
_3beep();
lcd_puts("Invalid Pass"); //qua 4 chu so
_delay_ms(500);
}
else if ((i>0)&&(i<5))
{
lcd_gotoxy(i,1);
lcd_putc(42);
}
} //end of IF phim bam tu 0-9
//bam D de nhap lai tu dau. xoa gia tri
else if(key2 == 'D')
{
lcd_clrscr();
number = 0;
_1beep();
i=0;
}//end of Xoa gia tri
// bam # de xoa ki tu vua nhap sai. 1234->123
else if (key2=='#')
{
lcd_gotoxy(i,1);
lcd_puts(" ");
i--;
number = number/10;
_1beep();
} //end of Xoa gia tri
// bam * (OK) de so sanh gia tri nhap vao voi pass de mo cua
else if (key2=='*')
{
_1beep();
_delay_ms(300);
// neu gia tri nhao vao bang pass luu san trong eeprom, mo cua
if (number == eeprom_read_word(&pass1))
{
_2beep();
_delay_ms(50);
open(); // open the door
_delay_ms(10000); // sau 10s dong cua //xung 8mhz
_2beep();
_delay_ms(50);
close(); //close the door
number=0,
i =0;
l=0;
}
//neu gia tri khac pass luu san trong eeprom, khong cho mo cua
else if (number != eeprom_read_word(&pass1))
{
l++;
lcd_clrscr();
_3beep();
lcd_puts("wrong pass"); // pass sai
_delay_ms(500);
if (l>3)
{
lcd_clrscr();
lcd_gotoxy(0,0);
_4beep();
lcd_puts("NOT ALLOW IN 30sec");
_delay_ms(30000); // dong bang he thong sau 4 lan nhap sai pass
l=0;
lcd_clrscr();
_2beep();
}
number=0,
i =0;
}
}
// bam phim A de vao che do changpass
else if (key2=='A') //bam A changepass
{
_1beep();
_delay_ms(100);
//neu giatri nhap vao bang gia tri luu san trong epprom thi cho changepass
if (number == eeprom_read_word(&pass1))
{
change_pass();
lcd_clrscr();
number=0,
i =0;
l=0;
}// end of change pass
else if (number != eeprom_read_word(&pass1))
{
l++;
lcd_clrscr();
_3beep();
lcd_puts("Wrong pass");
_delay_ms(500);
if (l>3)
{
lcd_clrscr();
lcd_gotoxy(0,0);
_4beep();
lcd_puts("NOT ALLOW IN 30sec");
_delay_ms(30000); // dong bang he thong sau 4 lan nhap sai pass
l=0;
lcd_clrscr();
_2beep();
}
number=0,
i =0;
}
}//end of changepass
}//end of while(1)
}//end of ham main
Chương trình Changepass:
/*
* changepass.h
*
* Created: 22/05/2014 7:23:09 SA
* Author: LeThanhTung
*/
#ifndef CHANGEPASS_H_
#define CHANGEPASS_H_
#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include "lcd.h"
#include "keypad.h"
#include "relay.h"
#include "buzzer.h"
#include "user.h"
void change_pass()
{ uint16_t key1,m=0,n=0;
unsigned char flag1=1, flag2 =1;
int j=0,k=0;
lcd_clrscr();
while(flag1==1)
{
lcd_gotoxy(0,0);
lcd_puts("Input new pass:");
key1=GetKeyPressed();
if((key1=='0')||(key1=='1')||(key1=='2')||(key1=='3')||(key1=='4')||(key1=='5')||(key1=='6')||(key1=='7')||(key1=='8')||(key1=='9'))
{
_1beep();
n = ((n*10) + (key1-48));
j++;
if((j>4)||(j<0))
{
_delay_ms(300);
j=0;
n=0;
lcd_clrscr();
lcd_gotoxy(0,0);
_3beep();
lcd_puts("Invalid Pass"); //qua 4 chu so
_delay_ms(500);
}
else if ((j>0)&&(j<5))
{
lcd_gotoxy(j,1);
lcd_putc(42);
}
}
else if(key1 == 'D') // bam D de huy nhap so
{
lcd_clrscr();
n = 0;
_1beep();
j=0;
}
else if (key1=='#') // bam # de huy 1 chu so vua nhap sai
{
lcd_gotoxy(j,1);
lcd_puts(" ");
j--;
n = n/10;
_1beep();
}
else if (key1=='B') //huy check va change pass
{
_1beep();
j=0;
n=0;
flag1=0;
}
else if (key1=='*') //check lai pass 1 lan nua
{
_1beep();
lcd_clrscr();
while(flag2==1)
{
lcd_gotoxy(0,0);
lcd_puts("Input again:");
key1=GetKeyPressed();
if((key1=='0')||(key1=='1')||(key1=='2')||(key1=='3')||(key1=='4')||(key1=='5')||(key1=='6')||(key1=='7')||(key1=='8')||(key1=='9'))
{
_1beep();
m = ((m*10) + (key1-48));
k++;
if((k>4)||(k<0))
{
_delay_ms(300);
k=0;
m=0;
lcd_clrscr();
lcd_gotoxy(0,0);
_3beep();
lcd_puts("Invalid Pass");
_delay_ms(500);
}
else if ((k>0)&&(k<5))
{
lcd_gotoxy(k,1);
lcd_putc(42);
}
}
else if(key1 == 'D')
{
lcd_clrscr();
m = 0;
_1beep();
k=0;
}
else if (key1=='#')
{
_1beep();
lcd_gotoxy(k,1);
lcd_puts(" ");
k--;
m = m/10;
}
else if (key1=='B') // huy check va change pass
{
_1beep();
j=0;
n=0;
flag2=0;
flag1=0;
}
else if (key1=='*') //bam OK
{
_1beep();
_delay_ms(300);
if (m == n)
{
lcd_clrscr();
lcd_puts("checked OK");
_2beep(); // neu check pass ok, se luu lai vao epprom va chuyen gia tri co ve 0=> thoat vong lap
_delay_ms(500);
eeprom_write_word(&pass1,m);
lcd_clrscr();
lcd_gotoxy(0,0);
lcd_puts("pass is changed");
_2beep();
_delay_ms(500);
lcd_clrscr();
flag2=0; //thoat vong lap check
flag1=0; //thoat ham change
}
else if(m != n)
{
lcd_clrscr();
lcd_puts(" checked Wrong"); // check pass sai, quay lai vong lap
m=0;
_3beep();
k=0;
flag2 =1; //lap lai check
flag1=1; //lap lai change
_delay_ms(500);
lcd_clrscr();
}
} //end of '*'
} //end while
}// end of check
} //end of change
} //thoat ham change
#endif /* CHANGEPASS_H_ */
Ngoài ra còn có thêm chương trình cho LCD và Còi chip, các bạn xem chi tiết trong file đính kèm.
PCB: mình thiết kế thành hai board: 1 board 1 lớp gồm mạch nguồn và 4 relays, 1 board 2 lớp gồm chip at8, keypad, lcd, jump, conector
board nguồn
2. Board điều khiển:
Mặt trên:
Mặt dưới
Linh Kiện:
Vi xử lý: atmega8, lcd 16x2, biến trở 3 chân 10k , buzzer 5V, led 3mm, diode dán ss43, tụ 103 dán 0805, tụ 104 dán 0805, trở 1k 330 Ohm dán, jump đực, jump cái, jump isp, header4 + dây 4, khóa điện.
IC nguồn 2576T (5 chân thẳng TO 220-5), tụ 470uF/35V, tụ 1000uF, tụ 104, cuộn cảm 220uH, công tắc nhấn 6 chân, jack DC IN, Relay 5v 10A, transistor npn ECB C1815, led 3mm, trở 330, header 4, header 2.
Video: vì mạch in mình đặt chưa được lấy nên mình cắm tạm lên boardtest trước
p/s: Lần này đăng chắc là hoàn chỉnh rồi, test không thấy có lỗi nữa. Ở board mạch relay và nguồn có 1 dây phải câu lên trên. mình định thêm mấy con diode chống dòng ngược nữa nhưng k thiết kế nổi 1 mặt, thực nghiệm thì thấy dòng ngược không bị ảnh hưởng nhiều ( khi tắt relays thì có thấy khóa điện "rung rinh" :).
Bên dưới mình đính kèm file bao gồm code, file thiết kế altium, một số screenshot. Riêng về khoản mô phỏng Proteus thì mình k biết mô phỏng có giá trị ban đầu của epprom như thế nào, toàn lỗi thôi. Với lại mình có kit ATmega8 rồi nên k cần dùng mô phỏng, cứ làm đến đâu thì nạp thẳng vào kit để test.
Cảm ơn mọi người đã quan tâm. Bạn nào có góp ý gì thì cứ đưa ra mình sẽ vui vẻ đón nhận :))
Nếu có sai sót gì thì báo mình luôn nhé :)
( Code compiler + Schematic + Simulation)
Khi nhấn nút "Tải Về Máy", bạn sẽ vào trang quảng cáo, vui lòng chờ 5 giây. Nút hiện ra ở góc phải phía trên, nhấn vào để đến trang download
( Code compiler + Schematic + Simulation)
Khi nhấn nút "Tải Về Máy", bạn sẽ vào trang quảng cáo, vui lòng chờ 5 giây. Nút hiện ra ở góc phải phía trên, nhấn vào để đến trang download
Theo xaxa9zt7 ( codientu.org)
thank you
Trả lờiXóa