Top view of partially taken apart final product, with everything turned off.
This project helps me easily dispense and track the number of toothpicks I use everyday. The power button turns on the device, allowing me to see how many toothpicks I've used today, past hour, and yesterday. While the device is powered on, I can press the open button to open the latch that dispenses toothpicks, which updates the toothpick count accordingly.
Shot with the cover off
Photo of the internals, including the screen, buttons, servo motor and battery pack
Another angle of the internal electronics including the real time clock (RTC), Arduino Micro, and my terrible soldering.
Shot of the inside of the box, specifically the toothpick reservoir.
In this video, I operate the device before having to put it into the box as the final product. First, pressing the power button, I illistrate that the device maintains the count after being turned off. When the open button is pressed, the servo is activated and the counter is updated accordingly. This new updated value remains even the the power button is unpressed and pressed again, maintaining the overall count of the device.
This picture shows my initial ideas and sketches for the project. Originally I had wanted the device to be more triangular to maintain it's structural integrity in my backpack, but that was scrapped due to complexity and space concerns. The centermost drawing is more reminiscent of the final product, with a servo at the top of the device to regulate the dispersal of toothpicks, a reservoir for the tooth picks, and the electronics down the side and bottom of the device.
Having sketched out an idea of how I wanted the device to be sized, I placed the components I knew I wanted (LCD screen, two buttons, 9V battery, Micro, servo) into the rectangle to see how they would fit. What this didn't include was the battery pack in place of the 9V (required to provide enough power to the servo, display, and RTC), and the RTC, both of which ended up taking more space than original anticipated or planned for.
Despite being one of my first steps in the process, creating the box was one of the longest for me, as it required me to get familiar with the box making website, Fusion, and the laser cutter in order to create what I didn't know would be the final product. I had originally designed the box to have cut outs for the screen, buttons, dispense hole (not seen here), and a cut out for the lid to be eventually glued shut. While it served it's purpose well, the final product would have benefitted from a larger form factor to contain all the necessary components I didn't realize would be necessary.
This video shows what I believed at the time to be most of the core components of the device working together as desired, really only missing the RTC and thus the saved count.
Once I realized the importance of having a RTC in order to not only more easily access the EEPROM data, but to also maintain an hourly and daily count, I had trouble wiring it to the already existing device. As illustrated in the video, the problem was that there was not enough power being given to all 3 major components from the 9V battery, forcing me to have to eventually upgrade to the larger but much more reliable 6V battery pack.
Picture of all the components mostly laid out on the table and me trying to figure out how fit them all in the tiny case as with wiring and soldering.
3. Discussion
(instructions are embedded below)
I'm honestly torn on this project. I like to think I spent my time well, and executed almost everything to the best of my ability given the information and skillset I had at every point in the project and would almost argue that more time wouldn't have changed very much. The only reason the project failed was because from the very beginning I underestimated how much space I would need and that problem snowballed into a bigger issue as more components that required more space that was not originally allocated for came into play. There was and still is a delicate balance between form and function where the device was still small enough to be handheld and easily portable in my backpack while not exceeding the size of a regular toothpick dispenser, but all the while still large enough to contain all the components, wiring and necessary soldering to get it to work properly. The only mistake I made was choosing the wrong size and not realizing it early enough in the process, before putting everything together and watching weeks of work literally turn into smoke right in front of my eyes.
I learned a lot from the project, especially in terms of how EEPROM can be used on Arduinos and how to access that memory similar to how one would access memory in classes I've taken like 15-213. But what I made up for in code, I severely lacked in soldering skill, as that was the second major part of why I believed the project failed. One of the critiques I had was a recommendation to use "a flat PCB rather than a flexible one to avoid potential shorts," which in retrospect, was probably the cause of my bad soldering . For what the flexible PCB made up for in space, it lost in terms of ease of use and risk of shorts.
Overall if I could change anything going back or if I decide to perfect it in the future, I would not only increase the size of the box but also make sure I knew where EVERYTHING would be, and how it would be mounted, rather than having a general idea, a roll of tape, and some prayers. This would allow me to use real protoboards and vastly improve the soldering and probably even create more space for more toothpicks if done correctly. I would also try and experiment with different materials for the device box, because it's something I never considered until receiving the comment that my "material choice might improve the durability... in the backpack." I think it's a valid point and using wood or even acrylic would probably be more structurally sound than the cardboard stock I used.
/*
Toothpick Dispenser Code
Saves daily/hourly toothpick count to RTC EEPROM while counting the number of
button presses/times the servo is used. Code written for Arduino Micro
pin mapping:
Arduino pin | role |
___________________________________________________________________
A1 input count button
6 output servo
Code released to the public domain by the author, 11/13/2025
Helios Gayibor, hgayibor@andrew.cmu.edu
RTC code from: https://lastminuteengineers.com/ds3231-rtc-arduino-tutorial/
*/
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <Servo.h>
#include "uRTCLib.h"
#include "uEEPROMLib.h"
int OLED_RESET = -1;
int BUTTON1PIN = 19;
int SERVOPIN = 6;
Servo servo;
uRTCLib rtc(0x68);
uEEPROMLib eeprom(0x57);
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
int countAddr = 0; //address to store number of tps today
int lastHourCountAddr = 4; //address to store number of tps used in last hour
int hourCountAddr = 8; //address to store number of tps in the current hour
int lastDayCountAddr = 12; //address to store number of tps yesterday
int prevHourAddr = 16; //address to store hour of lastHourCount
int prevDayAddr = 20; //address to store day of lastDayCount
/*Displays the rates and info onto the screen. If a new count is to be added,
addCount is set to true.*/
void display_rates(bool addCount = false) {
//Get the current values of the counts from eeprom
int count, lastHourCount, hourCount, lastDayCount, prevHour, prevDay;
eeprom.eeprom_read(countAddr, &count);
eeprom.eeprom_read(lastHourCountAddr, &lastHourCount);
eeprom.eeprom_read(hourCountAddr, &hourCount);
eeprom.eeprom_read(lastDayCountAddr, &lastDayCount);
eeprom.eeprom_read(prevHourAddr, &prevHour);
eeprom.eeprom_read(prevDayAddr, &prevDay);
//update saved times and counts accordingly
if (rtc.hour() - prevHour == 1 || rtc.hour() - prevHour == -23) {
lastHourCount = hourCount;
hourCount = 0;
prevHour = rtc.hour();
} else if (rtc.hour() != prevHour) {
lastHourCount = 0;
hourCount = 0;
prevHour = rtc.hour();
}
if (rtc.day() - prevDay == 1) {
lastDayCount = count;
count = 0;
prevDay = rtc.day();
} else if (rtc.day() != prevDay){
lastDayCount = 0;
count = 0;
prevDay = rtc.day();
}
bool changed = false;
if (addCount) {
count++;
hourCount++;
changed = true;
}
//updating the eeprom values
if (changed) {
eeprom.eeprom_write(countAddr, count);
eeprom.eeprom_write(lastHourCountAddr, lastHourCount);
eeprom.eeprom_write(hourCountAddr, hourCount);
eeprom.eeprom_write(lastDayCountAddr, lastDayCount);
eeprom.eeprom_write(prevHourAddr, prevHour);
eeprom.eeprom_write(prevDayAddr, prevDay);
}
//actually displaying the info we just calculated
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Toothpick Count: ");
display.println(count); //TODO: make the number constant distance away
display.print("Last Hour: ");
display.println(lastHourCount);
display.print("Yesterday: ");
display.println(lastDayCount);
display.display();
}
void setup() {
Serial.begin(9600);
URTCLIB_WIRE.begin();
/*If the clock needs to be reset, uncomment this code and change it accordingly*/
// rtc.set(0, 54, 23, 4, 29, 10, 25);
// rtc.set(second, minute, hour, dayOfWeek, dayOfMonth, month, year)
// set day of week (1=Sunday, 7=Saturday)
// eeprom.eeprom_write(countAddr, 0);
// eeprom.eeprom_write(lastHourCountAddr, 0);
// eeprom.eeprom_write(hourCountAddr, 0);
// eeprom.eeprom_write(lastDayCountAddr, 0);
// eeprom.eeprom_write(prevHourAddr, 0);
// eeprom.eeprom_write(prevDayAddr, 0);
pinMode(BUTTON1PIN, INPUT_PULLUP);
servo.attach(SERVOPIN);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
for(;;); // loop forever if screen fails
}
display_rates();
}
//just want a single button read for a press
bool prevButton1 = false;
void loop() {
rtc.refresh();
bool button1 = !digitalRead(BUTTON1PIN);
if (!prevButton1 && button1) {
display_rates(true);
}
prevButton1 = button1;
if (button1) {
servo.write(0);
} else {
servo.write(128);
}
}