29/06/2022
In an era where digital solutions are rapidly replacing their analogue predecessors across every industry, the humble taxi fare meter is no exception. Gone are the days when clunky mechanical devices dictated your journey's cost. Today, digital meters offer unparalleled accuracy, greater reliability, and significantly less maintenance, making them the superior choice for modern transport systems. Unlike the intricate gears, pinions, and cables found in old mechanical speedometers and odometers, digital systems leverage advanced sensors to provide precise measurements of speed and distance, ensuring a fair and transparent fare every time.

This detailed guide will walk you through the exciting process of creating a functional prototype of a digital taxi fare meter using an Arduino microcontroller. This project not only demonstrates the core principles behind modern fare calculation but also serves as an excellent entry point into embedded systems and sensor integration. By the end of this tutorial, you'll understand how to measure speed and distance accurately, calculate fares based on these metrics, and display the information clearly on an LCD screen.
- Understanding the Digital Taxi Meter Project
- The Heart of the System: The LM-393 Speed Sensor Module
- Calculating Your Fare: Speed, Distance & Cost
- Essential Components for Your Build
- Assembling Your Digital Meter: Circuitry Explained
- Bringing it to Life: Arduino Programming Insights
- Troubleshooting Common Issues
- Future Enhancements and Real-World Applications
Understanding the Digital Taxi Meter Project
At its core, a digital taxi meter project aims to replicate the functionality of commercial fare meters using readily available electronic components. The primary objective is to accurately measure the distance a vehicle travels and, based on a predefined rate, calculate the corresponding fare. Our prototype will use a small RC car chassis to simulate a vehicle, equipped with a speed sensor module and an encoder wheel attached to its motor. This setup allows us to precisely track wheel rotations, which are then translated into speed and distance. The data is continuously displayed on a 16x2 LCD, offering real-time feedback. A simple push button will trigger the fare calculation, providing a snapshot of the journey's cost.
The shift from analogue to digital metres is driven by several compelling advantages. Analogue systems, with their multitude of moving parts, are prone to wear and tear over time, leading to decreased accuracy and increased maintenance requirements. Think of the old-fashioned speedometer in vintage cars, which often needed regular calibration or part replacement. Digital meters, however, rely on electronic sensors that have no mechanical contact, drastically reducing wear and tear and ensuring long-term efficiency and precision. This robust design means less downtime and more reliable operation, which is crucial for commercial applications like taxi services.
The Heart of the System: The LM-393 Speed Sensor Module
Central to our digital taxi meter is the LM-393 Speed Sensor Module, specifically the FC-03 variant. This ingenious component is a slot-type optical interrupter, perfect for measuring the speed of rotation of an encoder wheel. Its operation is elegantly simple yet highly effective:
- Infrared Light Source and Phototransistor: The module comprises an infrared LED (light source) and a phototransistor (sensor), positioned opposite each other with a small gap in between.
- Interruption Principle: When an object passes through this gap, it interrupts the infrared light beam. This interruption causes the phototransistor to stop conducting current, resulting in a change in its output state.
- Generating Pulses: A slotted disc, or encoder wheel, is attached to the motor. As the wheel rotates, its slots and solid sections alternately pass through the sensor's gap. Each time a slot (or solid section) interrupts the beam, the sensor produces a distinct ON/OFF (HIGH/LOW) pulse.
- LM393 Comparator IC: The module incorporates an LM393 Comparator IC, which processes the phototransistor's output. This IC ensures that the digital output signals (HIGH or LOW) are clean, stable, and accurate, making them easily interpretable by a microcontroller like the Arduino.
The number of pulses generated directly corresponds to the rotation of the wheel. By counting these pulses over time, we can accurately determine the wheel's speed and, subsequently, the distance travelled. This non-contact sensing method is far superior to mechanical linkages, offering greater reliability and requiring virtually no maintenance.
Calculating Your Fare: Speed, Distance & Cost
Accurate measurement of speed and distance is paramount for any fare meter. Our system employs a straightforward methodology:
Measuring Speed
To determine the speed of rotation, we need two key pieces of information: the number of pulses detected and the number of slots on the encoder wheel. For our prototype, we'll assume an encoder wheel with 20 slots. When the wheel completes one full rotation, it generates 20 pulses at the sensor's output. The speed is then calculated as follows:
Speed (Revolutions Per Second, RPS) = Number of Pulses / Number of Slots
For example, if 40 pulses are detected in one second:
Speed = 40 pulses / 20 slots = 2 RPS
To convert this to Revolutions Per Minute (RPM), which is a more commonly understood unit for rotational speed, simply multiply by 60:
Speed (RPM) = Speed (RPS) * 60 = 2 RPS * 60 = 120 RPM
Measuring Distance
Calculating the distance travelled is equally simple once the circumference of the wheel is known. The circumference is the distance covered in one full rotation of the wheel.
Circumference of Wheel = π * d
Where 'd' is the diameter of the wheel, and 'π' (Pi) is approximately 3.14.
For our RC car wheel, with a diameter of 6.60 cm, the circumference is roughly 20.7 cm. In a real-world scenario, car wheels are significantly larger. For calculation purposes in this tutorial, we will assume a circumference of 230 cm (2.3 metres) to better reflect a typical vehicle's wheel size.
The total distance travelled is then calculated by multiplying the circumference by the number of complete wheel rotations. Since each rotation corresponds to the total number of slots, we can use the pulse count:
Distance Travelled = Circumference of Wheel * (Number of Pulses / Number of Slots)
So, if a wheel with a circumference of 20.7 cm registers 20 pulses (one full rotation of a 20-slot encoder wheel):
Distance Travelled = 20.7 cm * (20 pulses / 20 slots) = 20.7 cm
To convert the distance from centimetres to metres, divide by 100.
Calculating the Fare
Once the distance travelled in metres is accurately determined, calculating the fare is straightforward. It involves multiplying the distance by a predetermined rate per unit distance. For the purpose of this tutorial, we will assume a rate of 5 units of currency per metre. You can easily adjust this rate in the code to suit your specific requirements or local fare structures.
Total Fare = Distance Travelled (metres) * Rate per Metre
For example, if the vehicle travels 20 metres:
Total Fare = 20 metres * 5 units/metre = 100 units of currency
Essential Components for Your Build
To embark on this exciting project, you'll need the following components:
- Arduino UNO: The brain of our system, processing sensor data and controlling outputs.
- LCD (16x2): A standard character display to show speed, distance, and fare information.
- Push Button: Used to trigger the fare calculation on demand.
- Potentiometer (10k): Allows for manual adjustment of the motor's speed, simulating variable vehicle speed.
- ULN2003 Motor Driver IC: An integrated circuit necessary to safely control the DC motor from the Arduino, as Arduino pins cannot supply enough current directly.
- LM393 Speed Sensor Module (FC-03): The optical sensor that detects wheel rotation.
- RC Smart Car Chassis with Speed Encoder: Provides the physical platform and the motor with an integrated encoder wheel for easy setup.
- Battery (9V): To power the motor, usually connected via the motor driver.
- Breadboard: For prototyping and easy connection of components without soldering.
- Connecting Wires: Various jumper wires for making electrical connections.
Assembling Your Digital Meter: Circuitry Explained
Careful assembly of the components is crucial for the project's success. Here’s a breakdown of the connections:
Mounting the Speed Sensor
The LM393 Speed Sensor needs to be precisely aligned with the encoder wheel on the RC car chassis. Most RC car chassis designed for such projects will have a dedicated slot or mounting point for the sensor, ensuring the encoder wheel passes directly through the sensor's optical gap. This alignment is critical for accurate pulse detection.

