IoT based Smart Shopping Cart using RFID and NodeMCU

IoT based Smart Shopping Cart using RFID and NodeMCU

We all have waited in a queue for payment in shopping malls and other places, its very tiring and wastes a lot of time in the billing process. Today we will build a smart shopping cart with an automatic billing system that not only reduces the waiting time but also makes the process very smooth and easy.

 

Here we use RFID cards and RFID readers with NodeMCU to build the Smart Shopping Cart project. The cart information and total value will be displayed on the webpage as well as on LCD. Each RFID card is associated with a certain product and an RFID reader is installed in the cart, which reads the product details like Price and Product details and sends them to NodeMCU ESP8266. Then NodeMCU process the available items and total value in the cart and send them to ESP8266 Webserver, which can be monitored on a web browser from anywhere in the world. Web servers are used to control or monitor any sensor values using web browsers, we previously created many webservers using ArduinoESP8266NodeMCUESP32Raspberry Pi, etc.

 

Materials Required

  • ESP8266 NodeMCU -1
  • 16*2 Alphanumeric LCD-1
  • I2C module for 16*2 LCD-1
  • 4 pin Tactile switch-1
  • EM18 RFID Reader-1

 

EM18 RFID Reader and it's Working

EM18 RFID Reader Module

RFID stands for Radio-frequency identification. It refers to a technology, where digital data is encoded in RFID tags and decoded by an RFID reader using radio waves. RFID is similar to barcoding in which data from a tag is decoded by an RFID reader device. The RFID technology is used in various applications like inventory management, attendance system, door lock system, access to restricted areas, etc.

 

EM18 Reader is a very popular RFID module that can read the ID information stored in the RFID tags. The RFID tags stores a 12 digit unique number which can be decoded by an EM18 reader module, when the tag comes in a range of the Reader. This module has an inbuilt antenna that operates at a frequency of 125 kHz and a 5v DC power supply is required to power it up.

 

It gives a serial data output and has a range of 8-12cm. The serial communication parameters are 8 data bits, 1 stop bit and 9600 baud rate.

RFID Tag

 

EM18 RFID Reader Features: 

  • Operating  voltage: +4.5V to +5.5V DC
  • Current consumption:50mA
  • Operating frequency:125KHZ
  • Operating temperature: 0-80 degree C
  • Communication Baud Rate:9600
  • Reading distance: 8-12 cm
  • Antenna: Inbuilt

 

EM18 RFID Reader Pinout: 

EM18 RFID Reader Pinout

 

EM18 RFID Reader Pin description: 

VCC: 4.5- 5V DC voltage input

GND: Ground pin

Buzzer: Buzzer or LED pin

TX: Serial data Transmitter pin of EM18 for RS232 (Output)

SEL: This must be HIGH for using RS232 (LOW if using WEIGAND)

Data 0: WEIGAND data 0

Data 1: WEIGAND data 1

 

IoT based Smart Shopping Cart Circuit Diagram

Complete circuit diagram for RFID based Intelligent Shopping Trolley System is given below:

RFID based Intelligent Shopping Trolley System Circuit Diagram

This is how the whole setup looks on a breadboard:

Smart Shopping Cart using RFID and NodeMCU

 

Programming NodeMCU Using Arduino IDE

To upload code into NodeMCU using Arduino IDE, follow the steps below:

1. Open Arduino IDE, then go to File–>Preferences–>Settings.

Arduino IDE Settings

 

2. Type https://arduino.esp8266.com/stable/package_esp8266com_index.json in the ‘Additional Board Manager URL’ field and click ‘Ok’.

NodeMCU Programming

 

3. Now go to Tools > Board > Boards Manager. In the Boards Manager window, Type ESP8266 in the search box, select the latest version of the board and click on install.

Arduino IDE Programming

 

4. After installation is complete, go to Tools ->Board -> and select NodeMCU 1.0(ESP-12E Module). Now you can program NodeMCU with Arduino IDE.

 

