element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Project14
  • Challenges & Projects
  • More
Project14
Show and Tell! AI Voice Mood Lighting System
  • News
  • Member Updates
  • Competitions
  • Forum
  • Documents
  • Theme Suggestions
  • Polls
  • Members
  • More
  • Cancel
  • New
Join Project14 to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: karthickiot
  • Date Created: 30 Aug 2026 5:20 PM Date Created
  • Views 74 views
  • Likes 4 likes
  • Comments 2 comments
  • rgb led
  • Vosk Model
  • KEYWORD DETECTION
  • voice assistance
  • ai
  • speech recognition
Related
Recommended

AI Voice Mood Lighting System

karthickiot
karthickiot
30 Aug 2026

Hello everyone. 

My Project14 project is called “AI Voice Mood Lighting System.” The basic idea is simple: I speak a word → the system recognizes it → the word is mapped to an emotion or situation → the RDK X5 changes an RGB LED to the corresponding color.

For example:

  • Danger → Red Red circle
  • Freshness → Green
  • Peaceful → Blue Large blue circle
  • Happiness → Yellow
  • Sweetness → Cyan 
  • Honesty → White White circle
  • Royalty → Magenta 
  • Funny → Color-changing dance mode Rainbow
  • Sleep → Light OFF

This project interesting due to the speech-recognition part works offline using Vosk, while the RDK X5 handles the physical RGB LED.

What Inspired Me?

I wanted to build something that could demonstrate how a person can interact naturally with an embedded system. Instead of pressing a button or typing a command, I wanted to use voice. The idea developed from a simple question: Can I use voice recognition to control a physical RGB LED using the RDK X5? I also wanted the project to work without depending on the internet. That led me to combine: Voice + Offline AI + Embedded Hardware + RGB Visualization. The RGB LED gives an immediate visual response. 

For example, if I say: “Danger” the system recognizes the keyword and the RDK X5 changes the LED to red. If I say: “Peaceful” the LED changes to blue. This makes the project easy to demonstrate and understand.

Project Architecture

The project has two major parts.

PC side

The PC is responsible for:

  • Capturing microphone audio

  • Running the Vosk offline speech-recognition model

  • Converting speech into text

  • Detecting important keywords

  • Mapping keywords to colors

  • Sending HTTP commands to the RDK X5

  • Providing voice feedback through the PC speaker

RDK X5 side

The RDK X5 is responsible for:

  • Running the Flask server

  • Receiving HTTP commands

  • Controlling GPIO pins

  • Driving the RGB LED

The complete architecture is:

              HUMAN VOICE
                   │
                   ▼
            PC MICROPHONE
                   │
                   ▼
         VOSK OFFLINE MODEL
          Speech Recognition
                   │
                   ▼
          KEYWORD DETECTION
                   │
        ┌──────────┼──────────┐
        │          │          │
      Danger     Peaceful   Happiness
        │          │          │
       RED        BLUE       YELLOW
        │          │          │
        └──────────┼──────────┘
                   ▼
             HTTP REQUEST
                   │
                   ▼
          RDK X5 FLASK SERVER
                   │
                   ▼
               GPIO PINS
                   │
                   ▼
                RGB LED

Hardware Used

The main hardware components are:

  • RDK X5 development kit

  • Common-anode RGB LED

  • Current-limiting resistors

  • Jumper wires

  • PC or laptop

  • Microphone

  • Network connection between the PC and RDK X5

The RGB LED channels are connected as follows:

RGB Channel RDK X5 GPIO
Red GPIO 31
Green GPIO 36
Blue GPIO 37

I used board numbering with:

GPIO.setmode(GPIO.BOARD)

Each RGB channel is connected through an appropriate current-limiting resistor.

Common-Anode RGB LED

One important hardware detail in my project is that the RGB LED is common-anode. A common-anode RGB LED has three individual color channels:

  • Red

  • Green

  • Blue

By controlling these three channels, I can create several colors.

For example:

Red + Green       = Yellow
Green + Blue      = Cyan
Red + Blue        = Magenta
Red + Green + Blue = White

However, common-anode LEDs use inverted logic.

For my setup:

GPIO LOW  → LED ON
GPIO HIGH → LED OFF

Therefore, to turn on red:

