Arduino Drop Controller

I did a 365 photo project a few years ago in a bid to improve my photography by actually taking more pictures. As the first and last quarters of the project covered the times of year when the hours of daylight are limited at these latitudes and the weather (even in the summer) is often not conducive to trying to shoot outside, I spent a lot of time doing indoor shots. One of the recurring themes involved water: making waves, bubbles, drops and splashes, and trying to catch them being interesting using flash.

Focusing on the drops and splashes, I did manage to capture some reasonable shots, but it was very hit and miss business timing-wise with a lot of frames of a still water surface and no water drop visible at all. And I never got close to capturing one of those shots of a drop hitting the splash from the previous drop. So how do you capture water drop shots without missing the action most of the time? It’s all about getting two drops the right length of time apart and managing to trigger the flash just as they collide. This is either going to take:

  • an incredible amount of skill, both in the set up and timing the individual shots, or
  • a massive amount of luck, or
  • some electronics to improve the odds in your favour.

Taking the third option, you can buy off-the-shelf solutions like the Mumford Drip Kit, but these are quite expensive so unless you’ve got money to burn why not make your own using an Arduino? This is, after all, exactly the sort of application they’re very good at.

There are several ways to provide the user interface to enter the drop size and timing, but for this build I opted to keep the unit self-contained by using an Arduino keypad display shield – this may not give the most sophisticated user experience, but it has the advantage of only needing to develop code for the Arduino rather than having a second set of code (and development environment) for phone, tablet or computer.

Parts List

What you’re going to need (the list looks long, but the components are fairly cheap):

Plus, if you want to box the electronics:


While the hardware for the project is pretty straightforward, the major work for this project was writing the software. The bulk of the code is the user interface, and that’s likely to be that case no matter whether the user input part of the process is done using a computer, phone/tablet or the display keypad shield. With the display keypad it involves taking input from the very limited keypad and displaying the values on the basic two-line display: perhaps not the most elegant solution, but it does make the system self-contained. The actual valve control part of the software is very simple – open valve, delay close valve, delay …

The Arduino code uses two libraries for this application, the first is LiquidCrystal for interfacing to the keypad/display and the second is EEPROM to allow the parameters to be written to and loaded from the on board EEPROM. These libraries need to be added in the Arduino IDE.

The first thing to decide is what parameters the user needs to control – my assumption here was that the dropper needs to release one, two or three drops, and that we need to control the size of each drop (ie. the time the valve is open) and the spacing between drops (the time the valve is closed after each drop). While the camera output is going to trigger at the very start of the timing cycle, it is also necessary to provide a separate flash trigger output a user-defined time after the last drop is released, so that the action can be captured by a short bust of flash when the collisions are actually happening.

Drop size is defined by a valve opening of 1 to 99ms, and time between drops by a valve closure of 1 to 999ms: the time for a drop to fall is going to vary with the height of the dropper, so it seems like a good idea to allow a period of up to nearly a second between drops for flexibility. Flash delay is also programmable in the range 1 to 999ms.

My source code for the project can be downloaded here. It comes with no guarantees, but should be a good starting point for anyone building a keypad/display shield based dropper.

Programming the system is fairly simple: scroll through the options using the up/down keys and when the parameter you want to modify is on the top line of the display, select it using the select key. You can then modify its value using the up and down keys, and can change the size of the increment decrement with the left and right keys. Hitting the select key again allows you to go back to scrolling through the parameters.

If you press the select key when “Fire” is on the top line of the display, the current parameters are written to the on-board EEPROM, the display backlight turns off and the trigger cycle you’ve programmed commences. When the trigger cycle is complete the backlight turns on.


The Wet Bits

Wet side components

This is pretty straightforward, but will depend a lot on the valve and water reservoir you’ve chosen. I used a plastic food container with a snap on lid as the reservoir. Cut a hole in the bottom to fit the tank connector, then fit the piece of copper pipe to this, followed by the 15mm to ½” female adapter, the ½”to ¼” adapter and the valve. I used plumbing jointing compound on the compression fittings and PTFE tape on the screw threads, but with what’s effectively a zero pressure system like this it’s probably ok to couple the plumbing parts ’dry’.

Cut a hole in the lid of the container and seal in a short length of silicone tube that reaches close to the bottom when the lid is in place (see picture): this is a Mariotte syphon, which keeps the pressure in the container constant as the level inside drops. This should mean that the drop size will remain constant for any given valve-open time as the reservoir empties.

