Nikola Tesla 3D print

How To Make A Wireless DSLR Remote Shutter and Make a Time-lapse – Part 1

This is part 1 of a 2-part post on making a Wireless/Wifi Remote Shutter for any DSLR and creating a time-lapse of a 3D print.  Part 1 contains the Wireless Shutter construction, while Part 2 deals with the Time-lapse portion. When you’re done with Part 1, please click over to Part 2.

The Itch

After watching several (dozen) time-lapse videos of 3D prints on YouTube, I concluded that I had to make one or two for myself.  Something is hypnotizing about these videos, but there’s something equally attractive in learning the technical details behind making such a video.

There’s a lot of technical know-how behind making a time-lapse, from synchronizing your camera’s shutter and a 3D printer to compiling individual images from a camera into a time-lapse video.  And if you have an expensive DSLR that you want to use, how do you trigger it?

As you’ll see below, I used a combination of free software, electronics and a microcontroller to add WIFI triggering to my older DSLR. Next, I will lay out all the steps required to get yourself up and running with a similar setup to mine, using OctoPrint and OctoLapse. Finally, I’ll provide you with custom software to run on the microcontroller, along with instructions on how to make it all work together.

The Thought Process

So, I thought about it for a while, and I concluded that I needed a few things:

  1. One 3D printer
  2. A quality camera
  3. A way of triggering the camera when each layer of the print completes

1. I have a 3D printer, a Creality Ender 3 V2, which I really like.  It was a Christmas gift from my wife, or at least that’s what I told her.

2. I have a few cameras lying around, including a webcam and some point-and-shoot style models.

But my main camera is a Pentax K5 DSLR.  Operating at 16MP and styling some nice glass, I should be able to produce high-quality, sharp images that will produce a tack-sharp time-lapse video.  And with that much detail in each frame, I can Pan and Zoom to my heart’s content.

3. We need A way to trigger the camera

With my DSLR nearing its 10th birthday, my remote triggering options are limited. On my camera, my trigger options are an IR sensor and a standard 2.5mm shutter port.  I use a Canon-branded locking shutter with my Pentax K5, so designing something to use this port should be doable.

A Large Problem

How do you get a DSLR to take a picture at regular intervals, which just so happens to coincide with the completion of each layer of a 3D print?  Intervalometers can trigger your DSLR at regular intervals, but we need one that can be told when a new layer has been printed.  Our solution requires our 3D printing software to signal the camera when it’s time to take a shot.

The Micro Solution

A wireless DSLR shutter trigger using an ESP32 microcontroller (or an ESP8266) seems like a no-brainer for a project like this.  These system-on-a-chip modules are cheap, have a dual-core CPU running at 160MHz and 80MHz, respectively and have several programmable General Purpose Input/Output (GPIO) pins.  But, the most interesting part of these modules is that they have built-in WiFi!

Using the GPIO pins of these modules is pretty easy and quite powerful.  When combined with a little programming and Wifi, we can trigger a DSLR with the GPIO pins.  And via Wifi, we can command our ESP32 to focus and take a shot.

Bill of Materials

esp32 node mcu


An ESP32 (or esp8266)
OctoPrint Logo


Running on a Raspberry Pi




Standard 2.5mm pitch breadboard.


Check Prices
quick disconnects


These connectors allow you to easily connect and disconnect power to your breadboard.

3-way Connector

Check Prices
2n2222a transistor


You need 2 of these transistors
1Kohm resistor

1K-ohm resistors

You need 2 of these resistors

1K-ohm Resistor

Check Prices
1Kohm resistor

470-ohm resistor

You need 2 of these resistors

470-ohm Resistor

Check Prices
1Kohm resistor

220-ohm resistors

You need 3 of these resistors

220-ohm Resistor

Check Prices
2.5mm TRS Male Jack

2.5mm Male Plug

2.5mm Male Jack

Check Prices
Raspberry Pi 3 B+

Raspberry Pi

At least a model 3 or better

Raspberry Pi 3B+

Check Prices

Schematic Diagram

Electronic Schematic Diagram of Shutter Trigger

The shutter trigger circuit uses a standard 2.5mm male TRS (Tip-Ring-Sleeve) plug.  They contain 3 conductors for Shutter Trigger, Focus Trigger and Ground connection.  To make our camera do something, we need to short the Shutter or Focus conductor to the ground conductor.

