Dynamic Bluetooth password lock

Keywords: Single-Chip Microcomputer stm32

The foregoing:
QQ: 961209458
V X: F9986858
Undertake graduation project.

function

1. Use the 4 * 4 matrix key to enter the password
2. Passwords can be generated regularly and randomly
3. There is an external EEPROM that can store passwords to prevent power loss
4. Connect the mobile phone to Bluetooth and input specific instructions to obtain the security problems of security protection (there are three security problems, which are obtained randomly)
5. Enter the answer to the security question and get the password (valid within 10 seconds)
6. Enter password to unlock
7. Unlock prompt tone (one ring), wrong password for three times (three rings, regenerate random password, and answer the security question again)

Hardware scheme

The hardware of the electronic password lock is shown in Figure 1 below. The mobile phone is connected to the Bluetooth module, the single chip microcomputer sends the security question through Bluetooth, and the mobile phone answers the answer. Input the password with the matrix key, count the time through the clock module, and display the time in real time in the non unlocked state. After regularly updating the password, the password will be stored in the external storage to prevent power loss. Display time and some human-computer interaction interfaces through OLED. The switch of the door is simulated and controlled by the electromagnetic lock.

Software design scheme

The software part of electronic password lock is divided into two parts, which are composed of bluetooth access password unlocking and fingerprint module unlocking. In the part of obtaining the password through Bluetooth, first, the mobile phone sends specific instructions through Bluetooth, and the MCU sends the security question. After the answer is correct, the password will be sent to the mobile phone through Bluetooth. At this time, it can be unlocked through the password. At the same time, the electronic code lock has the function of unlocking the fingerprint module. If the fingerprint identification is correct, it will also be unlocked. In the part of entering password, the dynamic password will be generated regularly and automatically, and the password will be saved in external storage. Moreover, even after entering the wrong password three times in a row, the password will be automatically regenerated, and you also need to answer the security question again.

Hardware circuit diagram


Some core codes

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "usart2.h"
#include "AS608.h"
#include "timer.h"
#include "oled.h"
#include "DS1302.h"
#include "key.h"
#include "myiic.h"
#include "24cxx.h" 
#include "adc.h"
#include "stm32f10x_adc.h"
#include <stdlib.h>
#include <time.h>

SysPara AS608Para;
u16 ValidN;

//Instruction: ADDFR add fingerprint
//Instruction: DELFR delete fingerprint
unsigned char FRIGER[6]={'A','D','E','L','F','R'};   //Add or delete fingerprint instructions
unsigned char Change_HC05[3]={'Z','X','C'};          //Modify Bluetooth password acquisition instruction
unsigned char HC05_PassWord[5]={'1','2','3','4','5'};//Initial Bluetooth password acquisition command
unsigned char PassWord[6]={1,2,3,4,5,6};//6-digit password
unsigned char PassBuffer[6]; //Enter temporary password
unsigned char PassWord_OK=0; //0 wrong password 1 correct password
unsigned char Pass_Count=0;  //Enter password digit count 0-5
unsigned char old_hour,new_hour;//Generate random password at the whole time

void Add_FR(void);	//Add fingerprint
void Del_FR(void);	//Delete fingerprint
void Pre_FR(void);  //Compare fingerprints
void Time_Display(void);   //Time display
void Enter_Password(void); //Input password
void Check_HC05(void);     //Check Bluetooth for new password command
void Send_Time(void);      //Serial port sending time
void Generate_Password(void);//Regenerate random password

