Smart Shopping Cart with POS Thermal Printer, Barcode Scanner, 20x4 LCD and Raspberry Pi

Published  February 3, 2022   0
Smart Shopping Cart with Automatic Billing System

Today, in this project we are going to build a Smart Shopping cart by interfacing a thermal receipt printer, LCD, and a USB barcode scanner with Raspberry Pi. This Smart Shopping cart will scan an item’s Barcode, display its information on 20x4 LCD, create the invoice, and print it using a Point of Service (POS) Thermal Printer. We will be using a Google spreadsheet to retrieve the data associated with the respective scanned barcode, like item Name, Price, etc. Also, we will create an online database using Google Spreadsheet where the information of all the items is already stored. You should check out our previous articles, if you want to know the interfacing of Raspberry Pi and Barcode Scanner or Raspberry Pi with Thermal Printer or Raspberry Pi with LCD.

 

 

 

Components Required for Smart Shopping Cart

Raspberry Pi 3

1

Barcode Scanner

1

20x4 alphanumeric LCD

1

Thermal Printer

1

Power Supplies (Either Batteries or Adopter)

As required

Jumper Wires

As required

Note: For instance, we are using Adaptor of 9V for thermal printer and Adaptor of 5V for Raspberry Pi 3.

Smart Shopping Cart

In the above image, you can see the actual setup I've made for this project.

For the Enclosure of components, I've made a cardboard box of around 15cm X 12cm and it was looking like this,

Smart Shopping Cart Setup

Circuit Diagram for Smart Shopping Cart

Circuit Diagram for Smart Shopping Cart

The above image is showing you the connection diagram of an interfacing barcode scanner, Thermal printer, and LCD with Raspberry Pi 3. You can also take the reference from the following connection table.

Thermal Printer

Raspberry Pi 3

RXD

TXD i.e. GPIO 14

TXD

RXD i.e. GPIO 15

TDR

GND

GND

GND

Barcode Scanner

USB

USB

20x4 LCD

SCL

SCL i.e. GPIO 3

SDA

SDA i.e. GPIO 2

GND

GND

VCC

+5V

Programming the Smart Shopping Cart

Now after getting all the components connected, it's time to move on to the coding part of our smart shopping cart. Before we go further, let's revise the concepts that we have learned from our previous projects. I am creating a list of the key learnings from our previous article along with the link, so that, you can visit the link if you have any doubt.

Explanation of the Code

import gspread
from time import sleep
from RPLCD.i2c import CharLCD
lcd = CharLCD('PCF8574', 0x27)
from escpos.printer import Serial
from datetime import datetime
now = datetime.now()
dt_string = now.strftime("%b/%d/%Y %H:%M:%S")
lcd.cursor_pos = (0, 0)
lcd.write_string("Initiallising...")
#locating the spread sheet json file
gc = gspread.service_account(filename='/home/pi/Ali Proj/Proj 4 Shoping Cart with Thermal Printer/Shopping Cart on 20_4 LCD/shop-data-thermal-585dc7bffa1f.json')
#sheet name is to be passed
sh = gc.open("Shop Data for Thermal")
worksheet=sh.get_worksheet(0)

In the above piece of code, we are importing all the necessary Libraries like gspread for Google Sheets API, time and sleep for delay or sleep function, RPLCD for 20X4 LCD, escpos for controlling the Thermal Printer serially and datetime for getting the current date and time.

I have created a Google sheet named, “Shop Data for Thermal” using my Google account. You can make your own using any name you like. For creating the Google Sheet and JSON of the Google service account, please refer to the GSPREAD Documentation.

Now, we will open worksheet 1 by calling the get_worksheet(0) and will open it as sh.

""" 9600 Baud, 8N1, Flow Control Enabled """
p = Serial(devfile='/dev/serial0',
           baudrate=9600,
           bytesize=8,
           parity='N',
           stopbits=1,
           timeout=1.00,
           dsrdtr=True)

By this piece of code, we will be initializing and setting up the serial port by the given Parameters.

