Human Following Robot Using Arduino and Ultrasonic Sensor

Submitted by Gourav Tak on

Working of Human Following Robot Using Arduino

In recent years, robotics has witnessed significant advancements, enabling the creation of intelligent machines that can interact with the environment. One exciting application of robotics is the development of human-following robots. These robots can track and follow a person autonomously, making them useful in various scenarios like assistance in crowded areas, navigation support, or even as companions. In this article, we will explore in detail how to build a human following robot using Arduino and three ultrasonic sensors, complete with circuit diagrams and working code. Also, check all the Arduino-based Robotics projects by following the link.

The working of a human following robot using Arduino code and three ultrasonic sensors is an interesting project. What makes this project particularly interesting is the use of not just one, but three ultrasonic sensors. This adds a new dimension to the experience, as we typically see humans following a robot built with one ultrasonic, two IR, and one servo motor.  This servo motor has no role in the operation and also adds unnecessary complications. So I removed this servo and the IR sensors and used 3 ultrasonic sensors. With ultrasonic sensors, you can measure distance and use that information to navigate and follow a human target. Here’s a general outline of the steps involved in creating such a robot.

 

 

Components Needed for Human Following Robot Using Arduino

  • Arduino UNO board ×1

  • Ultrasonic sensor ×3

  • L298N motor driver ×1

  • Robot chassis

  • BO motors ×2

  • Wheels ×2

  • Li-ion battery 3.7V ×2

  • Battery holder ×1

  • Breadboard

  • Ultrasonic sensor holder ×3

  • Switch and jumper wires

Human Following Robot Using Arduino Circuit Diagram

Here is the schematic diagram of a Human-following robot circuit.

Arduino Human Following Robot Circuit Diagram

This design incorporates three ultrasonic sensors, allowing distance measurements in three directions front, right, and left. These sensors are connected to the Arduino board through their respective digital pins. Additionally, the circuit includes two DC motors for movement, which are connected to an L298N motor driver module. The motor driver module is, in turn, connected to the Arduino board using its corresponding digital pins. To power the entire setup, two 3.7V li-ion cells are employed, which are connected to the motor driver module via a switch.

Overall, this circuit diagram showcases the essential components and connections necessary for the Human-following robot to operate effectively.

arduino human following robot circuit

Circuit Connection:

Arduino and HC-SR04 Ultrasonic Sensor Module:

HC-SR04 Ultrasonic sensor Module

  • Connect the VCC pin of each ultrasonic sensor to the 5V pin on the Arduino board.

  • Connect the GND pin of each ultrasonic sensor to the GND pin on the Arduino board.

  • Connect the trigger pin (TRIG) of each ultrasonic sensor to separate digital pins (2,4, and 6) on the Arduino board.

  • Connect the echo pin (ECHO) of each ultrasonic to separate digital pins (3,5, and 7) on the Arduino board.

Arduino and Motor Driver Module:

  • Connect the digital output pins of the Arduino (digital pins 8, 9, 10, and 11) to the appropriate input pins (IN1, IN2, IN3, and IN4) on the motor driver module.

  • Connect the ENA and ENB pins of the motor driver module to the onboard High state pin with the help of a female header.

  • Connect the OUT1, OUT2, OUT3, and OUT4 pins of the motor driver module to the appropriate terminals of the motors.

  • Connect the VCC (+5V) and GND pins of the motor driver module to the appropriate power (Vin) and ground (GND) connections on the Arduino.

Power Supply:

  • Connect the positive terminal of the power supply to the +12V input of the motor driver module.

  • Connect the negative terminal of the power supply to the GND pin of the motor driver module.

  • Connect the GND pin of the Arduino to the GND pin of the motor driver module.

Human Following Robot Using Arduino Code

Here is a simple 3 Ultrasonic sensor-based Human following robot using Arduino Uno code that you can use for your project.

Ultrsonic Sensors on Robot

This code reads the distances from three ultrasonic sensors (‘frontDistance’, ‘leftDistance’, and ‘rightDistance’). It then compares these distances to determine the sensor with the smallest distance. If the smallest distance is below the threshold, it moves the car accordingly using the appropriate motor control function (‘moveForward()’, ‘turnLeft()’, ‘turnRight()’). If none of the distances are below the threshold, it stops the motor using ‘stop()’.

In this section, we define the pin connections for the ultrasonic sensors and motor control. The S1Trig, S2Trig, and S3Trig, variables represent the trigger pins of the three ultrasonic sensors, while S1Echo, S2Echo, and S3Echo, represent their respective echo pins.

The LEFT_MOTOR_PIN1, LEFT_MOTOR_PIN2, RIGHT_MOTOR_PIN1, and RIGHT_MOTOR_PIN2 variables define the pins for controlling the motors.

The MAX_DISTANCE and MIN_DISTANCE_BACK variables set the thresholds for obstacle detection.

// Ultrasonic sensor pins
#define S1Trig 2
#define S2Trig 4
#define S3Trig 6
#define S1Echo 3
#define S2Echo 5
#define S3Echo 7
// Motor control pins
#define LEFT_MOTOR_PIN1 8
#define LEFT_MOTOR_PIN2 9
#define RIGHT_MOTOR_PIN1 10
#define RIGHT_MOTOR_PIN2 11
// Distance thresholds for obstacle detection
#define MAX_DISTANCE 40
#define MIN_DISTANCE_BACK 5

Make sure to adjust the values of ‘MIN_DISTANCE_BACK’ and ‘MAX_DISTANCE’ according to your specific requirements and the characteristics of your robot.