RED   → LOW  → ON
GREEN → HIGH → OFF
BLUE  → HIGH → OFF

This produces red.

To make the programming easier, I created a common function that handles this inverted logic. Conceptually: GPIO.LOW if red else GPIO.HIGH This prevents me from having to manually remember the reversed logic for every color.

RGB Color System

I created functions for the different colors.

The logical mapping is:

DANGER      → RED
FRESHNESS   → GREEN
PEACEFUL    → BLUE
HAPPINESS   → YELLOW
SWEETNESS   → CYAN
HONESTY     → WHITE
ROYALTY     → MAGENTA
SLEEP       → OFF
FUNNY       → COLOR CHANGING

This gives the RGB LED the role of a simple visual emotion and situation indicator.

Bill of Materials (BOM) — Offline Voice-Controlled Emotion RGB Assistant

S.No. Component Specification / Purpose Qty.
1 RDK X5 Development Kit Main embedded controller, Flask server & GPIO control 1
2 Common-Anode RGB LED Displays different emotion/status colors 1
3 Resistors Current-limiting resistors for RGB LED channels 3
4 Jumper Wires GPIO and power connections 6–10
5 Breadboard Prototype circuit assembly 1
6 PC / Laptop Offline voice recognition and command processing 1
7 Microphone Captures voice commands 1
8 Network Connection PC Left right arrow RDK X5 communication using HTTP 1
9 USB Cable / Power Supply Power and/or connection for RDK X5 1
10 RDK X5 compatible power supply Provides power to the development kit 1

Software / AI Components

S.No. Software Purpose
1 Python Main programming language
2 Vosk Offline speech recognition
3 vosk-model-small-en-in-0.4 English-India offline speech model
4 Sounddevice Microphone audio capture
5 Flask HTTP server running on RDK X5
6 Requests PC-to-RDK X5 HTTP communication
7 RPi.GPIO / compatible GPIO library RGB LED GPIO control

First Development Stage – Testing the LED

I did not start by connecting everything together. Instead, I developed the project in stages. First, I tested the RGB LED independently. I tested:

OFF
 ↓
RED
 ↓
GREEN
 ↓
BLUE
 ↓
YELLOW
 ↓
CYAN
 ↓
MAGENTA
 ↓
WHITE
 ↓
OFF

This was important because I wanted to confirm that the GPIO connections and common-anode logic were correct before adding networking and voice recognition.

Building the RDK X5 LED Server

After confirming that the LED worked, I created a Python Flask server on the RDK X5.

from flask import Flask, request
import Hobot.GPIO as GPIO
import time
import atexit
# =====================================
# FLASK SERVER
# =====================================
app = Flask(__name__)
# =====================================
# GPIO SETTINGS
# =====================================
RED = 31
GREEN = 36
BLUE = 37
GPIO.setmode(GPIO.BOARD)
GPIO.setup(
    RED,
    GPIO.OUT
)
GPIO.setup(
    GREEN,
    GPIO.OUT
)
GPIO.setup(
    BLUE,
    GPIO.OUT
)
# =====================================
# COMMON ANODE RGB LED
# LOW = ON
# HIGH = OFF
# =====================================
def led_off():
    GPIO.output(RED, GPIO.HIGH)
    GPIO.output(GREEN, GPIO.HIGH)
    GPIO.output(BLUE, GPIO.HIGH)
def set_color(red, green, blue):
    GPIO.output(
        RED,
        GPIO.LOW if red else GPIO.HIGH
    )
    GPIO.output(
        GREEN,
        GPIO.LOW if green else GPIO.HIGH
    )
    GPIO.output(
        BLUE,
        GPIO.LOW if blue else GPIO.HIGH
    )
# =====================================
# COLORS
# =====================================
def red():
    set_color(1,0,0)
def green():
    set_color(0,1,0)
def blue():
    set_color(0,0,1)
def yellow():
    set_color(1,1,0)
def cyan():
    set_color(0,1,1)
def magenta():
    set_color(1,0,1)
def white():
    set_color(1,1,1)
# =====================================
# COMMAND HANDLER
# =====================================
def control_led(color):
    color = color.lower()
    if color == "red":
        red()
    elif color == "green":
        green()
    elif color == "blue":
        blue()
    elif color == "yellow":
        yellow()
    elif color == "cyan":
        cyan()
    elif color == "magenta":
        magenta()
    elif color == "white":
        white()
    elif color == "off":
        led_off()
    else:
        return False
    return True