count=0
item_cost=0
totalCost=0
SNo=0
scode=""
qty=1
scodePrev=0
item_name=""
entryF=[]
p.set(
    align="center",
    font="a",
    width=1,
    height=1, 
    )

Now we will initialize the required variables to ‘0’ or " " so that they will not contain any garbage values. Also, by set() function we will set the default mode of printing for thermal printer.

def print_receipt():
    p.text("\n")
    p.set(
            align="center",
            font="a",
            width=1,
            height=1,   
        )
    #Printing the image
    p.image("/home/pi/Ali Proj/Proj 3 Interfacing thermal printer with pi/CD_new_Logo_black.png",impl="bitImageColumn")
    #printing the initial data
    p.set(width=2,
         height=2,
         align="center",)
    p.text(" ===============\n")
    p.text("Tax Invoice\n")
    p.text(" ===============\n")
    p.set(width=1,
         height=1,
         align="left",)
    p.text("CIRCUIT DIGEST\n")
    p.text("AIRPORT ROAD\n")
    p.text("LOCATION : JAIPUR\n")
    p.text("TEL : 0141222585\n")
    p.text("GSTIN : 08AAMFT88558855\n")
    p.text("Bill No. : \n\n")
    p.text("DATE : ")
    p.text(dt_string)
    p.text("\n")
    p.text("CASHIER : \n")
    p.text(" ===========================\n")
    p.text("S.No     ITEM   QTY   PRICE\n")
    p.text(" ------------------------------\n")
    print(text_F)
    p.text(text_F)
    p.text(" -------------------------------\n")
    p.set(
            # underline=0,
            align="right",
         )
    p.text("     SUBTOTAL:  ")
    p.text(totalCostS)
    p.text("\n")         
    p.text("     DISCOUNT:  0\n")
    p.text("     VAT @ 0%: 0\n")
    p.text(" ===========================\n")
    p.set(align="center", 
       )
    p.text("    BILL TOTAL: ")
    p.text(totalCostS)
    p.text("\n")
    p.text(" --------------------------\n")
    p.text("THANK YOU\n")   
    p.set(width=2,
         height=2,
         align="center",)
    p.text(" ===============\n")
    p.text("Please scan\nto Pay\n")
    p.text(" ===============\n")
    p.set(
            align="center",
            font="a",
            width=1,
            height=1,
            density=2,
            invert=0,
            smooth=False,
            flip=False,      
        )
    p.qr("9509957951@ybl",native=True,size=12)
    p.text("\n")
    p.barcode('123456', 'CODE39')
    #if your printer has paper cuting facility then you can use this function
    p.cut()
    print("prnting done")

Now with the above piece of code, we will be creating a function that will print the bill at once. The format of the invoice is set in the same function.

p.barcode () function will let you print the barcode that contains ‘123456’.

We are using try and except concept for checking whether the scanned barcode is matched with the database sheet or not, if the scanned barcode is unknown or unauthorized, then a message will print on LCD and on Terminal that is

“Unknown Barcode or Item Not Registered”

This can be seen under the following piece of code.

