Documentation

Voice Recognition Module V3 for Arduino | ShillehTek Product Manual
Documentation / Voice Recognition Module V3 for Arduino | ShillehTek Product Manual

Voice Recognition Module V3 for Arduino | ShillehTek Product Manual

manualshillehtek

Overview

The Voice Recognition Module V3 (the widely used Elechouse VR3 design) adds offline spoken-command control to your projects. You train it by speaking your own commands — in any language, or even whistles — and it stores each one as a voiceprint record. Up to 80 commands can be saved on the module, with any 7 loaded into the active recognizer at once. When it hears a match, it reports the record number over a simple 9600-baud serial link, and your sketch decides what happens next: lights on, robot forward, lock open.

Everything runs on the module itself — no Wi-Fi, no cloud, no internet. That makes response instant and keeps the hardware simple: power, ground, and two UART wires are all it needs. Sound comes in through the included microphone on the 3.5 mm mono jack (a separate mic header is also broken out on the board), and a row of expansion I/O pins (OUT0-OUT6, IN0-IN2) is available for advanced use. The board runs from 4.5-5.5V and speaks 5V TTL serial, so it pairs natively with classic Arduinos, while 3.3V boards like the ESP32, Raspberry Pi, and Pico just need one resistor divider on the module's TXD line.

Because recognition is speaker-dependent — it matches the voice that trained it — the module is a natural fit for personal projects: voice-controlled robots, hands-free workshop lights, talking props, accessibility switches, and STEM demos. Train clearly, keep background noise down, and recognition accuracy can reach about 99% in a quiet environment.

At a Glance

Operating Voltage
4.5 - 5.5V DC
Interface
UART TTL @ 9600 baud
Command Capacity
80 stored / 7 active
Max Command Length
1500 ms
Microphone
3.5 mm mono jack (included)
Wiring Pins
GND, VCC, RXD, TXD

Specifications

Parameter Value
Recognition Type Speaker-dependent (trained to your voice), fully offline
Operating Voltage 4.5V - 5.5V DC
Operating Current < 40 mA
Interface UART, 5V TTL logic
Baud Rate 9600 default (2400 - 38400 configurable)
Stored Commands Up to 80 voiceprint records
Active Recognizer 7 records loaded at once
Command Length Up to 1500 ms per record
Recognition Accuracy Up to ~99% in a quiet environment
Audio Input 3.5 mm mono microphone jack + mic header pins
Expansion I/O OUT0 - OUT6 and IN0 - IN2 headers
Board Dimensions 50 x 31 mm

Pinout Diagram

Only the four-pin UART header needs wiring for normal use: GND, VCC (5V), RXD, and TXD. Remember the serial crossover — the module's TXD goes to your board's RX pin and RXD to your board's TX. The microphone plugs into the 3.5 mm jack on the right edge, the Winbond W25Q32JV flash chip stores your trained voiceprints so they survive power cycles, and the OUT0-OUT6 / IN0-IN2 headers are optional expansion I/O you can ignore for standard serial projects.

Elechouse Voice Recognition Module V3 pinout diagram showing GND, VCC, RXD, TXD UART pins, MIC jack, Winbond flash chip, and 50mm x 31mm dimensions

Wiring Guide

Arduino Wiring

The Arduino Uno is the module's home turf: both run 5V logic, so everything connects directly. The sensor sits on a SoftwareSerial port using pins 2 and 3, leaving the hardware serial free for the Serial Monitor.

Module Pin Arduino Pin
GND GND
VCC 5V
TXD D2 (SoftwareSerial RX)
RXD D3 (SoftwareSerial TX)
Tip: Train your commands first with the vr_sample_train example from the Elechouse VoiceRecognitionV3 library, then run the recognition sketch below. Each trained command gets a record number (0, 1, 2...) that the module reports when it hears a match.

ESP32 Wiring

Power the module from VIN (5V). The ESP32's GPIO is 3.3V only, so the module's 5V TXD line must pass through a voltage divider before reaching the ESP32's RX pin. The ESP32's 3.3V TX signal is high enough for the module to read directly.

Module Pin ESP32 Pin Details
GND GND
VCC VIN (5V) Module needs 4.5-5.5V
TXD GPIO 16 (RX2) Via voltage divider
RXD GPIO 17 (TX2) 3.3V signal - direct
Warning: The module transmits at 5V and ESP32 pins are not 5V tolerant. Divide the TXD line down: 1k resistor from module TXD to GPIO 16, then 2k from GPIO 16 to GND. That converts 5V to about 3.3V and protects the chip.

Raspberry Pi Wiring

The module connects to the Pi's GPIO UART. Free the port first: sudo raspi-config > Interface Options > Serial Port — answer "No" to the login shell, "Yes" to the serial hardware, then reboot.