# =====================================
# API ROUTES
# =====================================
@app.route("/led")
def led_control():
    try:
        color = request.args.get(
            "color"
        )
        if color is None:
            return "Missing color",400
        print(
            "Received:",
            color
        )
        result = control_led(
            color
        )
        if result:
            return "OK"
        else:
            return "Invalid color"
    except Exception as e:
        print(
            "LED ERROR:",
            e
        )
        return "ERROR"
@app.route("/status")
def status():
    return "RDK RGB SERVER OK"
# =====================================
# CLEAN EXIT
# =====================================
def cleanup():
    print(
        "GPIO cleanup"
    )
    led_off()
    GPIO.cleanup()
atexit.register(
    cleanup
)

# =====================================
# START
# =====================================
led_off()
print("==============================")
print("RDK X5 RGB LED SERVER READY")
print("==============================")

app.run(
    host="0.0.0.0",
    port=5000,
    threaded=True
)

The server is called: led_server.py, It listens on: Port 5000, The main endpoint is: /led, The color is provided as a URL parameter. For example:  /led?color=red , The RDK X5 receives the request and controls the GPIO pins accordingly. I also created a: /status endpoint. This allows me to check whether the LED server is running. The server is configured to accept network connections so that the PC can communicate with the RDK X5.

Testing Network Communication

Before adding voice recognition, I tested the network communication separately. The process was:

PC
 │
 │ HTTP command
 ▼
RDK X5 Flask Server
 │
 ▼
GPIO
 │
 ▼
RGB LED

For example, the PC can request:

color=red

The RDK X5 receives it and turns the LED red. I repeated this process for the other colors. This staged development helped me identify problems more easily.

Adding Offline Voice Recognition

Once the hardware and network control were working, I added voice recognition. For this, I used the Vosk offline speech-recognition engine. The model I used is: vosk-model-small-en-in-0.4. The PC microphone captures the audio using Python's sound device library. The audio configuration is:

Sample rate: 16000 Hz
Channels:    1
Format:      int16

The audio is placed into a queue and processed by Vosk. Vosk returns recognized text, which my Python program then analyzes. The important point is that the basic speech-recognition process happens locally, rather than sending my voice to a cloud speech-recognition service.

Keyword Detection

The system does not need to understand an entire conversation. It mainly needs to identify important keywords. For example: “happiness” ↓ yellow ↓ HTTP request ↓ RDK X5 ↓ RGB = Yellow Similarly: “peaceful” ↓ blue ↓ RDK X5 ↓ RGB = Blue I convert the recognized text to lowercase and then check for keywords. I also added variations to make the system more tolerant. For example:

happy / happiness
peace / peaceful
fresh / freshness
danger / dangerous
sweet / sweetness
honest / honesty
royal / royalty

This is useful because speech-recognition models do not always return exactly the word that I spoke.

START and STOP Control

I also added a simple activation mechanism. The system starts in an inactive state: active = False When I say: START the system becomes active. When I say: STOP the system becomes inactive and the LED is turned off. This prevents random conversations or background speech from continuously controlling the LED. It also makes the demonstration more controlled.

Funny / Dance Mode

I wanted to add something more interesting than just static colors. So I created a special command: FUNNY When I say FUNNY, the LED enters a small dance-light mode. It cycles through:

Red
Green
Blue
Yellow
Cyan
Magenta
White

The sequence repeats several times with a short delay. Finally, the LED turns off. This gives the project a more interactive and entertaining demonstration.

Sleep Command

I also added: SLEEP The purpose is simple. When the system recognizes the sleep command: SLEEP ↓ LED OFF This gives me a direct voice command for switching off the visual output.

import json
import queue
import requests
import win32com.client
import time
import os
import sounddevice as sd

from vosk import Model, KaldiRecognizer


# ============================================================
# RDK X5 SETTINGS
# ============================================================

RDK_IP = "192.162.6.167"   this should change according to your network

LED_URL = f"http://{RDK_IP}:5000/led"


# ============================================================
# OFFLINE VOSK MODEL
# ============================================================

MODEL_PATH = os.path.join(
    os.path.dirname(__file__),
    "vosk-model-small-en-in-0.4"
)