int main(void)
{
	u8 AS608_Time_Count;//Handshake time with fingerprint module: the technical time interval is 1 second, totaling 5 times
	delay_init();  	    //Initialization delay function
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//Set system interrupt priority group 2
	OLED_Init();        //OLED initialization
	uart_init(115200);	//The baud rate of initialization serial port 1 is 115200, which is used to support USMART
	usart2_init(57600); //Initialize serial port 2 for communication with fingerprint module
	PS_StaGPIO_Init();	//Initialize FR read status pin fingerprint module status pin
	DS1302_Init();      //Clock chip initialization
	KEY_Init();         //Matrix key and buzzer initialization
	Adc_Init();		  	//ADC initialization
	OLED_ShowString(0,0,"Wait Sys Init...",16);delay_ms(500);
	OLED_ShowString(0,2,"ShakHands...    ",16);delay_ms(500);
	while(PS_HandShake(&AS608Addr))//Handshake with fingerprint module
	{delay_ms(1000);if(++AS608_Time_Count>=5) break;}
	if(AS608_Time_Count<5) OLED_ShowString(0,4,"Connect Success!",16);
	else                   OLED_ShowString(0,4,"Connect Fail!   ",16);
	delay_ms(1000);
	if(AS608_Time_Count<5) OLED_ShowString(0,6,"Sys Init Success",16);
	else                   OLED_ShowString(0,6,"AS608 Init Fail!",16);
	delay_ms(1000);AS608_Time_Count=0;
	AT24CXX_Init();//EEPROM initialization AT24C02
	//AT24CXX_Write(1,PassWord,6);// Deposit
	AT24CXX_Read(1,PassWord,6);//Read saved password
	TIM4_Int_Init(99,7199);	   //10ms interrupt
	OLED_Clear();              //Complete initialization screen clearing
	while(1)
	{		
		Time_Display();  //Time display
		Enter_Password();//Input password
		Pre_FR();        //Contrast fingerprint
		Generate_Password();//Regenerate random password
		Check_HC05();    //Compare Bluetooth to obtain password instructions
	}
}
//Regenerate random password
void Generate_Password()
{
	char i;
	u16 adcx;
	old_hour=new_hour;
	new_hour=TIME[4];
	if(old_hour!=new_hour)//Arrive at hour Sharp
	{
		for(i=0;i<6;i++)
		{
			adcx=Get_Adc_Average(ADC_Channel_8,3);//Get ADC value
			srand(adcx);//Using adcx as seed
			PassWord[i] = rand() % 9;//Generate random integers from 0 to 9
			delay_ms(5);
		}
		AT24CXX_Write(1,PassWord,6);//Save new password
	}
}
//Parsing Bluetooth instructions
void Check_HC05()
{	
	char i;
	u16 mibao_num;
	u8  mibao_dat;
	if(Receive_Flag==1)
	{
		Receive_Flag=0;Receive_sum=0;
		//Whether to modify the password acquisition instruction
		if((USART_ReceiveString[0]==Change_HC05[0])&&
		   (USART_ReceiveString[1]==Change_HC05[1])&&
		   (USART_ReceiveString[2]==Change_HC05[2]))
		{
			/*
			for(i=0;i<5;i++) HC05_PassWord[i]=USART_ReceiveString[i+3];
			Send_Time();printf("Modify instruction successfully!!!\r\n");
			printf("Your instruction is:%c%c%c%c%c\r\n\r\n",HC05_PassWord[0],
			HC05_PassWord[1],HC05_PassWord[2],HC05_PassWord[3],HC05_PassWord[4]);
			*/
			mibao_num=Get_Adc_Average(ADC_Channel_8,3);//Get ADC value
			srand(mibao_num);//Using adcx as seed
			mibao_dat = rand() % 3;//Generate random integers from 0 to 9
			Send_Time();
			if(mibao_dat==0) 
			{
				printf("What is your Phone number?\r\n\r\n");
				HC05_PassWord[0] = '1';
				HC05_PassWord[1] = '3';
				HC05_PassWord[2] = '8';
				HC05_PassWord[3] = '9';
				HC05_PassWord[4] = '1';
			}
			if(mibao_dat==1) 
			{
				printf("What is your QQ number?\r\n\r\n");
				HC05_PassWord[0] = '2';
				HC05_PassWord[1] = '6';
				HC05_PassWord[2] = '4';
				HC05_PassWord[3] = '3';
				HC05_PassWord[4] = '7';
			}
			if(mibao_dat==2) 
			{
				printf("What is your birthday number?\r\n\r\n");
				HC05_PassWord[0] = '9';
				HC05_PassWord[1] = '9';
				HC05_PassWord[2] = '5';
				HC05_PassWord[3] = '2';
				HC05_PassWord[4] = '0';
			}
			
		}
		//Add fingerprint instruction
		else if((USART_ReceiveString[0]==FRIGER[0])&&
				(USART_ReceiveString[1]==FRIGER[1])&&
			    (USART_ReceiveString[2]==FRIGER[1])&&
				(USART_ReceiveString[3]==FRIGER[4])&&
			    (USART_ReceiveString[4]==FRIGER[5]))
		
				{Add_FR();}//Add fingerprint
				
		//Delete fingerprint instruction
		else if((USART_ReceiveString[0]==FRIGER[1])&&
			    (USART_ReceiveString[1]==FRIGER[2])&&
			    (USART_ReceiveString[2]==FRIGER[3])&&
		        (USART_ReceiveString[3]==FRIGER[4])&&
			    (USART_ReceiveString[4]==FRIGER[5]))
					
				{Del_FR();}//Delete fingerprint
		
		else//Compare and obtain password instruction
		{
			for(i=0;i<5;i++)
			{
				if(USART_ReceiveString[i]!=HC05_PassWord[i])
				{
					Send_Time();printf("Getting Password Command Error\r\n\r\n");
					for(i=0;i<12;i++) USART_ReceiveString[i]=0;
					USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//Open serial port to accept interrupt
					break;
				}
				if(i==4)
				{
					Send_Time();
					printf("Password: %d %d %d %d %d %d\r\n\r\n",
					PassWord[0],PassWord[1],PassWord[2],PassWord[3],PassWord[4],PassWord[5]);
				}
			}
		}
		for(i=0;i<12;i++) USART_ReceiveString[i]=0;
		USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//Open serial port to accept interrupt
	}
}

