基于STM32+JAVA宠物管理系统的设计与实现

【摘要】 本系统主要是由rfid自动识别技术,通过无线射频方式对宠物的电子标签进行读取,获取宠物的基本信息和在店内的所有消费,然后将数据通过网络传输至服务器。在应用层开发一个管理系统,对宠物信息、店内消费等各种行为进行管理。同时系统需有登录注册功能,宠物信息管理,店内消费管理等功能。
一、设计需求 本系统主要是由rfid自动识别技术,通过无线射频方式对宠物的电子标签进行读取,获取宠物的基本信息和在店内的所有消费,然后将数据通过网络传输至服务器。在应用层开发一个管理系统,对宠物信息、店内消费等各种行为进行管理。同时系统需有登录注册功能,宠物信息管理,店内消费管理等功能。
宠物店管理系统主要分为以下模块:
1.rfid模块:由天线和射频电路组成,通过自动识别电子标签,采集数据,采用rfid封装技术将其封装,并传输给服务器。
2.电子标签模块:接收外部信号和发送信号
3.店铺管理模块:管理员可以对店铺商品进行增删改操作,修改、删除顾客宠物信息以及店内消费行为。
4.登录注册模块:新用户可以进行注册和登录5.用户管理模块:对注册用户进行管理
二、设计需求总结 整个系统的设计:
(1). 宠物店每来一个新的宠物,就在软件端进行注册、注册时填入宠物的名称,宠物的类型,主人的电话号码、选择一张宠物的图片方便后面展示(图片可以预存几张猫、狗即可)、如果宠物后面在店里有消费也会记录包含时间,这些数据都保存在软件端的数据库里。
(2). 开卡: 新宠物注册之后,需要为这个宠物办理一张电子标签卡,这个卡里存放着这个宠物主人的电话号码,后面要查询这个宠物的信息,就读取整个电子标签里的电话号码,到数据库里查询。
(3). 开卡和查询的数据传输: 设备端与软件端采用 tcp网络方式进行通信;设备端当做tcp客户端,软件端当做tcp服务器;当设备端查询宠物的电子标签时,设备端读取电话号码之后,会通过约定的数据格式通过网络传递给软件端。 当软件端开卡注册时,也会用约定好的数据格式传递给设备端,如果设备端收到数据,开发板上的led会点亮;这时把ic拿到rc522射频模块上刷一下即可;如果成功写入led灯就会关闭。
(4). 软件端的设计(这个软件是给店家用的,功能都是针对店家这边方向开发):
有注册界面、登录界面;
主界面上显示店内有所有注册过的宠物信息,每个宠物有图片进行显示、宠物图片下面就显示宠物的名称;
商品界面: 展示一些狗粮、猫粮、药剂、一些宠物周边物品。 用于演示消费功能。 可以预定几个商品即可。 用户可以自己动态添加修改。
管理员界面: 可以对店内的商品进行添加、设计价格、修改宠物的信息等。
查询页面: 输入宠物信息可以查询这个宠物在店里的所有详细信息。
设备硬件部分:
这里的硬件刷卡部分采用的使用stm32开发的,更加灵活方便,完成对ic卡读写通过网络与java服务器通信,也可以换成扫码枪之类的其他设备。
\1. rc522刷卡模块负责对卡进行读写。
\2. esp8266wifi初始化工作在sta模式,连接到指定wifi,与软件所在的电脑处于同一个局域网,方便连接软件端的服务器进行数据通信,每次设备开机将会自动连接到程序里设置好wifi热点和服务器。
\3. 设备端上有一个led灯,用来显示刷卡的状态—成功与否。
三、硬件设备效果图与部分核心代码#include esp8266.hu8 esp8266_ip_addr[16]; //255.255.255.255u8 esp8266_mac_addr[18]; //硬件地址/*函数功能: esp8266命令发送函数函数返回值:0表示成功 1表示失败*/u8 esp8266_sendcmd(char *cmd){ u8 i,j; for(i=0;i<10;i++) //检测的次数--发送指令的次数 { usartx_stringsend(usart3,cmd); for(j=0;j<100;j++) //等待的时间 { delay_ms(50); if(usart3_rx_flag) { usart3_rx_buffer[usart3_rx_cnt]='\0'; usart3_rx_flag=0; usart3_rx_cnt=0; if(strstr((char*)usart3_rx_buffer,ok)) { return 0; } } } } return 1;}/*函数功能: esp8266硬件初始化检测函数函数返回值:0表示成功 1表示失败*/u8 esp8266_init(void){ //退出透传模式 usartx_stringsend(usart3,+++); delay_ms(50); return esp8266_sendcmd(at\r\n);}/*函数功能: 一键配置wifi为ap+tcp服务器模式函数参数:char *ssid 创建的热点名称char *pass 创建的热点密码 (最少8位)u16 port 创建的服务器端口号函数返回值: 0表示成功 其他值表示对应错误值*/u8 esp8266_ap_tcp_server_mode(char *ssid,char *pass,u16 port){ char *p; u8 i; char esp8266_sendcmd[100]; //组合发送过程中的命令 /*1. 测试硬件*/ if(esp8266_sendcmd(at\r\n))return 1; /*2. 关闭回显*/ if(esp8266_sendcmd(ate0\r\n))return 2; /*3. 设置wifi模式*/ if(esp8266_sendcmd(at+cwmode=2\r\n))return 3; /*4. 复位*/ esp8266_sendcmd(at+rst\r\n); delay_ms(1000); delay_ms(1000); delay_ms(1000); /*5. 关闭回显*/ if(esp8266_sendcmd(ate0\r\n))return 5; /*6. 设置wifi的ap模式参数*/ sprintf(esp8266_sendcmd,at+cwsap=\%s\,\%s\,1,4\r\n,ssid,pass); if(esp8266_sendcmd(esp8266_sendcmd))return 6; /*7. 开启多连接*/ if(esp8266_sendcmd(at+cipmux=1\r\n))return 7; /*8. 设置服务器端口号*/ sprintf(esp8266_sendcmd,at+cipserver=1,%d\r\n,port); if(esp8266_sendcmd(esp8266_sendcmd))return 8; /*9. 查询本地ip地址*/ if(esp8266_sendcmd(at+cifsr\r\n))return 9; //提取ip地址 p=strstr((char*)usart3_rx_buffer,apip); if(p) { p+=6; for(i=0;*p!='';i++) { esp8266_ip_addr[i]=*p++; } esp8266_ip_addr[i]='\0'; } //提取mac地址 p=strstr((char*)usart3_rx_buffer,apmac); if(p) { p+=7; for(i=0;*p!='';i++) { esp8266_mac_addr[i]=*p++; } esp8266_mac_addr[i]='\0'; } //打印总体信息 usart1_printf(当前wifi模式:ap+tcp服务器\n); usart1_printf(当前wifi热点名称:%s\n,ssid); usart1_printf(当前wifi热点密码:%s\n,pass); usart1_printf(当前tcp服务器端口号:%d\n,port); usart1_printf(当前tcp服务器ip地址:%s\n,esp8266_ip_addr); usart1_printf(当前tcp服务器mac地址:%s\n,esp8266_mac_addr); return 0;}/*函数功能: tcp服务器模式下的发送函数发送指令: */u8 esp8266_serversenddata(u8 id,u8 *data,u16 len){ u8 i,j,n; char esp8266_sendcmd[100]; //组合发送过程中的命令 for(i=0;i<10;i++) { sprintf(esp8266_sendcmd,at+cipsend=%d,%d\r\n,id,len); usartx_stringsend(usart3,esp8266_sendcmd); for(j=0;j)) { //继续发送数据 usartx_datasend(usart3,data,len); //等待数据发送成功 for(n=0;n))) { return 11; } //如果想要退出发送: +++ } //打印总体信息 usart1_printf(当前wifi模式:sta+tcp客户端\n); usart1_printf(当前连接的wifi热点名称:%s\n,ssid); usart1_printf(当前连接的wifi热点密码:%s\n,pass); usart1_printf(当前连接的tcp服务器端口号:%d\n,port); usart1_printf(当前连接的tcp服务器ip地址:%s\n,ip); return 0;}/*函数功能: tcp客户端模式下的发送函数发送指令: */u8 esp8266_clientsenddata(u8 *data,u16 len){ u8 i,j,n; char esp8266_sendcmd[100]; //组合发送过程中的命令 for(i=0;i<10;i++) { sprintf(esp8266_sendcmd,at+cipsend=%d\r\n,len); usartx_stringsend(usart3,esp8266_sendcmd); for(j=0;j)) { //继续发送数据 usartx_datasend(usart3,data,len); //等待数据发送成功 for(n=0;n 0) return resultdata.success(); return resultdata.fail(原始密码错误); } @postmapping(adduser.action) resultdata adduser(string token,@requestbody user user) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } user uu = (user) ss.getattribute(login_user); system.out.println( uu ); if( uu == null ) return resultdata.fail(请先登录!); if( !(admin.equalsignorecase(uu.getrole()) || root.equals( uu.getrole() ) ) ) { return resultdata.fail(请用管理员账号登录再添加); } um.adduser(user); return resultdata.success(); } @postmapping(delete.action) resultdata deleteuser(string token,@requestbody user user) { system.out.println( user); httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } user uu = (user) ss.getattribute(login_user); if( uu == null ) return resultdata.fail(请先登录!); if(admin.equalsignorecase(user.getrole()) || root.equals( user.getrole() )) return resultdata.fail(无法删除管理员用户!); if( !(admin.equalsignorecase(uu.getrole()) || root.equals( uu.getrole() ) ) ) { return resultdata.fail(请用管理员账号登录再删除); } um.deleteuser(user); return resultdata.success(); } @postmapping(getall.action) resultdata getall(string token) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } list list = um.getall(); for(user u:list) { u.setpassword(null); } return resultdata.success().setdata( list ); } @postmapping(logout.action) resultdata getalluser(string token) { httpsession ss = mysessioncontext.getsession( token ); if( ss != null ) { ss.invalidate(); } return resultdata.success(); } @postmapping(login.action) resultdata login(@requestbody user user,httpsession ss) { user rs = um.login( user ); if(rs != null ) { rs.setpassword( null ); ss.setattribute(login_user, rs ); mysessioncontext.addsession( ss ); return resultdata.success().setdata( rs ).settoken(ss.getid() ); }else { return resultdata.fail(用户名或密码错误!); } }},string>package com.common.wx;import org.springframework.web.socket.websocketsession;import org.springframework.web.socket.handler.textwebsockethandler;import com.common.bean.websocketproductholder;public class websocketserverservice extends textwebsockethandler{ @override public void afterconnectionestablished(websocketsession session) throws exception { websocketproductholder.setsession( session ); }} package com.common.bean;import java.io.ioexception;import java.net.serversocket;import java.net.socket;import org.springframework.beans.beansexception;import org.springframework.context.applicationcontext;import org.springframework.context.applicationcontextaware;import org.springframework.stereotype.component;import org.springframework.web.socket.textmessage;import org.springframework.web.socket.websocketsession;import com.alibaba.fastjson.jsonobject;import com.entity.product;import com.mapper.productmapper;@componentpublic class websocketproductholder implements applicationcontextaware{ private volatile static websocketsession onesession; private volatile static socket client; public websocketproductholder() { initserver(); } public static void setsession(websocketsession ss) { onesession = ss; } private static void initserver() { new thread() { public void run() { serversocket ss = null; try { ss = new serversocket(9988); system.out.println(初始化); while(true) { client = ss.accept(); byte [] b = new byte[128]; try { while(true) { int num = client.getinputstream().read(b);//数据少,一次读完就阻塞。 if(num != -1 ) { string cmd = new string(b,0,num); parsecmd( cmd); } } }catch (exception e) { system.out.println(连接断开...); } } }catch (exception e) { } } }.start(); } public static void register(string cardid)throws ioexception { if(cardid!=null && cardid.length() >0 && client!=null && client.isconnected()) { client.getoutputstream().write((register:+cardid+\r\n).getbytes()); } } private static void parsecmd(string cmd) { if(cmd.startswith(query)) { try { string cardid = cmd.split(:)[1].trim(); if( onesession != null ) { onesession.sendmessage( new textmessage( cardid ) ); } }catch (exception e) { system.out.println(数据错误:+cmd); } } } @override public void setapplicationcontext(applicationcontext applicationcontext) throws beansexception { initserver(); }} 商品名称商品价格商品数量商品分类商品描述商品图片提交 查询 当前共 {{datalist.length}} 件商品 商品编号商品名称商品分类商品价格商品数量商品图片操作 {{item.name}} {{item.sortname}} {{item.price|pricetext}} {{item.num}} 详情删除修改返回商品编号 {{detail.id}} 商品名称 {{detail.name}} 商品价格 {{detail.price|pricetext}} 商品数量 {{detail.num}} 商品分类 {{detail.sortname}} 商品描述 {{detail.detail}} 商品图片 商品名称商品价格商品数量商品分类商品描述商品图片提交
魅蓝note6什么时候上市?魅蓝note6配置参数汇总:魅蓝note6发布会倒计时,23日如期发布
Yoshua Bengio经验分享:聊 Bengio 的学术方法论和如何管理实验室
MWC2018:英特尔亮出了哪些5G杀手锏?
SiC工艺特点核心装备发展现状及趋势
74LS373在单片机接口的设计应用
基于STM32+JAVA宠物管理系统的设计与实现
国产512kbit串行SRAM----SCLPSRAC1
三星S8发布会汇总:三星S8配置、价格、颜值都是独具匠心!三星S8的优缺点抢先看
N倍压电路的工作原理
关于物联网定位技术最全面的解说
Eve推出采用IPS面板的240Hz刷新率27寸1440p显示器
中环半导体入选天津市制造业单项冠军企业名单
中国移动运营数据显示在有线宽带方面客户总数已达到1.5669亿户
STC89C52通过配置相关寄存器即可实现Timer的功能控制
TDK推出三款全新MEMS麦克风产品 突破了传统麦克风声学性能的界限
单片式降压型开关稳压器LT1938的性能特点及应用范围
基于MSP430和nRF905实现无线数传系统的设计
可学习编程的雪花状LED灯板设计
运用LabVIEW开发嵌入式系统的革新方式
3D打印的微型机器人问世,可以在生物体内运输细胞