print()
print("======================================")
print("Loading offline speech recognition...")
print("======================================")
print()


if not os.path.exists(MODEL_PATH):

    print("ERROR: Vosk model not found.")
    print()
    print("Expected model folder:")
    print(MODEL_PATH)
    print()

    input("Press Enter to exit...")
    exit()


model = Model(
    MODEL_PATH
)


recognizer = KaldiRecognizer(
    model,
    16000
)


print(
    "Offline speech recognition ready."
)

print()


# ============================================================
# LAPTOP SPEAKER
# ============================================================

speaker = win32com.client.Dispatch(
    "SAPI.SpVoice"
)

speaker.Rate = -1
speaker.Volume = 100


def speak(text):

    print(
        "LAPTOP SPEAKER:",
        text
    )

    speaker.Speak(
        text
    )


# ============================================================
# SEND COLOR COMMAND TO RDK
# ============================================================

def send_color(color):

    try:

        response = requests.get(

            LED_URL,

            params={
                "color": color
            },

            timeout=3
        )


        print(
            "RDK:",
            response.text
        )


        return True


    except requests.exceptions.RequestException as e:

        print()
        print(
            "RDK CONNECTION ERROR:"
        )

        print(
            e
        )

        print()


        speak(
            "RDK connection failed"
        )


        return False


# ============================================================
# FUNNY / DANCE LIGHTS
# ============================================================

def funny_lights():

    colors = [

        ("red", "Red"),

        ("green", "Green"),

        ("blue", "Blue"),

        ("yellow", "Yellow"),

        ("cyan", "Cyan"),

        ("magenta", "Magenta"),

        ("white", "White")

    ]


    print()
    print(
        "FUNNY / DANCE LIGHTS STARTED"
    )
    print()


    # Repeat the color sequence 3 times

    for repeat in range(3):

        for color, name in colors:

            send_color(
                color
            )


            print(
                "FUNNY:",
                name
            )


            time.sleep(
                0.5
            )


    # Turn all lights OFF after dance

    send_color(
        "off"
    )


    speak(
        "Funny dance completed"
    )


# ============================================================
# MICROPHONE AUDIO QUEUE
# ============================================================

audio_queue = queue.Queue()


def audio_callback(
    indata,
    frames,
    time_info,
    status
):

    if status:

        print(
            "AUDIO STATUS:",
            status
        )


    audio_queue.put(
        bytes(indata)
    )


# ============================================================
# SYSTEM STATUS
# ============================================================

active = False


# ============================================================
# PROCESS VOICE COMMAND
# ============================================================

