I have created a Raspberry Pi based Project, an Automatic Library Book Management System Project. Let me tell you first how this project plays an important role in the real world. As you are all aware of the current pandemic situation and now colleges/schools have been re-opened, it is important to maintain social distancing. In some colleges or schools, books are being issued to students manually by using barcode Reader and excel sheets. All of the books and student library ID cards have barcodes. To issue a book student have to give their book to the library teacher along with their library ID card and the library teacher issue the book by scanning the barcode on the book and student library ID card. If the Teacher/Student is sick then there might be chances that germs will be transferred to the Book or Library card. My project help in maintaining social distancing and also reducing close contact between people.
Through this project, students can easily Issue/Return books they just have to wave their hand on the right/left side(IR sensors) of the project and place their book and library ID card then the book will be issued/Return. Each book and library ID cards are being provided with a barcode. Instead of a barcode reader, in this project, I'm using a camera and using an OpenCV to detect the barcode value. Book and Library ID card Details are Stored in a Remote MySql Database. I have also created an App and a Website using python-Flask and Hosted it online on Heroku for free. Students can see their details on the website by entering their University Enrollment Number or Library ID Card Barcode Number. Advantage of Website in the worst-case scenario, if Hardware stopped working for some reason then the Teacher can manually issue/return the book to the student. The app is created Using MIT app inventor can only access it by a Library person for Security purposes, So that no one can steal the book from the library. Will explain it in more detail below.
The thing you should know about the Projects:-
- Each book can be issued to students for 14 Days. If the student exceeds the return date then he will be charged 2 Rs per Day (this value can be changed in the code).
- Students can only issue 5 Books, if they try to issue more than 5 books system will display or say that "You cannot issue Books More than 5". We can increase the number of books to issue but it will make the code lengthy as I have created the code with simple logic which is more effective and less buggy(error).
- Students can only Return/Reissue book after 7 days before that they won't be able to do that
As it's a prototype that's why I have created it in cardboard but in the practical world, a 3D printed box or sheet metal box can be created.
If you are new to OpenCV, you can follow our Getting started with OpenCV tutorial and can build more OpenCV image processing projects by following the link.
Component Required for Automatic Library Management
Project Used Hardware
- Raspberry pi 3 B+ Model,
- IR Sensors,
- Raspberry Pi TFT Display,
- USB webcam,
- USB sound card,
- Transformer,
- capacitor,
- diode,
- resistor,
- 7805 voltage rectifier,
- LED, power adaptor,
- jumper wire,
- PCB,
- box,
- LED Light,
- USB Speaker
Project Used Software
- Python,
- Open-cv,
- Pyzbar library,
- gtts library,
- Python-Flask,
- MySQL,
- MIT App Inventor(app),
- PHP,
- pysimplegui
Project Hardware and Software Selection
Here I have used the raspberry pi 3 b+ model which has 1.4ghz processor with built-in wifi and bluetooth functionality. In this project, I have opt-out for raspberry because of the need for high processing power, also it's easy to use, cheaper and it supports USB web camera. Raspberry pi also provides Gpio pins through that I was able to interface IR Sensor easily. To Make the User GUI (Graphical user interface ), I have used pysimplegui library through this I was able to display text (instructions) on TFT Display. Instead of a normal LCD, I have used TFT Display (3.5 inches) to make the project more user friendly. Power supply - Created AC to DC full bridge rectifier power supply which outputs 12v and 5v. This gives power to our both IR sensor and LED Light(12v). To give power to the raspberry pi, I have used 5v, 3A Adaptor and for Speaker, I have used another USB adaptor. I have connected all the input power to a single power cable. We have two options to read(detect) barcode of books or student ID cards either we go for a normal usb Barcode Reader or USB web camera. Here I have used USB Web- camera for detecting barcodes instead of a normal barcode reader because it's cheaper as compared to a barcode reader. The website which you see here( https:/ /librarybookmanager.herokuapp.com/ ) is being created using python-flask because through this I was able to use MySQL connector library which allows me to connect to my database and also issue/return/re-issue book manually or make changes in the database. The app will play an important role as it prevents the books from getting stolen. As the system is automatic that is why there might be chances that some students try to take books without issue. So to prevent this the library person will sit at the exit door of the library along with the mobile application and by scanning students, the library person will be able to see all the student detail like how many books are issued to them or which are those books and their total fine.
Circuit Diagram
On the hardware side, there is two IR sensor that is connected to Raspberry pi gpio. The right sensor output pin is connected to raspberry pi gpio pin 20 and the Left side Sensor output pin is connected to Raspberry pi gpio pin 21. VCC of both Sensors are connected to the 5v output of the power supply and ground to power supply ground. Raspberry pi Gnd pin also connected to power supply ground side. I have given separate power to the raspberry pi using 5v 3a adaptor and the speaker have been connected to a separate USB adaptor but all the power input are connected to a single power cord (plug). Speakers are connected to the raspberry pi through the Sound card so that we hear the loud sounds it boost the volume of the speaker. USB web-camera is connected to the USB port of the raspberry pi. LED Light is used to give our USB web camera better lighting so that the camera was able to get a clear view of the barcode. LED Light positive side is connected to power supply 12v output and ground is connected to power supply ground.
#!/usr/bin/python3 import time import datetime import mysql.connector as c import cv2 from pyzbar.pyzbar import decode import RPi.GPIO as GPIO from gtts import gTTS from mpyg321.mpyg321 import MPyg321Player import PySimpleGUI as sg sg.LOOK_AND_FEEL_TABLE['MyCreatedTheme'] = {'BACKGROUND': '#34495E', 'TEXT': '#FFCC66', 'INPUT': '#339966', 'TEXT_INPUT': '#000000', 'SCROLL': '#99CC99', 'BUTTON': ('#003333', '#FFCC66'), 'PROGRESS': ('#D1826B', '#CC8019'), 'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0, } sg.theme('MyCreatedTheme') layout1 = [[sg.Text('Welcome to Library book manager',justification='center',size=(80,4),font=("Helvetica", 20))], [sg.Text(size=(100,3),justification='center',key='-OUTPUT-',font=("Helvetica", 15))], [sg.Text(justification='center',size=(100,4),key='-LEFT-',font=("Helvetica", 13))]] window = sg.Window(title="Library book manager",layout=layout1,size=(600,700),resizable=True,use_custom_titlebar=True, alpha_channel=.5,right_click_menu = None, grab_anywhere=False,no_titlebar=True).finalize() window.Maximize() sensor1 = 20 sensor2 = 21 language = 'en' #welcometext = 'Welcome to Automatic Library book management system!' #myobj = gTTS(text=welcometext, lang=language, slow=False) #myobj.save("welcome.mp3") ##placebooktext = 'Please Place Book which you want to issue or re issue!' #myobj1 = gTTS(text=placebooktext, lang=language, slow=False) #myobj1.save("placebook.mp3") #placereturnbooktext = 'Please Place Book which you want to Return!' #myobj1 = gTTS(text=placereturnbooktext, lang=language, slow=False) #myobj1.save("placereturnbook.mp3") #placecardtext = 'Please Place Your LIBRARY ID CARD!' #myobj2 = gTTS(text=placecardtext, lang=language, slow=False) #myobj2.save("placecard.mp3") #bookissuetext = 'Book has been issued to you!' #myobj3 = gTTS(text=bookissuetext, lang=language, slow=False) #myobj3.save("bookissue.mp3") #bookreissuetext = 'Book has been re issued to you!' #myobj4 = gTTS(text=bookreissuetext, lang=language, slow=False) #myobj4.save("bookreissue.mp3") #bookreturntext = 'Book has been succesfully Returned!' #myobj5 = gTTS(text=bookreturntext, lang=language, slow=False) #myobj5.save("bookreturn.mp3") #morebooktext = 'YOU CANNOT ISSUE BOOKS MORE THAN 5' #myobj6 = gTTS(text=morebooktext, lang=language, slow=False) #myobj6.save("morebook.mp3") #nobooktext = 'Book Not Registered in Database' #myobj7 = gTTS(text=nobooktext, lang=language, slow=False) #myobj7.save("nobook.mp3") #nousertext = 'Book Not Registered in Database' #myobj8 = gTTS(text=nousertext, lang=language, slow=False) #myobj8.save("nouser.mp3") #errortext = 'You can only Return book after 7 Days' #myobj9 = gTTS(text=errortext, lang=language, slow=False) #myobj9.save("error.mp3") #error2text = 'Book is not isued to you or something went wrong' #myobj10 = gTTS(text=error2text, lang=language, slow=False) #myobj10.save("error2.mp3") player = MPyg321Player() player.play_song("welcome.mp3") GPIO.setmode(GPIO.BCM) GPIO.setup(sensor1,GPIO.IN) GPIO.setup(sensor2,GPIO.IN) cap = cv2.VideoCapture(0) cap.set(3, 320) cap.set(4, 240) flag1 = True flag2 = False flag3 = True flag4 = False con = c.connect(host="hostname", user="username", passwd="password", database="database name", port=3306 ) def mohit(frame): global flag1 global flag2 global bookname global bookuid global bookissuedto global cursor con.commit() if flag1 == True: for code in decode(frame): print(code.type) print(code.data.decode('utf-8')) id = code.data.decode('utf-8') cursor.execute("Select uid, bookname , available , issuedto FROM bookdatabase WHERE uid="+str(id)) result = cursor.fetchone() #print(result[2]) if result is not(None): if result[2] == 1: bookname = result[1] bookuid = result[0] bookissuedto = result[3] #cv2.destroyAllWindows() flag2= True function2(result[2]) flag1= False elif result is None: flag1=False print("Book not Registered!!") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Is Not Registered !!") window.finalize() player.play_song("nobook.mp3") def function2(res): if res == 1: print("Place Your LIBRARY ID CARD!!") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Place Your LIBRARY ID CARD !!") window.finalize() player.play_song("placecard.mp3") count = 0 maurya(count) def maurya(count): global flag1 global flag2 time.sleep(10) count_f_stop = 0 while count <= 100: if count_f_stop == 0: while count_f_stop <= 10: success, frame1 = cap.read() count_f_stop = count_f_stop + 1 count = count + 1 success, frame1 = cap.read() read(frame1) #cv2.imshow('test', frame) #cv2.waitKey(1) flag1 = True main() def read(frame1): global flag1 global flag2 global bookname global bookuid global intissuefine global cursor con.commit() if flag2 == True: for code1 in decode(frame1): print(code1.type) print(code1.data.decode('utf-8')) uid = code1.data.decode('utf-8') if uid == bookissuedto or bookissuedto == str(0): cursor.execute("Select lid, name , issued,fine FROM usersdatabase WHERE lid="+str(uid)) result1 = cursor.fetchone() if result1 is not(None): flag2 = False usedlid = result1[0] username = result1[1] userissued = result1[2] issuefine1 = result1[3] intissuefine = int(issuefine1) if userissued == 0: tday = datetime.date.today() tdelta = datetime.timedelta(days=14) returndate = tday + tdelta newuserissued = userissued + 1 query = """ UPDATE usersdatabase SET b1name = %s,b1uid = %s,b1issuedate=%s,b1returndate=%s,issued=%s WHERE lid = %s """ data = (bookname,bookuid,tday,returndate,newuserissued,uid) cursor.execute(query, data) con.commit() bquery = """ UPDATE bookdatabase SET issuedto=%s WHERE uid = %s """ bdata = (uid,bookuid) cursor.execute(bquery,bdata) con.commit() print("Book Has been issued to you") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Has been issued to "+str(username)+"\nReturn Date : "+str(returndate)) window.finalize() player.play_song("bookissue.mp3") if userissued == 1: tday = datetime.date.today() tdelta = datetime.timedelta(days=14) returndate = tday + tdelta cursor.execute("Select lid, name ,b1returndate,b1issuedate,issued FROM usersdatabase WHERE b1uid="+str(bookuid)) result2 = cursor.fetchone() if result2 is not(None): m1 = result2[2] ynew1 = m1[0:4] yint1 = int(ynew1) mnew1 = m1[5:7] mint1 = int(mnew1) dnew1 = m1[8:10] dint1 = int(dnew1) previousreturndate1 = datetime.date(yint1,mint1,dint1) tday = datetime.date.today() remainderdate=previousreturndate1 - tday remainderday = remainderdate.days #print(remainderday) if remainderday < 7 and remainderday >= 0: reissuequery1 = """ UPDATE usersdatabase SET b1name = %s,b1uid = %s,b1issuedate=%s,b1returndate=%s WHERE b1uid = %s """ newreturndate = returndate + remainderdate data1 = (bookname,bookuid,tday,newreturndate,bookuid) cursor.execute(reissuequery1,data1) con.commit() print("Book Has been reissued to you") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Has been reissued to "+str(username)+"\nReturn Date :"+str(newreturndate)) window.finalize() player.play_song("bookreissue.mp3") elif remainderday < 0 : absremainderday = abs(remainderday) fine = intissuefine + 2 * absremainderday reissuequery2 = """ UPDATE usersdatabase SET b1name = %s,b1uid = %s,b1issuedate=%s,b1returndate=%s,fine=%s WHERE b1uid = %s """ newreturndate = returndate + remainderdate data2 = (bookname,bookuid,tday,returndate,fine,bookuid) cursor.execute(reissuequery2,data2) con.commit() print("Book Has been reissued to you") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Has been reissued to "+str(username)+"\nReturn Date : "+str(newreturndate)+"\nTotal Fine: "+str(fine)) window.finalize() player.play_song("bookreissue.mp3") cursor.execute("Select lid, name ,b2returndate,b2issuedate,issued FROM usersdatabase WHERE b2uid="+str(bookuid)) result17 = cursor.fetchone() if (result17 is not(None)) and (result2 is None): m1 = result17[2] ynew1 = m1[0:4] yint1 = int(ynew1) mnew1 = m1[5:7] mint1 = int(mnew1) dnew1 = m1[8:10] dint1 = int(dnew1) previousreturndate1 = datetime.date(yint1,mint1,dint1) tday = datetime.date.today() remainderdate=previousreturndate1 - tday remainderday = remainderdate.days if remainderday < 7 and remainderday >= 0: reissuequery3 = """ UPDATE usersdatabase SET b2name = %s,b2uid = %s,b2issuedate=%s,b2returndate=%s WHERE b2uid = %s """ newreturndate = returndate + remainderdate data3 = (bookname,bookuid,tday,newreturndate,bookuid) cursor.execute(reissuequery3,data3) con.commit() print("Book Has been reissued to you") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Has been reissued to "+str(username)+"\nReturn Date :"+str(newreturndate)) window.finalize() player.play_song("bookreissue.mp3") elif remainderday < 0 : absremainderday = abs(remainderday) fine = intissuefine + 2 * absremainderday reissuequery4 = """ UPDATE usersdatabase SET b2name = %s,b2uid = %s,b2issuedate=%s,b2returndate=%s,fine=%s WHERE b2uid = %s """ newreturndate = returndate + remainderdate data4 = (bookname,bookuid,tday,returndate,fine,bookuid) cursor.execute(reissuequery4,data4) con.commit() print("Book Has been reissued to you") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Has been reissued to "+str(username)+"\nReturn Date : "+str(newreturndate)+"\nTotal Fine: "+str(fine)) window.finalize() player.play_song("bookreissue.mp3") cursor.execute("Select lid, name ,b3returndate,b3issuedate,issued FROM usersdatabase WHERE b3uid="+str(bookuid)) result18 = cursor.fetchone() if (result18 is not(None)) and (result17 is None) and (result2 is None): m1 = result18[2] ynew1 = m1[0:4] yint1 = int(ynew1) mnew1 = m1[5:7] mint1 = int(mnew1) dnew1 = m1[8:10] dint1 = int(dnew1) previousreturndate1 = datetime.date(yint1,mint1,dint1) tday = datetime.date.today() remainderdate=previousreturndate1 - tday remainderday = remainderdate.days if remainderday < 7 and remainderday >= 0: reissuequery5 = """ UPDATE usersdatabase SET b3name = %s,b3uid = %s,b3issuedate=%s,b3returndate=%s WHERE b3uid = %s """ newreturndate = returndate + remainderdate data5 = (bookname,bookuid,tday,newreturndate,bookuid) cursor.execute(reissuequery5,data5) con.commit() print("Book Has been reissued to you") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Has been reissued to "+str(username)+"\nReturn Date :"+str(newreturndate)) window.finalize() player.play_song("bookreissue.mp3") elif remainderday < 0 : absremainderday = abs(remainderday) fine = intissuefine + 2 * absremainderday reissuequery6 = """ UPDATE usersdatabase SET b3name = %s,b3uid = %s,b3issuedate=%s,b3returndate=%s,fine=%s WHERE b3uid = %s """ newreturndate = returndate + remainderdate data6 = (bookname,bookuid,tday,returndate,fine,bookuid) cursor.execute(reissuequery6,data6) con.commit() print("Book Has been reissued to you") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Has been reissued to "+str(username)+"\nReturn Date : "+str(newreturndate)+"\nTotal Fine: "+str(fine)) window.finalize() player.play_song("bookreissue.mp3") cursor.execute("Select lid, name ,b4returndate,b4issuedate,issued FROM usersdatabase WHERE b4uid="+str(bookuid)) result19 = cursor.fetchone() if (result19 is not(None)) and (result2 is None) and (result17 is None) and (result18 is None): m1 = result19[2] ynew1 = m1[0:4] yint1 = int(ynew1) mnew1 = m1[5:7] mint1 = int(mnew1) dnew1 = m1[8:10] dint1 = int(dnew1) previousreturndate1 = datetime.date(yint1,mint1,dint1) tday = datetime.date.today() remainderdate=previousreturndate1 - tday remainderday = remainderdate.days if remainderday < 7 and remainderday >= 0: reissuequery7 = """ UPDATE usersdatabase SET b4name = %s,b4uid = %s,b4issuedate=%s,b4returndate=%s WHERE b4uid = %s """ newreturndate = returndate + remainderdate data7 = (bookname,bookuid,tday,newreturndate,bookuid) cursor.execute(reissuequery7,data7) con.commit() print("Book Has been reissued to you") window['-LEFT-'].update(value="") window.finalize() window['-OUTPUT-'].update(value="Book Has been reissued to "+str(username)+"\nReturn Date :"+str(newreturndate)) window.finalize() player.play_song("bookreissue.mp3") elif remainderday < 0 : absremainderday = abs(remainderday) fine = intissuefine + 2 * absremainderday reissuequery8 = """ UPDATE usersdatabase SET b4name = %s,b4uid = %s,b4issuedate=%s,b4returndate=%s,fine=%s WHERE b4uid = %s """ newreturndate = returndate + remainderdate data8 = (bookname,bookuid,tday,returndate,fine,bookuid) cursor.execute(reissuequery8,data8)