Introduction: Photography of Bursting Bubbles Using an Arduino
After my exploration into high-speed photography via my tutorial on High-Speed Droplet Photography, I wanted a new challenge.
Bubbles are fascinating in their own right, but they are absolutely spectacular when they pop. Normally this happens too fast for us to appreciate, but my hope with this tutorial is to show you how you can stop time with some standard photography gear, a little electronics know-how, the application of some simple physics, and an Arduino.
If you're in for a challenge, then read on!
Step 1: A Quick Primer on High-speed Photography
I recommend reading my other instructable on this topic: High-Speed Droplet Photography with an Arduino for a more detailed treatment, but I'll provide a brief overview here.
High-speed photography is what it sounds like: capture events as fast as possible, so that you can effectively freeze time.
The key to high-speed photography is flash. The shutters on most cameras are too slow to really freeze time, but a flash unit can create a pulse of light that lasts a mere 50microseconds.
Since we're using the flash pulse to freeze or scene, we can just leave the shutter open on the camera to give myself a "window of opportunity". Here are the typical settings I use:
- 1 - 2 second exposure
- 100-400 ISO
- f/9 - f/f16
Of course, to get away with a 1-2 second exposure, you'll need a dimly lit room.
I also usually have my flash units set on their lowest setting as this provides the shortest pulse. You can use multiple flash units, but you'll need to make sure you can wire them all to fire simultaneously. Using a slave mode will not be fast enough, and you'll see ghosting. RF triggers, at least in my experience, also were prone to introducing delays which caused ghosting. I settled on hard-wiring all my flashes together.
Step 2: Things You Might Need
Here is a list of items that I used, and you may or may not need, depending on what you have at your disposal:
- A camera with a manual shooting mode, I shoot with a Canon 70D (https://goo.gl/17ga72)
- Off-camera flash units. I use a cheap pair that I got for $30 each that work nicely (https://goo.gl/qgKeUx)
- Flash sync cables (or you can hack into your flash unit and do some soldering) (https://goo.gl/1atGSb
- (Optional) extension tubes for your lens, if you want to take macro photos on the cheap. Good ones: https://goo.gl/IrlGyp, Cheap ones: https://goo.gl/kRGa7o
- Any Arduino -- I'm using a Leonardo (https://goo.gl/TH4mTA). If you're new to Arduino/circuits, it might be a good idea to get a starter kit: https://goo.gl/qgKeUx
- Various resistors / jumper wire / etc.
- A power supply (https://goo.gl/tRkSmI) -- An old computer power supply can also be configured and used for this role
- (Optional) servo for bubble-popping (https://goo.gl/lhSia8)
- (Optional) nicrhrome for bubble-popping (https://goo.gl/t8JIeL)
Other than the flash, camera, and arduino, much of this can be improvised. Automated popping mechanisms are nice if you're trying to get predictable/consistent pops, but otherwise aren't necessary.
Step 3: Physics of Soap Bubbles
You can skip this section, but stay if you're interested in the science!
Soap bubbles are fascinating in many ways, and have been the subject of much academic attention. Much of this is beyond me, but I'll cover a couple of interesting properties relevant to our goal.
Soap bubbles are thin films encapsulating air in a way that minimizes their surface area. Mathematically, a sphere is the best way to minimize surface area to volume.
The film itself a stable because surfactants -- long hydrophobic (water repelling) molecules with hydrophilic (water attracting) heads -- encapsulate a thin layer of water with a shell of these molecules on both sides. A simple solution of dish soap and water, in a 1-to-5 ratio, makes a good bubble solution. In dish soap, we most likely have anionic surfactants.
The surfactants " want" to minimize their contact with the water, and the water wants to maximize its contact with itself through cohesive forces. These effects lead to the phenomenon of surface tension, which broadly speaking is the tendency of a fluid surface to acquire the least possible surface area possible.
The thin films of soap bubbles exhibit a spectacular range of colors due to thin-film interference. This phenomenon can occur when there are two reflective or refractive interfaces that are within wavelength lengths of one another. This could be a thin layer of oil on water (think of the rainbow patterns you see on a rainy day where there's oil present), or in our case, the inside and outside surface of our soap bubbles.
When light strikes the outside surface of the bubble, some of that light is reflected back, and some penetrates. The light that penetrates may refract, and then strikes the inside surface of the bubble. Here, some of that light reflects back, and some passes through. The light that has reflected back will either constructively or destructively interfere with the light that was reflected back on the outside surface. This is because the light reflected from the inside surface has had to travel a further distance than the light on the outside surface, and will therefore (potentially) be out of phase.
The general equation governing constructive interference goes like:
2 * n * d * cos ( theta ) = (m - 1/2) * lambda
Or if we solve for the wavelength of light (lambda):
lambda = 2 * n * d * cos (theta) / (m - 1/2)
where n is the refractive index of the film, d is the thickness of the film, theta is the angle of incidence on the inner interface, and m is any integer.
Because m can be any integer, there's a literal rainbow of colors that will be alternately favored as d varies in thickness.
Rupture is interesting and will occur when the film breaks at any point with a hole larger than some critical dimension.
If this condition is met, the surface tension of the bubble causes it to rapidly unravel, which happens in just a few milliseconds and we see this as a burst.
Bubbles rupture on their own because of evaporation and gravity. Gravity tends to pull the fluid downward and around the shell of the sphere, causing thinning at the top. Evaporation also acts to remove water from the bubble. Both of these effects are significant when the film of the bubble is only a few hundred nanometers.
If you look at the photos, I've provided a sequence of a bubble just prior to rupture. You can see the hues of the reflect colors changing (due to thin-film-interference) as the film thins. You can also see an aggregation of super-thin pockets forming into one large "bald spot". This region is so thin that we see very little light being reflected.
I'm not completely sure what is going on here, but I do know that the super-thin region, the bald spot, must be on the order of 0-50nm is thickness, and that gradients surface tension, drying, and gravity quickly act to pull it apart until it's so thin that the bubble ruptures.
Step 4: Triggering Strategies
There are two main groups of strategies for triggering the flash units at the right moment, and those are responsive or assumptive.
Assumptive triggering uses an assumption based off a reference point. In my droplet photography tutorial (which you can find here), I used this kind of approach. The reference point was the time in which the solenoid was triggered, thereby releasing a droplet. All triggering was based off of this reference point by simply waiting a predefined time.
This approach was particularly well suited for droplet/splash photography, as we needed the solenoid in the project already. So we already had a reliable way to trigger an event, and because our Arduino can count time for us very accurately, we were able to obtain good results after some trial and error.
I experimented with several such methods for bubble popping as well.
Servo Actuated Poker
This is the simplest method I employed in my testing. Basically I hot glued a zip-tie to a micro-servo, and used this as a bubble-popping-swing-axe. It works. The timings are the servo swing are reliable enough that I could capture bubble pops using this trigger time:
time flash = time-servo-released + time-of-travel + time-delay
It was just a matter of finding the time-of-travel, which is a matter of trial and error. Mine worked out to be about 100-200ms.
There's a drawback to this method though, and that is that you're reliant on the servo to pop your bubble, which constrains any creative freedom.
Nichrome Wire (resistive heating)
I'll preface this section by saying that this method wasn't reliable enough to use to much success. However, it does provide a reliable "push-button" means to pop bubbles.
The basic idea is to make a bend of nichrome wire -- which becomes incredible hot when current is run through it -- and have this make contact with part of your bubble. You can then hook the wire up to a MOSFET. You can then use a pin on your Arduino to pop the bubble almost instantly.
However, the time-to-pop depends very much on the film-thickness of the bubble, which in turn depends on how long the bubble has been waiting to be popped, the thickness of the original film used to create the bubble, and many other factors. In the end, these factors will throw your timings off my 10-100ms, which makes it an unreliable reference point..
I did attempt to use this method again later, but the current involved interfered with the circuit (we'll get to that).
I tried using a 2W 445nm laser as a bubble-popper, but somewhat to my surprise, this does not work at all. The thin film of the bubble just doesn't absorb enough of the blue light for it to cause rupture. It's too bad, too, because being able to rapidly pulse and zap bubbles, in a reliable way, opens up a lot of freedom in how you frame/construct shots.
I'm confident that a infrared laser, like a 40W CO2 laser, would work great for this task. But let's face it, it's way over-kill, and way dangerous.
With responsive triggering, we want the bubble to let us know when it's popping, rather than telling it when to pop and assuming it popped.
Using a the reflective/refractive properties of a bubble could make a laser trigger feasible. A laser could be setup to shine in such a way that a photo-transistor is only exposed when the bubble is intact. My tests indicated that this would be finicky, at best, and I pursued it no further.
Bubble as part of a circuit
This is the method I ended up using, and I'll devote an entire section to it. But the basic idea is to exploit the conductive properties of water (and the dissolved surfactants) to complete a circuit. When the bubble pops, the circuit is broken, and the Arduino is able to sense this.
Step 5: The Bubble Circuit
Because bubbles contain water and some ionic surfactants, they are (weak) conductors of electricity.
The low conductivity of the soap solution, and the thinness of the soap film mean they are very weak conductors. In practice, they can be treated as a high value resistor. I actually measured the resistance as the bubble dried out and eventually popped. For my solution, and the size of bubbles I was using, the resistance went from ~200K-ohms to 5 - 10 M - ohms.
Bubble Voltage Divider
The Arduino won't measure resistance directly, but the analog pins can measure voltage as a relative value (between 0-1024).
A voltage divider is a simple circuit that contains two resistors, a voltage in, and a voltage out (see the figure). The voltage out is a function of the voltage in, and the values of the two resistors:
voltage-out = voltage-in * R2 / (R1 + R2)
If R2 is a fixed value, then the voltage out measured decreases as R1 increases. In our case, R1 is the bubble, and R2 is a resistor or a series of resistors selected to be on the same order of magnitude as the bubble's resistance.
Picking R2 is important. It needs to be chosen such that the voltage seen by the Arduino is high enough to read as a digital "1" value when the bubble is in contact, and low enough to read as a "0" value when the bubble pops. This value will be dependent on yoursetup, but a 470K-ohm resistor worked for me.
You can see in the plots provided (using Arudino's built-in serial plotter) that as the bubble naturally thins, the voltage eventually drops to zero -- at which point the bubble has popped. On the other hand, if I pop the bubble with my finger, you can see the voltage rapidly drop.
After these tests, I felt confident that this signal could be used as a digital input, and switched my "bubble sense pin" from the analog pin to a digital input.
My work flow was simple. I blew a bubble between the sense loop and +12v loop such that they both made good contact. Then I pressed a button which armed the system. Then I'd pop the bubble.
In the code I implemented the bubble sense circuit as follows:
- Has button been pressed? Yes --> Check for bubble.
- Is the bubble circuit complete (is digital pin 12 high)? Yes --> Arm system.
- Is bubble popped (is digital pin 12 low)? No --> continue waiting
- Bubble popped! --> Trigger flash.
That's the basic idea. There are some variations built-in, too, to trigger the camera when the system arms, which gives the user a "window of opportunity" in which to pop the bubble.
In general, I found this method to be incredibly reliable. It's also very responsive. The very instant a disconnect in the circuit due to the bubble popping occurs, the flashes fire.
You can see how responsive this method is by looking at the images provided in this section. The images are exposed the moment a disconnect occurs at the sense pin.
Step 6: Circuit and Code
The circuit is a modification of the circuit I used for the droplet photography tutorial.
We still have controls for the camera shutter and and flash trigger through NPN transistors.
The main addition is the input for the bubble sense loop. As can be seen, I have the Arduino's digital pin connected to to "bubble sense" and a large value resistor going to ground. This is the voltage divider circuit discussed and demonstrated earlier.
I also added a button that I could use to "ready" this system. This way I blow a bubble, press the button, the system arms, and the bubble pops which triggers everything else.
The resistor values are:
10K-ohm for the pull-downs/pull-ups
470K-ohm for the bubble-sense pin (you'll need to experiment to find a good value for your setup)
The other additions are purely optional:
- I used an N-channel MOSFET to enable current flow through the nichrome wire.
- I used a small servo motor to act as a swing-axe bubble popper when making some time-delay sequences.
The code is simple and crude, but gets the job done. I've commented the code to explain what's going on, so I recommend looking there to see how the concepts discussed in this article were employed.
Step 7: Results
Given that I only played with this setup for a day, I'm pretty happy with the results I was able to achieve.
One thing to note about the bubble sense method we employed: the moment you capture will depend on where the bubble starts to pop. For example. if you pop a bubble 90-degrees from the sense point, the flashes won't fire until half the bubble has popped, as this will be when the connection is broken.
You can use this to your advantage to get some different effects! You can also play with the trigger delay timings to make some animated popping sequences. The difficulty here though is getting consistent bubble sizes.
Experiment! Have fun! Try different lighting conditions / flash positions / camera settings / bubble sizes / popping mechanisms.
And of course, share your results with me!