🤖 Build Your Own Webcam Hand-Gesture Controlled RGB LED Strip Using Arduino Uno

 

🤖 Build Your Own Webcam Hand-Gesture Controlled RGB LED Strip Using Arduino Uno

📅 By Dinesh | LearnWithDTrend Blog | 2026

🚀 Introduction

Have you ever wanted to control an RGB LED strip just by showing hand gestures in front of a laptop webcam?

In this project, I built a simple and fun gesture-controlled lighting system using:

  • ✅ Arduino Uno

  • ✅ 12V RGB LED strip

  • ✅ BC547 transistor driver stage

  • ✅ Laptop webcam

  • ✅ HTML-based hand gesture detection

The idea is simple: when you show 5 fingers, the strip glows red. When you show 2 fingers, it glows green. When you show 1 finger, it glows blue.

This project is a great example of combining computer vision, web technology, and embedded systems in one compact build.


🧠 Project Concept

Here’s how the system works:

  1. The webcam captures your hand.

  2. The HTML page detects how many fingers are visible.

  3. Based on the gesture, the webpage sends a serial command to Arduino.

  4. Arduino reads the command and switches the RGB LED strip.

  5. The strip lights up in the selected color.

That means your hand becomes the controller.


🧰 Components Used

ComponentQuantity
Arduino Uno1
12V RGB LED Strip1
BC547 Transistor3
1kΩ Resistor3
Webcam Laptop / PC1
12V Battery or Adapter1
Jumper WiresAs needed
Breadboard / PerfboardAs needed

🔌 Connections

Arduino Pin Configuration

Arduino PinRGB Function
D3Red channel
D5Green channel
D6Blue channel

BC547 Transistor Wiring

Each RGB channel uses one BC547 transistor.

  • Arduino pin (D3 / D5 / D6)1kΩ resistorBC547 base

  • BC547 emitterGND

  • BC547 collector → corresponding RGB strip color wire

  • 12V strip positive+12V battery/adapter positive

  • Battery negativeArduino GND

  • Common ground must be shared between Arduino and power supply

Important Note

BC547 is suitable only for low-current lighting sections. If your RGB strip is long or draws more current, a MOSFET driver is a better option.


📟 Arduino Code

The Arduino listens for serial commands from the browser and controls the RGB strip.

#define RED_PIN   3
#define GREEN_PIN 5
#define BLUE_PIN  6

void setColor(byte red, byte green, byte blue) {
  analogWrite(RED_PIN, red);
  analogWrite(GREEN_PIN, green);
  analogWrite(BLUE_PIN, blue);
}

void setup() {
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  Serial.begin(9600);
  setColor(0, 0, 0);
}

void loop() {
  if (Serial.available()) {
    char cmd = Serial.read();

    if (cmd == '5') {
      setColor(255, 0, 0);   // Red
    }
    else if (cmd == '2') {
      setColor(0, 255, 0);   // Green
    }
    else if (cmd == '1') {
      setColor(0, 0, 255);   // Blue
    }
    else if (cmd == '0') {
      setColor(0, 0, 0);     // Off
    }
  }
}

🌐 HTML Web Interface

This HTML page does two jobs:

  • Uses the webcam to detect hand gestures

  • Sends the gesture result to Arduino through Web Serial


