Project 2:
Smart Sticky Notes
SiyuOu
SiyuOu
Note: these black boxes are instructions to you to make the documentation, and should not be included in your final submission!
1b. A photo that is a good overall view of the project. This image should be one of the "well-shot" images described below, or a cropped subset of one of them.
Smart Sticker-Device A
Smart Sticker-Device B
1c. A brief explanation of the project. This should be short and sweet.
This project helps me keep track of tasks more effectively, especially for people who have short attention spans or struggle with memory. Each “intelligent sticky note” represents one item on the to-do list, so the first note is for the current task, the next one over is for the following task, and so on. Five minutes before a task is set to begin, the sticky note generates noise and flashes a red light to draw the user’s attention. Once the user presses a button to indicate they have started working on the task, the note automatically shifts focus to the next item in the sequence. This way, users can easily stay on top of their responsibilities without forgetting what comes next.
1d. At least four good still images of the final project. If it's possible for you to take higher-quality image, like using a DSLR (here's the class DSLR photography guide) that's fine; but camera phone pictures are ok, too if they're carefully shot and good quality. Images:
Overall photo for proportion and scale (at least 1)
Detail photo of any part that you'd like to highlight (up to 3)
Images showing the thing being used (up to 3)
1e. Moving image (one or more), a .gif, .mp4, or .mov file. Your movie can be as short as a second or two if that's all that needed to show the interactivity of your device, but should go longer as is necessary. It can feature voice narration if you like, but does not need to.
Upload instructions: Do not merely link to an outside hosting service like YouTube and do not embed a YouTube or other video service frame into your page. Rather, the videos are inserted by uploading a video file to this Google Drive folder and then under the Insert tab on the right, selecting "Drive," then clicking on the Shared drive called "60-223 s25." By keeping video files in that Shared drive, we ensure that this documentation page will remain intact for the long term.
If the movie is not audibly narrated, a caption should describe the action of the movie so that a blind person would still be able to understand what is happening.
(Note that videos don't have captions or alt-text options on Google Sites, so you just need to write your own text boxes below them.)
In this video, it demonstrates how the lights and the buzzer respond when switching tasks by pressing a button, and the LCD screen also switches tasks accordingly.
This video demonstrates the process of signal transmission synchronization.
2. Process images and review
Your process section should have at least 4 photos each of which is captioned, and ~100–300 words describing any aspect(s) of your process you'd like your readers to know about. Did something surprise you with how well or how terribly it went? Did something take much longer than expected? Did you get lucky and something worked out unexpectedly? Tell us about it.
Add captions and alt text to your images so your reader understands their relevance and meaning.
Test different components and begin wiring and soldering.
Adjust the angle of the LCD screen and test it.
Complete the initial circuit connections and check how the button controls the circuit.
Continue testing the remote module, observe communication between the two devices, and repeatedly debug.
Measure the component lengths and prepare dimensions for laser cutting.
Complete the assembly of all components
Don't forget that this section also needs a brief bit of text, ~100–300 words describing any aspect(s) of your process you'd like your readers to know about. You can interleave this with the images or put it all at the top or bottom or however you'd like.
3. Discussion
(instructions are embedded below)
I really appreciate the suggestions regarding the noise output.
While implementing actual spoken phrases might be complicated, I can certainly explore playing pre-recorded audio clips or incorporating more pleasant music.
I also agree with the idea of making the device one-way while turning the other unit into a wearable—this is an exciting concept that would let me keep the device on me at all times, so that updates and notifications are seamless.
As for the signal and communication issues, I found that debugging radio transmission was indeed very tricky.
I spent a great deal of time attempting to address packet loss, but unfortunately, many of my efforts didn’t succeed as well as I had hoped.
Although the final result wasn’t perfect, I learned a lot throughout the process.
Hardware development often comes with unexpected hurdles, yet I enjoyed tackling them and discovering different approaches.
From a technical standpoint, coding was my biggest challenge.
Even for seemingly simple circuits, I found myself spending considerable effort writing and debugging code.
Often, I underestimated the importance of certain steps and only realized too late how critical they were.
If I could go back, I would try a unidirectional communication approach sooner, rather than getting stuck on bidirectional attempts for too long.
also recognize that my time management could have been better; when repeated efforts failed, I should have shifted focus to completing the laser-cut enclosure or exploring alternative methods instead of doubling down on a single solution.
Next time, I’d like to experiment with incorporating 3D-printed elements into my design so I can push my prototyping skills even further.
I might try to improve this project in the future by making the communication more efficient and incorporating some of the feedback to better serve specific user groups.
4. Technical information
4a. Include **schematic and block diagrams**, drawn in https://draw.ioref.org, and exported from that software as .png images.
The block diagram should legibly show all inputs, computational steps, and outputs of your project. The schematic should be done so that a competent person, reading your drawing and with the appropriate parts, could recreate the electrical system of the project. For both schematics and block diagrams, follow all of the standards described on the course schematics guidance page.
4b. Code submission, embedded into the project page
Optionally also including a Github or other version control service public-facing link. Your code should be reasonably commented throughout so that people other than you (the author) can better understand it. You don't need to explain every single line—that would be overkill—but leave useful notes in a reasonable measure.
Write a comment block at the top of the code including:
the project title,
(optionally) your name,
a description (short or long) of what the code does,
a description of pin mapping that would be useful to somebody else trying to recreate your work,
appropriate credit to any other person's/project's code that you incorporated into your project, and
(optionally) a license notice (i.e. copyright, CC BY-NC-SA 4.0, the MIT License, release it to the public domain, or just follow your heart. If you have written code that you wish to keep strictly proprietary for any reason, please speak with the instructor about an exception to this documentation requirement.
Add your code by using a text box with the "code" formatting option
Make sure that your final code as it appears on the public-facing post is correct and will compile!
//Smart Sticky Notes
//Siyu Ou
//This code manages a task reminder system using an LCD, NeoPixel LED, buzzer, RTC, and a transceiver module for wireless communication. It tracks tasks and checks if a task is due within 5 minutes. If so, the LED turns red, and the buzzer sounds. Pressing the button once starts the task, turning the LED yellow and stopping the buzzer. Pressing it again marks the task as complete, switching the LED to green and moving to the next task. If a task remains unfinished for 5 minutes, the reminder reactivates. The transceiver sends and receives task updates wirelessly, allowing remote task management. The system continuously updates the display, checks time, and synchronizes tasks.
#include <LiquidCrystal_I2C.h>
#include <Adafruit_NeoPixel.h>
#include <RTClib.h>
#define BUTTON_PIN 3
#define LED_PIN 6
#define NUM_LEDS 1
#define BUZZER_PIN 4
LiquidCrystal_I2C lcd(0x27, 16, 2);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
RTC_DS3231 rtc;
// Global variables
struct Task {
const char* name;
const char* time;
};
Task tasks[] = {
{"do the laundry", "13:08"},
{"finish the assignment1", "13:10"},
{"boil some water", "13:13"},
{"draw the diagram", "13:16"},
{"drink water", "13:20"}
};
const int numTasks = sizeof(tasks) / sizeof(tasks[0]);
int currentTaskIndex = 0;
bool taskStarted = false;
unsigned long taskStartTime;
unsigned long taskReminderTime = 5UL * 60UL * 1000UL; // 5 minutes
bool taskCompleted = false;
bool isRed = false; // showing if it is red
bool buzzerActive = false; // buzzer control
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
strip.begin();
strip.show();
lcd.init();
lcd.backlight();
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
rtc.adjust(DateTime(2025, 2, 24, 13, 6, 0)); //set time
// make sure the buzzer is off
noTone(BUZZER_PIN);
displayCurrentTask();
checkImmediateReminder(); // check the initial one
}
void loop() {
if (digitalRead(BUTTON_PIN) == LOW) {
handleButtonPress();
delay(500); // debounce
}
checkReminder();
displayCurrentTime();
controlBuzzer();
}
void displayCurrentTask() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(tasks[currentTaskIndex].name);
lcd.setCursor(0, 1);
lcd.print("Due: ");
lcd.print(tasks[currentTaskIndex].time);
}
void displayCurrentTime() {
DateTime now = rtc.now();
lcd.setCursor(0, 2);
lcd.print("Time: ");
lcd.print(now.hour());
lcd.print(":");
if (now.minute() < 10) {
lcd.print("0");
}
lcd.print(now.minute());
}
void handleButtonPress() {
if (!taskStarted) {
taskStarted = true;
taskCompleted = false;
taskStartTime = millis();
setLEDColor(255, 255, 0); // Yellow for ongoing task
isRed = false; // ban the red light
buzzerActive = false; // stop buzzer
noTone(BUZZER_PIN);
Serial.println("Task started");
} else if (!taskCompleted) {
taskCompleted = true;
taskStarted = false;
setLEDColor(0, 255, 0); // Green for completed task
Serial.println("Task completed");
advanceToNextTask();
}
}
void advanceToNextTask() {
currentTaskIndex++;
if (currentTaskIndex >= numTasks) {
currentTaskIndex = 0;
}
taskStarted = false;
taskCompleted = false;
checkImmediateReminder(); //check the task
displayCurrentTask();
Serial.println("Advanced to next task");
}
void checkReminder() {
DateTime now = rtc.now();
String currentTime = String(now.hour()) + ":" + String(now.minute());
if (taskStarted && !taskCompleted) {
unsigned long elapsedTime = millis() - taskStartTime;
if (elapsedTime >= taskReminderTime) {
setLEDColor(255, 0, 0); // Red for reminder
tone(BUZZER_PIN, 1000); // Play tone
delay(1000);
noTone(BUZZER_PIN);
Serial.println("Reminder: Task is ongoing for 5 minutes.");
}
}
if (!taskStarted && isTimeWithinFiveMinutes(currentTime, tasks[currentTaskIndex].time)) {
setLEDColor(255, 0, 0); // Red for task due within 5 minutes
isRed = true;
buzzerActive = true; // active buzzer
Serial.println("Immediate reminder: Task is within 5 minutes.");
} else if (!taskStarted) {
setLEDColor(0, 255, 0); // green
}
}
bool isTimeWithinFiveMinutes(String currentTime, String taskTime) {
int currentHour = currentTime.substring(0, currentTime.indexOf(':')).toInt();
int currentMinute = currentTime.substring(currentTime.indexOf(':') + 1).toInt();
int taskHour = taskTime.substring(0, taskTime.indexOf(':')).toInt();
int taskMinute = taskTime.substring(taskTime.indexOf(':') + 1).toInt();
int currentTotalMinutes = currentHour * 60 + currentMinute;
int taskTotalMinutes = taskHour * 60 + taskMinute;
return (taskTotalMinutes - currentTotalMinutes) <= 5 && (taskTotalMinutes - currentTotalMinutes) >= 0;
}
void checkImmediateReminder() {
DateTime now = rtc.now();
String currentTime = String(now.hour()) + ":" + String(now.minute());
if (isTimeWithinFiveMinutes(currentTime, tasks[currentTaskIndex].time)) {
setLEDColor(255, 0, 0); // Red for immediate reminder
isRed = true;
buzzerActive = true; // active buzzer
Serial.println("Immediate reminder: Task is already within 5 minutes.");
} else if (!taskStarted) {
setLEDColor(0, 255, 0); // if its not within 5 mins, turns green
}
}
void controlBuzzer() {
if (buzzerActive && !taskStarted) {
tone(BUZZER_PIN, 1500); //start noise
Serial.println("Buzzer Active");
} else {
noTone(BUZZER_PIN); // stop buzzer
}
}
void setLEDColor(int r, int g, int b) {
strip.clear();
strip.setPixelColor(0, strip.Color(r, g, b));
strip.show();
}