使用Arduino和Python的销售点交易系统
我们将建造一些独特而令人兴奋的东西。我们将使用硬件组件,并将它们与我们的Python代码集成。所有提出的组件都可以随时更新、修改和安全。基本的信息流是最值得关注的。让我们开始吧。
销售点 - POS
POS或销售点通常指的是销售或交易发生的地点。对于零售商和餐馆老板来说,POS通常意味着收银台或柜台周围的区域,在结账时接受付款。
什么是POS机?
销售点(POS)交易是指商家和顾客在购买产品或服务时发生的事情,通常使用销售点系统来完成交易。商家通常使用一个POS系统来完成销售交易。在其最基本的定义中,POS系统是POS硬件和POS软件的组合,以创建一个用于处理交易和付款的POS机。
项目概述
在科技迅猛发展的时代,携带多张卡和笨重的钱包并不时尚。因此,我们引入了一个智能身份证来代替钱包。这减少了进行交易的时间,特别是在超市和当地杂货店。它还可以用于其他各种用途,如国家身份证、借书卡和支付罚款(如果有的话)。
在这个项目中,我们使用支持RFID的ID卡进行交易,我们使用与Arduino连接的RFID扫描仪进行扫描。这个板子随后通过Arduino和客户机的串行通信将UID号码发送给客户。然后在套接字编程的帮助下,我们与拥有所有用户数据库的服务器建立连接。在服务器端,我们通过UID号码和每个用户特有的PIN码来检查用户的真实性。经过验证后,我们对有效的用户进行交易,否则报告数据库中的用户不存在。
硬件
RFID标签和扫描器
"RFID "是无线电频率识别的缩写。RFID使用电磁场来自动识别和跟踪附着在物体上的标签。标签包含电子存储的信息。无源标签从附近的RFID阅读器的询问无线电波中收集能量。
使用的RFID模块是MFRC522。该RFID模块与Arduino相连。在这里,我们使用RFID扫描仪读取一个人的身份证的UID号码。我们将UID值加载到RFID标签上。
软件
插座编程
在一个POS系统中,在整个建筑群的不同位置可能有许多服务提供者。因此,所有这些计算机都需要与主数据库服务器或甚至中间服务器建立连接。在所有客户机和服务器之间建立有线连接涉及到很多不必要的硬件和布线。因此,我们采用插座的方式,与服务器建立无线连接。使用连接到Arduino Uno板的RFID模块接收RFID数据,并通过串行通信将其传输到服务器程序。
认证阶段是由服务器发起的。在这里,我们在客户机和服务器机之间使用一个定时连接。这意味着,一旦交易完成,我们就会中断与服务器的连接,以防止服务器的负载过重。我们与服务器建立UDP连接,因为它比TCP更快,而且通过网络发送的数据也更少。
由于服务器位于一个恒定的IP地址,我们在客户端机器上保存了一个副本,这样我们就不需要在每次用户与服务器互动时寻找服务器机器。这节省了时间,使整个系统更有效率。客户端和服务器之间的连接是一个双向的单线连接。因为基于客户端的输入,服务器请求更多的数据,所有这些都发生在同一个连接中。
让我们来保存数据库。我们创建一个临时的数据库,叫做数据库.csv。你可以在client.py和server.py的同一目录下创建该文件。
数据库.csv
,ID,Pin,Name,Current_Balance,Transaction_Amt,Closing_Balance
0,AE9F7569,1234,Akshay,28510,0,28510
1,AEA46C69,4321,Kumar,4563,563,4000
2,AE9F6529,7896,Shah,7896,896,7000
3,AE9F7159,6987,Nikeish,1456,456,1000
4,AE9F7789,1478,Ranbir,8622,1234,8622
client.py
# Message Sender
import os
import serial
ser=serial.Serial("COM5")
ser.baudrate = 9600
from socket import *
host = "192.168.43.238" # set to IP address of target computer
port = 13000
addr = (host, port)
UDPSock = socket(AF_INET, SOCK_DGRAM)
Buffer_size = 1023
#send_data is to send data
def send_data(data):
UDPSock.sendto(data.encode(), addr)
#UDPSock.close()
#To recieve the acknowledgement from the server
def recieve_data():
r_data,addr = UDPSock.recvfrom(Buffer_size)
return r_data.decode()
while True:
tries=0
#reading data from port
# #Serial communication part
i=0
user_ID=[]
while(i<8):
user_ID.append(ser.read().decode('ascii'))
i=i+1
user_ID = (str(user_ID))
send_data(str(user_ID))
while tries<4:
data = recieve_data()
data = int(data)
if (data==1):
#Authentication and verification
PIN = int(input("Enter PIN:"))
send_data(str(PIN))
elif(data==2):
print("Authentication Successful")
#Sending the transaction amount if valid user
amount = int(input("Enter the amount:"))
send_data(str(amount))
break
elif(data==3):
print("Authentication Failed")
break
elif(data==4):
print("Insufficient funds")
break
else:
print("Server Error")
print("Rescan ID")
#UDPSock.close()
break
tries+=1
os._exit(0)
server.py
# Message Receiver
from os import *
import csv
from socket import *
import pandas as pd
host = ""
port = 13000
buf = 1024
addr = (host, port)
Buffer_size = 1023
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)
#To recieve the acknowledgement from the server
def recieve_data():
r_data,addr = UDPSock.recvfrom(Buffer_size)
return [r_data.decode(),addr]
#send_data is to send data
def send_data(data,addr):
UDPSock.sendto(data.encode(), addr)
#UDPSock.close()
# use base_dir if needed
BASE_DIR = ''
# data handling using pandas
df= pd.read_csv(BASE_DIR + 'Dataset.csv')
df = df.drop('Unnamed: 0', 1)
df.set_index('ID')
#The table indexing
id= df.iloc[:,0]
pin=df.iloc[:,1]
name=df.iloc[:,2]
cb=df.iloc[:,3]
ta=df.iloc[:,4]
clb=df.iloc[:,5]
#Starting the program for each user
while True:
status = 0
#This block which handles the user authentication and services
#Recieving the ID of the uder
user_ID,u_addr = recieve_data()
count=0
for count in range(len(id)-1):
if(id[count]==(user_ID)):
#Recieving the PIN and verifying it
print("User ID:",user_ID)
print("Waiting for PIN")
send_data("1",u_addr)
received_pin=recieve_data()[0]
if(pin[count]==int(received_pin)):
print("Authentication Successful")
status=1
break
else:
print("Authentication Failed")
send_data("3",u_addr)
print(count)
count=count+1
if(status==1):
print("Welcome ",name[count])
print("Waiting for amount")
send_data("2",u_addr)
ta1=recieve_data()[0]
ta1 = int(ta1)
if(ta1>cb[count]):
send_data("4",u_addr)
else:
clb[count]=cb[count]-ta1
cb[count]=clb[count]
ta[count]=ta1
print("Transaction successful\nThank you",name[count])
df.to_csv("C://Users//Kantesh//Desktop//CN PBL//Dataset.csv")
#os._exit(0)
arduino_code.c
下面的代码是在Arduino IDE中编写的,用于提取ID卡的UID。在运行程序之前,用户必须在Arduino IDE中加入MFRC522库。
如何安装MFRC522 RFID库到Arduino IDE中
- 从github.com/miguelbalbo…下载库
- 打开Arduino IDE。然后进入并选择Sketch->Include Library->Add .ZIP Library。
- 选择RFID-master.zip文件并点击打开。
关于RFID库的更多细节,请参考steemit.com。
#include <SPI.h>
#include <MFRC522.h>
constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above
constexpr uint8_t SS_PIN = 10; // Configurable, see typical pin layout above
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
MFRC522::MIFARE_Key key;
// Init array that will store new NUID
int nuidPICC[4];
String UID = "";
void setup() {
Serial.begin(9600);
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
void loop() {
// Look for new cards
if ( ! rfid.PICC_IsNewCardPresent())
return;
// Verify if the NUID has been read
if ( ! rfid.PICC_ReadCardSerial())
return;
//Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
//Serial.println(rfid.PICC_GetTypeName(piccType));
// Check is the PICC of Classic MIFARE type
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
if (rfid.uid.uidByte[0] != nuidPICC[0] ||
rfid.uid.uidByte[1] != nuidPICC[1] ||
rfid.uid.uidByte[2] != nuidPICC[2] ||
rfid.uid.uidByte[3] != nuidPICC[3] ) {
// Serial.println(F("A new card has been detected."));
// Store NUID into nuidPICC array
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
for (byte i = 0; i < 4; i++) {
Serial.print(nuidPICC[i],HEX);
}
}
// Halt PICC
rfid.PICC_HaltA();
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
}
发送插图和数据包分析
Wireshark是包分析的首选软件。它可以从www.wireshark.org/。下载后,我们使用Wireshark中的数据包分析器功能来分析发送和接收的数据包。
让我们使用Wireshark这个工具来捕获发送和接收的数据包。收到的输出如下
- 从客户端发送至服务器的数据
- 从服务器发送至客户端的数据
- 显示交易金额的信息
我们已经建立了一个建立交易的完整循环。因此,我们可以通过加密针脚的存储、保护传输数据和创建加密的ID来改进这个项目。所有这些建议都可以建立在上述项目的基础上。我们鼓励你使用Arduino和它的各种模块来加强和建立你的原型。