Smart Railway Ticket Verification using Raspberry Pi

Introduction

This prototype introduces an automated railway entry system that enhances ticket verification and passenger access control through a combination of QR code scanning and sensor integration. Passengers book tickets via a mobile app, which connects to the railway server and securely stores essential details in the database, such as name, age, and other ticket data. Upon booking, a unique QR code is generated for verification which stores the PNR value of the ticket. At the station, passengers scan this QR code at the entry, where an IoT device (Raspberry Pi) linked to the railway server verifies ticket authenticity. If valid, the IoT device will send a signal to open the gate and there is an ultrasonic sensor that checks if the person crossed the gate or not, and closes the gate based on that.

Acknowledgment

I would like to express my sincere gratitude to Dr. Rajbir Kaur for providing us with the invaluable opportunity to learn and apply the concepts taught in the Communication Technology for Internet of Things (CTIoT) elective. Her guidance was instrumental, particularly in the design of this prototype, and her support in facilitating the issuance of the Raspberry Pi from the lab enabled us to bring our ideas to life.

I would also like to extend my appreciation to my collaborator, Kanishk Garg. His dedication and active involvement were crucial to the successful completion of this project, and I am grateful for his partnership throughout this journey. Together, we were able to realize a meaningful and rewarding learning experience.

Requirements

To reproduce this prototype you need to have (hardware devices) :

  1. Raspberry Pi (I have used Raspberry Pi Model 3 B)

  2. SD Card (for installing Raspberry Pi OS)

  3. Ultrasonic Sensor (for measuring distance)

  4. LED Bulbs and jumper wires (male to female)

  5. Breadboard (to make this circuit)

  6. Pi Camera Module (for scanning QR Code) (although I had not used in this prototype but you can use it)

You also need to install some libraries/packages in your system and Raspberry Pi. (Software Requirements)

Your PC (which will act as the server)

Database Servers Made Easy: Explained with Illustrations

  1. SQLite (Link)

  2. Python (Link) (it will contain libraries such as sockets, zlib, sqlite3, and random (preinstalled)).

Raspberry Pi

  1. Python (it’s preinstalled in Raspberry Pi OS)

  2. OpenCV Library for Python : sudo apt-get install python3-opencv

  3. pyzbar library : pip install pyzbar

  4. GPIO (for I/O operations with RPi Pins) (it’s preinstalled most of the time) : sudo apt-get -y install python3-rpi.gpio

We used Raspberry Pi Model 3 B+ for this prototype with 64-bit raspberry Pi OS.

Also, many times you may not be able to use the pip command in Raspberry Pi directly, so you need to make an environment and then install the required libraries in that environment, and run code in that environment.

You can follow this link on how to do this : https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/

Also, you can access the code from this GitHub Repo : https://github.com/Shreyansh-Agarwal2022/SmartRailwayTicket

Demo Video

Understanding this Project Idea and Design

Design Diagram :

Let’s understand this step-by-step :

  1. You open the Railway app to book a train ticket, you will fill necessary details in the app, and click Generate Ticket.

  2. Then your mobile app will send all this information to the railway server and the server will generate the PNR number for your ticket, this number will be unique. This ticket will also inserted into the railway database for future purposes.

  3. The Railway Server will send a QR Code generated on your mobile app, which you will use at the Railway Station to get entry.

  4. Now, you go to the respective railway station to board the train. There will be a place where you will get this QR Code scanned at the QR Sensor (as shown in the figure) and get entry into the platform.

  5. The QR Sensor will decode the QR Code you scanned and will send the decoded value to the Microcontroller (RPi). The RPi will send this decoded value as PNR number to check on the Railway server.

  6. The Railway Server will check the PNR Number with the database. It will check how many times this PNR is being used and if this ticket is scanned for the correct railway station or not. If Yes, send True to the corresponding RPi and the RPi sends signal to open the Gate. If False is received a red light will be shown that ticket is wrong or already used.

  7. Also, the server will update that ticket appropriately. The ticket can only be used once for entry and exit both. Ticket is also checked at the exit because the passenger may book the ticket for a short distance and travel more distance than he/she had paid for.

  8. Also, the ultrasonic sensor helps to detect if the person has crossed the gate or not. This sensor is used as a proximity sensor, where distance changes when a person crosses the gate.

