Making a Working Model of Pupillary Light Reflex Using Arduino UNO
by Lakshya Yadav in Circuits > Arduino
187 Views, 3 Favorites, 0 Comments
Making a Working Model of Pupillary Light Reflex Using Arduino UNO

Hi everyone! My name is Lakshya Yadav, and I am a 3rd-year MBBS student at SMS Medical College, Jaipur. I originally created this project in February 2023 and uploaded a short video about it on YouTube. It was made for a science fair, and since then, many fellow students have shown interest in understanding how I built it, with some even trying to recreate it themselves.
I’ve finally decided to make an instructable to share the process in detail.
Supplies

.jpeg)
.jpeg)
.jpeg)
.jpeg)
.jpeg)
.jpeg)
.jpeg)
.jpeg)


Materials required-
1. We need a mechanical aperture whose diameter can be controlled by a lever or similar mechanism. This would represent the iris of our eyes. The best option I found was to extract the iris diaphragm from an old light microscope , However you could also make an aperture from Cardboard
2. Light Dependent Resistor (LDR) - this would sense the amount of light falling on it (ie. the eye)
3. Arduino Uno - this would take the inputs from the LDR, analyse them and command the servo motor to move the diaphragm accordingly
4. Micro Servo motor (I used an MG90S with metal gears)
5. Jumper Wires
6. Breadboard to make all the connections (optional, you can solder the circuit too...)
7.Torch - To give stimulus to our eye model
8. Resistors- only one resistance of 10k ohms was needed for this project but keep more just in case.
9. A base - to hold the aperture and servo motor in place. I used a Wooden base but you can experiment with pretty much anything
10. A Metal wire - To connect the servo motor with the lever of the aperture. It should strong enough so that it does not change it's shape while moving.
11. USB Cable - To connect the Arduino with your Laptop/Power Source.
12. Laptop/PC - You need to connect your Arduino atleast once to upload the code in it after which you could run it on external power supply.
13. Power Supply - Either by Your Computer or by a 9V battery or power bank
How It Works
The pupillary light reflex is a natural, involuntary response in which the pupil constricts (becomes smaller) when exposed to light and dilates (becomes larger) in darkness. This reflex helps the eye adapt to different lighting conditions by adjusting the amount of light that reaches the retina. To know more about it , click here
To replicate this mechanism, I used a Light Dependent Resistor (LDR). As the name suggests, the resistance offered by an LDR depends on the intensity of the light falling on it — decreasing as light intensity increases. The LDR detects the amount of light in the environment and sends this information to the Arduino.
In this project, the Arduino functions like the brain. It takes input from the LDR and compares it with a preset threshold intensity — the level at which we want the pupil (aperture) to constrict. When the light intensity exceeds this threshold, the Arduino sends a signal to a servo motor, which then rotates to constrict the aperture, mimicking the natural pupillary reflex.
Electronics !


In this step, we’ll assemble the electronic components that allow the Arduino to sense light and control the mechanical pupil. The setup is quite simple and beginner-friendly.
> Note: I’m attaching photos of the connections separately, as I’m typing this from my phone and don’t have access to make a Fritzing diagram right now.
How It Works:
We use the LDR and a 10k resistor to form a voltage divider. As the ambient light level changes, the resistance of the LDR changes — this alters the voltage at the junction point between the LDR and the resistor, which is then read by the Arduino’s analog pin. Based on this value, the Arduino sends a corresponding PWM signal to the servo to adjust the aperture size.
Wiring Instructions:
Here’s how to connect the components:
1. LDR and Resistor (Voltage Divider) :
- Connect one leg of the LDR to 5V on the Arduino.
- Connect the other leg of the LDR to Analog pin A0 and one leg of the 10k resistor.
- Connect the other leg of the resistor to GND.
- This forms a voltage divider: the analog voltage at A0 will change with light intensity.
2. Servo Motor :
- Orange (signal) wire to Digital pin 9 on Arduino.
- Red (VCC) wire to 5V on Arduino.
- Brown (GND) wire to GND on Arduino.
> Note: If your servo draws too much current and causes resets, consider powering it through an external 5V source with a common ground.
3. Optional Enhancements :
- Add an LED that lights up when light levels fall below a threshold (for extra feedback).
- Use Arduino Nano if you want a more compact and breadboard-friendly layout.
Installing the Mechanical Iris