Trip Shutter: Connect Red Conductor to the Black Conductor

Trip Focus: Connect White Conductor to the Black Conductor.

My design uses a transistor to temporarily short the Shutter or Focus conductor to the black conductor.  The ESP32 sets a GPIO pin HIGH which now supplies 3.3V through a resistor to the base of the transistor, turning it fully ON.  Once the transistor is ON, it actively shorts out its Collector/Emitter pathway, shorting out the RED to BLACK or WHITE to BLACK pathways.

Wireless Shutter Prototype

The circuit features two status LEDs.  The first is an RGB LED using 3 GPIO pins to turn each of the colours on or off.  The 2nd LED is tied directly to the base of the shutter’s transistor, indicating shutter activation.

This electrical circuit is what makes it possible for our microcontroller to control the DSLR. With a little programming, we can now Focus our camera and Trigger the shutter.  But, just as importantly, we can program the microcontroller to enable Wifi and accept commands from your computer or smartphone.

Programming the ESP32

Now that we have our circuit built on a breadboard, it’s time to talk about the software we’re uploading to the ESP32 microcontroller. 

To do the programming, I use Visual Studio Code in combination with PlatformIO.  VSCode provides a work environment with IntelliSense and support for most programming languages, while PlatformIO provides the tool-chain for nearly any microprocessor, including ESP32, ESP8266 and other Arduino compatible boards.  PlatformIO also provides a library manager with access to thousands of excellent libraries for nearly any programming task you come across.

We’re using good ‘old C++ for our programming.  It’s an established language with a long heritage and broad support on the ESP32.

From here on, I’m assuming you have VSCode and PlatformIO installed.  If not, there are great guides on the respective websites to get you going.

We need to add a library to our code called aREST by Marco Schwartz.  To do this, you need to add the following lines to your platformio.ini file, found in your SRC folder.


					lib_deps =
     marcoschwartz/aREST @ 0.0.0-alpha+sha.0e6b782568    


If you have more than one library dependency, write them out on separate lines, like so:

					lib_deps = 
     marcoschwartz/aREST @ 0.0.0-alpha+sha.0e6b782568    
     knolleary/PubSubClient @ ^2.8

Next, download WifiConnector.h and save it to the same folder as main.cpp.

Now download and copy main.cpp to the same folder as WifiConnector.h:

Don’t forget to fill in your own WIFI details on line 24:

WifiConnector MyWifi(“MY_SSID”, “MY_PASSWORD”);

Once you have main.cpp, WifiConnector.h and platformio.ini set up, you’re ready to compile and upload the firmware to your ESP32, but first, let’s discuss the software.

How The Software Works

Here’s how my software puts the pieces together:

First, we define the hardware GPIO pins.

					#define GPIOPin_Shutter 4
#define GPIOPin_AutoFocus 33
#define GPIOPin_LED_Red 27
#define GPIOPin_LED_Green 32
#define GPIOPin_LED_Blue 18

Then, we create a few variables to help out. Specifically, we’re using the aREST library, a Webserver and a helper class to connect our Wifi. 

					aREST rest = aREST();
WiFiServer server(80);

WifiConnector MyWifi("MY_SSID", "MY_PASSWORD");

And we need to define duty times for our Shutter and Focus pins.  In other words, how long should they be ON before being turned off?  

					int ShutterOnTime = 400;
int FocusOnTime = 1000;

We need to define a few functions to turn the shutter on or focus the camera.  Those functions will be called automatically by the aREST interface.

					// Called automatically by the aRest system when this url is requested :
int aRest_Focus(String command)

// Called automatically by the aRest system when this url is requested :
int aRest_Shutter(String command)


Calling SetShutterPin(true, true) turns ON the shutter GPIO pin and allows an automatic turn-off after several milliseconds.  The amount of time the shutter pin stays on is in the variable ShutterOnTime, which defaults to 400mS.

The way we register our functions to be called automatically by the aREST interface is like this:


Normally these lines might go in your setup() function as I did.

Now we can trigger our custom functions automatically when someone visits the following URLs (replace these IP addresses with your own ESP32’s IP address):


To keep our aREST interface operational, we need to give it some attention in our loop() function.

					// Take care of aRest Server
