High Speed Photography Controller

High Level Design


Our inspiration stemmed from photographs that freeze fleeting moments, like a water droplet splashing from a faucet or the split-second burst of a balloon. Such precise instants are often too swift for human reaction or standard camera shutter speeds to capture reliably. To tackle these challenges, we opted to integrate a microcontroller with diverse sensors and a high-intensity LED array to synchronize with the camera’s shutter. Typically, photographers interested in such shots face high costs for specialized equipment and lighting control systems, or they resort to capturing hundreds of frames in hopes of achieving the desired image. Our aim was to develop an affordable and dependable system for high-speed photography.

falling bottle opener
Photograph of a falling bottle opener taken with our system.


We opted to construct our system with a user interface reminiscent of a cellular phone. Utilizing a cost-effective, 1″x1″ color LCD screen and a keypad borrowed from a Motorola RAZR, we achieved a highly convenient method for camera control. A hierarchical menu system enables users to set sensor thresholds and other shot parameters and then activate the shot by awaiting trigger signals. Our setup includes various sensors allowing shots to be triggered by sound, infrared detection, or impact sensed via an accelerometer. Lastly, a custom-made flash unit ensures swift and precise illumination of moving objects during capture.

Implementation Details


The hardware components of this system include:

  • Microphone
  • Accelerometer
  • Infrared ranging unit
  • Camera shutter control circuit
  • High-powered LED flash unit
  • 132×132 12-bit color LCD
  • Keypad


Our microphone unit
Our microphone unit.

The microphone circuit comprises an electret microphone and an op-amp configured as a non-inverting amplifier. The microphone receives power from the MCU board via the +5V rail and is connected through a 10uF electrolytic capacitor for decoupling. Its signal is then directed to the non-inverting input of the op-amp. The output of the op-amp is looped back through a potentiometer, serving as a variable gain control for the circuit. This adjusted output is fed into the inverting input of the op-amp to set the gain.

The LM358 op-amp, while not providing rail-to-rail voltages and limited to a maximum output of 3.7V, suits our needs since our focus is on detecting sounds like snaps or claps rather than achieving maximum output amplitude. A user-defined threshold for triggering the camera is configured via the LCD menu system. Additionally, a meter displayed on the LCD shows the peak ADC input value averaged over 1-second intervals, aiding in adjusting for ambient noise levels.

IR Sensor

Our IR emitter and receiver unit.
Our IR emitter and receiver unit.

The IR sensor operates simply by reflecting infrared light off an object and detecting the reflected light with a photo-transistor tuned to the same frequency of infrared light. The LED and the photo-transistor are positioned next to each other, but the emitted light from the LED does not directly illuminate the photo-transistor. Both the LED and the photo-transistor have appropriate series resistances to limit current and adjust the voltage drop proportional to the distance from the object in front of the sensor. The effective sensing range of the device spans a few centimeters. To enhance object detection, placing a reflective surface between the object and the sensor can significantly improve performance. When an object moves between the sensor and the reflective surface, a notable decrease in the output signal is observed.


accelerometer unit
The accelerometer unit is taken from the FSAE lab surplus

The accelerometer is straightforward to use and is designed for automotive applications, featuring an exceptionally robust casing that is ideal for sensing various types of impacts. Its interface is user-friendly, providing an output signal that is a voltage linearly proportional to the detected acceleration. Similar to the other sensors, an on-screen meter allows the user to set a threshold based on the peak values detected over 1-second intervals.

Flash Unit

flash unit
The flash unit consists of 5 3W LED arrays

The flash unit comprises five 3W LEDs connected in series with a BUZ73 power NMOS transistor and a 1N4001 diode. This setup is powered by a 20V laptop charger, which is ideal due to its high current output and compact size. Each LED has a voltage drop of about 3.7V, while the diode drops between 0.7V and 1V depending on the voltage, helping regulate the current through the LEDs. The LEDs are mounted on a piece of scrap aluminum using thermally conductive adhesive to prevent overheating.