void Send_Time()
{
	printf("Time: %d%d%d%d-%d%d-%d%d  %d%d:%d%d:%d%d\r\n",
	DS1302_Time[0],DS1302_Time[1],DS1302_Time[2],DS1302_Time[3],DS1302_Time[4],
	DS1302_Time[5],DS1302_Time[6],DS1302_Time[7],DS1302_Time[8],DS1302_Time[9],
	DS1302_Time[10],DS1302_Time[11],DS1302_Time[12],DS1302_Time[13]);
}

//Input password
void Enter_Password()
{
	char i;
	
	/*-Matrix key scan-*/
	KEY_Scan();
	
	/*-------------------------Press the key to enter the password-------------------------*/
	//Number 0-9
	if((Key_Number==11)&&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=0;Pass_Count++;}
	if((Key_Number==1 )&&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=1;Pass_Count++;}
	if((Key_Number==2 )&&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=2;Pass_Count++;}
	if((Key_Number==3 )&&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=3;Pass_Count++;}
	if((Key_Number==4 )&&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=4;Pass_Count++;}
	if((Key_Number==5 )&&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=5;Pass_Count++;}
	if((Key_Number==6 )&&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=6;Pass_Count++;}
	if((Key_Number==7 )&&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=7;Pass_Count++;}
	if((Key_Number==8) &&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=8;Pass_Count++;}
	if((Key_Number==9) &&(PassWord_OK==0)&&(Pass_Count<6)) {Key_Number=0;PassBuffer[Pass_Count]=9;Pass_Count++;}

	/*------------------------Compare the entered password------------------------*/
	if((Key_Number==12)&&(Pass_Count==6)&&(PassWord_OK==0))
	{
		Key_Number=0;Pass_Count=0;
		for(i=0;i<6;i++)//Compare 6-digit passwords
		{
			if(PassBuffer[i]!=PassWord[i])    //Password error
			{
				Send_Time();
				printf("Password is error.\r\n\r\n");
				OLED_ShowString(0,6,"Password Error  ",16);
				PassWord_OK=0;Pass_Count=0;
				BEEP_ON();delay_ms(1000);BEEP_OFF();
				OLED_ShowString(0,6,"                ",16);
				OLED_ShowString(72,4,"      ",16);break;
			}
			if(i==5)                          //The password is correct
			{
				Send_Time();
				printf("Door is open by Password.\r\n\r\n");
				OLED_ShowString(0,6,"Password Right  ",16);
				PassWord_OK=1;Pass_Count=0;DOOR_ON();
				delay_ms(1000);delay_ms(1000);
				OLED_ShowString(0,6,"                ",16);
				OLED_ShowString(72,4,"      ",16);
			}
		}
	}
	/*------------------------Delete the entered password------------------------*/
	if(Key_Number==10)
	{
		Key_Number=0;
		if(Pass_Count>0) Pass_Count--;
		PassBuffer[Pass_Count]=0;//Clear
		OLED_ShowString(72+Pass_Count*8,4," ",16);//Write white space in deleted position
	}
	/*------------------------Displays the password entered------------------------*/
	OLED_ShowString(0,4,"Password:",16);
	for(i=0;i<Pass_Count;i++)
		OLED_ShowString(64+Pass_Count*8,4,"*",16);//Displays the password that has been entered* 
}