Holding it all up depends on the stand you’ve chosen: I used the column from an old enlarger I had lying around from the days when I used to do black and white printing. The valve/plumbing is attached by a 15mm plastic pipe clip which snaps on to the length of copper pipe between the valve and reservoir.

The Dry Bits

To keep the build simple I originally planned to use a stackable relay shield board to control the solenoid valve, camera shutter and flash – however, the display/keypad shield uses most of the Uno’s digital pins, including three of the four used to control the relays on the shield board, so that was a non-starter. It would be possible to use a non-stackable relay board mounted separately, but I opted to go for optoisolator and MOSFET based triggers instead as they are far faster and give more consistent timing than relays: a couple of low power optoisolators provide the triggering for camera and flash, and a power MOSFET is used to power the solenoid coil.

Working around the digital I/O pins used by the display/keypad shield, there are still enough outputs available to the control the valve, camera and flash. In my software they’re set up as follows:

  • Pin 2 –valve control,
  • Pin 3 – flash trigger,
  • Pin 11 – camera trigger.

The optoisolators were built onto the Arduino prototype shield board, giving a nice compact stack of boards for building into the case when it’s all finished and tested. The MOSFET module is very small and can be mounted separately on the case close to the solenoid trigger socket.

One final piece of electronics hardware I added was a voltage regulator. I was planning to power the system with an old 12 Volt DC supply I had lying around – I’ve no idea what it came from as it’s one of several that was separated from the obsolete bit of kit it powered long ago. Typically for these type of units it gave an output voltage reading of about 16V with no load applied. This is pretty high for the onboard regulator on the Arduino, and is higher than the suggested voltage for the valve. To drop it down to a regulated 12 volts only requires a SG7812 voltage regulator and two capacitors. These regulators can deliver an amp, which is plenty for the Arduino and valve.

To be honest a schematic for the whole system is going to make this all look a lot more complicated than it actually is, as using the LCD keypad shield makes the circuit diagram of that part of the unit irrelevant since you just have to plug the parts together. The circuit diagram of the the add-on parts is pretty simple, comprising a three-component voltage regulator, two two-component opto isolator circuits for the camera and flash triggers and the MOSFET module to control the valve. Connecting this lot to the Arduino gives this circuit :

Setting It Up

By now I had a system that’s capable of controlling the number, size and gaps between drops and the relative timing of the flash, so it was time to get it set up to produce some good splash shots. The starting point for this was the basic physics equation:

s = ut + ½ at2


s is distance (ie the height the drip starts above the target),

u is initial velocity, which in this case will be zero,

a is acceleration due to gravity (9.8 m/s2)

t is time (ie what we’re trying to work out)

Since the water drop is starting from a standstill the first part of the right hand side of the equation is zero, so this simplifies to:

s = ½ at2

Turning that around to solve for ‘t’:

t = √(2s / a)

With a height of 320mm (I set the end of the brass valve outlet at 300mm above the water surface, but the actual distance for the calculation should be the distance from roughly the bottom of the valve block to the water surface) this becomes:

t = √((2*0.320) / 9.8)

Which works out at a time of 0.2555 seconds for the drop to hit the water. That’s the theory, so putting it to the test I used a single drop with a size of 20ms and a flash delay reduced slightly to 245ms. Theoretically that should catch the drop just before it hits the water. In practice the following picture was what I captured:

Well, that was encouraging! Extending the flash delay (in this case to about 400ms) captures the post-impact column of water that’s shaping up exactly how you need it to be hit by the second drop to start getting really interesting results.

A second drop delayed by about 100ms starts to give the sort of splash patterns I was hoping for when I decided to build the system. Bear in mind that when you start to use multiple drops the flash delay should be reduced, as the way I wrote the software it’s the delay after the last drop that that triggers the flash. Here’s a two drop splash with drop sizes of 10ms and 10ms, a delay of 100ms between drops and a flash delay of 255ms:

Note: it’s well worth keeping a record of the settings you’re using for each shot, as juggling the timing of the inter-drop delay and the flash delay can sometimes appear to defy logic as you tune them up over a series of shots.