Find out Unique 12 digit Code for RFID Tag

Before programming the NodeMCU for the smart shopping cart project, first, we need to find out the 12 digit RFID tag unique code. As discussed before, RFID tags contain a 12 digit unique code and it can be decoded by using an RFID reader. When the RFID card is swiped near the Reader, the Reader will give the unique codes via the output serial port when it is connected to NodeMCU. First, connect the NodeMCU to the RFID reader as per the circuit diagram and then upload the code below to NodeMCU.

 

After successfully uploading the code, open the serial monitor and set the baud rate to 9600. Then swipe the card near the Reader and you can now see the 12 digit code on the serial monitor as shown in the snapshot below. Do this process for all the used RFID tags and note it down for future references.

int count = 0;
char card_no[12];
void setup()
{
   Serial.begin(9600);
}

void loop()
{
   if(Serial.available())
   {
      count = 0;
      while(Serial.available() && count < 12)
      {
         card_no[count] = Serial.read();
         count++;
         delay(5);
      }
      Serial.print(card_no);
   }
}

RFID Code

 

Code Explanation

After the successful completion of the hardware setup, now it's time to program NodeMCU. Complete code for this RFID based smart trolley project along with the video is given at the end of this tutorial. The stepwise description of the code is given below.

 

Start the code by including all the required library files in the code like ESP8266WiFi.h for ESP8266 board, LiquidCrystal_I2C.h for LCD, Wire.h for SPI communication, etc.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <LiquidCrystal_I2C.h>
#include<Wire.h>

 

Then create the ESP8266WebServer class object with the name server and default port number 80.

ESP8266WebServer server (80);

 

Now, declare the network credentials- i.e. SSID and password. It is required to connect the NodeMCU to the internet.

const char* ssid = "admin";
const char* password = "12345678";

 

For using the I2C module for 16*2 Alphanumeric LCD, configure it using the LiquidCrystal_I2C class. Here we have to pass the address, row, and column number which are 0x27, 16, and 2 respectively in our case.

LiquidCrystal_I2C lcd(0x27, 16, 2);

 

Inside setup (), declare all the input pins and output pins. Then print a welcome message on the LCD which will be displayed during the initialization of the project.

  pinMode(D3,INPUT_PULLUP);
  pinMode(D4,OUTPUT);
  Serial.begin(9600);
  WiFi.begin(ssid, password);
  Wire.begin(D2, D1);
  lcd.begin(16, 2);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("   WELCOME TO       ");
  lcd.setCursor(0, 1);
  lcd.print("   SMART CART       ");

 

Then, to connect NodeMCU to the internet, call WiFi.begin and pass network SSID and password as its arguments. Check for the successful network connection using WiFi.status() and after a successful connection, print a message on LCD with IP address.

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    lcd.setCursor(0, 0);
    lcd.print("WiFi connecting...          ");
  }
  lcd.setCursor(0, 0);
  lcd.print("WiFi connected          ");
  lcd.setCursor(0, 1);
  lcd.print(WiFi.localIP());
  delay(1500);

 

In the next step, an HTML page is created as shown below, which has an HTML table to show the product details and billing information in the cart. The HTML page is stored in a string variable so that it can be sent back on client request using a server.send() function.

