My project is a journaling companion lampshade that combines calming ambient light, motivational prompts, and interactive features to create a peaceful writing routine. The device generates a daily motivational quote and Dispenses Random Gifts to help me stay consistent.
It blends:
Motivational quote display – to spark positivity and reflection.
Gentle lighting – to set a relaxing, night-friendly atmosphere.
Interactive buttons – to choose between generating quotes, setting a timer, turning on the light, or dispensing a gift.
Lampshade design – laser-cut acrylic pieces forming a nighttime skyline.
I often struggle to stay consistent with my goals, even though I know how much it improves my mental health and helps me process my day. Writing in the dark is something I love, but I've noticed that I need a ritual that feels motivating, calming, and creative.
This project is deeply personal because it:
Creates the right environment for reflection with light and sound.
Provides daily affirmations so I never feel “stuck.”
Connects my passion for electronics, creativity, and wellbeing into one device.
Lamps with creative designs – I’ve always been inspired by how a lampshade can set a mood and tell a story through light.
Affirmation devices & mental health gadgets & Mental Health Apps – simple electronic devices that display a positive quote or thought of the day.
Arduino-based ambient projects – projects that use LEDs, sound, and movement to create calming environments.
To design my project, I used Autodesk Fusion 360 as the main CAD software. I chose Fusion 360 because it offers a comprehensive suite of tools for both 3D modeling and assembly. It also allows me to visualize how different components fit together, test tolerances, and ensure that the design can be practically fabricated. Another reason for choosing Fusion 360 is its cloud-based saving and easy collaboration features, which make the design workflow more efficient.
I used GrabCAD to download the electronics parts and upload them to my design.
Designed a rectangular panel as the base of the face.
Created cutouts for the LCD screen and four push buttons.
Added a T-slot mechanism on the sides to allow it to interlock with other faces of the box.
Then Joint the LCD and Push Buttons from GrabCAD
Made a copy of the first face and edited it
Removed the LCD and push button holders.
Added slots and cutouts for the Arduino Uno board and an ON/OFF switch.
Retained the T-slot feature for joining with other panels.
Draw a new face that is adjustable in the puzzle of the front face design.
Added a cutout for the door.
Designed a door panel along with a bracket to hold it securely in place.
Then I made joints to connect the Door, Door Holders, and Door Side.
Designed the side panel with no major edits other than the T-slot and a puzzle-type joint to connect with the base, with the Projection of the Door Panel.
This gave structural support and stability to the design.
Designed based on the projection of the puzzle connection between the sides.
Created holes for securing the gift box and the Arduino board.
I could assure alignment with the rest of the panels.
Designed with specific slots for 10 NeoPixels arranged in a circular pattern.
Added an acrylic holder with circular cutouts for each LED connection.
Integrated T-slot connections to join with the sides.
Laser Cutting
Software: LaserCAD
Machine: Malky ML64 CO₂ Laser Cutter
Material: Plywood
I used Plywood because it’s affordable, easy to cut, and ideal for creating detailed designs like logos or small prototypes.
Material: Acrylic
For the Top part of the Lightning to enable light to pass through it.
LaserCAD
It easily imports the.DXF file I exported from Fusion 360, preserving the 2D geometry exactly as designed.
3D Printing
Software: Ultimaker Cura
Machine: Creality Ender 3 3D Printer
Material: PLA
PLA was chosen because it’s beginner-friendly, environmentally friendly, and works well with the Ender 3 for producing smooth and accurate prints.
Cura
Used for slicing the.STL files of the side arms for 3D printing.
First, design the parts on fusion.
Use the DXF extension to make .dxf for all the parts.
Import Dxf files on LaserCAD
Convert PNG photos to DXF and import on the files
Make Black for the Cut and Blue for Speed Cut.
Upload the file on the machine
Make the Box
Start the machine
Recieve the fabricated parts
Get the Export of the parts from Fusion as .STL
Then Import them in Cura
Then make the adjustment of the files with no support as not needed
After than I Slice the project and get the Gcode
The Gcode was uploaded on the machine
After the machine finished I took the 3D printed parts
I didn't use Brim or Support as they were not needed. As, I just have flat surface to make it the base of all my parts.
My smart system consists of a combination of input components, action (output) components, and a controller, all integrated to perform interactive functions such as displaying messages, controlling a gift mechanism, and running NeoPixel lighting effects.
Push Buttons (Menu, Timer, Gift, Lightening, Home, etc.)
Function: Provide user control over different features of the system (e.g., start timer, open gift, activate lighting).
Integration: Connected as digital inputs to the Arduino. Each button press is detected in the main code and triggers a corresponding function.
LCD Display (20x4 I²C) (Minimum and Complete Feature)
Function: Provides visual feedback to the user, such as menu options, active modes, and system status.
Integration: Communicates with the Arduino over the I²C protocol, reducing wiring complexity.
NeoPixel RGB LEDs (WS2812, 10 LEDs) (Complete Feature)
Function: Produces colorful lighting effects (red, green, blue, rainbow) for visual enhancement. Runs continuously until the Home button is pressed.
Integration: Driven through a single Arduino digital pin using the Adafruit NeoPixel library.
Arduino Uno (or compatible microcontroller)
Function: Central control unit that reads inputs (button states), processes user commands, and drives outputs (LCD, NeoPixels).
Integration: Runs the main program logic, using modular header files for each subsystem (lighting, quotes/timer).
Arduino IDE → For programming and uploading the code.
Libraries Used:
LiquidCrystal_I2C (LCD communication)
Adafruit_NeoPixel (NeoPixel LED control)
Design/Documentation Tools: Flowcharts & diagrams for system logic.
TinkerCAD: for circuit simulation
System Integration
All components are connected to the Arduino:
Inputs (buttons) feed signals into digital pins.
Controller (Arduino) executes logic based on button presses.
Outputs (LCD, NeoPixels, buzzer) respond with corresponding actions.
The LCD guides the user, the buttons provide interaction, and the LEDs create lighting effects → together forming a complete interactive smart device.
LCD (I2C): VCC→5V, GND→GND, SDA→18, SCL→19
Buttons: Pins 2(Quote),3(Timer),4(Home), 7 (Light) → buttons → GND
NeoPixel 1: DIN→D6, VCC→5V, GND→GND
NeoPixel 2: DIN→D8, VCC→5V, GND→GND
Each Neopixel connected to the other ( Din → Dout, 5V →5V, GND→GND )
Power: Arduino 9V
The main power source of my project is a 9V DC Adapter. The converter reduces the voltage from 9V to a stable 5V DC, which is then used to power the Arduino Uno, NeoPixel LEDs, and LCD.
Why a 9V Adapter?
It provides enough voltage headroom for the step-down converter to regulate down to 5V reliably.
It is widely available, safe to use, and provides continuous power (better than a 9V battery, which drains quickly).
Selection Considerations:
Current Requirement:
Each NeoPixel LED can draw up to 60 mA at full brightness → for 12 LEDs, that is up to 720 mA.
The Arduino Uno and LCD typically draw ~100–150 mA.
Total estimated current = ~2A maximum.
The 9V adapter was chosen with a 2A+ rating to handle these loads.
Software/Tools Used for Power Planning:
Arduino IDE (to test components and measure power behavior during code execution).
Datasheets of NeoPixel (WS2812), and LCD to check current/voltage requirements.
The project code is modular and divided into separate header files with a main program (Main.ino). Each hardware component (LCD, Timer, and NeoPixel LEDs) is programmed as an independent module, and the main code integrates them through a menu system displayed on the LCD.
Library Used: LiquidCrystal_I2C.h
The 20x4 LCD is the central user interface. It displays the home page, navigation menus, motivational quotes, and timer countdowns.
Buttons connected to the Arduino allow the user to navigate through options:
Quote Button → Displays a random motivational quote.
Timer Button → Starts a 10-minute countdown timer.
Lightening Button → Activates NeoPixel light effects.
Home Button → Returns to the main menu and stops any running function.
The menu-driven LCD interface ensures the system is intuitive and interactive.
The Timer is implemented in Timer.h.
When the Timer Button is pressed, a 10-minute countdown starts.
The LCD displays the remaining minutes and seconds in real time.
When the timer finishes, the LCD shows “Time’s up!”
This feature makes the system useful for productivity and mindfulness breaks.
Library Used: Adafruit_NeoPixel.h
Two NeoPixel strips (10 LEDs each) are connected to pins 6 and 8.
Functions implemented:
showColor(r, g, b) → Displays a solid color on both strips.
rainbowStep() → Generates a smooth rainbow animation.
runLightening() → Cycles through multiple solid colors and rainbow animations until the Home button is pressed.
While running, the LCD shows “Lightening ON – Press HOME to exit.”
The main file (Main.ino) initializes all hardware components (lcd.init(), setupNeoPixel(), etc.).
In the loop(), button inputs are continuously checked, and the corresponding module is executed.
After finishing any function (quote, timer, or lightening), the program either returns to the main menu or keeps running (in the case of lightening effects) until the user exits with the Home button.
I didn't give it a prompt, and it automatically generated the full functional code for me. I was asking questions one by one when I faced an issue or did my research, and didn't know how to make it or how to deal with the issues I had.
First Problem (The memory of the Arduino was finished)
Prompt:
I gave it a screenshot of the problem, my first code, and asked it to help me solve this problem.
After it gave me the new code, I asked about ASCII and why it was used, and why he used it, and why he used const char instead of String Quotes[]
The LCD I’m using (with the LiquidCrystal_I2C library) only supports basic ASCII characters (codes 32–126).
If my Quotes.h has special characters like ’, “, é, or emojis, the LCD can’t display them properly and shows random symbols.
To fix this, I added the filterToASCII() function so only supported characters are sent to the screen.
String filterToASCII(const char *s) {
String out = "";
while (*s) {
uint8_t b = (uint8_t)*s++;
if (b >= 32 && b < 127) out += (char)b;
}
return out;
}
It loops through each character.
Keeps only characters in the printable ASCII range (32–126).
Builds a new string with only those safe characters.
If my quotes contain smart quotes, non-English letters, or symbols → I need the filter. (SO, I can use Arabic Quotes)
If all quotes are plain English with normal characters → I don’t really need it.
String quotes[] = {
"Keep moving!",
"Believe in yourself",
...
};
Each String object uses dynamic memory (heap).
On small boards like the Arduino Uno (2 KB SRAM), this can:
Fragment memory.
Causes random resets or crashes.
Example: 35 quotes × ~30 chars ≈ 1 KB+ RAM → already half of Uno’s memory!
2. Using const char[] in PROGMEM
const char quote_0[] PROGMEM = "Keep moving!";
Stores the text in Flash (program memory), not SRAM.
Flash is much bigger (Uno = 32 KB Flash vs 2 KB SRAM).
Since quotes are read-only, PROGMEM is perfect.
Keeps SRAM free for variables, LCD, button states, etc.
3. Why String is wasteful
String has extra overhead: pointers, buffer sizes, memory resizing.
const char[] = just raw characters → no overhead.
4. Trade-offs
String[] → super easy to use (quotes[random(n)]), wastes SRAM.
const char[] PROGMEM → very memory efficient, avoids crashes, trickier to use (need strcpy_P() to read from Flash).
I made a NeoPixel code that only blinks 4 colors (on/off).
Now I want to expand it into a more advanced project:
- An LCD to display status messages
- A HOME button to exit effects
- Solid colors and rainbow animations
- A function to go back to the main menu after exiting
Can you create the header file and modular code for this?
void rainbowStep(long firstPixelHue) {
for (int i = 0; i < strip1.numPixels(); i++) {
int pixelHue = firstPixelHue + (i * 65536L / strip1.numPixels());
strip1.setPixelColor(i, strip1.gamma32(strip1.ColorHSV(pixelHue)));
strip2.setPixelColor(i, strip2.gamma32(strip2.ColorHSV(pixelHue)));
}
strip1.show();
strip2.show();
Hue = the "color angle" on a color wheel (red → yellow → green → blue → purple → back to red).
In Adafruit’s ColorHSV(), hue is not 0–360°, but instead 0–65535.
0 and 65535 = pure red.
~21845 = green.
~43690 = blue.
So a full rainbow spans 0–65535.
This is the "starting color" for the rainbow.
If you increase it each frame (hue += 256; for example), the whole rainbow shifts/scrolls.
for (int i = 0; i < strip1.numPixels(); i++) {
int pixelHue = firstPixelHue + (i * 65536L / strip1.numPixels());
strip1.numPixels() = number of LEDs.
(i * 65536L / strip1.numPixels()) spaces the hues evenly across the strip.
Example: if you have 10 LEDs, LED 0 is red, LED 3 is green, LED 6 is blue, LED 9 is almost back to red.
Adding firstPixelHue shifts the entire rainbow pattern (animation effect).
strip1.setPixelColor(i, strip1.gamma32(strip1.ColorHSV(pixelHue)));
ColorHSV(pixelHue) → converts hue (plus fixed saturation & brightness = 100%) into an RGB color.
gamma32() → adjusts brightness to match human eye perception (gamma correction).
Without this, colors look “washed out” or uneven.
Both strips (strip1, strip2) get the same pattern.
strip1.show();
strip2.show();
Sends the updated RGB data to the LEDs.
Until you call .show(), the strip won’t actually change.
Each LED is assigned a hue spaced evenly across the rainbow wheel.
firstPixelHue shifts where the rainbow starts.
Increasing firstPixelHue over time makes the rainbow move/scroll along the strip.
Gamma correction makes colors look smoother.
Works for both strips simultaneously.
AI-Generated Photo
I uploaded the full code and asked it to generate a Flow-Chart.
Door Mechanism
Fixed the door holder to the door part.
Ensured smooth hinge movement for reliable opening/closing.
Base Assembly
Mounted the Arduino to the base using studs and nuts.
Attached the gift box firmly to the base.
Top Module
Connected NeoPixel strips to the acrylic holder and secured the acrylic face.
This allowed light diffusion and enhanced the visual effect.
Front Panel
Inserted the LCD (20x4 I2C) into its slot.
Placed the push buttons (QUOTE, TIMER, HOME) in their designated cutouts.
Final Assembly
Connected all faces together.
Used brackets to hold the top cover.
Fastened the base with T-slot brackets and studs/nuts.
Electronics & Code
Followed the full circuit connection guide.
Uploaded the Arduino code before wiring finalization to avoid conflicts.
Tested each module individually (LCD, buttons, NeoPixels) before full integration.
Verified that the LCD successfully displayed a random motivational quote upon system start or button press.
Ensured that the text was properly aligned and readable on the 20x4 display.
Before connecting the strips into the full assembly, both NeoPixel strips were tested independently.
Confirmed that:
Solid color changes (red, green, blue, etc.) displayed correctly.
Rainbow effect cycled smoothly across all 10 LEDs per strip.
No flickering occurred when powered with an external 5V supply.
Feature 1 – Lightening Mode
Tested by pressing the corresponding button.
NeoPixels correctly cycled through solid colors and rainbow animations.
LCD displayed “Lightening ON” and “Press HOME to exit”, confirming interactive feedback.
Feature 2 – 10-Minute Timer
Timer started correctly upon button press.
LCD displayed the countdown in minutes/seconds format.
At completion, the buzzer/indicator activated (if included), and the system returned to the home screen.
Uploaded the code prior to final wiring to avoid software conflicts.
Connected all modules (LCD, buttons, NeoPixels, giftbox mechanism, and acrylic parts).
Verified that all features worked seamlessly together without interference.
Observed stable performance under continuous operation with external 5V/2A power.
Results Summary
All individual modules functioned as expected.
Complete feature set (quotes, lightening, and timer) was successfully demonstrated.
Testing video (provided separately) shows full proof of system functionality.
During the design and fabrication stages of my project, I actively sought feedback from both my instructor and peers. Their input played an important role in improving the strength, accuracy, and overall quality of the design.
Puzzle Connection Strength
Initially, I fabricated the front face for holding the LCD and push buttons. However, the puzzle joints for connecting the faces were weak because the width was only 3 mm.
My instructor suggested increasing the width from 3 mm to 6 mm, since the project was relatively large and required stronger connections.
I applied this modification not only to the front face but also to all other faces before fabrication. This significantly improved the structural stability of the project.
LCD Fit Issue
Another issue was that the holes for the LCD did not align properly with the actual component after laser cutting.
My instructor advised me to carefully measure the deflection and tolerances.
One of my peers suggested searching for a ready-made LCD design model on GrabCAD that closely matched the real LCD.
I followed both suggestions: checked everything again in Fusion 360 and confirmed that the new design matched perfectly.
Prototype Testing
To avoid wasting material, my instructor recommended making a small prototype of the LCD holder on scrap acrylic before fabricating the entire front panel.
I applied this advice, tested the fit, and once it worked successfully, I fabricated the full face with confidence.
How I Helped My Peers: I shared my experience with prototype testing and suggested they also validate their critical parts on scrap material first, saving time and resources.
How My Peers Helped Me: They provided useful suggestions such as exploring existing CAD models (GrabCAD) and cross-checking real measurements against the Fusion design.
How I knew it was a problem:
I noticed the LCD only displayed the message header (“Your Quote:”) but not the actual quote. Then, when I tried uploading again with more quotes, the Arduino IDE showed a compilation error about SRAM being exceeded. This made it clear that the quotes were using too much dynamic memory (RAM).
How I solved it:
I researched the error and learned that the Arduino UNO has only 2 KB of SRAM. Since I was storing long text strings in normal String variables, they were all being loaded into RAM at startup. The solution was to move all quotes into Flash memory (PROGMEM), which has much more space. By rewriting my quotes file to store each line in PROGMEM and then reading them out with strcpy_P(), I was able to reduce memory usage and keep the code running smoothly.
How I now know how to solve it in the future:
From this experience, I learned that on small microcontrollers like the UNO, using too many String objects can quickly crash a program. The better approach is to store large amounts of text or constant data in PROGMEM and only load small chunks as needed. Now, whenever I see an out-of-memory error, I immediately think about moving big data into Flash, avoiding String, and working with char[] arrays instead.
Advice for others:
If someone else is doing this project, I would recommend:
Avoid using large String arrays directly in Arduino UNO code.
Use PROGMEM for storing quotes, menus, or other constant text.
Always check memory usage after adding new features.
Test with a small set of data first before adding a large set.
#pragma once
#include <Arduino.h>
// Store quotes in PROGMEM (Flash memory)
const char quote_0[] PROGMEM = "Keep moving!";
const char quote_1[] PROGMEM = "Believe in yourself";
const char quote_2[] PROGMEM = "Dream big.";
const char quote_3[] PROGMEM = "Stay positive!";
const char quote_4[] PROGMEM = "Never give up.";
const char quote_5[] PROGMEM = "Enjoy your day";
const char quote_6[] PROGMEM = "Be kind to yourself";
const char quote_7[] PROGMEM = "Smile at a stranger";
const char quote_8[] PROGMEM = "Focus on progress";
const char quote_9[] PROGMEM = "You are What You Think About";
const char quote_10[] PROGMEM = "U won't find the same person twice, not even in the same person";
const char quote_11[] PROGMEM = "Believe in Your Gut Feeling";
const char quote_12[] PROGMEM = "If it doesn't make me Happy, make me Money, make me Better: Sorry";
const char quote_13[] PROGMEM = "Chasing people is pointless. Focus on yourself, and the right ones will stay";
const char quote_14[] PROGMEM = "Overthinking solves nothing. Take action, adjust, and move forward";
const char quote_15[] PROGMEM = "Your habits shape your future more than your goals do";
const char quote_16[] PROGMEM = "Nothing changes if nothing changes";
const char quote_17[] PROGMEM = "Rest is productive. Burnout slows you down more than breaks";
const char quote_18[] PROGMEM = "Don't fight your being, you'll lose";
const char quote_19[] PROGMEM = "The ones you say they don't do the most are the ones who surprise you the most";
const char quote_20[] PROGMEM = "You can't get out of pain until you go through it";
const char quote_21[] PROGMEM = "If you fall, I will lift you up again. If I can't, I will lie down beside you";
const char quote_22[] PROGMEM = "What burns a person is not fire, but his negligence";
const char quote_23[] PROGMEM = "I'm crazily thinking about how much we died to live";
const char quote_24[] PROGMEM = "Confidence comes from competence; get good at something";
const char quote_25[] PROGMEM = "The better you become, the less you doubt yourself";
const char quote_26[] PROGMEM = "I was the friend I always wanted for myself";
const char quote_27[] PROGMEM = "Pursue yourself. Pursue becoming the healthiest, happiest, most healed, most present, most confident version of yourself";
const char quote_28[] PROGMEM = "Life owes you nothing";
const char quote_29[] PROGMEM = "Overthinking is fear in disguise";
const char quote_30[] PROGMEM = "Nobody cares about your excuses";
const char quote_31[] PROGMEM = "You can't fake self-belief.";
const char quote_32[] PROGMEM = "Most friendships are temporary";
const char quote_33[] PROGMEM = "Nobody is too busy, they just have different priorities";
const char quote_34[] PROGMEM = "While you think you have found all the answers, the questions change.";
// Array of pointers to quotes in PROGMEM
const char* const quotes[] PROGMEM = {
quote_0, quote_1, quote_2, quote_3, quote_4,
quote_5, quote_6, quote_7, quote_8, quote_9,
quote_10, quote_11, quote_12, quote_13, quote_14,
quote_15, quote_16, quote_17, quote_18, quote_19,
quote_20, quote_21, quote_22, quote_23, quote_24,
quote_25, quote_26, quote_27, quote_28, quote_29,
quote_30, quote_31, quote_32, quote_33, quote_34
};
const int numQuotes = sizeof(quotes) / sizeof(quotes[0]);
If I had more time to further develop this project, I would focus on the following enhancements:
Add an RTC (Real Time Clock) Module
Integrate a hardware RTC (such as DS3231) to display the actual time and date on the LCD.
This would make the device more functional, as it could serve as both a motivational quote display and a real-time clock.
Expand Timer Options
Currently, the timer is fixed. In the future, I would add multiple timer settings (e.g., 10 minutes, 30 minutes, 1 hour).
The user could select the timing directly from the LCD menu, making the system more interactive and customizable.
Improve Physical Design with 3D Printing or CNC
The hardware components could be housed in a custom 3D printed or CNC-machined enclosure, giving the project a professional and polished look.
This would also improve durability and make it easier to handle as a finished product.
Add Wireless Connectivity (Bluetooth / Wi-Fi)
By integrating a module like HC-05 (Bluetooth) or ESP8266/ESP32 (Wi-Fi), the project could be controlled via a mobile app.
This would allow remote control of the servo, lighting effects, and timer, making the project smarter and more user-friendly.