def process_command(command):

    global active


    command = command.lower().strip()


    print()
    print(
        "======================================"
    )

    print(
        "VOSK HEARD:",
        command
    )

    print(
        "======================================"
    )


    # ========================================================
    # NORMALIZE COMMON SPEECH
    # ========================================================

    command = command.replace(
        "wake up",
        "wakeup"
    )


    # ========================================================
    # START
    # ========================================================

    if command == "start":

        active = True


        speak(
            "Voice control started"
        )


        print(
            "SYSTEM STATUS: ACTIVE"
        )


        return


    # ========================================================
    # STOP
    # ========================================================

    if command == "stop":

        active = False


        send_color(
            "off"
        )


        speak(
            "Voice control stopped"
        )


        print(
            "SYSTEM STATUS: INACTIVE"
        )


        return


    # ========================================================
    # WAIT FOR START
    # ========================================================

    if active == False:

        print(
            "Voice control is OFF."
        )


        print(
            "Say start to activate."
        )


        return


    # ========================================================
    # DANGER → RED
    # ========================================================

    if (
        "danger" in command
        or "dangerous" in command
    ):

        if send_color(
            "red"
        ):

            speak(
                "Danger. Red color is on"
            )


        return


    # ========================================================
    # FRESHNESS → GREEN
    # ========================================================

    elif (
        "freshness" in command
        or "fresh" in command
    ):

        if send_color(
            "green"
        ):

            speak(
                "Freshness. Green color is on"
            )


        return


    # ========================================================
    # PEACEFUL → BLUE
    # ========================================================

    elif (
        "peaceful" in command
        or "peace" in command
    ):

        if send_color(
            "blue"
        ):

            speak(
                "Peaceful. Blue color is on"
            )


        return


    # ========================================================
    # HAPPINESS → YELLOW
    # ========================================================

    elif (
        "happiness" in command
        or "happy" in command
    ):

        if send_color(
            "yellow"
        ):

            speak(
                "Happiness. Yellow color is on"
            )


        return


    # ========================================================
    # SWEETNESS → CYAN
    # ========================================================

    elif (
        "sweetness" in command
        or "sweet" in command
    ):

        if send_color(
            "cyan"
        ):

            speak(
                "Sweetness. Cyan color is on"
            )


        return


    # ========================================================
    # HONESTY → WHITE
    # ========================================================

    elif (
        "honesty" in command
        or "honest" in command
    ):

        if send_color(
            "white"
        ):

            speak(
                "Honesty. White color is on"
            )


        return


    # ========================================================
    # ROYALTY → MAGENTA
    # ========================================================

    elif (
        "royalty" in command
        or "royal" in command
    ):

        if send_color(
            "magenta"
        ):

            speak(
                "Royalty. Magenta color is on"
            )


        return


    # ========================================================
    # FUNNY → DANCE / ALL COLORS
    # ========================================================

    elif (
        "funny" in command
        or "fun" in command
    ):

        speak(
            "Funny mode started"
        )


        funny_lights()


        return


    # ========================================================
    # SLEEP → ALL LIGHTS OFF
    # ========================================================

    elif "sleep" in command:

        if send_color(
            "off"
        ):

            speak(
                "Sleep. All lights are off"
            )


        return


    # ========================================================
    # EXIT
    # ========================================================

    elif "exit" in command:

        speak(
            "Program closed"
        )


        raise KeyboardInterrupt


    # ========================================================
    # UNKNOWN COMMAND
    # ========================================================

    else:

        print(
            "Command not recognized:"
        )


        print(
            command
        )


        speak(
            "Command not recognized"
        )


# ============================================================
# PROGRAM START
# ============================================================

print()
print("======================================")
print("RDK X5 OFFLINE EMOTION RGB ASSISTANT")
print("======================================")
print()


print(
    "RDK IP:",
    RDK_IP
)


print()


print(
    "VOICE COMMANDS"
)


print(
    "-------------------------------"
)


print(
    "START     -> Activate system"
)


print(
    "STOP      -> Deactivate system"
)


print(
    "DANGER    -> Red"
)


print(
    "FRESHNESS -> Green"
)


print(
    "PEACEFUL  -> Blue"
)


print(
    "HAPPINESS -> Yellow"
)


print(
    "SWEETNESS -> Cyan"
)


print(
    "HONESTY   -> White"
)


print(
    "ROYALTY   -> Magenta"
)


print(
    "FUNNY     -> Dance all colors"
)


print(
    "SLEEP     -> All lights OFF"
)


print(
    "EXIT      -> Close program"
)


print(
    "-------------------------------"
)


print()


speak(
    "System ready. Say start"
)


# ============================================================
# START MICROPHONE
# ============================================================

try:


    with sd.RawInputStream(

        samplerate=16000,

        blocksize=8000,

        dtype="int16",

        channels=1,

        callback=audio_callback

    ):


        print()
        print(
            "======================================"
        )


        print(
            "MICROPHONE READY"
        )


        print(
            "======================================"
        )


        print()


        print(
            "Say START to activate."
        )


        print(
            "Say STOP to deactivate."
        )


        print()


        while True:


            data = audio_queue.get()


            if recognizer.AcceptWaveform(
                data
            ):


                result = json.loads(

                    recognizer.Result()

                )


                command = result.get(
                    "text",
                    ""
                )


                if command:

                    process_command(
                        command
                    )


# ============================================================
# KEYBOARD INTERRUPT
# ============================================================

except KeyboardInterrupt:

    print()

    print(
        "Program stopped."
    )


# ============================================================
# PROGRAM ERROR
# ============================================================

except Exception as e:

    print()

    print(
        "PROGRAM ERROR:"
    )

    print(
        e
    )

    print()


# ============================================================
# CLEANUP
# ============================================================

finally:

    try:

        send_color(
            "off"
        )

    except Exception:

        pass


    print()

    print(
        "Voice control closed."
    )

    print()

PC-to-RDK X5 Communication

