【摘要】 本系統主要是由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.h"
u8 ESP8266_IP_ADDR[16]; //255.255.255.255
u8 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<10;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,">"))
{
//繼續發送數據
USARTx_DataSend(USART3,data,len);
//等待數據發送成功
for(n=0;n<200;n++)
{
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,"SEND OK"))
{
return 0;
}
}
}
}
}
}
}
return 1;
}
/*
函數功能: 配置WIFI為STA模式+TCP客戶端模式
函數參數:
char *ssid 創建的熱點名稱
char *pass 創建的熱點密碼 (最少8位)
char *p 將要連接的服務器IP地址
u16 port 將要連接的服務器端口號
u8 flag 1表示開啟透傳模式 0表示關閉透傳模式
函數返回值:0表示成功 其他值表示對應的錯誤
*/
u8 ESP8266_STA_TCP_Client_Mode(char *ssid,char *pass,char *ip,u16 port,u8 flag)
{
char ESP8266_SendCMD[100]; //組合發送過程中的命令
//退出透傳模式
//USARTx_StringSend(USART3,"+++");
//delay_ms(50);
/*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=1\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熱點信息*/
sprintf(ESP8266_SendCMD,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pass);
if(ESP8266_SendCmd(ESP8266_SendCMD))return 6;
/*7. 設置單連接*/
if(ESP8266_SendCmd("AT+CIPMUX=0\r\n"))return 7;
/*8. 配置要連接的TCP服務器信息*/
sprintf(ESP8266_SendCMD,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",ip,port);
if(ESP8266_SendCmd(ESP8266_SendCMD))return 8;
/*9. 開啟透傳模式*/
if(flag)
{
if(ESP8266_SendCmd("AT+CIPMODE=1\r\n"))return 9; //開啟
if(ESP8266_SendCmd("AT+CIPSEND\r\n"))return 10; //開始透傳
if(!(strstr((char*)USART3_RX_BUFFER,">")))
{
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<10;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,">"))
{
//繼續發送數據
USARTx_DataSend(USART3,data,len);
//等待數據發送成功
for(n=0;n<200;n++)
{
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,"SEND OK"))
{
return 0;
}
}
}
}
}
}
}
return 1;
}
四、JAVA端效果圖與部分代碼示例
如果需要資料包可以去這里下載: https://download.csdn.net/download/xiaolong1126626497/20687600
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.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;
@Component
public 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}}
商品圖片
商品名稱商品價格商品數量商品分類商品描述商品圖片提交
-
嵌入式
+關注
關注
5082文章
19109瀏覽量
304837 -
STM32
+關注
關注
2270文章
10896瀏覽量
355766 -
JAVA
+關注
關注
19文章
2966瀏覽量
104704
發布評論請先 登錄
相關推薦
評論