WiFiClient client = server.available();
    if (client) {

First, we see if our Webserver has a client connected (a browser).  If so, we wait until the client is ready with the request, then pass it off to the aREST interface using the handle() function.

This is when our custom functions aRest_Shutter() and aRest_Focus() will be called.

Upload the Software and Test the Wireless Shutter

When you are finished modifying the source code to work with your wifi, you can upload it to your ESP32 with CTRL+ALT+U.  This automatically builds the firmware and uploads it via your USB port to the ESP32.

When your wireless shutter starts up, it goes through a series of steps as it connects to your Wifi access point.  The status LED starts off RED and will turn GREEN when successfully connected and ready to accept commands.  If you’re monitoring the serial port with the built-in PlatformIO monitor, then you’ll also see a series of messages printed to the screen, including the ESP32’s IP address.  This brings me to the next subject…

Find Your ESP32's IP Address

There are multiple ways to determine the IP address of your ESP32.

Using VS Code and PlatformIO Serial Monitor

If you are connected to your ESP32 with a USB cable, you can monitor the bootup sequence of the PlatformIO Serial Monitor IconESP32. At the bottom left of the screen in VS Code, click the Serial Monitor icon to open the PlatformIO Serial Monitor.  Press your ESP32’s Restart button and watch as your IP address is printed on the screen.

Using a Network Scanner

Suppose your ESP32 isn’t connected to a computer, no worries.  You can still use a network scanner to find your ESP32 on the local network.  Personally, I’ve used FING for years. It’s available here:

Look At Your Router’s DHCP Tables

If you have access to your router, you can inspect your DHCP’s server’s IP lease table. Look for an entry with the hostname “espressif” or something similar.

While you’re in there, you may as well add a static lease on your ESP32, so it does not change IP addresses upon reboot.

In your browser address bar, using your own ESP32’s IP address, enter the following:

You should see the status LED turn Red momentarily (approximately 1000mS).  If so, we have completed a successful Focus test of the software.

Next, try issuing the following in your browser address bar:

This time, the status LED should light up Blue, and the shutter LED itself will turn blue too.  The shutter LED is connected to the same GPIO pin as the GPIO_Shutter pin, number 4, by default.  In other words, as long as the shutter circuit’s transistor is powered on, the shutter LED will be lit.

If you’re happy with the tests and all went well, you can move to the next step, testing with your DSLR.

Connect the 2.5mm plug into your DSLR’s shutter port. Next, turn your camera on and repeat the Focus and Shutter tests.  Your camera should now focus and take a photo without you touching it.

About MQTT and HTTP Support

MQTT is a messaging protocol that uses a client and a broker/server scheme.  Clients can publish messages via the broker on topics and subscribe to receive messages from topics.  This way, a machine could publish its status as it performs some work. Any number of clients could be listening to the machine and acting accordingly.  For example, if the machine goes down, a client program could page a millwright.

Originally I wrote the software to use MQTT rather than an HTTP/Rest interface.  The MQTT functionality is still present but has been remarked out as I added HTTP support.  Feel free to experiment with MQTT and the Wifi Shutter.

If you enable MQTT support, the Wifi shutter subscribes to the topics dslr/focus and dslr/shutter.   You only need to publish a message on these topics to trigger the focus and shutter.

If you decide MQTT is for you,  go check out Node-Red. It supports MQTT and HTTP which means, Node-Red makes a great controller for your wireless shutter.

By the way,  MQTT and HTTP run happily side by side on the same device.

The following two files are ONLY required IF you decide to use MQTT.  Apart from that, you can safely ignore them.

Here’s a very short teaser video showing me testing my camera’s synchronization with OctoLapse.  Everything looks like it’s working.

If you want to see how this Wifi Shutter can be used in a 3D print time-lapse, you need to read the next post!  I’ll even show you how to use the very best free video editing software to turn your still pictures into a video file. And if you feel adventurous, the software I’m recommending will let you add pan, zoom and other animations.

This is part 1 of a 2-part post on making a Wireless/Wifi Remote Shutter for any DSLR and creating a time-lapse of a 3D print.  Part 1 contains the Wireless Shutter construction while Part 2 deals with the time-lapse portion. When you’re done with Part 1, please click over to Part 2.