Controlling an LED with Hand Recognition Using HuskyLens V2 + ESP32 (C Language)

I recently worked on a project where I combined hand recognition with distance-based LED control using the HuskyLens V2 and an ESP32, programmed in C.

Instead of simply turning the LED on or off, I made the LED gradually brighten or dim depending on the distance between the fingertip and the sensor.

The HuskyLens detects my index finger and provides distance information.
Then the ESP32 converts this distance into a PWM value, allowing the LED brightness to smoothly increase as the finger gets closer, and decrease as it moves away.

This creates a very natural and interactive effect — almost like controlling light with “air gestures.”

This project shows how powerful and intuitive vision-based interaction can be when combined with microcontrollers.

Next steps: gesture-controlled servos, touchless sliders, or a full hand-tracking interface.

CODE
  #include "DFRobot_HuskylensV2.h"
#include <Wire.h>
#include <math.h>
#include <Arduino.h>
#define SDA_PIN 21
#define SCL_PIN 22
#define LED_PIN 23
#define DAC1 25  // Broche GPIO25 (DAC1)
HuskylensV2 huskylens;

// ⚙️ Configuration PWM pour ESP32
const int PWM_CHANNEL = 0;
const int PWM_FREQ = 5000;
const int PWM_RES = 8;

// 🧠 Variable de filtrage
float filteredPWM = 0;  // valeur lissée
const float smoothFactor = 0.2;  // entre 0.1 et 0.3 selon le niveau de lissage

void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println("Initialisation HuskyLens...");

  Wire.begin(SDA_PIN, SCL_PIN);

  // Initialisation PWM (spécifique à ESP32)
  //ledcSetup(PWM_CHANNEL, PWM_FREQ, PWM_RES);
  //ledcAttachPin(LED_PIN, PWM_CHANNEL);

  // Initialisation du capteur
  while (!huskylens.begin(Wire)) {
    Serial.println("❌ Erreur de connexion au HuskyLens !");
    delay(1000);
  }

  Serial.println("✅ HuskyLens initialisé !");
}

void loop() {
  if (huskylens.getResult(ALGORITHM_HAND_RECOGNITION)) {
    while (huskylens.available(ALGORITHM_HAND_RECOGNITION)) {
      HandResult *result = static_cast<HandResult *>(huskylens.popCachedResult(ALGORITHM_HAND_RECOGNITION));

      // 📏 Coordonnées des extrémités du pouce et de l’index
      float x1 = result->thumb_tip_x;
      float y1 = result->thumb_tip_y;
      float x2 = result->index_finger_tip_x;
      float y2 = result->index_finger_tip_y;

      // Calcul de la distance
      float distance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));

      // Limiter la distance entre 0 et 255
      if (distance < 0) distance = 0;
      if (distance > 255) distance = 255;

      // Conversion en valeur PWM
      int targetPWM = (int)distance;

      // 💡 Lissage du signal (anti-clignotement)
      filteredPWM = filteredPWM + smoothFactor * (targetPWM - filteredPWM);

      // Écriture PWM lissée
      dacWrite(DAC1, (int)filteredPWM+50);

      // Debug série
      Serial.print("Distance: ");
      Serial.println(distance, 1);
      Serial.print(" → PWM filtré: ");
      Serial.println((int)filteredPWM);

      //delay(50);
    }
  }
}
License
All Rights
Reserved
licensBg
0