This is a slight aside from the project build, but if you don’t light the splashes properly you’re not going to get decent results. The good news is that you only need a single strobe pointing at (or through) the background, but it must have a very short duration to freeze the motion of the drops and the splash pattern. Most studio flashes don’t give a short enough flash burst (some of the newer ones which have IGBT circuitry will be ok), but portable strobes with a manual power setting should work fine. The strobe should be set to manual power mode with (close to) its lowest power setting selected, as this gives the shortest flash duration. The unit I’ve done most testing with is a Yongnuo YN568 EXII  – apparently this has about a 1/20,000 second flash duration at 1/128 (minimum) power. That said I’ve also used several of my older strobes at their lowest power settings: Canon 540EZ (at 1/128 power), Canon 430EZ (at 1/32 power), Canon 420EZ (at 1/32 power) and an Achiever 632LCD (at 1/16 power). All appear to have a short enough duration to give a workable image.

Boxing the Electronics

Once the electronics was working I used it for several sessions with the Arduino shields and the two other boards just lying on the table at a safe distance so they wouldn’t get wet. However, as a long-term solution this isn’t ideal since at some point the boards are liable to get splashed or shorted and the wires broken or otherwise damaged. The sensible approach is to put the electronics in a project box: this also gives an opportunity to replace the horrible push-button switches on the display board with something a bit more tactile.

The project box needs a bit of surgery to start with – a rectangular cut out for the display, five holes for the switches (up, down, left right and select) and a further four for power-in, solenoid, camera trigger and flash trigger. In addition there are four holes for attaching the Arduino stack and two each for the MOSFET module and power regulator. Then it’s just a bit of soldering for switches and sockets, followed by bolting the boards into the box.

Boxed, before closing up, the final stack of Arduino, prototype shield and display/keypad, with external MOSFET module and voltage regulator looks like this:

To keep the front panel tidy I threw together a quick layout, printed it on white paper and laminated it. Once all the cut-outs were done to match the top of the box,  it was stuck on using Evo Stick impact adhesive and the switches and sockets were attached. Job done! Not the prettiest looking device, but a lot less work than lettering the top of the box by hand, and considering it’s going to spend most of its working life in a darkened room it’ll do just fine:

The Setup

Working with a single strobe, my setup looks like this:

The background is a sheet of opal perspex with the strobe firing through it. The black tray holding the water is the plastic type you get ready-meals in, wile the second one below it catching the overflow (and allowing you to fill the water tray right to the top) is just a regular oven tray.


In use it takes a while to work out the timings to get decent results, but once you start to understand the way the splashes form it’s reasonably easy to make interesting patterns. There can be a bit of variation in the splashes produced with exactly the same timings – several factors may be playing out to cause this:

  • variability in the timing of the valve opening (it is electro-mechanical after all),
  • drop size: if the drop size is set too large a secondary drop is sometimes produced, which creates unpredictable results,
  • variation in the way the drop comes out of the valve’s output port,
  • residual liquid in the valve outlet from the previous drop.

That’s my guess anyway. Below are a few of the images produced in the first few sessions using the system.