Connecting the Speed Sensor to Arduino
| SPEED SENSOR (FC-03) | ARDUINO |
|---|---|
| VCC | 5V |
| GND | GND |
| D0 (Digital Output) | Digital Pin 2 |
Connecting Arduino & 16x2 LCD
The LCD requires several connections for power, ground, contrast, and data lines:
| LCD Pin | ARDUINO Pin |
|---|---|
| VSS | GND |
| VDD | +5V |
| V0 (Contrast) | From potentiometer output |
| RS (Register Select) | Digital Pin 12 |
| RW (Read/Write) | GND |
| EN (Enable) | Digital Pin 13 |
| D4 | Digital Pin 8 |
| D5 | Digital Pin 9 |
| D6 | Digital Pin 10 |
| D7 | Digital Pin 11 |
| A (LED Anode) | +5V (through a current-limiting resistor, typically 220 ohms) |
| K (LED Cathode) | GND |
Connecting Arduino & ULN2003 Motor Driver
The ULN2003 is essential for powering the DC motor, as the Arduino's output pins cannot supply enough current directly. It acts as an interface between the Arduino and the motor:
| ARDUINO Pin | ULN2003 Pin |
|---|---|
| Digital Pin 5 | IN1 |
| GND | GND |
Connecting ULN2003, DC Motor and 9V Battery
The ULN2003 then connects to the motor and the external power source (9V battery):
| ULN2003 Pin | DC MOTOR | 9V BATTERY |
|---|---|---|
| OUT1 | -Ve Motor Terminal | |
| COM | +Ve Battery Terminal | |
| GND | -Ve Battery Terminal |
- Push Button: Connect one terminal of the push button to Arduino Digital Pin 3. Connect the other terminal to GND via a 10k ohm pull-down resistor. This ensures the pin is LOW when the button is not pressed and HIGH when pressed.
- Potentiometer: Connect one outer pin of the 10k potentiometer to +5V, the other outer pin to GND. Connect the middle (wiper) pin to Arduino Analog Pin A0. This will provide a variable analogue voltage input to control motor speed. Also, connect the V0 pin of the LCD to the potentiometer's wiper for contrast adjustment.
Bringing it to Life: Arduino Programming Insights
The Arduino code is the brain that orchestrates all the hardware components, transforming raw sensor data into meaningful speed, distance, and fare information. The programme relies heavily on interrupts and timers to ensure precise and timely data acquisition.
Key Libraries and Global Variables
We begin by including necessary libraries and declaring global variables:
#include "TimerOne.h": This library provides precise timing capabilities, crucial for measuring pulses over a specific interval (e.g., one second).#include <LiquidCrystal.h>: This standard library simplifies interaction with the 16x2 LCD.- Global Variables: Variables like
counter(for pulses per second),rotation(total pulses),rotationinm(distance in metres), andspeed(in RPM) are declared globally so they can be accessed and modified by different functions, including Interrupt Service Routines (ISRs). These are often declared asvolatileto ensure the compiler doesn't optimise away reads/writes, as their values can change unexpectedly due to interrupts.
Setup Function (void setup())
The setup() function initialises the Arduino pins, the LCD, and configures the interrupts:
- Pin Modes: Pin A0 is set as an
INPUTfor the potentiometer, and Pin 5 as anOUTPUTto control the motor via the ULN2003. - LCD Initialisation:
lcd.begin(16,2);sets up the LCD, and a welcome message is displayed. - TimerOne Configuration:
Timer1.initialize(1000000);sets Timer1 to trigger an interrupt every 1,000,000 microseconds, which is exactly 1 second.Timer1.attachInterrupt( timerIsr );then links this timer interrupt to our customtimerIsr()function. This ensures that our speed and distance calculations are updated precisely once per second. - External Interrupts:
attachInterrupt(digitalPinToInterrupt(2), count, RISING);: This configures Digital Pin 2 (connected to the speed sensor's D0 output) as an interrupt pin. Whenever a RISING edge (transition from LOW to HIGH) is detected, thecount()ISR is immediately called. This is crucial for capturing every pulse from the sensor accurately.attachInterrupt(digitalPinToInterrupt(3), generatefare, HIGH);: Digital Pin 3 (connected to the push button) is configured to trigger thegeneratefare()ISR when it detects a HIGH signal (i.e., when the button is pressed).
Interrupt Service Routines (ISRs) Explained
ISRs are special functions that run automatically and immediately when a specific event (an interrupt) occurs. They are vital for real-time applications like this one.
count()ISR:- This ISR is triggered by the speed sensor. Its sole purpose is to increment the
counterandrotationvariables.countertracks pulses within the one-second interval for speed calculation, whilerotationaccumulates total pulses for overall distance. A smalldelay(10);is added to help debounce the sensor signal, preventing false multiple readings from a single pulse.
- This ISR is triggered by the speed sensor. Its sole purpose is to increment the
timerIsr()ISR:- This ISR executes every second, thanks to TimerOne. It's the core of our calculation logic.
- Interrupt Detachment: It temporarily detaches both the speed sensor interrupt and TimerOne itself. This is a critical step to prevent potential issues (like re-triggering or data corruption) while the ISR performs calculations and updates the LCD, which can take a relatively long time compared to the speed of incoming pulses.
- Speed Calculation:
float speed = (counter / 20.0) * 60.0;calculates the RPM based on the pulses counted in the last second (counter) and the 20 slots of the encoder wheel. - Distance Calculation:
float rotations = 230( rotation / 20);calculates the distance in centimetres based on the total pulses (rotation) and the assumed wheel circumference of 230 cm. This is then converted to metres:rotationinm = rotations/100;. - LCD Display: The calculated speed and distance are then displayed on the LCD.
- Counter Reset:
counter=0;is crucial here. It resets the pulse counter for the next one-second interval, ensuring that the speed calculation reflects the current rate of rotation. - Motor Speed Control: The potentiometer's analogue input (read by
analogRead(A0)) is mapped to a PWM (Pulse Width Modulation) value (0-255) using themap()function. This PWM value is then written to Digital Pin 5 usinganalogWrite(5,motorspeed);, controlling the speed of the motor. This allows for dynamic adjustment of the simulated vehicle speed. - Interrupt Re-attachment: Finally, the detached interrupts are re-attached, allowing the system to resume monitoring the speed sensor and the timer.
generatefare()ISR:- This ISR is activated when the push button is pressed.
- Interrupt Detachment: Similar to
timerIsr(), it detaches the speed sensor and timer interrupts to ensure stable display of the fare. - Fare Calculation:
float rupees = rotationinm5;calculates the total fare by multiplying the total distance travelled in metres by the assumed rate of 5 units per metre. - LCD Display: The calculated fare is then displayed prominently on the LCD, along with the rate per metre.
This intricate interplay of hardware and software, leveraging interrupts for real-time responsiveness and timers for precise measurement intervals, forms the backbone of our digital taxi fare meter. It demonstrates the power of microcontrollers in handling complex tasks with relatively simple components, offering vast potential for customisation and further development.
Troubleshooting Common Issues
Even with careful assembly, you might encounter issues. Here are some common problems and their solutions:
- LCD Not Displaying Text or Showing Blocks: Check the V0 pin connection to the potentiometer. Adjust the potentiometer to change the contrast. Ensure VCC and GND are correctly wired.
- Speed Sensor Not Detecting Pulses: Verify the LM393 sensor's alignment with the encoder wheel. Ensure the IR LED and phototransistor are clean and unobstructed. Check power (5V) and ground connections to the sensor. Test the D0 output with a multimeter or by printing its state to the serial monitor.
- Motor Not Spinning or Spinning Incorrectly: Double-check the ULN2003 connections to the Arduino, motor, and 9V battery. Ensure the battery has sufficient charge. Verify the
analogWrite()pin (Pin 5) is correct. - Inaccurate Speed or Distance Readings: Re-verify the number of slots on your encoder wheel in the code (it's 20 in the example). Measure your RC car wheel's diameter accurately and update the circumference value (230cm assumed in the code for real cars) if you want precise measurements for the RC car itself. Ensure the sensor is securely mounted and not wobbly.
- Fare Not Calculating or Incorrect: Check the push button wiring, ensuring the pull-down resistor is correctly installed and the button is sending a HIGH signal to Pin 3 when pressed. Confirm the
rotationinmvariable is accumulating distance correctly. Adjust the fare rate (5 in the example) as needed.
Future Enhancements and Real-World Applications
While this prototype provides a solid foundation, the potential for further development and real-world application is immense. Here are some ideas for enhancement:
- Increased Accuracy and Robustness: Implement more sophisticated filtering algorithms for sensor data to reduce noise and improve precision. Consider using a higher-resolution encoder or a more robust sensor type for commercial applications. Enclose the electronics in a durable, waterproof casing.
- GPS Integration: For real-world taxi applications, integrating a GPS module would significantly enhance functionality. This would allow for independent distance measurement, route tracking, and even real-time mapping, adding a layer of verification and advanced features.
- Android/Mobile App Integration: Develop a companion mobile application that connects to the meter (e.g., via Bluetooth module). This app could display fare details, journey history, allow digital payment options, and even offer navigation.
- Digital Payment Systems: Incorporate payment processing capabilities, allowing passengers to pay directly through the meter using contactless cards or mobile payment services.
- Dynamic Fare Adjustments: Implement logic for variable fare rates based on time of day (e.g., night rates), traffic conditions, or specific zones. This would require more complex programming and potentially real-time data input.
- Printer Integration: Add a small thermal printer to provide customers with a physical receipt, detailing the journey, distance, and fare.
- Regulatory Compliance: For commercial use, a digital taxi meter would need to meet stringent regulatory standards for accuracy, tamper-proofing, and data logging. This would involve rigorous testing and certification processes.
This project serves as an excellent learning platform, demonstrating how simple components and clever programming can create a highly functional device. The principles of sensing, data processing, and output display are fundamental to countless embedded systems, making this a valuable exercise for anyone interested in electronics and programming. The scalability of this concept, from a basic RC car prototype to a fully-fledged commercial product, highlights the power of modern electronics in solving real-world problems and enhancing daily life.
Frequently Asked Questions (FAQs)
Q1: Can I use a different type of speed sensor for this project?
A1: Yes, absolutely. While the LM393 optical sensor is straightforward for a prototype, you could use Hall effect sensors with magnets, or even more advanced rotary encoders for higher precision. The core principle of counting pulses per rotation remains the same, though the wiring and specific code for reading the sensor might differ slightly.
Q2: How can I make the distance calculation more accurate for a real car?
A2: For a real car, the most crucial factor is knowing the precise rolling circumference of the tyre, which can vary slightly with tyre pressure and load. Using a high-resolution encoder attached directly to the drivetrain or wheel axle would also improve accuracy. GPS integration offers an independent verification method for distance, which is often used in commercial systems.
Q3: Is it possible to add a start/stop button for the fare calculation?
A3: Yes, you can easily modify the code to include a start/stop button. Instead of immediately calculating the fare, the push button could toggle a boolean variable (e.g., isJourneyActive). The distance and fare would only accumulate when this variable is true, and pressing the button again would stop the accumulation and display the final fare.
Q4: How can I store journey data, like total distance travelled or fare history?
A4: To store data, you would need non-volatile memory. An SD card module connected to the Arduino is a popular choice for logging extensive data. For smaller amounts of data, you could use the Arduino's EEPROM (Electrically Erasable Programmable Read-Only Memory) to save information that persists even when the power is turned off.
Q5: What if I want to adjust the fare rate without reprogramming the Arduino?
A5: You could add another potentiometer or a set of DIP switches to your circuit. The Arduino could then read the analogue value from the potentiometer or the state of the switches in the setup() function, and use that to set the fare rate dynamically. This provides a simple user interface for adjusting the rate without needing to upload new code.
Q6: Can this system account for waiting time charges?
A6: To account for waiting time, you would need to incorporate a real-time clock (RTC) module and modify the code. When the vehicle speed drops below a certain threshold (indicating it's stationary or moving very slowly), the system could start a timer, accumulating a 'waiting charge' based on a separate per-minute rate. This charge would then be added to the distance-based fare.
If you want to read more articles similar to Build Your Own Digital Taxi Fare Meter, you can visit the Taxis category.