//Add fingerprint
void Add_FR(void)
{
	u8 i=0,ensure ,processnum=0;
	u16 ID;
	while(1)
	{
		switch (processnum)
		{
			case 0:
				i++;
				OLED_ShowString(0,6,"Touch finger!   ",16);//Please press your finger
				ensure=PS_GetImage();
				if(ensure==0x00) 
				{
					ensure=PS_GenChar(CharBuffer1);//Generating features
					if(ensure==0x00)
					{
						OLED_ShowString(0,6,"Fingerpr correct",16);//The fingerprint is correct
						i=0;
						processnum=1;//Skip to step two	
					}			
				}					
				break;
			
			case 1:
				i++;
				OLED_ShowString(0,6,"Touch again!!   ",16);	
				ensure=PS_GetImage();
				if(ensure==0x00) 
				{
					ensure=PS_GenChar(CharBuffer2);//Generating features			
					if(ensure==0x00)
					{
						OLED_ShowString(0,6,"Fingerpr correct",16);//The fingerprint is correct
						i=0;
						processnum=2;//Skip to step 3
					}	
				}	
				break;

			case 2:
				OLED_ShowString(0,6,"Compare fingerpr",16);//Compare the fingerprints twice
				ensure=PS_Match();
				if(ensure==0x00) 
				{
					OLED_ShowString(0,6,"Twice finge same",16);//The two fingerprints are the same
					processnum=3;
				}
				else 
				{
					OLED_ShowString(0,6,"Compare fail!!! ",16);
					i=0;processnum=0;
				}
				delay_ms(1000);
				break;

			case 3:

				OLED_ShowString(0,6,"Generate Success",16);//Created successfully
				delay_ms(1000);
				ensure=PS_RegModel();
				if(ensure==0x00) 
				{
					OLED_ShowString(0,6,"Save Success!!! ",16);//Fingerprint template generated successfully
					processnum=4;
				}else {processnum=0;}
				delay_ms(1000);
				break;
				
			case 4:	
				OLED_ShowString(0,6,"Please enter ID ",16);
				while((Key_Number==0)||(Key_Number>9))
				{KEY_Scan();}//Enter ID
				ID=Key_Number;Key_Number=0;
				ensure=PS_StoreChar(CharBuffer2,ID);//Save template
				if(ensure==0x00) 
				{
					Send_Time();
					OLED_ShowString(0,6,"Add success!!!! ",16);
					printf("Add fingerprint succeed!!!\r\n");
					printf("Dingerprint ID is:%d\r\n",ID);
					PS_ValidTempleteNum(&ValidN);
					delay_ms(1500);OLED_ShowString(0,6,"                ",16);
					return ;
				}
				else {processnum=0;}					
				break;				
		}
		delay_ms(800);
		if(i==5)
		{
			break;	
		}				
	}
}