Comments 13

  1. Hello,

    first , sorry for my bad english.
    I did build this arduino dropler and al seems working ok, but i only get dark pictures, camera settings 1/125 sec shutter, fstop 8, flash power set to 1/64, somtimes when i press fire, it looks like the trigger for the camera is the first, and then followed bij the valve and flash. all is connected ok, if i set 3 drops, then the led on the mosfet module flashes 3times .
    Please can anyone help me out with this

    1. Post

      Hello Leo,

      It sounds like the unit is doing the right things – when you press fire the camera should trigger first, then the valve and finally the flash. You should be working with the camera set to the “bulb” setting, as the shutter stays open for the whole drop cycle and it’s just the flash burst that freezes the drop. The shutter only closes after the flash has fired: to make this work you need to be working in a darkened room. If you use a shutter speed of 1/125 second the shutter will likely have opened and closed before the drop reaches the water and the flash fires, which should explain the dark pictures. Try with a single drop first, as it’s a lot eaier to work out the timing than with multiple drops. Good luck.

  2. Thank for the reply, when i look at the leds on the modules i use then the unit is working as you described, and later i figured out about the bulb mode. i will give it another shot soon, im still working on it,
    In future i will try to add a second valve and one or more flashes. adding the flashes must be no problem, they have to fire at the same time i gues?, but adding a second valve will be another story on the programming.

    greeting Leo

  3. Hello John,
    I want to thank you so much for publishing your Arduino water drop controller design ! It is exactly what I was looking for !
    I searched the internet for months and months until I found your photobuilds website. Thanks!
    It works like a charm and I have published my project on see here:

    Because I did not have exactly the same hardware components I made a few additions/changes in your nice design and software:

    * a start message “splash controller V1” showing the software version for a few seconds.

    * I used an LCM 1602 I2C LCD display instead of your LCD 1602 keypad shield. (this display needs only 4 wires to the Arduino, SDA,SCL, VCC and GND).

    * Separate analog keyselection (values 0-1023) with a resistor chain on my PCB connected to input A1 and a different Mosfet design integrated on this PCB. I found a lot of discussions on the internet about the Mosfet IRF520 not working with Arduino because the gate voltage should be more than 5 VDC. So I added an optoisolator between the Arduino and the gate and now it switches with appr. 10 VDC.

    * I used EEPROM instructions with GET/PUT instead of read/write to store the integer numbers from ParamValues. Some are >255 and these integer numbers each need 2 bytes per number… The EEPROM read/write instructions can only store and retrieve single byte numbers (0-255).

    * I added a “clear valve” routine (press btnDOWN during startup, when ready press btnSELECT to stop). This opens the valve continuously to empty the siphon. This is a routine to clear the valve or change the content of the siphon.

    Thanks again for your design !


    1. Post

      Hi Alex,

      Thanks for your comment, and I’m glad my post was helpful. I just took a look at your instructable and it looks like a nice job you’ve done there, and your code modifications are definiely improvements. Interesting point about GET/PUT vs read/write: I just looked up my notes from the last sessions I did with the controller and none of the delays were > 255ms, so I hadn’t seen a problem. Lucky so far perhaps, but I’ll definitely be making a change to the code. Thanks for that.

      The MOSFET module I used says it’s good for 3.3v to 5V: I don’t have a schematic for the module so don’t know what other components are in there but I haven’t had any problems with it triggering .


      1. Hello John,
        About the Mosfet IRF520:
        You are right, the complete Mosfet driver module you use is compatible with Arduino. I think the load of the water valve is not that critical for the Mosfet so it works fine.
        I am now going to make more droplet photos with colored water and changing the thickness of the water for different results. I will publish them on instructables..
        I am thinking about an addition with a laser sensor mounted under the valve, this might be neccessary if the valve releases droplets with irregular mechanical timing. Your Arduino software can handle this addition too I think.

        Your website is very interesting, it reads like a book.

        Thanks again,

  4. I have the Camera AXE-4 and it does also water droplets, sound and other triggers.
    You have very nice pictures and I love that you made it yourself! Keep adding functions and have fun with it.
    You can also drop 2 colors – the base has one color and the liquid has a different color. Also the way you light up your background and use more lights it will create interesting backgrounds and some of that color will affect your droplets and the dish colors.
    Nice job!

  5. Pingback: Arduino Blog » This system can take close-up photos of water droplets

  6. Pingback: This system can take close-up photos of water droplets

  7. Pingback: This system can take close-up photos of water droplets – Arduino Project Book

  8. Pingback: This system lets you take close-up photos of water droplets with a DSLR camera | ブログドットテレビ

  9. Hello John,

    I experimented with your code and setup and had good results. Nice work. Thank you. I added an external wired button, so I don’t have be near the Arduino to fire. I use a PC817 4-Channel Optocoupler (camera, flash and external trigger button) and a 5V 1 Channel Relay Board Module for the valve.

    I found a minor problem in the sketch with the storage and retrieval of the values in EEPROM. The integer values greater than 256 (such as gaps and flash delays) are not stored properly in EEPROM address. Each EEPROM address can hold only one byte (0-256). This situation can be solved by breaking the number in 2 bytes. I found the solution at I tried it and it works well. I hope this enhancement will be useful.

    Here is the code to do it:

    int j = 0;
    for (int i=0; i<=6; i++) {
    // read last settings used from EEPROM
    byte byte1 = + j);
    byte byte2 = + j + 1);
    ParamValues[i] = (byte1 << 8) + byte2;
    j = j + 1;

    int j = 0;
    for (int i=0; i> 8);
    EEPROM.write(i + j + 1, ParamValues[i] & 0xFF);
    j = j + 1;

    Best regards,


    1. Post

      Hi JM,

      Thanks for your feedback, and yes you’re right there is an error in the way I write/read delay values into eeprom which I will correct – with my setup I haven’t encountered the problem as I’ve never yet run with a delay over 255mS.

      It looks like there’s a slightly easier way to deal with this in Arduino by using EEPROM.put() and EEPROM.get() methods, which appear to automatically support the type of the variable being stored or retreived. There’s also EEPROM.update() which will only write data if it’s different to what’s already stored. I think I’ll try these out when I do the mod.


Leave a Reply

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