This is the component that gives this project its most realistic touch — a mechanical pupil that dynamically opens and closes in response to light.
Using a Real Iris Diaphragm
Instead of constructing a mechanical iris from scratch, I repurposed a real iris diaphragm from an old, spare light microscope that was no longer in use at my college. These iris mechanisms are typically used to control light entering the objective lens and are built to be smooth and precise — perfect for simulating a real human pupil.
Mounting the Iris Diaphragm
To house the iris diaphragm, I built a simple wooden frame:
1. Cut a circular hole in the wood to fit the diameter of the diaphragm snugly. This keeps it secure and centered.
2. Just below this central hole, I made a second hole for mounting the servo motor. This allows the servo horn to reach the diaphragm’s control lever without obstruction.
3. The diaphragm was fixed in place using small screws and a few drops of wood glue, ensuring it didn’t wobble during servo operation.
Connecting the Servo Motor
The servo horn was attached to one of the small levers on the diaphragm that controls its opening and closing. A thin piece of stiff wire or even a bent paperclip can be used to connect the servo horn to the lever arm.
> When the servo rotates, it pulls or pushes the lever, causing the aperture to expand or contract — mimicking the constriction and dilation of a pupil.
For Those Without a Microscope Iris:
If you don’t have access to a microscope diaphragm, there are great alternatives:
- 3D-printable iris diaphragms are available on platforms like Thingiverse.
- You can also make a DIY version using cardboard or plastic, by layering multiple blade-like shapes in a circular pattern.
Tips:
- Ensure that the servo is aligned properly so that it can move the diaphragm lever smoothly.
- The movement range of the servo (usually 0° to 180°) should correspond to the full opening and closing range of the iris.
- If using a DIY diaphragm, reduce friction at pivot points using paper washers or light oil.
Downloads
Writing and Uploading the Code