lcd.cursor_pos = (0, 0)
lcd.write_string('Please Scan...')
while 1:
    try:
        scode=input("Scan the barcode")      
        if scode=="8906128542687": #Bill Printing Barcode pasted on the Thermal Printer
            print("done shopping ")
            lcd.clear()
            print(*entryF)
            print("in string")
            print(len(entryF))
            text_F=" "
            for i in range(0,len(entryF)):
                text_F=text_F+entryF[i]
                i=i+1          
            lcd.cursor_pos = (0, 0)
            lcd.write_string("Thanks for Shopping")         
            lcd.cursor_pos = (1, 7)
            lcd.write_string("With Us")          
            lcd.cursor_pos = (3, 0)
            lcd.write_string("Printing Invoice...")
            print_receipt()
        else:
            cell=worksheet.find(scode)
            print("found on R%sC%s"%(cell.row,cell.col))
            item_cost = worksheet.cell(cell.row, cell.col+2).value
            item_name = worksheet.cell(cell.row, cell.col+1).value
            lcd.clear()
            SNo=SNo+1   
            entry = [SNo,item_name,qty,item_cost]
            entryS=str(entry)+'\n'
            print("New Item ",*entry)
            lcd.cursor_pos = (0, 2)
            lcd.write_string(str(SNo))
            lcd.cursor_pos = (0, 5)
            lcd.write_string("Item(s) added")          
            lcd.cursor_pos = (1, 1)
            lcd.write_string(item_name)          
            lcd.cursor_pos = (2, 5)
            lcd.write_string("of Rs.")
            lcd.cursor_pos = (2, 11)
            lcd.write_string(item_cost)           
            item_cost=int(item_cost)
            totalCost=item_cost+totalCost           
            lcd.cursor_pos = (3, 4)
            lcd.write_string("Cart Total")           
            lcd.cursor_pos = (3, 15)
            lcd.write_string(str(totalCost))           
            entryF.append(entryS)   #adding entry in Final Buffer
            sleep(2)           
    except:
        print("Unknown Barcode or Item Not Registered")
        lcd.clear()
        lcd.cursor_pos = (0, 0)
        lcd.write_string("Item Not Found...")
        lcd.cursor_pos = (2, 0)
        lcd.write_string("Scan Again...")
        sleep(2)

Full code can be found at the bottom of this page.

How to use the Cart

  1. Scan the barcode of the Item
  2. Put it in the cart
  3. Check whether the details shown on the LCD is correct
  4. Scan another item and do the same
  5. After getting all the required things, scan the Bill triggering Barcode pasted on the Thermal Printer
  6. Collect the invoice and scan the QR for Payment through UPI.

Conclusion

So that's how we can build our own Smart Shopping cart which has a barcode scanner to scan the Item’s Barcode, grab the price from the database, display the scanned item details on LCD for assistance, and a thermal receipt printer for printing the Invoice. We can use the same setup in multiple applications. We will be happy to know from you as well. For more exciting projects stay connected. And, if you have any questions or suggestions, you can put them in the comment section or can use our forum.

Code

# import sys
#  
# sys.path.insert(0, '/home/pi/Ali Proj/Libraries')
import gspread
from time import sleep
from RPLCD.i2c import CharLCD
lcd = CharLCD('PCF8574', 0x27)
from escpos.printer import Serial
from datetime import datetime
now = datetime.now()
dt_string = now.strftime("%b/%d/%Y %H:%M:%S")
lcd.cursor_pos = (0, 0)
lcd.write_string("Initiallising...")
#locating the spread sheet json file
gc = gspread.service_account(filename='/home/pi/Ali Proj/Proj 4 Shoping Cart with Thermal Printer/Shopping Cart on 20_4 LCD/shop-data-thermal-585dc7bffa1f.json')
#sheet name is to be passed
sh = gc.open("Shop Data for Thermal")
worksheet=sh.get_worksheet(0)
count=0
item_cost=0
totalCost=0
SNo=0
scode=""
qty=1
scodePrev=0
item_name=""
entryF=[]
""" 9600 Baud, 8N1, Flow Control Enabled """
p = Serial(devfile='/dev/serial0',
           baudrate=9600,
           bytesize=8,
           parity='N',
           stopbits=1,
           timeout=1.00,
           dsrdtr=True)
p.set(
    align="center",
    font="a",
    width=1,
    height=1,    
    )