The PC communicates with the RDK X5 using HTTP. The Python program sends a request similar to:

requests.get(
    LED_URL,
    params={"color": color},
    timeout=3
)

The important advantage of this design is that the PC does not directly control the RDK X5 GPIO.

Instead:

PC
 │
 │ HTTP
 ▼
Flask API
 │
 ▼
GPIO
 │
 ▼
RGB LED

This creates a clean separation between the software and hardware. I also added timeout and exception handling so that if the RDK X5 cannot be reached, the PC program can report the connection problem instead of simply crashing.

A Major First Challenge – Offline Speech Recognition

The biggest challenge I faced was offline keyword recognition accuracy. Initially, I expected the offline model to recognize my keywords consistently. But during testing, I discovered that some words were not recognized correctly every time. The result could be affected by:

  • Pronunciation

  • Microphone quality

  • Background noise

  • Speaking distance

  • Speaking volume

  • The vocabulary of the model

For example, I might speak a keyword correctly, but Vosk could sometimes return a different word. That becomes a problem because my application needs to detect a specific keyword before it can select a color.

Offline vs Online Recognition

During development, I also compared the offline recognition with an online speech-recognition approach. In my testing, the online system performed better for some of my phrases. It could recognize certain words more accurately and consistently. However, I specifically wanted this project to demonstrate offline operation. If I simply replaced Vosk with an online service, I would lose an important part of my project concept. So I treated this as an engineering trade-off:

ONLINE RECOGNITION
      │
      ├── Better recognition in my testing
      └── Requires internet/cloud service
OFFLINE VOSK
      │
      ├── Local processing
      ├── No cloud dependency
      └── More challenging recognition

Instead of hiding this limitation, I used it as a learning opportunity.

Improved the Recognition

I added multiple variations for some keywords. For example:

happy / happiness
peace / peaceful
fresh / freshness
danger / dangerous

This means the program does not depend on only one exact form of a word. I also kept the speech-recognition system separate from the LED-control system. That means I can improve the recognition algorithm later without changing the RDK X5 GPIO implementation.

Second Challenge – Common-Anode Logic

Another challenge was understanding the behavior of the common-anode RGB LED. With a common-cathode LED, the logic is different. But with my common-anode LED: LOW = ON, HIGH = OFF Initially, I had to make sure that my software matched the electrical behavior. I solved this by creating a dedicated set_color() function. This made the rest of the program much easier to understand. Instead of thinking about GPIO levels everywhere, I can simply say: set_color(1,0,0) for red, or: set_color(0,1,1) for cyan.

Third Challenge – Network Communication

The PC and RDK X5 also need to communicate over the network. The PC sends the HTTP command to the RDK X5. Therefore, both devices need to be reachable on the same network. I used an IP address for the RDK X5 and port 5000 for the Flask server. I also added a timeout to the HTTP request. This taught me that even when individual components work correctly, the complete system can still fail because of communication problems.

Final Demonstration

For my final demonstration, I will show the complete system. Step 1 Start the RDK X5 Flask LED server. Step 2 Start the PC voice-control program. Step 3 Say: START The system becomes active. Step 4 Say: DANGER The RDK X5 receives the command. The LED becomes: Red circle RED Step 5 Say: PEACEFUL The LED changes to: Large blue circle BLUE Step 6 Say: HAPPINESS The LED changes to: YELLOW Step 7 Say: FUNNY The LED starts cycling through multiple colors. Rainbow Dance Mode Step 8 Say: SLEEP The LED turns off. The complete demonstration is:

VOICE
  ↓
OFFLINE SPEECH RECOGNITION
  ↓
KEYWORD DETECTION
  ↓
COLOR SELECTION
  ↓
HTTP COMMAND
  ↓
RDK X5
  ↓
GPIO
  ↓
RGB LED

Demonstration Video

I also created a demonstration video of the project:

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Future Improvements

The RGB LED is only the first stage of my idea. I would like to develop this prototype into a more useful AI-assisted care and interaction device.

1. Better Offline Recognition

I would like to investigate:

  • Better Vosk models

  • Smaller command vocabularies

  • More robust keyword matching

  • Better noise handling

Instead of allowing a large vocabulary, I could focus recognition specifically on the commands required by my project.

2. Better Noise Handling