server.on("/", []()
  {
    page = "<html><head><title>E Cart using IoT</title></head><style type=\"text/css\">";
    page += "table{border-collapse: collapse;}th {background-color:  #3498db ;color: white;}table,td {border: 4px solid black;font-size: x-large;";
    page += "text-align:center;border-style: groove;border-color: rgb(255,0,0);}</style><body><center>
    page += "<h1>Smart Shopping Cart using IoT</h1><br><br><table style=\"width: 1200px;height: 450px;\"><tr>";
    page += "<th>ITEMS</th><th>QUANTITY</th><th>COST</th></tr><tr><td>Biscuit</td><td>"+String(p1)+"</td><td>"+String(c1)+"</td></tr>";
    page += "<tr><td>Soap</td><td>"+String(p2)+"</td><td>"+String(c2)+"</td></tr><tr><td>Rice(1KG)</td><td>"+String(p3)+"</td><td>"+String(c3)+"</td>";
    page += "</tr><tr><td>Tea(50g)</td><td>"+String(p4)+"</td><td>"+String(c4)+"</td></tr><tr><th>Grand Total</th><th>"+String(count_prod)+"</th><th>"+String(total)+"</th>";
    page += "</tr></table><br><input type=\"button\" name=\"Pay Now\" value=\"Pay Now\" style=\"width: 200px;height: 50px\"></center></body></html>";
    page += "<meta http-equiv=\"refresh\" content=\"2\">";
    server.send(200, "text/html", page);
  });
  server.begin();

 

Inside loop(), the digital pin where the push button is connected is read using digitalRead() and stored in an integer variable. Here we are using a button to remove a product from the cart.

int a=digitalRead(D3);

 

Now in the below code, the unique 12 digit codes of the RFID tags are decoded and stored in an array. Then the elements of the array will be matched with the Stored Tag numbers in the memory, to get the product details.

count = 0;
    while (Serial.available() && count < 12)
    {
      input[count] = Serial.read();
      count++;
      delay(5);
    }

 

Here, we compare the received array with the stored tag codes, if the button is not pressed and the code matches, then the below condition is executed and the product is added in the shopping cart. The same information will be displayed on LCD. The below code increase the product numbers in the cart and add the price in total cart value.

if ((strncmp(input, "0B00291F5B66", 12) == 0) && (a == 1))
      {
        lcd.setCursor(0, 0);
        lcd.print("Biscuit Added       ");
        lcd.setCursor(0, 1);
        lcd.print("Price(Rs):35.00      ");
        p1++;
        digitalWrite(D4,HIGH);
        delay(2000);
        total = total + 35.00;
        count_prod++;
        digitalWrite(D4,LOW);
        lcd.clear();
      }

 

Now the below condition will be executed when the button is pressed, and the RFID tag codes are matched with the stored array. This means we have to remove this product from the cart and subtract the product price from the total cart value.

else if ((strncmp(input, "0B00291F5B66", 12) == 0) && (a == 0))
      {
        if(p1>0)
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Biscuit Removed!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        p1--;
        total = total - 35.00;
        count_prod--;
        lcd.clear();
        digitalWrite(D4,LOW);
        }
        else
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Not in cart!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        digitalWrite(D4,LOW);
        lcd.clear();
        }
      }

 

Finally, the individual costs of the products are calculated as follows. Here some random cost values are chosen which you can be changed as per choice.

    c1=p1*35.00;
    c2=p2*38.00;
    c3=p3*55.00;
    c4=p4*45.00;

 

In the end, call server.handleClient() to handle new requests and check them.

server.handleClient();

IoT based Smart Shopping Cart Working

Smart Shopping Cart using IoT

So this is how a Smart Shopping Trolley using RFID can be built and can be monitored on a webpage from anywhere in the world.

Code

#include<ESP8266WiFi.h>
#include<WiFiClient.h>
#include<ESP8266WebServer.h>
#include<LiquidCrystal_I2C.h>
#include<Wire.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const char* ssid = "admin";//Replace with your network SSID
const char* password = "12345678";//Replace with your network password

ESP8266WebServer server(80);

String page = "";
char input[12];
int count = 0;


int a;
int p1=0,p2=0,p3=0,p4=0;
int c1=0,c2=0,c3=0,c4=0;

