Smile Detector

MediaPipe Face Landmarker → XIAO ESP32S3 over Web Serial

disconnected
Loading model...
smile: 0%
No smile detected
Last command sent:
XIAO ESP32S3 Arduino sketch
// XIAO ESP32S3 — RGB rainbow on D7/D8/D9 driven by serial commands
// Wiring: common-cathode RGB LED with current-limiting resistors on each leg.
// For common-anode, set COMMON_ANODE to true.

#define COMMON_ANODE false
const int PIN_R = D7;
const int PIN_G = D8;
const int PIN_B = D9;

bool rainbow = false;
float hue = 0.0f;

void writeRGB(uint8_t r, uint8_t g, uint8_t b) {
  if (COMMON_ANODE) { r = 255 - r; g = 255 - g; b = 255 - b; }
  analogWrite(PIN_R, r);
  analogWrite(PIN_G, g);
  analogWrite(PIN_B, b);
}

void hsvToRgb(float h, float s, float v, uint8_t &r, uint8_t &g, uint8_t &b) {
  float c = v * s;
  float x = c * (1 - fabsf(fmodf(h / 60.0f, 2) - 1));
  float m = v - c;
  float rf, gf, bf;
  if (h < 60)       { rf = c; gf = x; bf = 0; }
  else if (h < 120) { rf = x; gf = c; bf = 0; }
  else if (h < 180) { rf = 0; gf = c; bf = x; }
  else if (h < 240) { rf = 0; gf = x; bf = c; }
  else if (h < 300) { rf = x; gf = 0; bf = c; }
  else              { rf = c; gf = 0; bf = x; }
  r = (uint8_t)((rf + m) * 255);
  g = (uint8_t)((gf + m) * 255);
  b = (uint8_t)((bf + m) * 255);
}

void setup() {
  Serial.begin(115200);
  pinMode(PIN_R, OUTPUT);
  pinMode(PIN_G, OUTPUT);
  pinMode(PIN_B, OUTPUT);
  writeRGB(0, 0, 0);
}

void loop() {
  if (Serial.available()) {
    String cmd = Serial.readStringUntil('\n');
    cmd.trim();
    if (cmd == "RAINBOW") rainbow = true;
    else if (cmd == "OFF") { rainbow = false; writeRGB(0, 0, 0); }
  }
  if (rainbow) {
    uint8_t r, g, b;
    hsvToRgb(hue, 1.0f, 1.0f, r, g, b);
    writeRGB(r, g, b);
    hue += 0.6f;
    if (hue >= 360.0f) hue -= 360.0f;
    delay(15);
  }
}