Module Pin Raspberry Pi Pin Details
GND Pin 6 (GND)
VCC Pin 2 (5V)
TXD Pin 10 (GPIO 15, RXD) Via voltage divider
RXD Pin 8 (GPIO 14, TXD) 3.3V signal - direct
Warning: Raspberry Pi GPIO is 3.3V only. Use a 1k/2k voltage divider on the module's 5V TXD line before it reaches GPIO 15, or you risk damaging the Pi.
Note: Training is easiest done once from an Arduino with the Elechouse library (the voiceprints are stored on the module's flash, so they stay trained when you move it to the Pi).

Raspberry Pi Pico Wiring

UART0 on GP0/GP1 talks to the module, with 5V power from VBUS while the Pico runs on USB. Like the Pi and ESP32, the Pico needs the module's TXD divided down to 3.3V.

Module Pin Pico Pin Details
GND GND (pin 38)
VCC VBUS (pin 40) 5V from USB
TXD GP1 (pin 2, UART0 RX) Via voltage divider
RXD GP0 (pin 1, UART0 TX) 3.3V signal - direct
Warning: Pico GPIO is 3.3V only — divide the module's 5V TXD with 1k/2k resistors before GP1, exactly as on the ESP32 and Raspberry Pi.

Code Examples

Arduino

Install the Elechouse VoiceRecognitionV3 library (download from the Elechouse GitHub repository and add via Sketch > Include Library > Add .ZIP Library). Train records 0-2 with the bundled vr_sample_train example, then run this sketch.

vr3_recognize_arduino.ino
// Voice Recognition Module V3 - Arduino Example
// Module TXD -> D2, Module RXD -> D3, VCC -> 5V, GND -> GND
// Library: Elechouse VoiceRecognitionV3 (github.com/elechouse/VoiceRecognitionV3)
// Train records 0-2 first with the vr_sample_train example.

#include <SoftwareSerial.h>
#include "VoiceRecognitionV3.h"

VR myVR(2, 3);   // RX = D2 (from module TXD), TX = D3 (to module RXD)

uint8_t records[7];
uint8_t buf[64];

void setup() {
  Serial.begin(115200);
  myVR.begin(9600);

  if (myVR.clear() == 0) {
    Serial.println("Recognizer cleared.");
  } else {
    Serial.println("Module not found - check wiring.");
    while (1);
  }

  // Load trained records 0, 1, 2 into the active recognizer
  if (myVR.load((uint8_t)0) >= 0) Serial.println("Record 0 loaded");
  if (myVR.load((uint8_t)1) >= 0) Serial.println("Record 1 loaded");
  if (myVR.load((uint8_t)2) >= 0) Serial.println("Record 2 loaded");

  Serial.println("Speak one of your trained commands...");
}

void loop() {
  int ret = myVR.recognize(buf, 50);

  if (ret > 0) {
    // buf[1] holds the record number that was recognized
    switch (buf[1]) {
      case 0:
        Serial.println("Command 0 recognized!");
        // digitalWrite(LED_BUILTIN, HIGH);  // your action here
        break;
      case 1:
        Serial.println("Command 1 recognized!");
        break;
      case 2:
        Serial.println("Command 2 recognized!");
        break;
      default:
        Serial.println("Record not handled");
    }
  }
}

ESP32 (Arduino IDE)

vr3_recognize_esp32.ino
// Voice Recognition Module V3 - ESP32 Example (raw protocol)
// Module TXD -> GPIO 16 via divider, Module RXD -> GPIO 17, VCC -> VIN
// Train the records first using an Arduino and the Elechouse library -
// the voiceprints stay stored on the module.

HardwareSerial vrSerial(2);  // UART2

void loadRecord(uint8_t rec) {
  // Frame: AA | LEN | 30 (load) | record | 0A
  uint8_t cmd[5] = {0xAA, 0x02, 0x30, rec, 0x0A};
  cmd[1] = 2;  // LEN = command + data bytes
  vrSerial.write(cmd, 5);
  delay(50);
}

void setup() {
  Serial.begin(115200);
  vrSerial.begin(9600, SERIAL_8N1, 16, 17);
  delay(500);

  // Load trained records 0-2 into the recognizer
  loadRecord(0);
  loadRecord(1);
  loadRecord(2);

  Serial.println("Speak one of your trained commands...");
}

void loop() {
  // Recognition frames arrive as: AA | LEN | 0D | data... | 0A
  static uint8_t frame[32];
  static int pos = -1;

  while (vrSerial.available()) {
    uint8_t b = vrSerial.read();

    if (pos < 0) {
      if (b == 0xAA) { pos = 0; frame[pos++] = b; }
    } else {
      frame[pos++] = b;
      if (b == 0x0A || pos >= 32) {
        // frame[2] = 0x0D means "voice recognized";
        // frame[4] holds the record number
        if (pos > 5 && frame[2] == 0x0D) {
          Serial.printf("Recognized record #%d\n", frame[4]);
        }
        pos = -1;
      }
    }
  }
}

Raspberry Pi (Python)

vr3_recognize_rpi.py
#!/usr/bin/env python3
# Voice Recognition Module V3 - Raspberry Pi Example (raw protocol)
# Module TXD -> GPIO 15 via divider, Module RXD -> GPIO 14, VCC -> 5V
# Setup: sudo raspi-config (disable serial console, enable serial port)
#        pip3 install pyserial
# Train the records first with an Arduino - they stay on the module.

import time
import serial

ser = serial.Serial('/dev/serial0', baudrate=9600, timeout=0.1)

def load_record(rec):
    # Frame: AA | LEN | 30 (load) | record | 0A
    ser.write(bytes([0xAA, 0x02, 0x30, rec, 0x0A]))
    time.sleep(0.05)

# Load trained records 0-2 into the active recognizer
for r in (0, 1, 2):
    load_record(r)

print('Speak one of your trained commands (Ctrl+C to stop)...')

buffer = bytearray()

try:
    while True:
        data = ser.read(32)
        if data:
            buffer.extend(data)

            # Complete frames start with 0xAA and end with 0x0A
            while 0xAA in buffer and 0x0A in buffer[buffer.index(0xAA):]:
                start = buffer.index(0xAA)
                end = buffer.index(0x0A, start)
                frame = buffer[start:end + 1]
                del buffer[:end + 1]

                # frame[2] == 0x0D means "voice recognized";
                # frame[4] holds the record number
                if len(frame) > 5 and frame[2] == 0x0D:
                    print('Recognized record #{}'.format(frame[4]))
        time.sleep(0.02)

except KeyboardInterrupt:
    print('Stopped by user')
finally:
    ser.close()

Raspberry Pi Pico (MicroPython)

vr3_recognize_pico.py
# Voice Recognition Module V3 - Pico MicroPython Example (raw protocol)
# Module TXD -> GP1 via divider, Module RXD -> GP0, VCC -> VBUS
# Train the records first with an Arduino - they stay on the module.

from machine import UART, Pin
import time

uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1), timeout=100)

