智能门锁项目总结

本文介绍了作者参与的智能门锁项目,通过Linux系统和C语言实现动态密码、远程开锁功能。项目采用ARM S5PV210开发板,通过短信服务和WiFi连接进行密码管理和开锁操作。作者主要负责数据处理、密码服务器交互和驱动程序调试。项目面临了进程通信、数据偏移等问题,使用fifo进行进程间通信。虽然存在不足,但作者从中获得了宝贵的实践经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

人们出行旅游住宿的话,住酒店是躲不过的,那么酒店的安全管理则愈发重要。本项目旨在打造一款模拟智能门锁产品,针对酒店服务。

需求分析

前期构思:

1、密码锁,动态生成密码

2、触摸屏输入密码,6位数密码

3、手机app填入手机号用短信接收密码

4、屏幕触碰显示,长不用息屏

5、密码可设置到期时间

6、门锁连WiFi

 

后期更改:

1、密码锁,前台发送设置动态密码

2、手机输入密码,6位数密码

3、手机web网页填入IP和短信接收到的随机密码

4、密码可设置到期时间

5、门锁连WiFi,开机自启程序

项目分工

同学A,查找相关资料,找到linux下与短信服务商的C接口,用作密码服务器,并发送给短信服务商发送短信。

同学B,在安卓手机上弄一个app,与云端linux服务器通信,进行用户信息传送。(后期改成了web)

我,处理数据,针对来自密码服务器的密码以及来自用户开锁的密码还有驱动程序进行处理和调试。

虚拟场景

设备及器材

ARM S5PV210开发板(装载linux系统)、linux虚拟机、阿里云linux、PC机、继电器、灯泡(前代替门锁)、手机

我的详细部分

接收来自服务端的字符串,判断其长度,若长度为9则将字符串分割成密码和天数(前六位为密码,后三位为天数)。密码和天数字符串传给等待开锁比对模块,并将天数与系统时间计算出有效期,过期则清空密码。板子服务端模块只需接收客户端给的字符串,如果为设置密码,则需要9个字符;如果为清空密码,则只需3个字符。(其中9个字符是“六位数密码加三位数时间”,例如"123456002";其中3个字符是“门牌号”,例如"001"。)

等待开锁比对模块则是控制驱动操控板子上的IO口(被人说过不安全), 也是,就一个IO口确实是有点简单了。

大致架构

本项目由两个服务器(1号密码短信服务器和2号用户服务器),门锁上一个“主进程”(main),两个“辅助进程”(c1, c2),用户手里一个app,前台一个app。后来发现我们弄的app只能在虚拟机上能连通云端,一放到手机上就没反应,找了很多资料也无法解决,有说是sdk等级太低,也有说手机系统等级过高。后来我决定采用web服务器的形式,将2号用户服务器用http实现,这样做的好处是甭管你是什么系统的什么端,手机也好电脑也罢,都可以实现和服务器的通信,做到了跨平台的效果。

通信过程最复杂的在于“门锁”上,由于会被随时更换密码的状况发生,那么有一个客户端程序必须一致待命接收1号服务器的信息,传给主程序,即用c1代替;2号服务器则是用户填入的密码,传给“门锁”上的c2接收,也传给主程序。它们之间用fifo通信,因此我把一个处理程序叫做“主程序”, 另外两个叫做“辅助程序”。

其实还有一个驱动程序,等待主程序中的模块来写入字符从而驱动开锁。

遇到的问题

在我负责的这一部分里遇到了许多问题。例如,如果只有一个进程的话,那么当客户端函数接收到服务器发来的消息后客户端函数就结束了,也就是说一运行程序只能收到一次消息,如果是每次执行完开锁后或者是密码输入错误后才跳转到客户端函数的话,这样就违背了即时性,因为服务器随时都可能给客户端发送消息。所以这里我需要把客户端函数分离出来,当成一个独立的进程,确切的说不能叫做独立的进程,因为进程本来就是独立的。

那么,有了客户端进程后,就可以随时接收服务器的讯息了。可是这样又衍生出一个新的问题,就是需要进行进程间通信,进程间通信有信号、管道、共享内存等方式,这里选择了命名管道fifo里来通信,因为fifo可以让两个没有半点关系的进程进行通信。好了,知道了用fifo之后更多的问题接踵而至,例如write是阻塞的,有一个注意事项就是要先开启write端的进程,也就是先开启客户端的进程,它会阻塞在write,如果read的进程没开的话。而一开始我就是纯粹用的read函数,没有加非阻塞,这我才意识到会出问题,必须让它非阻塞的读管道里的内容。

后续在读管道内容时,一旦更改密码多次之后会出现数据偏移情况,一直未能解决,所以这个fifo管道很让人捉摸不透。

代码详情

头文件:

/**
******************************************************************************
* @file    Func.h
* @author  邓子康
* @version V1.0
* @date    2018-05-02
* @brief   门锁头文件
******************************************************************************
**/
#ifndef __FUNC_H
#define __FUNC_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

int fdsocket;

void mybzero(char *str)
{
	bzero(str, sizeof(str));
	str[sizeof(str) - 1] = '\0';
}

#endif

门锁的主程序代码:

/**
******************************************************************************
* @file    main.c
* @author  邓子康
* @version V1.0
* @date    2018-05-02
* @brief   开锁主程序
******************************************************************************
**/
#include "Func.h"

void main()
{
	while(1)																 //无限循环(好像没什么用,不过嵌入式程序一般都是无限循环)
	{
		flag = 0;
		int ret = 0;														 //接收各模块的返回值,还有他用
		char *namer = "CtoP";												 //命名管道的名字(读端)读取客户端
		char *namew = "PtoS";												 //命名管道的名字(写端)写入“屏幕”
		ret = myfifo(namew, namer); 										 //创建管道并打开读、写管道
		if(ret != 0)														 //判断函数返回是否正确
		{
			printf("func myfifo() err: %d\n", ret);							 //不正确打印错误信息
			return;															 //结束程序
		}
		usleep(1000);														 //睡一下等待接收信息
		char buffer[10] = {0};												 //装载来自客户端的信息
		char buffptos[2] = {0}; 											 //发给屏幕的标志
		read(fdCtoP, buffer, sizeof(buffer));								 //读取客户端的信息给buffer
		
		char *pwd1 = NULL, *pwd2 = NULL, *day = NULL, *time = NULL;			 //pwd1:服务器密码 pwd2:来自屏幕的密码 day:天数 time:过期时间
		char buff[10] = {0}; 												 //装载服务器信息(备份,为了跳转)	
		
		pwd1 = (char *)malloc(pwdlen + 1);									 //开辟空间(+ 1是为了放'\0')
		pwd2 = (char *)malloc(pwdlen + 1);									 //同上
		day = (char *)malloc(dwdlen + 1);									 //同上
		time = (char *)malloc(30);											 //同上,装载时间的空间需要大一点
		
 loop:  																	 //loop标号
		ret = strlen(buffer);												 //ret这里是为了获
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值