//Contrast fingerprint
void Pre_FR(void)
{
	SearchResult seach;
	u8 ensure;
	if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)&&(PassWord_OK==0))
	{
		OLED_ShowString(0,6,"Search Finger...",16);delay_ms(1000);
		ensure=PS_GetImage();
		if(ensure==0x00)//Image acquisition succeeded 
		{	//Generating features
			ensure=PS_GenChar(CharBuffer1);
			if(ensure==0x00)//Feature generation succeeded
			{	//High speed search fingerprint database
				ensure=PS_HighSpeedSearch(CharBuffer1,0,300,&seach);
				if(ensure==0x00)//Search succeeded
				{
					PassWord_OK=1;
					OLED_ShowString(0,6,"Search Success!!",16);
					delay_ms(1000);DOOR_ON();
					Send_Time();printf("Door is open by Fingerprint.\r\n\r\n");
				}
				else //search failed
				{
					Send_Time();printf("Fingerprint is error.\r\n\r\n");
					OLED_ShowString(0,6,"Search Fail     ",16);
					BEEP_ON();delay_ms(1000);BEEP_OFF();
				}	
			}
			else //Feature generation failed
			{OLED_ShowString(0,6,"Generate Fail   ",16);delay_ms(1000);}	
		}
		else//Failed to get image
		{
			OLED_ShowString(0,6,"PS_GetImage Fail",16);
			BEEP_ON();delay_ms(1000);BEEP_OFF();
		}
		Pass_Count=0;
		OLED_ShowString(0,6,"                ",16);
		OLED_ShowString(72,4,"      ",16);
	}
}
//Delete fingerprint
void Del_FR(void)
{
	u8 ensure;
	ensure=PS_Empty();//Start delete delete
	if(ensure==0)//Delete succeeded
	{
		OLED_ShowString(0,6,"DEL FRIGER OK   ",16);
		Send_Time();printf("Delete fingerprint succeed!!!\r\n\r\n");
		delay_ms(1000);
		OLED_ShowString(0,6,"                ",16);
	}
}
//Time display
void Time_Display()
{
	DS1302_ReadTime();//Read time
	OLED_ShowNum(0,0, DS1302_Time[0],1,16);	 //Annual thousands
	OLED_ShowNum(8,0, DS1302_Time[1],1,16);  //Annual hundred
	OLED_ShowNum(16,0,DS1302_Time[2],1,16);	 //Ten in the year
	OLED_ShowNum(24,0,DS1302_Time[3],1,16);	 //Year bit
	OLED_ShowNum(40,0,DS1302_Time[4],1,16);	 //Month ten
	OLED_ShowNum(48,0,DS1302_Time[5],1,16);	 //Month bit
	OLED_ShowNum(64,0 ,DS1302_Time[6],1,16); //Day ten
	OLED_ShowNum(72,0, DS1302_Time[7],1,16); //Daily bit
	//OLED_ShowNum(106,0,DS1302_Time[14],1,16);// Zhou Shiwei
	OLED_ShowNum(114,0,DS1302_Time[15],1,16);//Week bit
	OLED_ShowNum(0,2 ,DS1302_Time[8],1,16);	 //Hour ten
	OLED_ShowNum(17,2,DS1302_Time[9],1,16);  //Hour bits
	OLED_ShowNum(49,2,DS1302_Time[10],1,16); //Ten minutes
	OLED_ShowNum(65,2,DS1302_Time[11],1,16); //Minute bits
	OLED_ShowNum(97,2, DS1302_Time[12],1,16);//Ten bits per second
	OLED_ShowNum(113,2,DS1302_Time[13],1,16);//Bits per second
	
	OLED_ShowString(32,0,"-",16);OLED_ShowString(56,0,"-",16);
	
	if(DS1302_Time[13]%2)
	{OLED_ShowString(33,2,":",16);OLED_ShowString(81,2,":",16); }
	else
	{OLED_ShowString(81,2," ",16); OLED_ShowString(33,2," ",16);}
}