LCD & Shutter Control

main unit
The main unit has an LCD for the menu and a button pad similar to that of a cell phone

The shutter is controlled by a single NPN MOSFET. The camera is designed for remote shutter operation using a 2.5mm stereo mini-jack, where the shutter opens when the middle pin is shorted with the first pin. The NPN MOSFET acts as a switch, shorting the pin when the gate is driven high by the MCU. The LCD is powered by an external 2xAA battery pack, supplying the 3.3V needed by the SparkFun carrier board. Since the MCU outputs a 5V signal and the LCD requires a 3.3V input, a 1k resistor is placed between the MCU and the LCD to drop the signal to an appropriate voltage for the LCD.


The simplest implementation of this project requires minimal additional programming beyond what was done in the labs. Essentially, the project involves polling the A/D converter to detect threshold breaches and then using a state machine to open the shutter, activate the flash, and close the shutter. The challenging and interesting part of the software aspect was our menu system.

Our menu was hierarchically organized with 10 different pages, some static and others animated. This was implemented as an extensive state machine, where transitions were triggered by button presses, causing the LCD to update accordingly. Besides the menu state machine, we adapted a keypad state machine from the keypad library used in lab 2. The final state machine controlled the camera hardware by managing the sequence of taking a picture: opening the shutter, waiting for the sensor to be triggered, activating the flash, and then turning off the flash and closing the shutter. The menu and keypad state machines operated on 200ms and 30ms timers, respectively, while the camera state machine used a 10-microsecond timer for finer control of the flash unit.

Menu State Machine

The menu state machine manages various state variables, including the current page, menu choices for navigation pages, and the selected input box for settings pages. Navigation pages are controlled by up/down buttons to change menu choices, along with select and back buttons to navigate through the menu. Some pages allow users to configure camera settings such as sensor thresholds or flash duration. Thresholds are adjusted by moving an indicator next to an analog meter, which displays the current sensor signal, enabling the user to set a threshold suitable for the ambient noise. Other settings, like exposure time or flash duration, are set numerically using a 10-digit keypad. Camera settings can be saved to EEPROM for persistence between uses. The menu also initiates a shot and displays an animated progress bar to indicate the camera system is working.

The main loop checks for menu updates every 200ms. If a button is pressed or the page contains animated content, the menu is updated by changing states and redrawing the menu on the LCD. Drawing functions are extracted into a separate library to improve code readability. Similarly, camera control functions (such as getting and setting parameters, starting, and stopping shots) are maintained in a separate library.

Keypad State Machine

The keypad state machine operates at a higher frequency than the menu system to ensure quick debouncing of button presses. Based on the keypad library from lab 2, we designed a state machine to poll the 4×4 button matrix horizontally and then vertically. When a button press is detected, a flag is set upon button release to signal that the menu needs updating. A lookup table translates 8-bit keypad readings into their corresponding button values.

Drawing Functions

The LCD drawing details were implemented using utilities adapted from Refik Hadzialic’s LCD library (see reference below). The basic operations of this library include clearing the screen, drawing various menu pages, and highlighting different choices. For navigational pages, drawing was abstracted to use a common method across multiple pages. However, settings pages were more unique and often required their own specific drawing methods.

The LCD library was based on code from www.e-dsp.com. While this code served as the foundation for getting the LCD operational, significant modifications were made to enhance functionality, speed, and usability. The init() function was revised to improve readability and to enable 12-bit color instead of the original 8-bit color, with James Lynch’s tutorial providing useful guidance for these changes. Additional functions were added, including LCD_put_bitmap(), which draws an image at specified coordinates. This function can draw from arrays in both flash and RAM. A set_drawing_area() function was also created to reduce the redundant code found in many functions and to speed up drawing. Previously, each pixel was drawn individually, but the LCD controller allows setting a region to draw in, followed by a command to write information into that area sequentially. The draw_box function uses set_drawing_area to color regions efficiently.

