Python software for Arduino RFID

HK RFID Monitor is a Python based software for RFID modules. The monitor reads the data coming into the COM port and displays it on your laptop screen.

Components

Hardware components

  • Arduino UNO × 1
  • USB cable × 1

Software

The data used in this project is student IDs, names and numbers coming from a microcontroller (AVR or just Arduino). The software reads the values ​​using the “Serial” Python module and displays them using the “Tkinker”.

HK RFID Monitor

You can download or copy the monitor code below:

import serial
from tkinter import messagebox
import ttk
import sqlite3
import time
import datetime
try:
    from tkinter import *
except:
    from tkinter import *


def pro():
    messagebox.showinfo(title= "About Project", message="RFID attendance system made by Fabiha Umar. ")
    return
def dev():
    messagebox.showinfo(title= "About Developer", message="This is a python based software made by HK developers. Place an order at: [email protected]")
    return
def ex():
    ex = messagebox.askyesno(title= "Quit", message="Are you Sure?")
    if ex >0:
        root.destroy()
        return
thing = ' '

class main:

    db_name="rfid.db"
    def __init__(self,root,ser):
        self.ser=ser
        self.root=root
        self.root.title("RFID DATA MONITOR")
        self.root.geometry('700x300-30+30')
        self.root.resizable(width=False,height=False)

        self.s = StringVar()
        self.s1 = StringVar()
        self.s2 = StringVar()

        self.tree = ttk.Treeview(root)
        self.tree["columns"] = ("TimeStamp", "ID", "UserName", "RollNo")
        self.tree.column("TimeStamp", width=150)
        self.tree.column("ID", width=100)
        self.tree.column("UserName", width=100)
        self.tree.column("RollNo", width=100)
        self.tree.heading("TimeStamp", text="Time")
        self.tree.heading("ID", text="ID")
        self.tree.heading("UserName", text="Name")
        self.tree.heading("RollNo", text="Roll Number")
        self.tree.pack()
        self.root.after(60,self.min)

    def min(self):

        thing = self.ser.readline().decode('ascii')
        string = str(thing)
        print(string)
        i=0
        j=0
        k=0
        for i in range(2, len(string)):
            if string[i] == ';':
                break
        v = string[3:i]
        for j in range(10, len(string)):
            if string[j] == ';':
                break
        c = string[i + 7:j]
        for k in range(20, len(string)):
            if string[k] == len(string):
                break
        p = string[j + 13:k-1]
        self.s.set(v)
        self.s1.set(c)
        self.s2.set(p)
        self.root.after(500, self.min)

        conn = sqlite3.connect('rfid.db')
        call = conn.cursor()
        if len(v)>0 and len(c)>0 and len(p)>0:
            print("id= " + v)
            print("i= " + c)
            print("p= " + p)
            unix = time.time()
            date = str(datetime.datetime.fromtimestamp(unix).strftime('%Y-%m-%d %H:%M:%S'))
            call.execute("INSERT INTO rfid (datestamp, id, name, rollnumber) VALUES (?,?,?,?)", (date, v, c, p))
            conn.commit()

            call.execute('SELECT * FROM rfid ORDER BY datestamp DESC LIMIT 5')
            for row in call.fetchall():
                    print(row)
            self.tree.insert("", 0, text="FETCHED --- >", values=(date, v, c, p))
        self.root.update()
        # Hamza Khalid Data ---> Voltage: 128V Current: 128A Load: 128W

def stopServer():
    sure=messagebox.askyesno(title="Quit",message="Are you Sure?")
    if sure >0:
        root.destroy()
        return
def startServer():
    try:
        com = portNo.get()
        ser = serial.Serial(com, 9600, timeout=0)
        print('Serial port is open')
        main(root,ser)
        Button1.destroy()
        Button2 = Button(root, text="       Stop Server and Exit      ", command=stopServer, font=("Arial","14"))
        Button2.place(x=230, y=240)
    except:
        Labelerror = Label(root, text="Invalid Port or Error Reading", font=("Arial","14"),  fg='red')
        Labelerror.place(x=110, y=150)
    return