How does the Prototype work?

In this prototype, we will use a Local Area Network(LAN) to make the connection between our computer (which runs the server.py code) and RPi (which scans the QR Code and has Ultrasonic sensor attached).

Note : In this prototype, I was unable to use the Pi Camera Module, I have saved some sample QR Code Images and I will send these images by giving a file path.

Also, here we are assuming the ticket scanned at the correct railway station.

Now, let’s understand what is happening inside this prototype :

  1. Database : SQLite

    We are using SQLite for the railway database, where we have saved the database with the name ticketInfo. There we have only one table name tickets.

Schema :

CREATE TABLE tickets (
  hval INTEGER PRIMARY KEY UNIQUE NOT NULL,
  name TEXT,
  age INTEGER,
  trainNo INTEGER,
  coach INTEGER,
  seat INTEGER,
  randint INTEGER NOT NULL,
  used INTEGER DEFAULT 0
);

The hval attribute acting as the PNR Number, which is unique and acts as Primary Key for indexing in the table.

Also, we have randint attribute that restricts ticket PNR from getting regenerated from the information of the passenger (to achieve irreversibility).

The used attribute helps to keep track of how many times the ticket is being used. Its default value is 0 and this entry gets deleted automatically after used == 2.

Why we used SQLite is because it’s very lightweight and easy to use. It has mature libraries built for every popular programming language.

A sample of how the entries in the table look like :

  1. Connection in LAN using Sockets

    Since both devices : Computer (acting as Server) and Raspberry Pi will to connect to the same network (same LAN). We are connecting them using Socket Programming where we will provide IP of the Server to RPi to establish the connection. For socket programming, we are using Python in this case. Code can be accessed using GitHub Repo Link, see server.py and clientqr.py files for how sockets are working. Files contains comments and you can copy and paste code to ChatGPT and ask doubts on how the code works.

Why Python? Python has a range of inbuilt libraries to connect to sqlite and connection through sockets can be done using a few lines of code. Python is good for this prototype for faster development.

  1. Generating Hash Value

    We are using a 32-bit unsigned integer hash value, hashing algorithm is CRC32 (Cyclic Redundancy Check 32-bit) algorithm, which generates a 32-bit static hash.

Code for generating hash value :

import sqlite3
import zlib
import random

# Generate 32-bit Hash Value based on string provided
def generate_hash(s):
    return zlib.crc32(s.encode())

# Connecting to Database
con = sqlite3.connect("ticketInfo")
# Cursor, which is used to get current row of the select commands
cur = con.cursor()
while True:
    try:
        # Taking Inputs based on which we add entries
        name = input("Enter Name : ")
        age = int(input("Enter Age : "))
        train = int(input("Enter Train No : "))
        coach = int(input("Enter Coach : "))
        seat = int(input("Enter Seat : "))
        # r is randint
        r = random.randint(10000, 99999)
        used = 0
        hval = generate_hash(name + str(age) + str(train) + str(coach) + str(seat) + str(r))

        # Checking if this same entry already exists in DB or not
        temp = cur.execute("SELECT EXISTS(SELECT 1 FROM tickets WHERE name = ? AND age = ? AND trainNo = ? AND coach = ? AND seat = ? )",(name,age,train,coach,seat,)).fetchone()[0]
        if temp == 1:
            raise ValueError('A very specific bad thing happened.')

        # Inserting in DB
        cur.execute("INSERT INTO tickets VALUES (? , ? , ? , ? , ? , ? , ? , ?)", (hval,name,age,train,coach,seat,r,used,))
        res = cur.execute("SELECT * FROM tickets WHERE hval = ?",(hval,))
        con.commit()
        print(res.fetchall())
    except:
        print("Error Occured")
        break

# Closing Connection
con.close()
  1. OpenCV (for extracting value out of QR Code)

    Code :