void DS1302_Init(void)
{
	Ds1302_gpio_init();  //Port initialization
	DS1302_CE = 0;  DS1302_delay_us(2);
	DS1302_SCK = 0; DS1302_delay_us(2);

	Ds1302_writedata(0x8e,0x00); //Remove write protection and allow data to be written, 0x8e,0x00

	Ds1302_writedata(ds1302_year_add,TIME[1]);		//year
	Ds1302_writedata(ds1302_month_add,TIME[2]);	    //month
	Ds1302_writedata(ds1302_date_add,TIME[3]);		//day
	Ds1302_writedata(ds1302_hr_add,TIME[4]);		//Time
	Ds1302_writedata(ds1302_min_add,TIME[5]);		//branch
	Ds1302_writedata(ds1302_sec_add,TIME[6]);		//second
	Ds1302_writedata(ds1302_day_add,TIME[7]);		//week
	Ds1302_writedata(0x8e,0x80);//Turn on the write protection function to prevent data writing caused by interference.
	DS1302_ReadTime();//Read time
	new_hour=TIME[4];old_hour=new_hour;//Avoid regenerating the password every time you power on
}

void DS1302_ReadTime()
{
	TIME[1]=Ds1302_readdata(ds1302_year_add);		//year 
	TIME[2]=Ds1302_readdata(ds1302_month_add);		//month 
	TIME[3]=Ds1302_readdata(ds1302_date_add);		//day 
	TIME[4]=Ds1302_readdata(ds1302_hr_add);		    //Time 
	TIME[5]=Ds1302_readdata(ds1302_min_add);		//branch 
	TIME[6]=(Ds1302_readdata(ds1302_sec_add))&0x7f; //Second, mask the 7th bit of second to avoid exceeding 59
	TIME[7]=Ds1302_readdata(ds1302_day_add);		//week 
	
	
	DS1302_Time[0]=(TIME[0]>>4);   //Separate the Millennium
	DS1302_Time[1]=(TIME[0]&0x0F); //Separate the annual hundred 
	DS1302_Time[2]=(TIME[1]>>4);   //Separate the 10th place in the year
	DS1302_Time[3]=(TIME[1]&0x0F); //Separate year bits 

	DS1302_Time[4]=(TIME[2]>>4);   //Separate the tenth of the moon
	DS1302_Time[5]=(TIME[2]&0x0F); //Separate month bits 

	DS1302_Time[6]=(TIME[3]>>4);   //Separate the day ten
	DS1302_Time[7]=(TIME[3]&0x0F); //Separate the day bits 

	DS1302_Time[8]=(TIME[4]>>4);   //Separate out ten hours
	DS1302_Time[9]=(TIME[4]&0x0F); //Separate hour bits
	DS1302_Time[10]=(TIME[5]>>4);   //Separate ten minutes
	DS1302_Time[11]=(TIME[5]&0x0F); //Separate minute bits
	DS1302_Time[12]=(TIME[6]>>4);   //Separate ten bits per second
	DS1302_Time[13]=(TIME[6]&0x0F); //Separate bits
	
	DS1302_Time[14]=(TIME[7]>>4);   //Separate the week ten
	DS1302_Time[15]=(TIME[7]&0x0F); //Separate the weekly bits
}

Posted by melody on Tue, 09 Nov 2021 16:45:52 -0800