With the hardware ready, it's time to breathe life into the system using code. This step involves programming the Arduino to detect light levels through the LDR and respond by adjusting the iris diaphragm using a servo motor — mimicking the pupillary light reflex.
Installing the Arduino IDE (if you haven't already):
1. Download the Arduino IDE from https://www.arduino.cc/en/software
2. Install and launch the application.
Uploading Your Code:
1. Connect your Arduino to your computer via USB.
2. Open the Arduino IDE and select your board and port from the Tools menu.
3. Paste the following code into a new sketch:
How This Code Works:
- The LDR is continuously read using analogRead().
- If the light level is high (LDR value ≥ 800), the servo rotates to 170°, causing the iris to close (like pupil constriction in bright light).
- If the light level is low, the servo rotates to 10°, causing the iris to open (like dilation in darkness).
- The servo is updated every 200 milliseconds to make the transition smoother.
Serial Monitor (Optional Debugging)
You can uncomment the Serial.println(ldr); lines to monitor live light values using the Serial Monitor in the IDE (Ctrl + Shift + M). This helps calibrate the threshold (e.g., 800) depending on your lighting conditions.Feel free to adjust the threshold value (800), the servo angles (170 and 10), or the delay based on your specific hardware behavior and iris diaphragm range.
Testing and Demonstration
This step is just about seeing our project in action — verifying that all components work together and showcasing the reflex-like behavior of the iris in response to changes in light.
Initial Testing Checklist:
Before testing dynamically, make sure of the following:
- The LDR is properly exposed and not covered.
- The servo motor is securely connected and can move freely.
- The iris diaphragm is not obstructed and responds to servo movement.
- The Arduino is powered either via USB or an external power source.
Testing the Reflex Functionality:
1. Power on your Arduino with the uploaded code.
2. Shine a torch or mobile flashlight directly at the LDR.
The iris should close or constrict (servo moves to angle 170).
3. Block the light or turn it off.
The iris should open or dilate (servo moves to angle 10).
4. Repeat the light/dark transitions to observe the smooth pupil-like movement.
Fine-Tuning (if needed):
If the servo does not move as expected, double-check:
- The LDR and servo pin connections.
- The threshold value (800) in the code — try printing ldr values using the Serial Monitor to calibrate better.
- If the motion is jittery, you can increase the delay slightly or add smoothing logic in the code.
Downloads
Painting and Aesthetic Enhancements





To make the project not just functional but visually engaging and educational, I spent some time on painting and detailing — giving it the look and feel of a human eye and adding a creative visual pathway demonstration.
Painting the Wooden Base and Frame:
I coated the wooden base of the project with a rich Prussian Blue shade using spray paint, giving it a sleek and clean finish.
For the wooden frame holding the iris diaphragm:
- I first applied a layer of white watercolour as a base.
- Then, using black watercolour and a sketch pen, I detailed the frame to mimic the external anatomy of the human eye — making it look more realistic and eye-catching.
- This black-and-white contrast helped highlight the moving diaphragm and simulate the sclera and pupil appearance.
Creating a 3D Eye Model:
To enhance the visual representation further:
I painted a spherical ball (to represent the eyeball) using various watercolours, simulating the iris, sclera, and pupil.
This gave a 3D appearance of a human eye, useful for both display and teaching.
Connecting to a Brain Model (Visual Pathway):
To complete the biological context:
I used a POP model of the human brain available in our lab.
Then I connected the painted eye model to the brain using a strip of LEDs, symbolizing the optic nerve and visual pathway.
This not only added to the project's realism but also served as a great teaching aid to demonstrate how light enters
the eye and signals are sent to the brain.
Conclusion and Future Scope

Conclusion:
This project is a simple yet effective simulation of the human pupillary light reflex, combining basic electronics, Arduino coding, mechanical design, and a bit of creativity. By using an LDR to sense light and a servo motor to control an iris diaphragm, it realistically demonstrates how pupils respond to changes in light.
Beyond just being a functional circuit, this model transforms into a visual learning tool — thanks to aesthetic painting, a 3D eye, and even a representation of the visual pathway using an LED strip and a brain model. It has great utility in both classroom education and science exhibitions.
Future Scope & Improvements:
Although the project functions well, there’s always room to build on it:
1. Proportional (Analog) Control:
Currently, the iris responds in a binary manner — either fully open or fully closed — based on a threshold brightness. In future versions, this could be improved by mapping the analog LDR input to a corresponding servo angle, allowing the diaphragm to gradually adjust in response to varying light intensities — just like the human eye does.
For example, the servo could constrict more as brightness increases, and open proportionally as light reduces.
2. OLED Display for Light Level Readout:
Add a small OLED screen to show the current light level numerically — helping with calibration and offering a great educational visualization.
3. Dual-Eye Setup:
Mimic consensual light reflex by building a second unit for the other eye and linking the control signals — just like in human physiology.
4. Biological Accuracy Enhancements:
Use more anatomically accurate eye models, lenses, or even transparent domes to simulate cornea and anterior chamber.
5. Simulating Drug Effects with Manual Controls:
Another interesting addition would be to add buttons or toggle switches that can manually constrict or dilate the pupil. This could simulate the effect of pharmacological agents — such as atropine, which causes dilation (mydriasis), or pilocarpine, which causes constriction (miosis). This would make the model even more valuable as a teaching tool in pharmacology and clinical demonstrations.
6. Response to Light of Different Wavelengths (Colors):
In real life, pupils respond differently to lights of various wavelengths — blue light, for example, causes a stronger constriction compared to red light. A future version of this project could include color-sensitive sensors or use RGB LEDs with filters to simulate and test the pupillary response under different colors of light, making it even more physiologically accurate
Final Note:
I’m also attaching a YouTube video showcasing the working model of this project. I highly encourage everyone to watch the video, and if you have any doubts or questions, feel free to ask in the comments section.
If you decide to replicate this project, I would love to see your version — please do share photos or videos with me!
Also, if you notice any errors or missing points in this Instructable, please don’t hesitate to point them out. I deeply appreciate your feedback and engagement!