<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Hand Gesture RGB Control</title> <style> body { font-family: Arial, sans-serif; text-align: center; background: #111; color: #fff; margin: 0; padding: 20px; } video, canvas { width: 640px; max-width: 95vw; border: 2px solid #444; border-radius: 10px; margin-top: 12px; } button { padding: 12px 18px; font-size: 16px; border: none; border-radius: 8px; margin: 8px; cursor: pointer; } #status { margin-top: 12px; font-size: 18px; } </style> </head> <body> <h2>Gesture Control for RGB Strip</h2> <button id="connectBtn">Connect Arduino</button> <div id="status">Status: Not connected</div> <video id="video" autoplay playsinline muted></video> <canvas id="canvas" width="640" height="480"></canvas> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.js"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js"></script> <script> const video = document.getElementById("video"); const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const statusText = document.getElementById("status"); const connectBtn = document.getElementById("connectBtn"); let port = null; let writer = null; let lastSent = ""; let stableCount = 0; let lastGesture = ""; async function connectArduino() { try { port = await navigator.serial.requestPort(); await port.open({ baudRate: 9600 }); writer = port.writable.getWriter(); statusText.textContent = "Status: Arduino connected"; } catch (err) { console.error(err); statusText.textContent = "Status: Connection failed"; } } async function sendCommand(cmd) { if (!writer) return; const data = new TextEncoder().encode(cmd); await writer.write(data); } connectBtn.addEventListener("click", connectArduino); function countFingers(landmarks, handednessLabel) { const tips = [8, 12, 16, 20]; const pips = [6, 10, 14, 18]; let count = 0; if (handednessLabel === "Right") { if (landmarks[4].x < landmarks[3].x) count++; } else { if (landmarks[4].x > landmarks[3].x) count++; } for (let i = 0; i < 4; i++) { if (landmarks[tips[i]].y < landmarks[pips[i]].y) count++; } return count; } function gestureToCommand(fingers) { if (fingers === 5) return "5"; if (fingers === 2) return "2"; if (fingers === 1) return "1"; return "0"; } const hands = new Hands({ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file}` }); hands.setOptions({ maxNumHands: 1, modelComplexity: 1, minDetectionConfidence: 0.7, minTrackingConfidence: 0.7 }); hands.onResults((results) => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(results.image, 0, 0, canvas.width, canvas.height); if (results.multiHandLandmarks && results.multiHandLandmarks.length > 0) { const landmarks = results.multiHandLandmarks[0]; const handednessLabel = results.multiHandedness[0].label; drawConnectors(ctx, landmarks, HAND_CONNECTIONS, { color: "#00FF00", lineWidth: 2 }); drawLandmarks(ctx, landmarks, { color: "#FF0000", lineWidth: 1 }); const fingers = countFingers(landmarks, handednessLabel); const command = gestureToCommand(fingers); if (command === lastGesture) { stableCount++; } else { stableCount = 0; lastGesture = command; } if (stableCount > 4 && command !== lastSent) { sendCommand(command); lastSent = command; statusText.textContent = `Detected: ${fingers} fingers → Sent ${command}`; } else { statusText.textContent = `Detected: ${fingers} fingers`; } } else { statusText.textContent = "No hand detected"; } }); async function startCamera() { const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480 } }); video.srcObject = stream; const camera = new Camera(video, { onFrame: async () => { await hands.send({ image: video }); }, width: 640, height: 480 }); camera.start(); } startCamera().catch(err => { console.error(err); statusText.textContent = "Camera access failed"; }); </script> </body> </html>

🧠 How the System Works

Here is the working flow of the project:

  • The webcam detects your hand.

  • The HTML page counts the number of raised fingers.

  • The command is sent to Arduino through USB serial communication.

  • Arduino reads the command and drives the RGB strip.

  • The BC547 transistors act as switching devices for the LED channels.

Gesture to Color Mapping

GestureCommandColor
5 fingers5Red
2 fingers2Green
1 finger1Blue
No valid gesture0Off

🛠️ Build Process

First, I connected the RGB strip to the BC547 transistor driver stage and shared the ground between the Arduino and the 12V supply.

Next, I uploaded the Arduino code and checked whether the strip responded properly to serial commands.

Then, I opened the HTML page in the browser, allowed webcam access, and connected the Arduino using Web Serial.

Finally, I tested the gestures:

  • Showing 5 fingers turned the strip red

  • Showing 2 fingers turned the strip green

  • Showing 1 finger turned the strip blue


🎮 Control Features

  • Webcam-based hand detection

  • Finger count recognition

  • Browser-to-Arduino serial communication

  • Automatic RGB color switching

  • Simple and interactive gesture control


📌 Important Notes

  • Open the HTML file in Chrome or Edge.

  • Run it from a local server because Web Serial and camera access need browser permissions.

  • BC547 is fine for small loads, but for a higher-power RGB strip, use a MOSFET.

  • Make sure the Arduino GND and 12V power GND are connected together.


🎉 Final Result

✅ Webcam gesture detection working
✅ Arduino serial communication working
✅ RGB LED strip switching properly
✅ Red / Green / Blue colors mapped to hand gestures
✅ A clean mini-project that mixes hardware and web technology

This project is a simple but impressive way to show how AI-style hand detection, HTML, and Arduino electronics can work together.


❤️ Let’s Connect

You can use this project for your blog, mini project submission, or portfolio demo.

It also makes a nice beginner-friendly project for students who want to learn:

  • Arduino programming

  • Webcam-based gesture detection

  • HTML and JavaScript control

  • Serial communication

  • Transistor switching for LED strips


LearnWithDTrend Blog Draft — ready for publishing

Comments

Popular posts from this blog

🎯 Build Your Own RFID Attendance System Using Arduino + ESP32 + Google Sheets

How to make a Rfid id tag to turn on the Motor

Build Your Own Timer Plug – Automatic Mobile Charger Cut-Off Using ESP32 (Hotspot Mode)