【摘要】 基于rfid的自动识别技术,通过无线射频方式实时获得磁卡对超市物品的电子标签进行读取,然后将数据通过网络传输至服务器,在应用层开发一个管理系统,对超市物品信息、店内消费等各种行为进行管理和显示。系统需有登录注册功能,商品的信息管理,付款等功能。
一、设计需求 基于rfid的自动识别技术,通过无线射频方式实时获得磁卡对超市物品的电子标签进行读取,然后将数据通过网络传输至服务器,在应用层开发一个管理系统,对超市物品信息、店内消费等各种行为进行管理和显示。系统需有登录注册功能,商品的信息管理,付款等功能。
拟解决的主要问题:
(1)使用rfid自动识别技术,对超市商品信息进行读取
(2) 将接受到的数据传输给服务器
(3)在应用层管理系统中对信息进行管理
(4) 管理员对整个后台系统的商品进行管理
二、设计需求总结 整个系统的设计:
(1). (管理员操作)超市每上架一个新产品时,就在软件端进行入库注册、注册时填入商品的名称、编号(可以使用uuid动态生成)、数量、价格、图片、数据都保存在软件端的数据库里。
(2). (管理员操作)开卡-入库: 上架的新产品入库注册之后,需要为这个产品办理一张电子标签卡,这个卡里存放着产品的编号;这个卡就放在产品货架上(与产品对应),如果后面这个产品的信息如果查询,就读取电子标签里的编号,到数据库里查询。
(3). (管理员操作)开卡和查询的数据传输: 设备端与软件端采用 tcp网络方式进行通信;设备端当做tcp客户端,软件端当做tcp服务器;当设备端查询产品的电子标签时,设备端读取编号之后,会通过约定的数据格式通过网络传递给软件端。 当软件端开卡注册时,也会用约定好的数据格式传递给设备端,如果设备端收到数据,开发板上的led会点亮;这时把ic拿到rc522射频模块上刷一下即可;如果成功写入led灯就会关闭。
(4). 软件端的设计:
有注册界面、登录界面;
主界面上显示店内有所有登记入库的商品信息,每个产品有图片进行显示、图片下面就显示产品的数量与价格;
管理员界面: 可以进行商品添加、设计价格、修改信息等。
查询页面: 输入产品的信息,可以查询产品的所有详细信息。
顾客可以选择购买的商品进行,然后点击支付。
软件端与硬件端的数据格式:
(1). 开卡注册数据格式-字符串(软件—>设备): register:86382684638434
(2). 设备查询上传的数据格式-字符串(设备—>软件): query: 86382684638434
商品的编号限制在16个字节内。
这里的设备硬件部分采用stm32最小系统板当做刷卡器,完成对ic卡读写,如果不需要stm32也可以替换成其他扫码枪之类的都可以的:
rc522刷卡模块负责对卡进行读写。 esp8266wifi初始化工作在sta模式,连接到指定wifi,与软件所在的电脑处于同一个局域网,方便连接软件端的服务器进行数据通信,每次设备开机将会自动连接到程序里设置好wifi热点和服务器。 设备端上有一个led灯,用来显示刷卡的状态—成功与否。 三、相关硬件 3.1 stm32f103最小系统板 stm32f系列属于中低端的32位arm微控制器,该系列芯片是意法半导体(st)公司出品,其内核是cortex-m3。
该系列芯片按片内flash的大小可分为三大类:小容量(16k和32k)、中容量(64k和128k)、大容量(256k、384k和512k)。
芯片集成定时器timer,can,adc,spi,i2c,usb,uart等多种外设功能。
3.2 esp8266串口wifi esp8266 系列模组集成 wi-fi 芯片 esp8266,设计紧凑、集成度高、rf 性能突出。通过 srrc, fcc, ce 等多国无线电认证,适用于各类物联网应用场景。
性能卓越
esp8266ex 芯片内置超低功耗 tensilica l106 32 位 risc 处理器,cpu 时钟速度最⾼可达 160 mhz,⽀持实时操作系统 (rtos) 和 wi-fi 协议栈,可将⾼达 80% 的处理能⼒应用于编程和开发。
高度集成
esp8266 芯片高度集成天线开关、射频巴伦、功率放大器、低噪声接收放大器、滤波器等射频模块。模组尺寸小巧,尤其适用于空间受限的产品设计。
认证齐全
rf 认证:srrc、fcc、ce-red、kcc、telec/mic、ic 和 ncc 认证;
环保认证:rohs、reach;
可靠性认证:htol、htsl、μhast、tct、esd。
丰富的产品应用
esp8266 模组既可以通过 esp-at 指令固件,为外部主机 mcu 提供 wi-fi 连接功能;也可以作为独立 wi-fi mcu 运行,用户通过基于 rtos 的 sdk 开发带 wi-fi 连接功能的产品。用户可以轻松实现开箱即用的云连接、低功耗运行模式,以及包括 wpa3 在内的 wi-fi 安全支持等功能。
3.3 rc522无线射频模块 mf rc522 是应用于13.56mhz 非接触式通信中高集成度读写卡系列芯片中的一员。是nxp 公司针对“三表”应用推出的一款低 电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携式手持设备研发的较好选择。
概述
mfrc522 是应用于13.56mhz 非接触式通信中高集成度读写卡系列芯片中的一员。是nxp 公司针对“三表”应用推出的一款低 电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携 式手持设备研发的较好选择。
mf rc522 利用了先进的调制和解调概念,完全集成了在13.56mhz 下所有类型的被动非接触式通信方式和协议。支持 iso14443a 的多层应用。其内部发送器部分可驱动读写器天线与iso 14443a/mifare卡和应答机的通信,无需其它的电路。接收器部分提供一个坚固而有效的解调和解码电路,用于处理iso14443a 兼容的应答器信号。数字部分处理iso14443a 帧和错误检测(奇偶 &crc)。此外,它还支持快速crypto1 加密算法,用于验证mifare 系列产品。mfrc522 支持mifare?更高速的非接触式通信,双向数据传输速率高达424kbit/s。
作为13.56mhz 高集成度读写卡系列芯片家族的新成员,mf rc522 与mf rc500和 mf rc530 有不少相似之处,同时也具备诸多特点和差异。它与主机间的通信采用连线较少的串行通信,且可根据不同的用户需求,选取spi、i2c 或串行uart(类似rs232)模式之一,有利于减少连线,缩小pcb 板体积,降低成本。
特性
◆高集成度的调制解调电路;
◆采用少量外部器件,即可将输出驱动级接至天线;
◆支持 iso/iec 14443 typea 和mifare®通信协议;
◆ 读写器模式中与 iso 14443a/mifare®的通信距离高达50mm,取决于天线的长度和调谐。
◆支持 iso 14443 212kbit/s 和424kbit/s 的更高传输速率的通信。
◆支持 mifare® classic 加密;
◆支持的主机接口:
-10mbit/s 的spi 接口
-i2c 接口,快速模式的速率为400kbit/s,高速模式的速率为3400kbit/s
-串行uart,传输速率高达1228.8kbit/s,帧取决于rs232 接口,电压电平取决于提供的管脚电压
◆64 字节的发送和接收fifo 缓冲区;
◆灵活的中断模式;
◆可编程定时器。
◆具备硬件掉电、软件掉电和发送器掉电 3 种节电模式,前两种模式雷同于mfrc500 和 cl rc400,其特有的“发送器掉电”则可关闭内部天线驱动器,即关闭rf 场;
◆内置温度传感器,以便在芯片温度过高时自动停止 rf 发射;
◆采用相互独立的多组电源供电,以避免模块间的相互干扰,提高工作的稳定性;
◆具备 crc 和奇偶校验功能,crc 协处理器的16 位长crc 计算多项式固定为:x16+x12+x5+1,符合iso/1ec14443 和cctitt 协议;
◆内部振荡器,连接 27.12mhz 的晶体;
◆2.5~3.3v 的低电压低功耗设计;
◆工作温度范围-30~+85℃;
◆5mm×5mm×0.85mm 的超小体积。
应用场合
mf rc522 适用于各种基于iso/iec 14443a 标准并且要求低成本、小尺寸、高性能以及单电源的非接触式通信的应用场合。
▲三表;
▲板上单元;
▲公共交通终端;
▲便携式手持设备;
▲非接触式公用电话。
3.4 ic卡 ic卡 (integrated circuit card,集成电路卡),也称智能卡(smart card)、智慧卡(intelligent card)、微电路卡(microcircuit card)或微芯片卡等。它是将一个微电子芯片嵌入符合iso 7816标准的卡基中,做成卡片形式。ic卡与读写器之间的通讯方式可以是接触式,也可以是非接触式。由于ic卡具有体积小便于携带、存储容量大、可靠性高、使用寿命长、保密性强安全性高等特点,ic卡的概念是在20世纪70年代初提出来的,法国的布尔公司于1976年首先创造出了ic卡产品,并将这项技术应用于金融、交通、医疗、身份证明等行业,它将微电子技术和计算机技术结合在一起,提高了人们工作、生活的现代化程度。
产品原理
ic卡是集成电路卡,ic卡芯片具有写入数据和存储数据的能力,可对ic卡存储器中的内容进行判定。在卡上封装有符合iso标准的芯片,有6~8个触点和外部设备进行通信,在ic卡上可以有彩色图案和说明性文字按iso标准,ic卡的部分触点及其定义为:vcc:ic卡工作电源;gnd:接地;vpp:存储器编程电源;clk:有关信号的定时与同步;i/o:卡中串行数据的输入与输出;rst:复位信号。当ic卡插入ic卡读卡器后,各接点对应接通,ic卡上的超大规模集成电路就开始工作。
ic卡种类
根据卡中所镶嵌集成电路的不同,ic卡可分为存储卡、非接触式ic卡、光卡、非接触式智能ic卡、智能卡 。
存储卡
存储卡,也称记忆卡(memory card),卡内有具有存储功能的集成电路存储器,还有数据存储器(eeprom)、工作存储器(ram)或程序存储器(eprom)。存储卡使用半导体存储器。存储器中所有存储单元的总和称为存储容量,存储卡的最大容量目前为512 kb。存储卡读出/写入一个字的时间称作读/写时间,读写器在接收地址和读命令时,即可将卡中的内容读出,读出时间约为几微秒,读写器在送来地址、要写数据和写命令时,即可进行写入,写入一个数据的时间比读出一个数据的时间长得多,一般需要5~10 ms。
非接触式ic卡
非接触式ic卡又称射频卡,是近几年发展起来的一项新技术,它将射频识别技术和ic卡技术结合在一起,解决了无源(卡中无电源)和免接触的技术问题。
非接触式ic卡与接触式ic卡相比有以下特点:
(1)可靠性高。由于读写之间无机械接触,避免了由于接触读写而产生的各种故障;且非接触式ic卡表面无裸露的芯片,无芯片脱落、静电击穿、弯曲损害等后顾之忧 。
(2)操作方便。无接触通信使读写器在10 cm的范围内就可以对卡片进行操作,且非接触式ic卡在使用时无方向性,卡片可以以任意方向掠过读写器表面完成操作,既方便又提高了速度 。
(3)防冲突。非接触式ic卡中有快速防冲突机制,能防止卡片之间出现数据干扰,读写器可以“同时”处理多张非接触式ic卡 。
(4)可以适应多种应用。非接触式ic卡存储器结构的特点使其适于一卡多用,可以根据不同的应用设定不同的密码和访问条件 。
(5)加密性能好。非接触式ic卡的序号是唯一的,在出厂前已固化,其与读写器之间有双向验证机制;非接触式ic卡在处理前要与读写器进行3次相互认证。
四、硬件设备成品效果图 程序需要修改的地方:
五、硬件设备端代码完整资料可以去这里下载: https://download.csdn.net/download/xiaolong1126626497/20687551#include stm32f10x.h#include led.h#include delay.h#include key.h#include usart.h#include #include timer.h#include esp8266.h#include rfid_rc522.h/*相关的硬件连接引脚说明:led----pc13key----pa0espb266---pb10(tx)(esp8266-rx) 和pb11(rx)(esp8266-tx) rc522射频模块外部的接口: *1--sda pb5--片选脚*2--sck pb4--时钟线*3--mosipa12--输出*4--misopa11--输入*5--悬空*6--gnd gnd*7--rst pa8--复位脚*8--vcc vcc*///u8 key[6]={0xff,0xff,0xff,0xff,0xff,0xff}; //卡密码-初始密码--白卡的出厂密码--//u8 mima_1[16]={88,88,88,88,88,88,0xff,0x07,0x80,0x29,88,88,88,88,88,88}; //扇区1的密码 格式(a密码 控制位 b密码 )//u8 mima_2[16]={88,88,88,88,88,88};//扇区1的a密码unsigned char sn[4]={88,88,88,88}; //默认卡号char sendbuff[10];/*函数功能: 打印卡号*/void print_info(unsigned char *p,int cnt){ int i; for(i=0;i=20) { cnt=0; led1=!led1; } //接收服务器下发的数据 if(usart3_rx_flag) { usart3_rx_buffer[usart3_rx_cnt]='\0'; usart1_printf(%s,usart3_rx_buffer); usart3_rx_cnt=0; usart3_rx_flag=0; } //读取卡号 if(readcardnumber()) { sprintf(sendbuff,%x%x%x%x\r\n,sn[0],sn[1],sn[2],sn[3]); esp8266_clientsenddata((u8*)sendbuff,strlen(sendbuff)); } //查看连接状态 key=key_scan(0); if(key) //发送at { usartx_stringsend(usart3,at+cipstatus\r\n); //查看状态信息 } }};i++)> 六、java端效果图 如果完整资料包可以去这里下载地址: https://download.csdn.net/download/xiaolong1126626497/20687551
配套资料齐全,视频讲解代码,部署环境。
七、java端的代码package com.controller;import java.io.ioexception;import javax.servlet.http.httpsession;import org.springframework.beans.factory.annotation.autowired;import org.springframework.web.bind.annotation.postmapping;import org.springframework.web.bind.annotation.requestbody;import org.springframework.web.bind.annotation.requestmapping;import org.springframework.web.bind.annotation.restcontroller;import com.common.bean.mysessioncontext;import com.common.bean.resultdata;import com.common.bean.websocketproductholder;import com.entity.product;import com.mapper.productmapper;@restcontroller()@requestmapping(/product)public class productcontroller { @autowired private productmapper pm; @postmapping(update.action) resultdata update(string token,@requestbody product update) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } pm.update( update ); return resultdata.success(); } @postmapping(byid.action) resultdata getbyid(string token,@requestbody product query) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } return resultdata.success().setdata( pm.getbyid( query.getid() ) ); } @postmapping(delete.action) resultdata deletepro(string token,@requestbody product delpro) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } pm.deletepro( delpro ); return resultdata.success(); } @postmapping(query.action) resultdata query(string token,@requestbody product query) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } return resultdata.success().setdata( pm.query( query ) ); } @postmapping(all.action) resultdata getall(string token) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } return resultdata.success().setdata( pm.getall() ); } @postmapping(add.action) resultdata adduser(string token,@requestbody product pro) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } pm.add( pro ); try { //把商品的编号通过tcp长连接传给stm32,写入rfid卡。 websocketproductholder.register(pro.getid()+); } catch (ioexception e) { system.out.println(注册失败!); } return resultdata.success(); } }package com.controller;import java.io.file;import java.io.ioexception;import java.util.uuid;import javax.servlet.http.httpservletrequest;import org.springframework.web.bind.annotation.postmapping;import org.springframework.web.bind.annotation.requestmapping;import org.springframework.web.bind.annotation.requestparam;import org.springframework.web.bind.annotation.restcontroller;import org.springframework.web.multipart.multipartfile;@restcontroller@requestmapping(/upload)public class uploadcontroller { @postmapping(/uploadimg) public string uploadimg(@requestparam(file) multipartfile file, httpservletrequest rq){ //获取上传文件名,包含后缀 string originalfilename = file.getoriginalfilename(); //获取后缀 string substring = originalfilename.substring(originalfilename.lastindexof(.)); //保存的文件名 string dfilename = uuid.randomuuid()+substring; //保存路径 //springboot 默认情况下只能加载 resource文件夹下静态资源文件 string path = d:\\uploadimg\\; //生成保存文件 file uploadfile = new file(path+dfilename); system.out.println(uploadfile); //将上传文件保存到路径 try { file.transferto(uploadfile); } catch (ioexception e) { e.printstacktrace(); } return uploadfile.getname(); } }package com.controller;import java.util.list;import java.util.map;import javax.servlet.http.httpsession;import org.springframework.beans.factory.annotation.autowired;import org.springframework.web.bind.annotation.getmapping;import org.springframework.web.bind.annotation.postmapping;import org.springframework.web.bind.annotation.requestbody;import org.springframework.web.bind.annotation.requestmapping;import org.springframework.web.bind.annotation.restcontroller;import com.common.bean.mysessioncontext;import com.common.bean.resultdata;import com.entity.user;import com.mapper.usermapper;@restcontroller()@requestmapping(/user)public class usercontroller { @autowired private usermapper um; @postmapping(changepswd.action) resultdata changepswd(string token,@requestbody map map) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } user uu = (user) ss.getattribute(login_user); if( uu == null ) return resultdata.fail(请先登录!); string password = map.get(password); string newpassword = map.get(password2); int num = um.updatepassword(uu.getid(), password, newpassword); if( num > 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.controller;import java.text.simpledateformat;import java.util.date;import java.util.list;import java.util.map;import javax.servlet.http.httpsession;import org.springframework.beans.factory.annotation.autowired;import org.springframework.web.bind.annotation.postmapping;import org.springframework.web.bind.annotation.requestbody;import org.springframework.web.bind.annotation.requestmapping;import org.springframework.web.bind.annotation.restcontroller;import com.common.bean.mysessioncontext;import com.common.bean.resultdata;import com.entity.order;import com.mapper.ordermapper;@restcontroller()@requestmapping(/order)public class ordercontroller { @autowired private ordermapper ordermapper; @postmapping(calc.action) resultdata update(string token,@requestbody list list) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } for( order od : list ) { ordermapper.add( od ); } return resultdata.success(); } @postmapping(query.action) resultdata query(string token,@requestbody map map) { httpsession ss = mysessioncontext.getsession( token ); if( ss == null ) { return resultdata.fail(请先登录!); } long t1 = map.get(start); long t2 = map.get(end); date d1 = new date();d1.settime(t1); date d2 = new date();d2.settime(t2); string start = new simpledateformat(yyyy-mm-dd hh:mm:ss).format( d1 ); string end = new simpledateformat(yyyy-mm-dd hh:mm:ss).format( d2 ); list list = ordermapper.query(start, end); return resultdata.success().setdata( list ); }},long>
生态种养怎样利用好大数据
当自动驾驶撞上5G | R17中的Sidelink技术
续航力MAX!华为手机360度无死角充电
高精度纳安级电流发生器
基于多路开关检测器件MC33993实现开关检测电路的设计方案
基于JAVA超市自助购物系统的设计与实现
常用的7种传感器介绍
Intel和AMD的烤肉比拼,谁更香?
AI和云计算将推动物联网市场增长
中国移动现场体验5G 未来生活离你真的不远
国网与信通联合创意信息“思极有容”数据库
5G关键特征将如何影响数据平台架构?
称重传感器的输出阻抗类型
FULL IN CELL高端触控再添新丁
我国制造的歼-20战机将全部换装国产发动机
湖北大学与长江存储科技在3D存储芯片研究上开展合作
Model X上配备了250多个英飞凌的半导体部件
格科微在半导体行业及临港集成电路产业建设中发挥重要作用
键盘
SSC扩频时钟概述和主要参数