Converting the code from 8-bit to 12-bit color required special consideration, as it involved changing from sending 1 byte per pixel to 2 bytes per pixel. Each pixel is represented by three sets of 4 bytes for red, green, and blue. Colors represented as integer values needed to be parsed into the proper format for the LCD. Finally, a set of functions for drawing characters on the screen was also implemented.

Camera Control

We aimed to separate the control parameters and camera functions from the graphical interface by storing and updating the camera variables in a dedicated library. All thresholds and other settings were stored in EEPROM, and the menu system accessed them exclusively through getter and setter methods in the camera library. Additionally, the camera library directly managed the camera state machine via the checkShot() method. This separation of functions from the main menu loop helped maintain clean and readable code.

Main Control Loop

The program starts in menu.c by initializing state variables for the various state machines and configuring the MCU control registers. Timer 0 is set with a clock prescaler of 64, triggering a compare-on-match interrupt every 250 ticks, resulting in a 1ms timer. This timer is used for the keypad and menu state machines. Timer 2 also uses a prescaler of 64 but interrupts every 25 ticks, creating a 100-microsecond clock for more precise timing in the camera loop. The ADC is configured to use AVCC (5V) for calculations with a prescaler of 128 on the XTAL frequency.

The main while loop checks and resets the timers. The LCD is checked every 200ms and updated if a button has been pressed (indicated by the refreshLCD flag) or if the menu is on a dynamic page (indicated by the onDynamicPage() method). The camera state machine is then checked every iteration for fine-grain control. Finally, the maximum ADC values are checked to update the analog meter on the threshold settings pages.


Using our system, we successfully captured fleeting moments in time. Oscilloscope testing showed that the delay between the triggering event and the start of the flash is only a few hundred microseconds. This is a significant improvement compared to the camera alone, which has a delay of at least 100ms and sometimes as high as 200ms. For our purposes, a 100ms delay before opening the shutter is impractical. Our flash unit reduces the delay to fractions of a millisecond, allowing us to capture precise moments, such as a wine bottle breaking.

However, our design lacks the flash power needed for extremely fast pictures. To achieve adequate exposure, we had to run the flash for about 1ms or more. In contrast, a dedicated flash unit for an SLR camera can produce much more light in less than 1/15000th of a second. A midrange consumer-grade flash unit costs around $250, while ours was built for less than $25.

Safety considerations for this project are left to the user. It is generally not advisable to look directly into bright lights for any duration. However, given the light output of our flash unit compared to a typical xenon flash lamp found in most modern cameras, it is unlikely to cause permanent eye damage. The duration and intensity of our flash are not sufficient to cause more than temporary spots in one’s vision.

bottles before

bottles after

Before and after of two bottles breaking and triggering the microphone sensor. Note the cracks forming in the wine bottle in the before picture.


We were pleased with the outcome of our project as we successfully achieved nearly all of our goals. While we did not achieve professional-quality photos, this was expected given the significant cost savings compared to professional systems. Using the microcontroller, we effectively controlled our camera and captured high-speed shots triggered by audio, accelerometer, and light events. Our improvised flash unit provided the necessary immediate illumination. The graphical menu proved to be intuitive and user-friendly, and the device operated efficiently on battery power for portability.

Looking back, there are several improvements we would consider if we were to undertake this project again. We did not have time to encase the project, and we would have preferred a more aesthetically pleasing design. Adding connectors for CAT5 cables to link sensors with the MCU would have been convenient. Although we intended to use the keypad from the Motorola RAZR, we often found it more practical to directly press the buttons. Additionally, we opted not to implement the “number of shots” functionality since its application seemed limited. While it could be beneficial for extended exposure scenarios requiring regular interval shots, our high-speed setup did not allow for fast enough shutter operation to capture multiple shots.

We are confident that this product will prove valuable in the future, particularly for photography enthusiasts. We hope our project proves beneficial to others interested in this hobby, and we are available to address any questions via the email addresses provided above.

Follow this link for complete project: High Speed Photography Controller

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top