Front view of the belonging device, light turned off as all objects are placed.
Brief explanation of the project
This project helps me to place 3 of my belongings that I take outside everyday in the same spot as well as tracking/notifying me whether the items are placed after coming back or if I have taken the items with me when I go outside. There are three holes on top of the tray where I place the objects the infrared proximity sensor will sense the object when the object is placed on the hole correctly. There are 2 different modes for different times.
8:00 am(Going Out) - Red light will start glowing and notify me that I have to take my belongings with me when I go outside. The light will turn off only when I take all of the objects with me.
6:00 pm(Back Home) - Red light will be glowing and notify me until I place all my belongings, and then the light will turn off.
Pictures
All of the arduino and soldered components including the infrared proximity sensor sensors, battery and real-time clock.
Top view of the project
#1 Iteration of the project : Gray filament model
When all object is placed after returning home the light is turned off
Side view of the project / Detail shot of the form
While the gray model creates ambient light through the gaps between the top and base cover.
#2 Iteration of the product : White filament model
The white model is translucent, light can be seen through the object.
When an object is placed before going out the light will keep glowing
Moving images
Mode A: In this video, I show what will happen from 8:00am to 6:00pm. I place an airpod case, covering the holes and the redlight starts to glow. When I have at least one object covering the hole, the red glowing light will keep being on. If I don't have any objects covering the holes, the lights will go off. This mode is used when I am going outside, ensuring and notifying me that I take all the belongings with me before I go out.
On a white 3D printed cylindrical object, I place an airpod covering one of the holes and red light starts to glow.
Mode B: In this video, I show what will happen from 6:00pm to 8:00am. I cover all the holes with an object(belonging) the red light will turn off with a sudden blue light indication. Unless I cover the whole holes, the red glowing light will keep being on. This mode is used when I return back tom my house from being outside, ensuring and notifying me that I place all the belongings on this product when I return back home.
On a white 3D printed cylindrical object, red light is glowing. On the top part, there is a student ID card and an airpod case covering the holes and I place a paper which is used to indicate as a belonging on the hole and a sudden blue light glows and the light turns off.
Process images and review
First time getting to work with the infrared proximity sensor sensor and the led strip.
CAD modeling the cover with solidworks and preparing for 3D printing.
Fully functioning prototype with a turn on/off switch which eventually replaced by real-time clock for the final product.
Soldering components on breadboards, trying to make everything slim in order to fit everything in the cover.
#1 version of the product: White filament - translucent material - more see through and glowing light effect
#2 version of the product: Gray filament - Opaque material - ambient light effect
Placing all compoents and testing them on how they would work and look like.
I began the project by building the electronic prototype. My main focus was getting the infrared proximity sensors to detect an object and making the LED strip respond correctly. After creating a working prototype of the logic and functionality, I moved on to CAD modeling. I designed two versions of the product: a white model with a slimmer base and a gray model with a thicker base. I realized that both versions worked the same electronically, but each produced very different lighting effects. The white model allowed more light to glow through the material, while the gray model created ambient lighting through the gap between the top and bottom pieces. Finally, I used a 9V battery, an Arduino Pro Micro, and soldered thin perfboards to build a slimmer final model.
I’ve always wondered how the products around us that we use every day are actually made. But through this project, I gained confidence and a sense of how the world and the products that we use would have been made and how they would work. Overall, I enjoyed the process of making it, as it was my first time 3D printing an object as well as making a device that I can actually use in my daily life. However, my expectations and the actual outcome were a bit different as I was only able to use 3D printing to get closest to my desired form and material. I used both white and gray filaments to observe the different outcomes I achieved. The light was able to be seen through the white filaments, which created an effect that I wanted, and the gray filament product was opaque, but it was also able to create ambient lighting. I was happy that I was able to explore different types of filaments and also various options to show the light. As a person who is pursuing product design, it was a wonderful experience developing and designing with choices like this. Also, through this project, I learned how to wire and solder all the components, including the Arduino, to be thin enough for the components to fit in a thin cover. Specifically, I learned how to use Arduino Pro Micro and also make it battery powered, which I have not done before. It would be useful to make the future products battery-powered if I wanted the object to be portable in the future.
Thinking of the next step from this project, I discovered a lot from the comments of my peers. Yutong commented that “an on/off button to manually adjust it would be helpful”, which I recognize is needed and regret removing the button as I used to have it in my prototype. I believe having both the real-time clock and the button could have been more useful. Also, Estee commented that she “loves how simple the design is and the light pulsing is a nice touch”. I was satisfied with how the lights were glowing and the blue light showing before turning off. I think I can implement some of the light animation techniques I have learned in my future projects.
Also, if I can, I would like to create another iteration of this project. I would want to create the whole product to be even thinner. Also, I would like the holes for the sensor to be covered with dark black acrylic, so that small objects or smaller parts don't go into the holes. Overall, I am very satisfied with the outcome of this project as I have accomplished the goals that I have set for myself, which were to detect 3 objects, have a light animation, and also make it portable.
Code
/* ===============================================================
PROJECT: Time-Based Belonging Sensor
Russell Sang
DATE: 2025/11/13
DESCRIPTION:
This project uses an Arduino Pro Micro, 3 infrared reflective
sensors, an addressable LED strip, and a DS3231 Real Time Clock
(RTC) to create time-based interactive lighting behavior.
• Between 8:00 AM and 6:00 PM → Mode B:
- Any sensor triggered → Red breathing glow
- No detection → LEDs off
• Between 6:00 PM and 8:00 AM → Mode A:
- Idle → Red breathing glow
- When ALL THREE sensors detect stably → Blue pulse animation
that fades out once, then returns to red glow.
This project will be used to notify the user their 3 main belongings if they have taken with them outside and also if they have placed them after coming back home.
Hysteresis is used to stabilize noisy sensor readings.
All LED animations are non-blocking using millis() timing.
PIN MAPPING (Arduino Pro Micro):
LED strip data → Pin 7
Sensor 1 → A0
Sensor 2 → A1
Sensor 3 → A2
RTC SDA → Pin 2 (I²C)
RTC SCL → Pin 3 (I²C)
GND & 5V → Power rails
LIBRARIES USED:
• RTClib (Adafruit) – for DS3231 RTC
• Wire.h – I²C communication
• PololuLedStrip – control WS281x-type LEDs
CREDITS:
For this code (logic structuring, animation smoothing,
hysteresis behavior, and time-based mode control) were developed
with the ChatGPT 5.1 (OpenAI).
I provided the hardware connections, design rules, and desired
interactive behaviors; ChatGPT assisted in producing optimized
code structure and integrating multiple animation states.
=============================================================== */
#include <Wire.h>
#include <RTClib.h>
#include <PololuLedStrip.h>
// -------- PIN CONFIG (for Arduino Pro Micro) --------
#define LED_PIN 7
#define SENSOR1_PIN A0
#define SENSOR2_PIN A1
#define SENSOR3_PIN A2
#define NUM_LEDS 31
// -------- SENSOR THRESHOLDS --------
int thOn1 = 700, thOff1 = 740;
int thOn2 = 700, thOff2 = 740;
int thOn3 = 700, thOff3 = 740;
const int DETECT_CONSEC_REQUIRED = 4;
// -------- COLORS & ANIM SPEED --------
const uint8_t RED_R = 255, RED_G = 0, RED_B = 0;
const uint8_t BLUE_R = 0, BLUE_G = 0, BLUE_B = 255;
const unsigned long redStepMs = 20;
const unsigned long blueStepMs = 15;
// -------- GLOBALS --------
RTC_DS3231 rtc;
PololuLedStrip<LED_PIN> ledStrip;
rgb_color colors[NUM_LEDS];
int redVal = 0; bool redUp = true;
int blueVal = 0; bool blueUp = true;
unsigned long lastStep = 0;
enum AnimState { MODE_RED_GLOW, MODE_BLUE_PULSE, MODE_OFF };
AnimState animState = MODE_RED_GLOW;
// false = Mode A, true = Mode B
bool modeB = false;
bool lastModeB = false;
bool det1 = false, det2 = false, det3 = false;
int allDetCount = 0;
// -------------------------------------------------------
void setup() {
Serial.begin(9600);
Wire.begin();
rtc.begin();
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println("RTC time set to compile time.");
}
clearStrip();
ledStrip.write(colors, NUM_LEDS);
Serial.println("RTC Time-Based Mode Setup Complete");
}
// -------------------------------------------------------
void loop() {
DateTime now = rtc.now();
int hour = now.hour();
int minute = now.minute();
// Time-based mode: 8AM–6PM = Mode B, else Mode A
modeB = (hour >= 8 && hour < 18);
if (modeB != lastModeB) {
lastModeB = modeB;
animState = MODE_RED_GLOW;
redVal = 0; redUp = true;
blueVal = 0; blueUp = true;
lastStep = millis();
Serial.print("\nTime ");
Serial.print(hour);
Serial.print(":");
if (minute < 10) Serial.print("0");
Serial.print(minute);
Serial.print(" → Switched to Mode ");
Serial.println(modeB ? "B" : "A");
}
// --- Read sensors ---
int s1 = analogRead(SENSOR1_PIN);
int s2 = analogRead(SENSOR2_PIN);
int s3 = analogRead(SENSOR3_PIN);
det1 = updateDetectWithHysteresis(s1, det1, thOn1, thOff1);
det2 = updateDetectWithHysteresis(s2, det2, thOn2, thOff2);
det3 = updateDetectWithHysteresis(s3, det3, thOn3, thOff3);
bool allDetectedInstant = det1 && det2 && det3;
bool anyDetectedInstant = det1 || det2 || det3;
// Stable detection counter
if (allDetectedInstant) {
if (allDetCount < DETECT_CONSEC_REQUIRED) allDetCount++;
} else {
allDetCount = 0;
}
bool allDetectedStable = (allDetCount >= DETECT_CONSEC_REQUIRED);
// --- Mode A Behavior ---
if (!modeB) {
switch (animState) {
case MODE_RED_GLOW:
if (allDetectedStable) {
animState = MODE_BLUE_PULSE;
blueVal = 0;
blueUp = true;
lastStep = millis();
} else {
runRedGlow();
}
break;
case MODE_BLUE_PULSE:
runBluePulse();
if (!blueUp && blueVal <= 0) {
animState = MODE_OFF;
clearStrip();
ledStrip.write(colors, NUM_LEDS);
}
break;
case MODE_OFF:
if (!allDetectedInstant) {
animState = MODE_RED_GLOW;
} else {
clearStrip();
ledStrip.write(colors, NUM_LEDS);
}
break;
}
} else {
// --- Mode B Behavior ---
if (anyDetectedInstant) {
runRedGlow();
} else {
clearStrip();
ledStrip.write(colors, NUM_LEDS);
redVal = 0; redUp = true;
}
}
}
// -------------------------------------------------------
void runRedGlow() {
unsigned long nowMs = millis();
if (nowMs - lastStep >= redStepMs) {
lastStep = nowMs;
redVal += redUp ? 5 : -5;
if (redVal >= 255) { redVal = 255; redUp = false; }
if (redVal <= 0) { redVal = 0; redUp = true; }
setColorAllScaled(RED_R, RED_G, RED_B, redVal);
}
}
void runBluePulse() {
unsigned long nowMs = millis();
if (nowMs - lastStep >= blueStepMs) {
lastStep = nowMs;
blueVal += blueUp ? 10 : -10;
if (blueVal >= 255) { blueVal = 255; blueUp = false; }
if (blueVal <= 0) { blueVal = 0; }
setColorAllScaled(BLUE_R, BLUE_G, BLUE_B, blueVal);
}
}
bool updateDetectWithHysteresis(int sample, bool prevDetect, int thOn, int thOff) {
if (!prevDetect)
return (sample < thOn);
else
return !(sample > thOff);
}
void setColorAllScaled(uint8_t r, uint8_t g, uint8_t b, uint8_t scale0to255) {
for (int i = 0; i < NUM_LEDS; i++) {
colors[i] = (rgb_color){
(uint8_t)((uint16_t)r * scale0to255 / 255),
(uint8_t)((uint16_t)g * scale0to255 / 255),
(uint8_t)((uint16_t)b * scale0to255 / 255)
};
}
ledStrip.write(colors, NUM_LEDS);
}
void clearStrip() {
for (int i = 0; i < NUM_LEDS; i++)
colors[i] = (rgb_color){0, 0, 0};
}