def load_record(rec):
    # Frame: AA | LEN | 30 (load) | record | 0A
    uart.write(bytes([0xAA, 0x02, 0x30, rec, 0x0A]))
    time.sleep_ms(50)

# Load trained records 0-2 into the active recognizer
for r in (0, 1, 2):
    load_record(r)

print("Speak one of your trained commands...")

buffer = bytearray()

while True:
    data = uart.read()
    if data:
        buffer.extend(data)

        # Complete frames start with 0xAA and end with 0x0A
        while 0xAA in buffer:
            start = buffer.index(0xAA)
            end = buffer.find(b'\n', start)   # 0x0A terminator
            if end < 0:
                break
            frame = buffer[start:end + 1]
            del buffer[:end + 1]

            # frame[2] == 0x0D means "voice recognized";
            # frame[4] holds the record number
            if len(frame) > 5 and frame[2] == 0x0D:
                print("Recognized record #", frame[4])
    time.sleep_ms(20)

Frequently Asked Questions

How many voice commands can it recognize?
The module stores up to 80 trained records in its onboard flash, and up to 7 of them can be loaded into the active recognizer at any moment. A common pattern for bigger vocabularies is grouping: use one always-loaded "wake" command to switch which set of 7 records is loaded next.
Does it need an internet connection or an app?
No. All training and recognition happen on the module itself, so it works completely offline with instant response. That also means your voice never leaves the device — nothing is streamed anywhere.
Will it recognize anyone's voice, or just mine?
It is speaker-dependent: it matches the specific voiceprint that trained each record, so it responds most reliably to the person who trained it. That is a feature for personal access projects, but it also means family members usually need to train their own records. Any language — or even non-word sounds — can be a command.
Can I use it with 3.3V boards like the ESP32, Raspberry Pi, or Pico?
Yes. Power the module from a 5V pin, connect your board's 3.3V TX line directly to the module's RXD (3.3V registers as logic high), and put a simple 1k/2k voltage divider on the module's 5V TXD line before it reaches your board's RX pin. That one divider is the only extra component needed.
How do I train commands in the first place?
Use the vr_sample_train example from the Elechouse VoiceRecognitionV3 Arduino library: open the Serial Monitor, type train followed by a record number, and speak the command twice when prompted. Voiceprints are saved to the module's flash chip, so they persist across power cycles and even when you move the module to a Pi or Pico afterward.
Recognition is unreliable. How do I improve it?
Train and use the module in similar conditions: same distance to the mic, similar tone and pace, and low background noise. Pick command words with distinct sounds (two syllables or more work better than short grunts), keep each under 1.5 seconds, and re-train any record that consistently misfires. Also confirm the mic plug is fully seated in the 3.5 mm jack.
What are the OUT0-OUT6 and IN0-IN2 pins for?
They are expansion GPIO broken out from the module's controller. Standard serial projects can ignore them entirely — every recognition result already arrives over the UART — but advanced users can drive them with the module's protocol commands for direct hardware signaling without a host microcontroller.

Related Tutorials