Automatic Curtain System – Assembly Video & Arduino Code

Code

// C++ Arduino Code (Copy Below)

#include <Servo.h>

// Pins (as you used before)
const int TRIG_PIN  = 5;
const int ECHO_PIN  = 6;
const int SERVO_PIN = 9;


// Distances & timing
const int NEAR_CM        = 15;    // trigger distance to detect a hand
const int FAR_CM         = 18;    // small hysteresis to release detection
const unsigned long COOLDOWN_MS = 1500;  // ignore re-triggers for this time


// Servo angles (adjust for your mechanism)
const int OPEN_ANGLE  = 0;    // curtain open
const int CLOSE_ANGLE = 90;   // curtain closed

Servo curtain;
bool curtainClosed = false;    // start opened
bool wasNear = false;          // previous "near" state
unsigned long lastToggleMs = 0;


long readDistanceOnceCM() {

  // Send pulse
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Listen with timeout to avoid blocking forever
  unsigned long duration = pulseIn(ECHO_PIN, HIGH, 25000UL); // ~4.3 m max

  if (duration == 0) return 999; // no echo
  return (long)(duration * 0.0343 / 2.0); // cm

}

// Median of 3 reads for stability
long distanceCM() {

  long a = readDistanceOnceCM();
  delay(10);
  long b = readDistanceOnceCM();
  delay(10);

  long c = readDistanceOnceCM();

  // sort a,b,c and return median
  if (a > b) { long t=a; a=b; b=t; }
  if (b > c) { long t=b; b=c; c=t; }
  if (a > b) { long t=a; a=b; b=t; }

  return b;
}

 

void moveCurtain(bool closeIt) {

  if (closeIt) {
    curtain.write(CLOSE_ANGLE);

  } else {
    curtain.write(OPEN_ANGLE);
  }

  curtainClosed = closeIt;
}

 

void setup() {

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  curtain.attach(SERVO_PIN);

  // Start opened
  moveCurtain(false);
}

 

void loop() {

  long d = distanceCM();

  // Determine current "near" with hysteresis
  bool isNear;

  if (wasNear) {

    // remain "near" until it moves past FAR_CM

    isNear = (d < FAR_CM);

  } else {

    // become "near" only when inside NEAR_CM

    isNear = (d < NEAR_CM);
  }

  unsigned long now = millis();

  // Edge-detect: far -> near and cooldown passed
  if (!wasNear && isNear && (now - lastToggleMs >= COOLDOWN_MS)) {

    moveCurtain(!curtainClosed);    // toggle
    lastToggleMs = now;

  }

  wasNear = isNear;

  delay(30); // small loop delay
}

What You Need for This Project

To build this Automatic Goalkeeper, we used the following parts from the Plzpapa Basic Robotic Kit:

  • Arduino Uno Board
  • Servo Motor (SG90)
  • Ultrasonic Sersor
  • Wooden Goalkeeper Structure
  • Jumper Wires
  • (No soldering required!)

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top