double total = 0;
int count_prod = 0;
void setup()
{
  pinMode(D3,INPUT_PULLUP);
  pinMode(D4,OUTPUT);
  
  Serial.begin(9600);
  WiFi.begin(ssid, password);
  Wire.begin(D2, D1);
  lcd.begin(16, 2);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("   WELCOME TO       ");
  lcd.setCursor(0, 1);
  lcd.print("   SMART CART       ");

  delay(2000);

  lcd.clear();

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  lcd.setCursor(0, 0);
  lcd.print("WiFi Connecting...  ");
  }
  Serial.print(WiFi.localIP());
  lcd.setCursor(0, 0);
  lcd.print("WiFi Connected");
  lcd.setCursor(0, 1);
  lcd.print(WiFi.localIP());
  delay(1000);
  
  lcd.setCursor(0, 0);
  lcd.print(" PLZ ADD ITEMS     ");
  lcd.setCursor(0, 1);
  lcd.print("    TO CART          ");

server.on("/", []()
  {
    page = "<html><head><title>E Cart using IoT</title></head><style type=\"text/css\">";
    page += "table{border-collapse: collapse;}th {background-color:  #3498db ;color: white;}table,td {border: 4px solid black;font-size: x-large;";
    page += "text-align:center;border-style: groove;border-color: rgb(255,0,0);}</style><body><center>";
    page += "<h1>Smart Shopping Cart using IoT</h1><br><br><table style=\"width: 1200px;height: 450px;\"><tr>";
    page += "<th>ITEMS</th><th>QUANTITY</th><th>COST</th></tr><tr><td>Biscuit</td><td>"+String(p1)+"</td><td>"+String(c1)+"</td></tr>";
    page += "<tr><td>Soap</td><td>"+String(p2)+"</td><td>"+String(c2)+"</td></tr><tr><td>Rice(1KG)</td><td>"+String(p3)+"</td><td>"+String(c3)+"</td>";
    page += "</tr><tr><td>Tea(50g)</td><td>"+String(p4)+"</td><td>"+String(c4)+"</td></tr><tr><th>Grand Total</th><th>"+String(count_prod)+"</th><th>"+String(total)+"</th>";
    page += "</tr></table><br><input type=\"button\" name=\"Pay Now\" value=\"Pay Now\" style=\"width: 200px;height: 50px\"></center></body></html>, page);
  });
  server.begin();
}
void loop()
{
  int a=digitalRead(D3);
  if (Serial.available())
  {
    count = 0;
    while (Serial.available() && count < 12)
    {
      input[count] = Serial.read();
      count++;
      delay(5);
    }
    if (count == 12)
    {
      if ((strncmp(input, "0B00291F5B66", 12) == 0) && (a == 1))
      {
        lcd.setCursor(0, 0);
        lcd.print("Biscuit Added       ");
        lcd.setCursor(0, 1);
        lcd.print("Price(Rs):35.00      ");
        p1++;
        digitalWrite(D4,HIGH);
        delay(2000);
        total = total + 35.00;
        count_prod++;
        digitalWrite(D4,LOW);
        lcd.clear();
      }
      else if ((strncmp(input, "0B00291F5B66", 12) == 0) && (a == 0))
      {
        if(p1>0)
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Biscuit Removed!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        p1--;
        total = total - 35.00;
        count_prod--;
        lcd.clear();
        digitalWrite(D4,LOW);
        }
        else
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Not in cart!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        digitalWrite(D4,LOW);
        lcd.clear();
        }
      }
      else if ((strncmp(input, "0B002920D0D2", 12) == 0) && (a == 1))
      {
        lcd.setCursor(0, 0);
        lcd.print("Soap Added          ");
        lcd.setCursor(0, 1);
        lcd.print("Price(Rs):38.00         ");
        total = total + 38.00;
        digitalWrite(D4,HIGH);
        delay(2000);
        p2++;
        count_prod++;
        digitalWrite(D4,LOW);
        lcd.clear();
      }
      else if ((strncmp(input, "0B002920D0D2", 12) == 0) && (a == 0))
      {
         if(p2>0)
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Soap Removed!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        p2--;
        total = total - 38.00;
        count_prod--;
        lcd.clear();
        digitalWrite(D4,LOW);
        }
        else
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Not in cart!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        lcd.clear();
        digitalWrite(D4,LOW);
        }
      }
      else if ((strncmp(input, "0B002948A8C2", 12) == 0) && (a == 1))
      {
        lcd.setCursor(0, 0);
        lcd.print("Rice(1KG) Added       ");
        lcd.setCursor(0, 1);
        lcd.print("Price(Rs):55.00      ");
        total = total + 55.00;
        digitalWrite(D4,HIGH);
        delay(2000);
        count_prod++;
        p3++;
        lcd.clear();
        digitalWrite(D4,LOW);
      }
      else if ((strncmp(input, "0B002948A8C2", 12) == 0) && (a==0))
      {
        if(p3>0)
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Rice(1KG) Removed!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        total = total - 55.00;
        p3--;
        count_prod--;
        lcd.clear();
        digitalWrite(D4,LOW);
        }
        else
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Not in cart!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        lcd.clear();
        digitalWrite(D4,LOW);
        }
      }
      else if ((strncmp(input, "0B00283BFEE6", 12) == 0) && (a == 1))
      {
        lcd.setCursor(0, 0);
        lcd.print("Tea(50g) Added            ");
        lcd.setCursor(0, 1);
        lcd.print("Price(Rs):45.00        ");
        total = total + 45.00;
        count_prod++;
        digitalWrite(D4,HIGH);
        p4++;
        delay(2000);
        lcd.clear();
        digitalWrite(D4,LOW);
      }
      else if ((strncmp(input, "0B00283BFEE6", 12) == 0) && (a == 0))
      {
        if(p4>0)
        {
        lcd.clear();
        total = total - 45.00;
        lcd.setCursor(0, 0);
        count_prod--;
        p4--;
        lcd.print("Tea(50g) Removed!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        lcd.clear();
        digitalWrite(D4,LOW);
        }
        else
        {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Not in cart!!!        ");
        digitalWrite(D4,HIGH);
        delay(2000);
        lcd.clear();
        digitalWrite(D4,LOW);
        }
      }
      else if (strncmp(input, "0B00292BADA4", 12) == 0)
      {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Total Prod:");
        lcd.setCursor(11, 0);
        lcd.print(count_prod);
        lcd.setCursor(0, 1);
        lcd.print("Price:");
        lcd.setCursor(6, 1);
        lcd.print(total);
        
        digitalWrite(D4,HIGH);
        delay(2000);

        lcd.clear();
        digitalWrite(D5,LOW);
        lcd.setCursor(0, 0);
        lcd.print("   Thank you        ");
        lcd.setCursor(0, 1);
        lcd.print("  for Shopping        ");
        digitalWrite(D4,LOW);
      }
    }
    c1=p1*35.00;
    c2=p2*38.00;
    c3=p3*55.00;
    c4=p4*45.00;
  }
server.handleClient();
}

Video

34 Comments

you have not shown connections of ESP8266 NodeMCU in circuit diagram
would you plz show the proper circuit diagram

Please send code in this mail vmanikandanece26@gmail.com

12 digit decoder code not working . It shows only empty box
and
main code error line 32 & 33
32 : LiquidCrystal_I2C has no member named 'init'(lcd.init)

33 : No matching function for call to LiquidCrystal_I2C::begin(int,int)

Please help me . Very very urgent

esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header
how do i solve this error?
i tried uploading by pressing and not pressing the button as well.

My lcd is not displaying any letters. And the compiler saying there is an error regarding lcd.begin and lcd.init() is urgent. Please mail the code sir. It's my major project and I don't have time

I have tried your steps....while finding RFID code....i get this error :

Error Request upload failed with message Upload error Failed uploading X uploading error exit status 2

Please give me a solution

If any one facing any problem in code part then contact me I will help you. This code having few errors in display part and html part I solved that problem I will help you.
+917653851434 in this number.