Arduino Smart Switch

The smart light switch is a simple solution to turning on and off lights. The switch is distance and light sensed and it can be easily swapped to meet different needs. The switch utilizes a servo motor and a bracket on a custom switch plate designed in CAD. All files and code are below!
Supplies

An Arduino IDE, plate, breadboard, wires, servo motor, ultrasound distance sensor, photoresistor, wires
Print Plate
Step 1: 3D Print the plate - STL file attached below
Construct Arduino

Wire the Arduino and breadboard matching the diagram above. The breadboard will be taped upside down on the shelf part of the switch plate and the Arduino will sit on the bottom.
Enter and Adjust Code
Here is the Arduino code:
#include <Servo.h>
//Pins
const int servoPin = 9;
const int trigPin = 12;
const int echoPin = 11;
const int photoPin = A0;
const unsigned long motionTimeout = 1800000UL;
//Thresholds
const int lightThreshold = 500; //Light level below this is considered dark
const int distanceThreshold = 150; //Distance for motion detected
Servo lightSwitchServo;
//create condition for light being in the state on or off
bool lightIsOn = false;
unsigned long lastMotionTime = 0;
void setup() {
Serial.begin(9600);
lightSwitchServo.attach(servoPin);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(photoPin, INPUT);
lastMotionTime = millis(); //motion timer
lightSwitchServo.write(0); //assume light starts off (can be changed)
}
void loop() {
int lightLevel = analogRead(photoPin);
float distance = getDistance();
//check light conditions
bool isDark = lightLevel < lightThreshold;
bool motionDetected = distance > 0 && distance < distanceThreshold;
//print values to check code/adjust light values as needed
Serial.print("Light Level: ");
Serial.print(lightLevel);
Serial.print(" Distance: ");
Serial.print(distance);
Serial.print("Light Is On: ");
Serial.println(lightIsOn);
unsigned long timeSinceMotion = millis() - lastMotionTime;
// TURN ON condition: dark and motion detected while light is off
if (isDark && motionDetected && !lightIsOn) {
lightSwitchServo.write(40); // Adjust angle as needed
lightIsOn = true;
Serial.println(" Turning Light ON");
}
//light OFF conditions
else if ((lightLevel >= lightThreshold || timeSinceMotion > motionTimeout) && lightIsOn) {
lightSwitchServo.write(0); //Adjust angle as needed
lightIsOn = false;
Serial.println("Turning Light OFF");
}
delay(100)
}
//distance function
float getDistance() {
digitalWrite(trigPin, LOW);
delay(2);
digitalWrite(trigPin, HIGH);
delay(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000);
if (duration == 0) return -1; //No object detected
float distanceCm = (duration * 0.0343) / 2.0;
return distanceCm;
}
Attach to the switch and adjust values as needed (timing, degrees, distance, light levels, etc.)
Add New Components
Add and experiment with new components such as a piezo buzzer or temperature sensor! Set the timing for bedtime reading or routines! If adjustment on the motor is needed, attaching string around the motor and switch is an alternative method. Enjoy!
** note: ChatGPT was utilized to proofread code and align conditions- the code has been ran in TinkerCad and Arduino successfully and can be adjusted as needed!