I would like to test the system with:

  • Background noise

  • Different microphones

  • Different speaking distances

  • Different speaking volumes

  • Multiple speakers

This would help determine how reliable the system is in real-world conditions.

3. Camera-Based Mood Detection

A future version could include a camera.

The system could combine:

Voice + Facial Expression

to obtain more information about a person's mood.

For example:

VOICE
  +
CAMERA
  ↓
MOOD INFORMATION
  ↓
AI PROCESSING
  ↓
APPROPRIATE RESPONSE

4. Motion Sensor

I would also like to add a motion sensor. This could help the system understand whether a person is moving or whether unusual activity is occurring.

5. Alerts

For a command such as DANGER, a future version could do more than turn the LED red.

It could potentially:

DANGER
  ↓
RED LED
  +
ALARM
  +
NOTIFICATION
  +
CAREGIVER ALERT

6. More Visual Effects

I could also add:

  • Breathing colors

  • Blinking

  • Smooth color transitions

  • Emergency flashing

  • Rainbow effects

  • Emotion-specific animations

This would make the RGB output more expressive.

Long-Term Vision

long-term goal is to develop the prototype into a small AI-assisted care and interaction device.

The future concept could look like this:

                    PERSON
                       │
             ┌─────────┴─────────┐
             │                   │
           VOICE              CAMERA
             │                   │
             └─────────┬─────────┘
                       │
                 MOTION SENSOR
                       │
                       ▼
                ┌─────────────┐
                │   RDK X5    │
                │     AI      │
                └──────┬──────┘
                       │
             ┌─────────┼─────────┐
             ▼         ▼         ▼
           RGB       ALERT     OTHER
           LED       SYSTEM    DEVICES
             │         │         │
             └─────────┼─────────┘
                       ▼
                USER / CAREGIVER

The device could eventually combine different types of information instead of relying only on one voice keyword.

Possible Applications

The concept could potentially be useful in areas such as:

Children

A simple interactive device could provide visual feedback when a child speaks a command.

Elder Care

Voice commands could provide a simple interface for communicating basic needs or situations.

Patient Assistance

In a future and more carefully validated version, voice commands could help communicate simple requests or situations when normal communication is difficult.

These are future possibilities, not capabilities of my current prototype.

What I Learned

The most important thing I learned from this project is that building an AI system is not just about making the model work once. There is a big difference between: “The model can recognize speech.” and “The model can reliably recognize the exact commands my application needs.” My testing showed that online speech recognition could be more accurate for some phrases, while the offline model gave me the advantage of local processing and no cloud dependency.

This taught me about:

  • Speech-recognition limitations

  • Vocabulary

  • Microphone input

  • Background noise

  • Keyword matching

  • Error handling

  • HTTP communication

  • Flask servers

  • GPIO control

  • RGB electronics

  • System architecture

  • The trade-offs between offline and online AI

I also learned the importance of developing a project in stages. First I tested the LED. Then I tested the network. Then I added voice recognition. Finally, I connected everything together. This made it much easier to identify and solve problems.

Conclusion

My current system demonstrates: Voice → Offline AI → Keyword → HTTP → RDK X5 → GPIO → RGB LED

It combines: Python + Vosk + Sounddevice + Flask + HTTP + GPIO + RGB LED

The most important part of this project for me was not simply making an LED change color. It was understanding the complete journey from human speech to physical hardware, and learning how to solve the practical problems along the way. The main challenge I am continuing to work on is improving the reliability of offline keyword recognition. In the future, I would like to expand the project from: Voice + RGB LED into: Voice + Camera + Motion → AI Understanding → Useful Action

My ultimate goal is to develop this prototype into a more robust, standalone, AI-assisted device that can provide simple and useful interaction for people.

Thank you.

  • Sign in to reply
Parents
  • TheRehn
    TheRehn 3 days ago

    This is such a cool project and so well explained, using offline VOSK speech recognition seems to open up options for running it on dev board. Now wondering if it would be possible to have a 'mood badge' you could set the colour of by voice Thinking

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • TheRehn
    TheRehn 3 days ago

    This is such a cool project and so well explained, using offline VOSK speech recognition seems to open up options for running it on dev board. Now wondering if it would be possible to have a 'mood badge' you could set the colour of by voice Thinking

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube