Skip to content

Final Project

Summary

My asset files are here.

Pill Dispenser Introduction

I would like to make a pill dispenser that would help my nephew take his medication for the day. Then send him a reminder before letting my sister in law know if my nephew has taken his medication for the day.

Breaking it down into sections: - pill dispenser body - pill cartridge - sensor or camera in dispensor area - app to notify - electronics to make it work

I worked with my daughter, Sage Kanofsky, to make sketchs of a pill dispenser. She is in Industial Design school at Georgia Institute of Technology. She is currently studying abroad the Polytechnic University of Valencia.

Sage Sketch Sage Sketch 2

Past Pill Dispensers at Fab

[Griffin van Horne - Fab Academy 2021] (https://fabacademy.org/2021/labs/dassault/students/griffin-vanhorne/projects/final-project/) made a small handheld version with bluetooth.

Corey M. Rice : Fab Academy 2017 made one that distributes the right amount of a whole bottle of pills.

Arsheena.E.P Feb 2016

Lily Yeazell at MIT made the cutest pill box!!

Loes Fab 2021 made a box with alarms.

Miriam Choi showed this instructables project in her presentation. It is very similar in many ways to what I was thinking.

3D models

Then later I worked in Fusion 360 to make a 3D model Relative

We've been discussing this dispenser and a few other items in what we call the "remember me" line. This would be helpful not only to Mika, but also to me and my family as I age. My father had alzhiemers and as he aged, the more things that he had to help with memory, the more independent he could remain. I would like to create things that make the burden on family less, and increase the feeling of independence for all who struggle with memory for one reason or another.

I have seen that other pill dispensers have been done as fab projects. I hope that mine will be different in a couple of ways:

  • Cartidges that can be preloaded

  • Messages sent first to the pill taker, and second to the car giver

Timeline

Timeline

Then I also met with DR. Taylor who helped me related each part of my project even better to the weeks we will have in Fab. Timeline Dr. Taylor

3D Printing

During the modeling week, I worked on my body parts and cannister. The body I printed was too small for the motors that we are using at the lab. I could ordeer a smaller motor, but I want to stick with what we know for now and get everything working, so I will change the model a bit to fit the NEMA 17.

PICTURES of trying to fit the NEMA into the body

I made many notches and other additions to the CAD model to make the mechanics of the dispenser easier. Example: the stop for the acrylic piece at the top so that it doesn't spin past the edges when its closed.

lid notch

notch from teh body to the bottom body. body to body notch

Notch for the catridge to seat on the top body cartridge to body notch

During the modeling week, I worked on my body parts and cannister. The body I printed was too small for the motors that I had. I asked for a NEMA 8 which is smaller and still has enough torque for my application.

My first print of the cartride outer body, i had a few errors. I had combined the outer rim and the bottom to one stl to print, but didn't notice that i had made the bottom a slight be smaller in case i wanted it to spin in the original desdign. I also needed to cut the center in a cirlce so the key can spin freely inside the cartdidge and only turns the pill divider to push the pills.

cartidge taped together with keyhole instead of circular cutout

When printing the divider, the edges were coming up on my prusa MK3s. classmate Angela Horstman suggested that I add more of a brim to help it adhere better.

white divider edges coming up I

I printed a new pill cartidge all as one piece with a cut out in the middle for the "key" to spin.

The tree supports on the latest body print are so cool. I had to take a pic. tree supports

Computer Controlled Cutting

I used the laser cutter to make the top pf the cartridge lid that will swing open.

lid

I cut my lid on the laser at the lab. Our laser with the picture line up was being repaired, so I used the older laser that you manually align. I brought my lid file in corel draw on the laser computer from an SVG off the fusion file. I used the epilog settings for Acrylic.

Epilog settings acrylic

When it ran on the laser, Collin Kanofsky pointed out that the laser was running twice in certain areas but not others. So I needed to modify the corel file to remove the overlapping lines.

pictre of overlapping path

It wasn't cutting through so we needed to run it multiple times. When trying to adjust our cut path, I moved the part in the file and then it cut through the wrong part.

pictre of cut over wrong path

I separated the two and then deleted the extra and then ran it again over 3 inches to a clean spot. I had to run the cut multiple times to cut through. Possible dirty lense?

pictre of cut new path

Electronics Design

I started working on the stepper motor and the electronics design with a tutorial. I used first the RP 2040 and then did it again with the ESP32C6. In the end, I went with the XIAO ESP32C6 to move forward with my project.

I used a breadboard to start laying it out to see if it would work.

breadboard prototyping

During our electronics design week, I designed a board that I could use in the final project. I may need to make it smaller or change the shape if I want it to fit into my project. or it can be on the side since it fits the theme.

Final Layout

Computer Controlled Machining

I'd like to make my base for my pill dispenser from wood for aesthetics.

I did some preliminary work in easel, but ran out of time during the CCM week, hopefully I will get back to it.

base plate screen shot

easel_cutSettings

Electronics Production

During our electronics design week, we learned to mill boards. My final board had a smaller shape than the original cool brain to fit into the machine, but a similar component layout.

I'm using the board that I milled in week10 but didn't finish that week.

Soldering

Classmate Dorian Fritze sent me a link to these medical grabbers that lock. They were a COMPLETE game changer for soldering.

I laid out my components and got to work.

Soldering

Drilling

I manually attached the power connector. I used a trick from Collin Kanofsky by putting the phone as a flashlight to locate my traces and mark out where I wanted to drill.

flashlight drill location marking

Then I put the board in a vice and drilled with the smallest bit I had, which was unfortunately a 1/16th - still pretty big. but worked.

drillSetup

Testing Lots of Testing

I used the multimeter in continuity mode to test test and test some more.. every connection, and every gpio to each other. I found that I had some solder bridging and had to go back in and clean it up so there would not be connections where I didn't want them.

TestingSoldering-resized

TestingSoldering2-resized

NEMA 8 Stepper Motor

Following the same tutorial that Mr. Dubick sent, I tried the twist test on the four wires that connect the stepper motor to figure out which two wires of my NEMA8 are a pair.

my nema 8

When the twist was clicky, those were a pair compaired to smooth when you turn the motor shaft. This wasn't convincing for me so I to find the phases using the multimeter. Continuity testing will determine theo ne phase of the motor that goes on 1A and 1B pins, and the other phase on 2A and 2B pins.

labeled motor wires

A4988 Motor Driver Current Limiting

I need to adjust the current limit of the driver to be lower than the current rating of the motor, so that the motor will NOT overheat.

I hooked everything up. It took me a really long time because I was really worried about the 12V current and making sure that I didn't mess anything up (i.e. burn up the chip especially after how long it took me to mill the board and solder everything on).

I found the tiny sense resistors on the 4988 and they were 100mOhm (I would use .1 in my calculations). They connect to the motor coils.

I then measured the Vref reading by measuring over the potentiomer to the ground with a multimeter set to Voltage reading. The below picture from the tutorial was really helpful.

Setting the-A4988-current-limit-by-measuring-the-reference-voltage

I turned the potentiomer to be less than my calculated Vref for a 0.6 max Amp motor. This meant that it should read ~0.39 for my project.

vRefCalculations1

Photoresistor

To incorporate the photo resistor, I had to put heat shrink around one leg so they didnt touch in the tunnel. Then on the ends, I used an extension to connect to the board. One one end of the extension, I used the shrink wrap tube with solder into it to extend it.

shrink wrapping one end of photorsistor

I decided to try traditional soldering for the other end becuase I worried about the heat gun melting my 3D printed part.

Two Buck Chuck

I have two power sources coming from device. One from the chip and another powering the motor. I did some research and it sonds like I need a to use a small DC-DC buck converter to step it down to 5V for the XIAO. So I will split the currnt coming using another little chip that I will mill and then have a buck on it and two outputs.. a 12V (power to the motor) and a 5V (power to the chip).

Embeded Programming

I started with the codes I had made in the weeks coming up to combine together to make the code. I have the following code pieces:

  • code that turns on and off light a light from a browser on my phone
  • code that reads the light value from my photo resistor and then takes an action
  • code that spins a stepper motor 1/8 a turn

I used a series of prompts and then took pieces from each to keep modifying my initial code working towards a final code.

Motor Programming

I have started working on programming a motor to move in steps. I need 8 steps per revolution to match my design. I found some documentation to help me with the arduino stepper library. For the example motor I have from my ELEGOO kit.. its 2048/8. I have another motor that i want to try that I got from the lab. More research is needed.

I started learning using the stepper.h library but the A4982 doesn't work that way. It only wants a STEP pulse and a DIR signal. So my code uses delayMicroseconds(1000) to set up step pulse timing. I found that 20,000 had it spinning too fast and at 8,000 it was missing steps. I ended with delays 15,000 and that worked well. It's a bit jerky. The fix for that is microstepping, but that will be in V2 becuase I grounded my microsteppers on the PCB under my chip. The stepping will work accurately enough for what I need in V1.

PROMPT: my motor is warm - not hot hot , but warm. is that ok?

CLAUDE: Yes, warm is totally normal for a stepper motor — actually expected. Steppers are always energized even when standing still, so they generate heat continuously. Your NEMA 8 is a small motor so it'll warm up faster than a bigger one.

The rule of thumb: if you can hold your hand on it comfortably, you're fine. If it's too hot to touch, that's when to worry.

A few things that affect how warm it runs:

  • Current limit (Vref) — if your Vref is set higher than needed, the motor runs hotter. Worth checking that your Vref is dialed in for 0.6A
  • Holding torque — when the motor is just sitting there energized between moves it still draws current. You can add a disable-when-idle feature later if heat becomes a concern:
// after a move, disable the driver
digitalWrite(ENABLE_PIN, HIGH);  // HIGH = disabled on most drivers

// re-enable before next move
digitalWrite(ENABLE_PIN, LOW);

My Vref is way below my calculation. So, I incorporated that code to disable the motor, and moved on.


Another issue with the code was that my initial print line asking how many slots I wanted to turn was not coming up..

PROMPT: the initial print line is not coming up from void set up

CLAUDE: Try adding a longer delay

I did that and it worked


I wanted to add some timing in so that the user would have the motor turn at the same time every day to dispense the pills.

PROMPT: I want the stepper motor to rotate one step based on the time of day that was input by the user

CLAUDE: 2:36 PM Here's the plan before I write the code — just to make sure we build it right:

User types a time (like 08:00) into Serial monitor Motor advances 1 slot at that time each day ESP32 tracks time internally after the user sets it A few quick questions:

Q: How should the user enter the time? A: Hour and minute (e.g. 08:30)

Q: Does the ESP32 need to know the current time, or just count down from when it's powered on? A: Know real current time (needs RTC or NTP)

2:37 PM Since you need real current time, the easiest approach for the ESP32-C6 is NTP (Network Time Protocol) — it grabs the time from the internet over WiFi. No extra hardware needed since the ESP32-C6 has WiFi built in.

I need two more things before I write the code:

Q: What timezone are you in?

A: Eastern (UTC-5/-4)

Q: Should the dispensed time be changeable without re-uploading code?

A: Yes - user sets it via Serial monitor each boot

How it works at boot:

  1. Connects to WiFi
  2. Syncs current time from NTP
  3. Asks you to type the dispense time (e.g. 08:30)
  4. Checks every 30 seconds and fires when the time matches
  5. Won't dispense twice in the same day

I realized I didnt want the code checking all the time becuase its a set it once in a while but really its there... and I dont want to loose it at a reboot.

PROMPT: Eventually I will want this information to come from an app and stay in the memory if the power goes out and comes back on. Do I need to change anything in the code. The time will not be changed often.

Good thinking to plan ahead. Yes, you'll need two additions eventually:

  1. NVS (Non-Volatile Storage) — saves the dispense time to the ESP32's flash memory so it survives a power outage. The Preferences library handles this and is built into Arduino for ESP32.
  2. WiFi communication — instead of Serial input, a simple web server or MQTT broker lets your app send the time to the ESP32.

The good news is the core motor code won't change at all. The only thing that changes is how the dispense time gets set and where it's stored.

Here's the upgrade priority order:

steps Description
Current code: Serial input → RAM (lost on power off)
Next step: Serial input → NVS flash (survives power off)
Final step: App → WiFi → NVS flash (survives power off)

I'd suggest we add the Preferences NVS storage now since it's a small change and solves the power outage problem immediately. Then when you're ready to build the app we just swap the Serial input for a WiFi endpoint.

Want me to add the Preferences storage to the current code? It would:

Save the dispense time to flash the first time you enter it

On reboot, load the saved time automatically and skip the Serial prompt

Only ask for a new time via Serial if none has been saved yet


PROMPT: i need a way to change the time later if i want to..

CLAUDE: Easy fix — we can check Serial on boot and give a short window to override the saved time:

Boot behavior:

  1. Load saved time from flash
  2. Print "Saved time is 08:30 — press any key in 5 seconds to change it"
  3. If no key pressed → run with saved time
  4. If key pressed → prompt for new time, save it, run

That way normally it just boots and goes, but you have an escape hatch to change it anytime by just opening the Serial monitor right after a reset.

Boot behavior:

  • First boot ever → asks for time, saves it
  • Every boot after → shows saved time, waits 5 seconds
  • Open Serial monitor quickly after reset and press any key to change it
  • No key press → runs automatically with saved time

When you're ready to add the app, we just add a WiFi endpoint that calls saveTime() and updates dispenseHour/dispenseMinute — everything else stays exactly the same.


At first, I wasn't able to get to the reset, but by increasing the delay after the Serial.begin, I was able to get to the part where I could change the time. I tried a time that was 30 seconds later and it worked .. the stepper motor moved 1/8 rotation.

Next I went to test my photosensor

photoresistor code

I brought in my code from my photo resistor from week 9 inputs and started to work with it changing the pin numbers to match what was on my board. I noticed that the numbers wer much higher and that they were going up when I put my hand over the sensor instead of down.

I loaded my code into Claude and started working.

PROMPT: strange light calues... really high when its dark like 3000,,, whats goingo n

The problem is ADC_11db attenuation — that's actually the issue with your photoresistor readings.

What's happening

analogSetAttenuation(ADC_11db) sets the ADC input range to 0–3.9V, which sounds good, but on the ESP32-C6 specifically, 11db attenuation is known to be noisy and inaccurate, especially at the low end of the range. You get garbage high readings even with little/no light.

Fix options

Option 1 — Drop the attenuation (easiest)

// Remove this line entirely, or change to:
analogSetAttenuation(ADC_0db);  // 0–1.1V range

The tradeoff is a smaller input voltage range, but photoresistors in a voltage divider usually don't need the full 3.9V range anyway.

Option 2 — Use 6db instead

analogSetAttenuation(ADC_6db);  // 0–2.2V range — better noise behavior

Option 3 — Average multiple readings (helps regardless)

int readLight() {
  long sum = 0;
  for (int i = 0; i < 8; i++) {
    sum += analogRead(lightPin);
    delay(5);
  }
  return sum / 8;
}

Then call readLight() instead of analogRead(lightPin).

Also check your wiring

Make sure your photoresistor is in a proper voltage divider with a pulldown resistor (typically 10kΩ) to GND — a floating pin will also give wild readings.

3.3V → [photoresistor] → A1 → [10kΩ] → GND

Try removing the analogSetAttenuation line first — that's almost certainly the culprit.

I removed the analogSetAttenuation line, but the numbers were still reversed.. I had my wiring backwards

So I flipped the logic and changed the threshold to match my currrent set up. I can't change the wiring this time.. V2... I will need to get new values for lighting with different pills.

Coding to Application.. going to layer 7

It's networking week.. time to figure this out again... and better..

Working with Claude a bunch.. Here was our conversation.

System Integration

Testing

Light Sensor Tuning

Using the IP address an the/lightstatus in my browser, I was able to take multiple readings in different light conditions with different pills.

pills used

readings in browser

Light/Pill Status ADC Value Threshold setting Pill taken?
Dim Light Raw ADC: 2400 Threshold: 2000 Pill taken: NO
Dim Light + B-12 Raw ADC: 3317 Threshold: 2000 Pill taken: NO
Dim Light + Lysine Raw ADC: 3299 Threshold: 2000 Pill taken: NO
Dim Light + Zyrtec Raw ADC: 3206 Threshold: 2000 Pill taken: NO
Bright Light Raw ADC: 946 Threshold: 2000 Pill taken: YES
Bright Light + Zyrtec Raw ADC: 2919 Threshold: 2000 Pill taken: NO
Bright Light + Zyrtec2 Raw ADC: 2943 Threshold: 2000 Pill taken: NO
Bright Light + Lysine Raw ADC: 2739 Threshold: 2000 Pill taken: NO
Bright Light + B-12 Raw ADC: 3256 Threshold: 2000 Pill taken: NO

2000 Threshold is too low. Maybe closer to 2600… would be more reasonable.


MIDTERM REVIEW REQUIREMENTS

On your final project site post - a system diagram for your project, list the tasks to be completed, - make a schedule for doing them, - meet with your local and global instructors to review these and your weekly assignments. (scheduled for 4/20/2026)

System Diagram

Bill of Materials Here

Diagram

Claude Co work Assisted PROMPT: help me make A map of my pill dispenser project and all of the components - maybe in power point of google slides so i can edit it

FinalSystem3

FinalSystem3

FinalSystem3

List of things to be completed

  • Reprint 3D cartridge body, divider and stepper motor key
  • test function and tune settings
  • implement power splitter - buck?
  • System integration
  • Create code
  • Create interface
  • make slide
  • make video

My Claude assisted Time Line is Here

PROMPT: make a gaant style time line for getting these things done by the end of May