import cv2  # OpenCV for image processing
from pyzbar.pyzbar import decode  # To decode QR codes
def read_qr_code_from_image(image_path):
    """
    Reads a QR code from the specified image file and returns the decoded data.
    """
    try:
        # Load the image
        image = cv2.imread(image_path)

        # Decode the QR code
        decoded_objects = decode(image)

        if decoded_objects:
            # Assume the first QR code found is the one we want
            qr_data = decoded_objects[0].data.decode('utf-8')
            print("QR Code data:", qr_data)
            return qr_data
        else:
            print("No QR code found in the image.")
            return None
    except Exception as e:
        print("An error occurred while reading the QR code:", e)
        return None

You can also do this using Pi Camera Module. Google it how to do this.

To generate QR Code Images, you can use this link .

  1. Find IP Address of the Server

You will need this IP address to be given to the clientqr.py file when running so that the connection can start. The IP Address of the IPv4 format and is a Private IP in the local network. You can find this address using commands in the terminal :

  • Windows : ipconfig

  • Linux : ifconfig

Eg.

  1. Ultrasonic Sensor as Proximity Sensor

    Robocraze Banggood HC-SR04 DC 5V Ultrasonic Module Distance Measuring Transducer Sensor

    In my college, I didn’t find any Proximity Sensor, so I used an Ultrasonic Sensor as a distance-measuring sensor. So, how this works is we capture how much time it takes for sound to come after bouncing back. And we multiply this time taken with the speed of sound. We can use this distance between the sensor and the object. If this distance goes down a particular threshold we close the door.

You can see the code from the clientqp.py file how this works. If the server returns True for the ticket, then we will start continuously measuring distance using an infinite loop and break after the distance drops a particular threshold. In this prototype, the green light starts and after the distance reaches a threshold, the light stops means the door is closed.

  1. Making Circuit using GPIO Pins

    Every sensor has pins that can be input, output, Vcc, and Ground. You can google how a sensor is used, and connected, and how these pins connect. GPIO Pins in the RPi are for Input and Output from the Sensor.

How to run this Prototype by yourself

  1. Install the necessary libraries on RPi and Your Computer.

  2. Run server.py on your PC and sometimes your server may not work because of network firewall so you have to disable it.

  3. Run clientqr.py on RPi after the circuit is done and make necessary changes in the clientqr.py file code based on what pins you connected with different sensors.

  4. Enter the server's private IP address in the client terminal to initiate the connections.

  5. Give a QR Code image path for decoding and sending to the server.

Limitations

This prototype has many limits and it should have as it’s just a stepping stone. Some limitations you can work upon :

  1. Using the Pi Camera Module and scanning the QR Code using that.

  2. Using better techniques to generate tickets and using better DBMS software.

  3. Making a network based on RPi address to identify if a ticket can be used for this railway station or not.

  4. Making different logic for entry and exit gate(s).

  5. Deploying this application on the internet.

  6. Making this prototype more secure.

Conclusion

We hope you can understand our prototype and the project idea. We didn’t learn all these once or just from watching a single tutorial. We had an idea and we tried to implement this idea into a small prototype.

We learned things step-by-step like how to make circuits with multiple sensors, how socket connections work, and how to set up and use SQLite database, etc. You need curiosity to start and maintain motivation if something doesn’t work. We got to know how theory can used in implementation and practical knowledge is also important. We extensively used Google, ChatGPT, and help from different friends to make things work. I will also edit this blog when I will get time to add some more topics.

Note : This blog is being submitted to Dr. Rajbir Kaur Ma’am for the CTIoT course evaluation component. We hope she allows me to post this on the internet. The code and content in this blog are free-to-use from our side.

You can contact me for any doubt on Twitter(𝕏).

0
Subscribe to my newsletter

Read articles from Shreyansh Agarwal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Shreyansh Agarwal
Shreyansh Agarwal

👩‍💻 Computer Science Enthusiast | 🚀 Programmer | 🐍 Python | Always 🌱 learning and 📝 blogging about tech