root = Tk()

portNo = StringVar()
root.geometry("500x250+50+50")
root.title('RFID DATA MONITOR')
root.resizable(width=False,height=False)
Labelh=Label(root,text="Enter port Name. E.g: COM4",font=("Arial","14")).place(x=120,y=40)
entry1=Entry(root,textvariable=portNo).place(x=185,y=80)
Button1= Button(root,text="Start Server", command=startServer, font=("Arial","10") )
Button1.place(x=205,y=110)

#Menu
menubar=Menu(root)
optionsmenu = Menu(menubar, tearoff = 0)
optionsmenu.add_command(label="Project", command = pro)
optionsmenu.add_command(label="Developer", command = dev )
optionsmenu.add_command(label="Exit", command= ex)
optionsmenu.add_separator()
menubar.add_cascade(label="Options",menu=optionsmenu)
root.config(menu=menubar)
root.mainloop()

How does data arrive at the COM port?

In this project, Arduino is used to send data to the COM port to make it easier to understand how the data goes to the COM port for those who have worked with an Arduino or AVR microcontroller.

Let’s assume our microcontroller board (Arduino UNO) is connected to COM port 4 of our PC, and take the following Arduino code:

void setup() {  
Serial.begin(9600);  }

void loop() {    
Serial.print("id=1000; name=Hamza Khalid; rollnumber=115;");    
Serial.print("n ");  delay(3000);    
Serial.print("id=1001; name=Ahmed Arif; rollnumber=120;");    
Serial.print("n ");    
delay(3000);    
Serial.print("id=1002; name=Ammar Ahmed; rollnumber=142;");    
Serial.print("n ");    
delay(3000);
}

So the output to the Arduino serial monitor would be:

id=1000; name=Hamza Khalid; rollnumber=115;id=1001; name=Ahmed Arif; rollnumber=120;id=1002; name=Ammar Ahmed; rollnumber=142; (... continue)

How does the software process data?

The next line (line 121) in our Python file allows us to enter the name of the port on which the data is received. Since the Arduino is connected to port 4, we write “COM4” in the input field:

Labelh=Label(root,text="Enter port Name. E.g: COM4",font=("Arial","14")).place(x=120,y=40)

Now the python program starts reading ‘COM4’ and stores the data into a string variable with the following lines (lines 55, 56):

thing = self.ser.readline().decode('ascii')        
string = str(thing)

The program parses the strings to separate the student ID, name, and number values ​​with the following strings (lines 72-83):

for i in range(2, len(string)):       
    if string[i] == ';':           
        break   
v = string[3:i]   
for j in range(10, len(string)):       
    if string[j] == ';':           
        break   
c = string[i + 7:j]    
or k in range(20, len(string)):       
    if string[k] == len(string):           
        break    
p = string[j + 13:k-1]

Saving in the database

The values ​​for id, name and numbers are stored in the variables v, c and p, respectively. The values ​​are then stored in the sqlite3 database and displayed on the software screen with the following lines:

call.execute("INSERT INTO rfid (datestamp, id, name, rollnumber) VALUES (?,?,?,?)", (date, v, c, p))                
    conn.commit()
call.execute('SELфECT * FROM rfid ORDER BY datestamp DESC LIMIT 5')for row in call.fetchall():    
    print(row)
self.tree.insert("", 0, text="FETCHED --- >", values=(date, v, c, p))

What changes to make under your own data:

  • the Arduino code that sends data to the COM port (note that the source of sending data to the COM port can be anything, so change accordingly),
  • lines 61-72 of the Python program, which are used to parse strings to separate the values ​​(in our case id, name and number),
  • the names of the columns in the database.

About: Morozov Dmitry

My specialisation is software engineer. I am 35 years old and have been working in the IT field for over 15 years. I have accumulated experience in programming, project management, training and administration.