def print_receipt():
    p.text("\n")
    p.set(
            align="center",
            font="a",
            width=1,
            height=1,    
        )
    #Printing the image
    p.image("/home/pi/Ali Proj/Proj 3 Interfacing thermal printer with pi/CD_new_Logo_black.png",impl="bitImageColumn")
    #printing the initial data
    p.set(width=2,
         height=2,
         align="center",)
    p.text(" ===============\n")
    p.text("Tax Invoice\n")
    p.text(" ===============\n")
    p.set(width=1,
         height=1,
         align="left",)
    p.text("CIRCUIT DIGEST\n")
    p.text("AIRPORT ROAD\n")
    p.text("LOCATION : JAIPUR\n")
    p.text("TEL : 0141222585\n")
    p.text("GSTIN : 08AAMFT88558855\n")
    p.text("Bill No. : \n\n")
    p.text("DATE : ")
    p.text(dt_string)
    p.text("\n")
    p.text("CASHIER : \n")
    p.text(" ===========================\n")
    p.text("S.No     ITEM   QTY   PRICE\n")
    p.text(" -------------------------------\n")
    print(text_F)
    p.text(text_F)
    p.text(" -------------------------------\n")
    p.set(
            # underline=0,
            align="right",
         )
    p.text("     SUBTOTAL:  ")
    p.text(totalCostS)
    p.text("\n")          
    p.text("     DISCOUNT:  0\n")
    p.text("     VAT @ 0%: 0\n")
    p.text(" ===========================\n")
    p.set(align="center",  
         )
    p.text("    BILL TOTAL: ")
    p.text(totalCostS)
    p.text("\n")
    p.text(" --------------------------\n")
    p.text("THANK YOU\n")   
    p.set(width=2,
         height=2,
         align="center",)
    p.text(" ===============\n")
    p.text("Please scan\nto Pay\n")
    p.text(" ===============\n")
    p.set(
            align="center",
            font="a",
            width=1,
            height=1,
            density=2,
            invert=0,
            smooth=False,
            flip=False,      
        )
    p.qr("9509957951@ybl",native=True,size=12)
    p.text("\n")
    p.barcode('123456', 'CODE39')
    #if your printer has paper cuting facility then you can use this function
    p.cut()
    print("prnting done")   
lcd.cursor_pos = (0, 0)
lcd.write_string('Please Scan...')
while 1:
    try:
        scode=input("Scan the barcode")       
        if scode=="8906128542687": #Bill Printing Barcode
            print("done shopping ")
            lcd.clear()
            print(*entryF)
            print("in string")
            print(len(entryF))
            text_F=" "
            for i in range(0,len(entryF)):
                text_F=text_F+entryF[i]
                i=i+1           
            lcd.cursor_pos = (0, 0)
            lcd.write_string("Thanks for Shopping")           
            lcd.cursor_pos = (1, 7)
            lcd.write_string("With Us")           
            lcd.cursor_pos = (3, 0)
            lcd.write_string("Printing Invoice...")
            print_receipt() 
        else:
            cell=worksheet.find(scode)
            print("found on R%sC%s"%(cell.row,cell.col))
            item_cost = worksheet.cell(cell.row, cell.col+2).value
            item_name = worksheet.cell(cell.row, cell.col+1).value
            lcd.clear()
            SNo=SNo+1   
            entry = [SNo,item_name,qty,item_cost]
            entryS=str(entry)+'\n'
            print("New Item ",*entry)
            lcd.cursor_pos = (0, 2)
            lcd.write_string(str(SNo))
            lcd.cursor_pos = (0, 5)
            lcd.write_string("Item(s) added")           
            lcd.cursor_pos = (1, 1)
            lcd.write_string(item_name)           
            lcd.cursor_pos = (2, 5)
            lcd.write_string("of Rs.")
            lcd.cursor_pos = (2, 11)
            lcd.write_string(item_cost)           
            item_cost=int(item_cost)
            totalCost=item_cost+totalCost           
            lcd.cursor_pos = (3, 4)
            lcd.write_string("Cart Total")           
            lcd.cursor_pos = (3, 15)
            lcd.write_string(str(totalCost))           
            entryF.append(entryS)   #adding entry in Final Buffer
            sleep(2)           
    except:
        print("Unknown Barcode or Item Not Registered")
        lcd.clear()
        lcd.cursor_pos = (0, 0)
        lcd.write_string("Item Not Found...")
        lcd.cursor_pos = (2, 0)
        lcd.write_string("Scan Again...")
        sleep(2)

Video

Have any question realated to this Article?

Ask Our Community Members