The suitable values for ‘MIN_DISTANCE_BACK’ and ‘MAX_DISTANCE’ depend on the specific requirements and characteristics of your human-following robot. You will need to consider factors such as the speed of your robot, the response time of the sensors, and the desired safety margin

Here are some general guidelines to help you choose suitable values.

‘MIN_DISTANCE_BACK’ This value represents the distance at which the car should come to a stop when an obstacle or hand is detected directly in front. It should be set to a distance that allows the car to back safely without colliding with the obstacle or hand. A typical value could be around 5-10 cm.

‘MAX_DISTANCE’ This value represents the maximum distance at which the car considers the path ahead to be clear and can continue moving forward. It should be set to a distance that provides enough room for the car to move without colliding with any obstacles or hands. If your hand and obstacles are going out of this range, the robot should be stop. A typical value could be around 30-50 cm.

These values are just suggestions, and you may need to adjust them based on the specific characteristics of your robot and the environment in which it operates.

These lines set the motor speed limits. ‘MAX_SPEED’ denotes the upper limit for motor speed, while ‘MIN_SPEED’ is a lower value used for a slight left bias. The speed values are typically within the range of 0 to 255, and can be adjusted to suit our specific requirements.

// Maximum and minimum motor speeds
#define MAX_SPEED 150
#define MIN_SPEED 75

The ‘setup()’ function is called once at the start of the program. In the setup() function, we set the motor control pins (LEFT_MOTOR_PIN1, LEFT_MOTOR_PIN2, RIGHT_MOTOR_PIN1, RIGHT_MOTOR_PIN2) as output pins using ‘pinMode()’ . We also set the trigger pins (S1Trig, S2Trig, S3Trig) of the ultrasonic sensors as output pins and the echo pins (S1Echo, S2Echo, S3Echo) as input pins. Lastly, we initialize the serial communication at a baud rate of 9600 for debugging purposes.

void setup() {
  // Set motor control pins as outputs
  pinMode(LEFT_MOTOR_PIN1, OUTPUT);
  pinMode(LEFT_MOTOR_PIN2, OUTPUT);
  pinMode(RIGHT_MOTOR_PIN1, OUTPUT);
  pinMode(RIGHT_MOTOR_PIN2, OUTPUT);
  //Set the Trig pins as output pins
  pinMode(S1Trig, OUTPUT);
  pinMode(S2Trig, OUTPUT);
  pinMode(S3Trig, OUTPUT);
  //Set the Echo pins as input pins
  pinMode(S1Echo, INPUT);
  pinMode(S2Echo, INPUT);
  pinMode(S3Echo, INPUT);
  // Initialize the serial communication for debugging
  Serial.begin(9600);
}

This block of code consists of three functions (‘sensorOne()’, ‘sensorTwo()’, ‘sensorThree()’) responsible for measuring the distance using ultrasonic sensors.

The ‘sensorOne()’ function measures the distance using the first ultrasonic sensor. It's important to note that the conversion of the pulse duration to distance is based on the assumption that the speed of sound is approximately 343 meters per second. Dividing by 29 and halving the result provides an approximate conversion from microseconds to centimeters.

The ‘sensorTwo()’ and ‘sensorThree()’ functions work similarly, but for the second and third ultrasonic sensors, respectively.

// Function to measure the distance using an ultrasonic sensor
int sensorOne() {
  //pulse output
  digitalWrite(S1Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(S1Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(S1Trig, LOW);
  long t = pulseIn(S1Echo, HIGH);//Get the pulse
  int cm = t / 29 / 2; //Convert time to the distance
  return cm; // Return the values from the sensor
}
//Get the sensor values
int sensorTwo() {
  //pulse output
  digitalWrite(S2Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(S2Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(S2Trig, LOW);
  long t = pulseIn(S2Echo, HIGH);//Get the pulse
  int cm = t / 29 / 2; //Convert time to the distance
  return cm; // Return the values from the sensor
}
//Get the sensor values
int sensorThree() {
  //pulse output
  digitalWrite(S3Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(S3Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(S3Trig, LOW);
  long t = pulseIn(S3Echo, HIGH);//Get the pulse
  int cm = t / 29 / 2; //Convert time to the distance
  return cm; // Return the values from the sensor
}

In this section, the ‘loop()’ function begins by calling the ‘sensorOne()’, ‘sensorTwo()’, and ‘sensorThree()’ functions to measure the distances from the ultrasonic sensors. The distances are then stored in the variables ‘frontDistance’, ‘leftDistance’, and ‘rightDistance’.

Next, the code utilizes the ‘Serial’ object to print the distance values to the serial monitor for debugging and monitoring purposes.

void loop() {
  int frontDistance = sensorOne();
  int leftDistance = sensorTwo();
  int rightDistance = sensorThree();
  Serial.print("Front: ");
  Serial.print(frontDistance);
  Serial.print(" cm, Left: ");
  Serial.print(leftDistance);
  Serial.print(" cm, Right: ");
  Serial.print(rightDistance);
  Serial.println(" cm");

In this section of code condition checks if the front distance is less than a threshold value ‘MIN_DISTANCE_BACK’ that indicates a very low distance. If this condition is true, it means that the front distance is very low, and the robot should move backward to avoid a collision. In this case, the ‘moveBackward()’ function is called.

if (frontDistance < MIN_DISTANCE_BACK) {
    moveBackward();
    Serial.println("backward");

If the previous condition is false, this condition is checked. if the front distance is less than the left distance, less than the right distance, and less than the ‘MAX_DISTANCE’ threshold. If this condition is true, it means that the front distance is the smallest among the three distances, and it is also below the maximum distance threshold. In this case, the ‘moveForward()’ function is called to make the car move forward.

else if (frontDistance < leftDistance && frontDistance < rightDistance && frontDistance < MAX_DISTANCE) {
    moveForward();
    Serial.println("forward");

If the previous condition is false, this condition is checked. It verifies if the left distance is less than the right distance and less than the ‘MAX_DISTANCE’ threshold. This condition indicates that the left distance is the smallest among the three distances, and it is also below the minimum distance threshold. Therefore, the ‘turnLeft()’ function is called to make the car turn left.

else if (leftDistance < rightDistance && leftDistance < MAX_DISTANCE) {
    turnLeft();
    Serial.println("left");

If neither of the previous conditions is met, this condition is checked. It ensures that the right distance is less than the ‘MAX_DISTANCE’ threshold. This condition suggests that the right distance is the smallest among the three distances, and it is below the minimum distance threshold. The ‘turnRight()’ function is called to make the car turn right.

else if (rightDistance < MAX_DISTANCE) {
    turnRight();
    Serial.println("right");

If none of the previous conditions are true, it means that none of the distances satisfy the conditions for movement. Therefore, the ‘stop()’ function is called to stop the car.

 else {
    stop();
    Serial.println("stop");

In summary, the code checks the distances from the three ultrasonic sensors and determines the direction in which the car should move based on the 3 ultrasonic sensors with the smallest distance.

 

Important aspects of this Arduino-powered human-following robot project include:

  • Three-sensor setup for 360-degree human identification
  • Distance measurement and decision-making in real-time
  • Navigation that operates automatically without human assistance
  • Avoiding collisions and maintaining a safe following distance

 

 

Technical Summary and GitHub Repository 

Using three HC-SR04 ultrasonic sensors and an L298N motor driver for precise directional control, this Arduino project shows off the robot's ability to track itself. For simple replication and modification, the full source code, circuit schematics, and assembly guidelines are accessible in our GitHub repository. To download the Arduino code, view comprehensive wiring schematics, and participate in the open-source robotics community, visit our GitHub page.

Code Schematics Download Icon

 

Frequently Asked Questions

⇥ How does an Arduino-powered human-following robot operate?
Three ultrasonic sensors are used by the Arduino-powered human following robot to determine a person's distance and presence. After processing this data, the Arduino manages motors to follow the identified individual while keeping a safe distance.

⇥ Which motor driver is ideal for an Arduino human-following robot?
The most widely used motor driver for Arduino human-following robots is the L298N. Additionally, some builders use the L293D motor driver shield, which connects to the Arduino Uno directly. Both can supply enough current for small robot applications and manage 2-4 DC motors.

⇥ Is it possible to create a human-following robot without soldering?
Yes, you can use motor driver shields that connect straight to an Arduino, breadboards, and jumper wires to construct a human-following robot. For novices and prototyping, this method is ideal.

⇥ What uses do human-following robots have in the real world?
Shopping cart robots in malls, luggage-carrying robots in airports, security patrol robots, elderly care assistance robots, educational demonstration robots, and companion robots that behave like pets are a few examples of applications.

 

Conclusion

This human following robot using Arduino project and three ultrasonic sensors is an exciting and rewarding project that combines programming, electronics, and mechanics. With Arduino’s versatility and the availability of affordable components, creating your own human-following robot is within reach.

Human-following robots have a wide range of applications in various fields, such as retail stores, malls, and hotels, to provide personalized assistance to customers. Human-following robots can be employed in security and surveillance systems to track and monitor individuals in public spaces. They can be used in Entertainment and events, elderly care, guided tours, research and development, education and research, and personal robotics.

They are just a few examples of the applications of human-following robots. As technology advances and robotics continues to evolve, we can expect even more diverse and innovative applications in the future.

Explore Practical Projects Similar To Robots Using Arduino

Explore a range of hands-on robotics projects powered by Arduino, from line-following bots to obstacle-avoiding vehicles. These practical builds help you understand sensor integration, motor control, and real-world automation techniques. Ideal for beginners and hobbyists, these projects bring theory to life through interactive learning.

 Simple Light Following Robot using Arduino UNO

Simple Light Following Robot using Arduino UNO

Today, we are building a simple Arduino-based project: a light-following robot. This project is perfect for beginners, and we'll use LDR sensor modules to detect light and an MX1508 motor driver module for control. By building this simple light following robot you will learn the basics of robotics and how to use a microcontroller like Arduino to read sensor data and control motors.

Line Follower Robot using Arduino UNO: How to Build (Step-by-Step Guide)

Line Follower Robot using Arduino UNO: How to Build (Step-by-Step Guide)

This step-by-step guide will show you how to build a professional-grade line follower robot using Arduino UNO, with complete code explanations and troubleshooting tips. Perfect for beginners and intermediate makers alike, this project combines hardware interfacing, sensor calibration, and motor control fundamentals.

Have any question related to this Article?

How to Build an ESP32 Offline Speech Recognition

Submitted by Anand D on

Speech recognition models like OpenAI’s Whisper offer high levels of accuracy, but their base model itself consumes up to 140MB and running them on a low-end device like an ESP32 is difficult. In this tutorial, we are going to run Cactus Compute’s Whisper Speech-to-Text Model launched on 2nd of October 2026. The actual size of the model is 16.9MB, which won't fit into an ESP32 with 16MB Flash. In this tutorial, we will compress the 16.9MB Cactus Whisper down to 14.52MB, so that it fits into the ESP32 Flash memory.

This setup reads audio via an INMP441 I²S digital microphone, processes speech upon a button press, and triggers live actions on an onboard RGB LED that's connected to the GPIO pin 48, all this 100% offline with zero cloud API dependencies. Several other cloud providers offer STT services as well. We have already covered one such tutorial using Wit.ai with minimal latency. If interested, you can check out our ESP32 Speech-to-Text using Wit tutorial as well. Now, let's check out the components required to build this project.

Components Required

Below are the components required to build this project.

Components Required for ESP32 Speech Recognition

First, we have the ESP32-S3 board with 16MB of Flash and 8MB of PSRAM. This specific module is the ESP32-S3 CAM Module that comes with a camera. But we are not utilising the camera part in this project. Then we have the INMP441 microphone to record audio. The push button is used to trigger audio recording and stop it on press. We will be assembling the whole circuit on a breadboard, as it is the easiest way to get things started. Jumper wires will be used to make all the connections. Below is the list of components, neatly provided in a table for easy reference.

S.noItem                      Description
1ESP32-S3To be used as the main microcontroller
2INMP441 I2S MICTo record the audio
3Push ButtonTo trigger audio recording and to stop recording
4BreadboardWhere we will be setting up the circuit
5Jumper WiresTo connect all the parts as per the circuit diagram

Circuit Diagram

The following is the circuit diagram for this project.

Circuit Diagram for ESP32 Speech Recognition

As in the circuit diagram, there are mainly 3 components. One is the ESP32-S3 Board itself, which has 16MB of Flash and 8MB of PSRAM, where we will be running the STT model. Then we have the INMP441 I2S microphone to capture the audio and then a push button pressing on which, it starts recording and releasing which it stops recording. We will be controlling the onboard RGB LED, which is connected to GPIO48 of the ESP32, using this setup, so we don’t need to connect any external output devices. But the code can be completely modified to meet the project requirements. Along with the onboard RGB LED response, we will have a response in the TUI(Terminal User Interface) Monitor as well.

Hardware Connections

Connect the INMP441 microphone and push button according to the following pinout. If you’re someone who wants offline speech recognition but doesn't want to use an ESP32 for that, we have a dedicated tutorial on Low-Cost Offline Voice Recognition using a low-cost module. Now, let's take a look at the connection required to set this up.

Component PinESP32-S3 Board PinDescription
INMP441 VDD3V3Do NOT connect to 5V
INMP441 GNDGNDGround
INMP441 L/RGNDSelects left channel
INMP441 SCKGPIO 4I²S bit clock
INMP441 WSGPIO 5I²S word select
INMP441 SDGPIO 6I²S serial data
Push Button Pin 1GPIO 7Uses internal pull-up
Push Button Pin 2GNDGround
WS2812 RGB LEDGPIO 48Onboard LED (Default)

Step-by-Step Instructions

We are going to use ESP-IDF. Download and install it from the official website. Here, in this tutorial, ESP-IDF Version 5.5.5 is being used. Version 5.5 or above is required. Once installed, open it from the Start menu and go to the desired directory where we plan to clone the repo. The following is the directory where we will be working. Let's CD into it.

cd $HOME\Documents\Projects

Clone the Whistle-ESP32 repository and CD into the project directory using the following commands.

git clone https://github.com/andrisgauracs/whistle-esp32.git
cd whistle-esp32

Let's create a virtual environment named “venv” so that we can install all the required packages in that venv.

python -m venv .venv

Activate the newly created venv using the following command.

.\.venv\Scripts\Activate.ps1

If it throws an error, run this command to unblock scripts for the current PowerShell session.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process

Install the required tools.

pip install numpy rich pyserial huggingface_hub 
pip install esptool

Now, let's download & Strip the Whistle Model. Make sure we are in the following directory:
C:\Users\Pavilion\Documents\Projects\whistle-esp32

Create the model directory:

mkdir -Force model\whistle

Download the model from Hugging Face: 

python -c "from huggingface_hub import hf_hub_download; import shutil; shutil.copy(hf_hub_download('Cactus-Compute/whistle','whistle.cact'), 'model/whistle/whistle.cact')"

Strip the model down to 4 layers (14.5 MB):

python tools\whistle_strip.py model\whistle\whistle.cact 4 model\whistle\whistle_d4.cact
 Model Size of Cactus Whisper

In the image above, we can clearly see the actual downloaded model size, which is 16.9MB and the size after stripping down the model, which is 14.52MB.

Make sure we are in the following directory :
C:\Users\Pavilion\Documents\Projects\whistle-esp32\esp32\whistle_demo
We don't want to activate the venv as of now, as the project's local virtual environment (.venv) may conflict with ESP-IDF's own dedicated Python environment. If it's activated by any chance, use the following command to deactivate it.

deactivate

Now, the default installation directory for ESP-IDF 5.5 on Windows is usually inside the user directory or under C:\Espressif, rather than C:\esp-idf. We need to find that out.
Run this command in PowerShell to automatically find where export.ps1 is located on your machine:

Get-ChildItem -Path "C:\Espressif", "C:\Users\$env: USERNAME" -Filter "export.ps1" -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName

How to Export ESP-IDF Based on the Location

Once the script outputs the path, run it with a dot operator at the beginning. For example:

If it is inside C:\Espressif:

. C:\Espressif\frameworks\esp-idf-v5.5.5\export.ps1

Or if it is in your User directory:

. C:\Users\Pavilion\esp\esp-idf\export.ps1

Build and Flash the Firmware

Now, let's proceed with the set-target and build commands:

idf.py set-target esp32s3
idf.py build

Flash the firmware using the following command. Replace the “x” with the actual COM Port of your ESP32. It can be seen in Device Manager on Windows.

idf.py -p COMx flash

Flash the Model

Go back to the project root
cd ..\..
Reactivate the project venv
.\.venv\Scripts\Activate.ps1
Flash the 14.52MB model binary to partition 0x210000
esptool.py --chip esp32s3 -p COM6 -b 921600 write_flash 0x210000 model\whistle\whistle_d4.cact

  Successfully Flashing the Model to ESP32-S3

The above message will show up once the model is successfully flashed onto our ESP32.

Run the TUI(Terminal User Interface) Monitor

Once the model write reaches 100%, launch the TUI monitor to test your board. 
At this point, we need to connect the ESP32-S3 board to its 2nd Type-C port labelled as USB-OTG instead of USB-UART. This is because the USB-UART port connects to the external CP2102 or CH340 USB-to-Serial bridge chip attached to the hardware UART0 pins (TX0/RX0).
Since the whistle-esp32 repository connects directly to the native USB peripheral inside the ESP32-S3 silicon, we need to connect it to the USB-OTG port.

Before running the following command, make sure to replace the “x” with the actual COM Port of the ESP32.

python tools\needle_tui.py --whistle --serial COMx
 TUI Monitor Interface

The above will be the TUI Monitor interface that will pop up immediately when we run the above command. It even shows ESP32-S3 is connected to COM8. Once we are at this level, we can proceed to the next steps and see the results.

Result

Below are some of the commands that can make some actions with this setup. Apart from the following set of commands, it can understand any context and perform some actions. As of now, we don't have too many I/O devices connected to it and programmed, so below are some valid commands. It even converts any random text that is spoken to it and displays it in the TUI Monitor.

SNoCommandAction
1Change colour to RedRed light flashes
2Flash green light for 5 secondsGreen colour flashes for 5 seconds
3Blink violet every half secondViolet blinks for half a second
4PurplePurple colour flashes
 TUI Monitor Interface While Recording

When the push button is pressed, the TUI Monitor shows the status as “Recording” and starts recording the audio that is spoken to the INMP441 Mic. The recording keeps going until the button is released. At this point, the onboard RGB LED shows white.

 TUI Monitor Interface While Transcribing

Once the button is released, the "Recording" status changes to “Transcribing”, meaning the spoken audio is being transcribed to text. This process typically takes 6 seconds. At this point, the onboard RGB LED blinks white slowly, indicating that transcription is going on. If no text is detected, it immediately blinks Red colour twice. The possible reason for this may be that the MIC is not good, or the MIC connection is wrong.

 TUI Monitor Interface With Output

Once the transcription is done, we can see the output in the TUI Monitor. It displays the response to the action. For this command, the onboard RGB LED turns red. It behaves as per the command provided. It's also visible that this action took less than 6 seconds. 

Run Voice Recognition locally on a $10 Chip- Demo

Conclusion

The successful deployment of Cactus Compute’s Whistle model on the ESP32-S3 demonstrates that modern, Transformer-based speech-to-text is no longer locked behind cloud APIs or high-power Linux single-board computers. By combining structural layer pruning with INT8 vector quantisation, a $10 microcontroller can run multilingual, offline speech recognition locally.
This project proves that privacy-first voice control, sub-second hardware response times, and zero-latency cloud independence are fully achievable on resource-constrained edge hardware. Now, if the transcribed text needs to be converted into audio, we have a dedicated tutorial that teaches how to build an ESP32 Text-to-Speech offline system so that this can also be integrated into this project. Text-to-speech can also be done using our ESP32-C3 Text-to-Speech Using Wit tutorial as well. For more ESP32-based projects, check out our collection of ESP32 projects.

Official Andrisgauracs GitHub Repository

ESP32 Offline Speech Recognition GitHub RepoESP32 Offline Speech Recognition Download Zip

Projects Related to Smart Offline Voice Assistant

This collection explores the development of smart, offline embedded systems using Arduino and ESP32 microcontrollers.It covers accessing Wikipedia without an internet connection, converting text into speech using Arduino, and implementing offline voice recognition using Edge Impulse. Together, these projects demonstrate how microcontrollers can enable intelligent, voice-controlled, and speech-based applications without relying on continuous internet connectivity.

DIY Raspberry Pi Pico Text-to-Speech Using Wit.ai

DIY Raspberry Pi Pico Text-to-Speech Using Wit.ai

In Raspberry Pi Pico TTS setups, the Pico sends text to an online service where speech is generated and returned as audio. The device then plays the sound through a speaker, allowing clear speech output without overloading the hardware or increasing system complexity.

Arduino based Text to Speech (TTS) Converter

Arduino-based Text-to-Speech (TTS) Converter

In this tutorial, we will learn how to make a text-to-speech converter using Arduino. This step involves the conversion of the symbols, numbers and abbreviations into words that can be read by the machine.

ESP32 Offline Voice Recognition Using Edge Impulse

ESP32 Offline Voice Recognition Using Edge Impulse

We’ll build a mini yet expandable ESP32 voice assistant using Edge Impulse, with the ESP32 as the main microcontroller. The goal of ESP32 offline speech recognition is to keep it simple while still leaving room for future upgrades.

Have any question related to this Article?

How to Run Wikipedia Offline on ESP32

Submitted by Anand D on

These days, we are heavily dependent on cloud computing, high-speed internet and all. We rarely think about what happens if the internet goes down or what happens in areas where the network is not reachable or information access is very difficult. The main solution is having the data and its processing locally so that they are reachable anytime, even without internet. In this project, we will be building an Offline Wikipedia that runs completely on an ESP32-S3 Board so that we can access the data anytime, anywhere without an internet connection. This is all possible thanks to Kiwix, a non-profit organisation that is making free knowledge accessible everywhere. An ESP32 offline Wikipedia is a pocket-sized Wikipedia server built on an ESP32-S3 board with a microSD card. 

We will load the data onto an SD Card and use it in the onboard SD Card reader of the ESP32 module so that it itself becomes the database. Then we will flash the firmware that runs a web server on the ESP32 so that we can access the data in any browser without the internet. Running a web server on an ESP32 becomes very helpful, as we can visualise the data anytime, anywhere using any device. If you’d like to learn the basics of running a web server on an ESP32 Dev Module, we have a getting started tutorial that helps you build a simple ESP32 LED Webserver.

What You Will Learn in This ESP32 Offline Wikipedia Tutorial

  • Selection of the appropriate ZIM file (language, flavour, and size) for the microSD card.
  • Utilisation of the ESP32 offline Wikipedia repository on GitHub for the transformation of the ZIM file into data chunks easily readable by the ESP32.
  • Preparation and setting of the FAT32-formatted microSD card with the processed data.
  • Flashing the web server firmware using PlatformIO, along with checking SD card mounting.
  • Making connection to the ESP32 Wi-Fi point and search images-containing articles through any browser.
  • Overview of how this ESP32 version compares to setups with Raspberry Pi and smartphone Kiwix.

Hardware Required for the ESP32 Offline Wikipedia

Below is the hardware required to build this project.

Components for the ESP32 offline Wikipedia: an ESP32-S3 board with an onboard microSD slot, a microSD card and a USB data cable

First of all, we need an ESP32-S3 module with a microSD card slot. The memory card used here is a 4GB one for this demonstration. Memory card size depends on the file size that will be downloaded, as per the instructions provided below. A suitable memory card size is 16 GB or 32 GB as larger the file size, larger is the information that it holds. But still, one can even use a 2 GB memory card, provided the file size is within it. Then, we need a data cable to program the ESP32 Board.

Step-by-Step Guide to Build an Offline Wikipedia on ESP32

Step 1⇒ Download the Right Kiwix ZIM File
First of all, we need to go to the Kiwix ZIM Archive Page. There are several downloadable files listed. If we take a closer look, the letters “en, af, ru, fr…” in the file name suggest that the downloadable file is in a specific language, such as English, Afrikaans, Russian, French and many more. Below is a table that shows how to properly identify the right file for the right purpose. Make sure that the downloadable file size is within the capacity of the memory card that is going to be used. 

S NoTag                                                            Meaning
1simpleSimple English Wikipedia (easier vocabulary, fewer total articles, significantly smaller file sizes)
2allContains general Wikipedia articles across all topics rather than a specific subject. 
3maxiFull version including complete text and images
4nopicText-only version (no pictures), resulting in much smaller file sizes.  
mini: Lead/intro paragraphs of articles only
52026-xxThe year and month the snapshot was taken

Apart from Wikipedia, there are files specific to topics like physics, mathematics, football, chess, etc., which have rich information about the specific topics. Make sure to check the file size of the download as well. If we don't want images in the offline wiki, we can download the file that has “nopic” in the file name.

Topic-specific Kiwix archives let you build a focused offline reference, for example only physics or mathematics

The table below shows how languages are tagged in the file name. Identify the desired language and download the file. Listed below are just some samples. Actually, a wide range of languages are available on the website for download.

Language codes used in Kiwix Wikipedia ZIM file names for the ESP32 offline Wikipedia, such as en, fr, ru and af Language codes in Kiwix file names. Choose the code for the language you want to read offline

Step 2⇒ Clone the ESP32 Offline Wikipedia GitHub Repository
We will complete the entire tutorial in VS Code with the PlatformIO extension installed. To make everything easier, all the code and files have been uploaded to GitHub and can be accessed from the GitHub link provided below. After cloning the repo, we need to be in the following directory in the terminal for the following steps.

C:\Users\Pavilion\Downloads\Offline-Wikipedia-ESP32-master\Offline-Wikipedia-ESP32-master>

Step 3⇒ Preprocess the ZIM File with Images
Below is the command to be run to preprocess/re-compress the contents of the .zim file so that the ESP32 board can read the data efficiently. It will extract all articles, render all images/diagrams into .dat chunks, and generate the index files. The default thumbnail size is 320x212, but we can use --thumb-size 480x320 for sharper images. Here, we are using 480x320 as we are aiming for sharper images.

& "C:\Users\Pavilion\.platformio\penv\Scripts\python.exe" preprocessor\build_wiki_db.py --all-jpeg --thumb-size 480x320 "C:\Users\Pavilion\Downloads\wikipedia_en-simple_all_maxi_2026-09.zim" preprocessor\output_en_wiki

Once the above command is run, we can see the following logs in the terminal. It takes a decent amount of time to complete the task, as it depends on the zim model that we are preprocessing. Once this task is successful, it creates a folder named “output_en_wiki” under the preprocessor folder. We need the contents of this folder. You can edit the final directory name (here, it is output_en_wiki) to the correct name that matches the file that you have downloaded. In this case, it's an English version of the Wiki. That's why it's named “output_en_wiki”. It can be like “output_af_wiki” if we are using the Afrikaans version. After the process, open the same folder in your file explorer and copy all the contents of that folder. Make sure the microSD card has enough space to store all the data.

Preprocessor log while converting the Simple English ZIM file into ESP32-ready chunks.

Step 4⇒ Copy the Data to the microSD Card
Plug the microSD card (16 GB or 32 GB recommended) into your PC using a card reader. Format it as FAT32. Formatting a microSD card as FAT32 is easy. In Windows, right-click the drive > Format > FAT32.
Create a folder named wiki on the root of the SD card.
Copy all files from preprocessor\output_en_wiki\ into /wiki/, the folder that we need to create inside the microSD card’s root directory. The following are the files that are to be transferred to the folder named wiki on the SD Card.

The preprocessed index and chunk files that go into the /wiki folder on the microSD card.

After copying the files, the SD card folder structure should look something like the following. All the copied files are under a root folder named wiki.

SD Card Root/
└── wiki/
   ├── index.bin
   ├── sparse_index.bin
   ├── id_index.bin
   ├── index_meta.txt
   ├── articles_0000.dat
   ├── articles_0001.dat
   ...
   ├── img_index.bin
   ├── img_meta.txt
   ├── img_0000.dat
   ├── img_0001.dat

Insert the card into the built-in Micro SD Card slot on the ESP32-S3 CAM board and proceed to the next steps.
Step 5⇒ Flash the ESP32-S3 Web Server Firmware
Connect the ESP32-S3 CAM Module via USB and run the following command. Nothing needs to be changed; it will flash the firmware directly to the ESP32 Board.

cd firmware
$env:PYTHONIOENCODING="utf-8"
& "C:\Users\Pavilion\.platformio\penv\Scripts\pio.exe" run -e s3-cam-web -t upload

Flashing the firmware doesn’t take too much time, unlike when re-compressing the data. It shows the upload progress in the terminal window, just like how we can see the upload progress in Arduino IDE when we upload code to an Arduino / ESP32 Board.

PlatformIO confirms a successful upload of the offline Wikipedia web-server firmware.

Above is the success message that will come up once the firmware is flashed successfully. If we didn’t get a success message here, the most possible reason is the board being used shouldn’t be an ESP32-S3 board. This repo highly expects an ESP32-S3 board for successful operation.

Step 6⇒ Verify the SD Card Mount in the Serial Monitor
You can watch the boot output in the Serial Monitor to verify the mount:

& "C:\Users\Pavilion\.platformio\penv\Scripts\pio.exe" device monitor

You will see the following, which indicates everything is fine and a total of 129909 articles are available. These numbers vary depending on the file that is being used.

[wiki_db] Initialising storage...
[wiki_db] Setting custom SD_MMC pins: CLK=39, CMD=38, D0=40
[wiki_db] SD_MMC mounted successfully (1-bit mode)!
[wiki_db] Database ready: 129909 articles
[wiki_db] Images: 129909 available

Step 7⇒ Connect to the Hotspot and Browse Wikipedia Offline
Power on the ESP32-S3 CAM. On your phone, tablet, or laptop, open Wi-Fi settings and connect to the Wi-Fi network named Wikipedia-Offline that's hosted by the ESP32. It will be an open network, so there's no need to enter a password.

Joining the open Wikipedia-Offline Wi-Fi network created by the ESP32-S3.

Open any web browser and go to:
http://192.168.4.1/, which is the default fallback IP for AP mode in the ESP32 network stack.
You will be greeted with the full offline Wikipedia search engine, rich articles, and high-resolution images served directly from your ESP32-S3. (The Serial Monitor also remains active simultaneously for diagnostics!) As we start to search for something in the search bar, it will bring up related contents/articles. Clicking any item from the list will display the whole content of that article.

Result: Searching and Reading Wikipedia Offline on the ESP32

The following are some snapshots from the final results. As we can see, the initial window is one that says “Welcome to Offline Wikipedia”. It shows information like the total number of articles in the memory and all. As we start to type in a keyword, the system will show available articles related to the keyword. Once we click a keyword, the screen populates with the article's content. The content includes text and images. If we opt to use or download a “nopic” version, it will show text only and not any images.

Offline Wikipedia Running in the ESP32-S3 Board

Running Wikipedia Offline on an ESP32: Video Demo

Watch the complete ESP32 offline Wikipedia in action, running on an ESP32-S3 board with nothing more than a microSD card and its own Wi-Fi hotspot. The demo shows a phone joining the Wikipedia-Offline network, searching for a topic and opening a full article with images, all without an internet connection. It is a quick way to see the final result before you start building, and to check that your own setup behaves the same way.

Practical Uses of an Offline Wikipedia Server

∗ Emergency and survival kits: reference information when mobile networks are unavailable.
∗ Countryside classrooms and libraries: an encyclopedia accessible where internet is scarce or mobile data is too expensive.
∗ Field research: carrying out research in places without coverage.
∗ Learning about embedded systems: a project for hands-on learning about SD card technology and web servers using ESP32.

Conclusion

By bringing Kiwix’s open-source ZIM archives onto a low-cost microcontroller, this project proves that you don't need expensive server gear or active Wi-Fi to access global knowledge. Whether you're building an emergency survival kit, an off-grid educational tool, or just exploring the limits of microcontrollers, pairing the ESP32 with compressed offline data puts an entire library right in the palm of your hand. You can easily modify the repo and pair it with a TFT Display so that, instead of viewing the result on a web server, you can see it on the TFT Display. As an extension of this project, you can also integrate it with an offline speech system so the Wikipedia content is read aloud. We already have an article on building an ESP32 Text-to-Speech Offline System. Another option is to use some cloud-based services to run a text-to-speech system like our Text-to-Speech System using ESP32 and Wit.ai. For more builds like this, explore our ESP32 projects.

GitHub Repository

The complete source code for this ESP32 offline Wikipedia project is available in our GitHub repository, including the Python preprocessor that converts Kiwix ZIM files and the PlatformIO firmware for the ESP32-S3 web server. Clone or download the repository, follow the steps above, and you can have your own offline Wikipedia running in a single session.

ESP32 Offline Wikipedia GitHub RepisitoryESP32 Offline Wikipedia Downloadable Zip

Frequently Asked Questions About ESP32 Offline Wikipedia

⇥ What are Kiwix ZIM files?
ZIM files are file formats that have been compressed to enable offline web content to be read. Kiwix, which is charitable in nature, provides pre-prepared ZIM files in numerous languages on various topics. These files contain all the articles, images, and a search index, meaning that the internet is not required for reading.

⇥ Which ZIM file to use with the ESP32?
Select "simple", as it is smaller than the English Wikipedia. Select "maxi" when you want to view files with images, go for "nopic" whenever you wish to see only written articles or choose "mini" for articles that have summaries only. It is wise to check the size of your download and the capacity of your microSD card because its data must fit into the card.

⇥ What microSD card size is required?
This depends on the file you are going to convert. You can fit the Simple English version that has pictures on a 4GB card, while you will need higher capacity, such as 16 GB and 32 GB, for other compilations. A 2GB card may also work in some cases where only small articles are being converted.

⇥ Why do we have to format the microSD card as FAT32?
The microSD card will be used with the SD_MMC driver of the ESP32. This driver will only work with FAT32 format. Windows formatting utility only supports FAT32 formatting for cards up to 32GB of storage size. So, to format cards larger than that, special software needs to be downloaded and used. Also, thanks to the fact that the database is saved in small chunks, the limitation of 4GB for each file in FAT32 format won't be an issue.

Explore More AI-Powered Embedded Projects

Explore these DIY projects to build intelligent embedded systems using ESP32-CAM, AI-powered speech recognition, and Arduino-based text-to-speech. Learn to describe surroundings with an AI vision assistant, convert spoken words into text, and generate speech from text using simple hardware and practical step-by-step tutorials.

ESP32-CAM AI Vision Assistant Pendant for the Visually Impaired

ESP32-CAM AI Vision Assistant Pendant for the Visually Impaired

Here in this tutorial, we are going to explore an AI Vision Assistant for Visually Impaired People using an ESP32-CAM. A vision-based solution gives feedback based on the real surroundings and situations, which is more reliable than a proximity sensor-based solution.

ESP32 Speech-to-Text using Wit.ai

ESP32 Speech-to-Text using Wit.ai

In this project, we’ll be learning how to build an ESP32 Speech-to-Text system using an ESP32 development board. We’ll use an I2S MIC to record speech and an OLED display to display the converted text.

Arduino based Text to Speech (TTS) Converter

Arduino based Text to Speech (TTS) Converter

Today in this tutorial, we will learn how to make a text-to-speech converter using Arduino. Here in this Text-to-Speech converter, we’ve used an amplifier circuit to reduce the noise and get a clear sound. The amplifier circuit is made using the IC LM386.

Have any question related to this Article?

How Semtech Thinks About IoT Devices That Have to Last in the Field

Semtech’s Robert Comanescu, Vice President of R&D and Applications for Wireless ICs, and Tamir Reshef, Vice President of Products and Applications for the Analog and Mixed Signals business unit, discussed the challenges of building IoT devices that communicate reliably and withstand real-world conditions at electronica India and productronica India 2026 in Bengaluru.

Kikobot Robotics Went From a 3D-Printed Prototype to Industrial Robot Arms

Submitted by Staff on

Kikobot Robotics is an early-stage hardware startup in Pune. It began by building robotic arms for education and research and has since moved into industrial-grade arms and its own actuators. Raghvendra says the company builds robot arms for education, research and physical AI, and arms for industrial use cases as well. The lineup includes cobots, delta robots and gantry systems.

Getting Started with the PUI Audio AMP2X15 Audio Amplifier Board and Speakers

Adding a speaker to an embedded project is not always as simple as connecting it directly to a microcontroller or single-board computer. Most audio sources provide a relatively low-level signal, while a speaker needs more power to produce useful sound output. This is where an audio amplifier becomes important. The PUI Audio AMP2X15 is designed to bridge this gap, providing a compact two-channel amplification solution for driving speakers from a low-level audio source.

Peer Robotics Builds Collaborative Robots That Skip the Warehouse Retrofit

As part of our India Tech Tour series, we visited Peer Robotics' facility in Pune, where Ritwik walked us through the company's robots, manufacturing setup, and engineering processes. We also spoke with Ruchit, Vice President of Software Engineering at Peer Robotics, about the company's approach to deploying autonomous mobile robots in industrial environments.

Getting Started with ESP32-P4X-EYE: ESP32-P4 Vision Development Board

Vision development boards are useful when an embedded project needs to combine image capture, local display, audio input, storage and wireless connectivity in a single platform. The ESP32-P4X-EYE takes this approach around the ESP32-P4, adding an ESP32-C6 wireless module, a 2MP MIPI-CSI camera, a 1.54-inch SPI LCD, a digital microphone, MicroSD storage, USB interfaces and a 2 × 10-pin expansion header.