ESP32 oder ESP8266 als Fernauslöser für eine Nikon Kamera in MicroPython - Teil 1 - AZ-Delivery

This manual is also available as PDF document

For my first cameras I had a cable release to avoid camera shake on the tripod. To be able to press the button at greater distances, I later added a pneumatic shutter release with a 3m hose. Today I replace wire and hose by infrared light and cell phone. In addition, I let the shutter release be actuated interval-controlled. This provides serial shots, which can be put together to a time-lapse movie. The circuit consists of just four parts and also the program for an ESP32 or ESP8266 is short and very clear, so a quick project for beginners from the series.

MicroPython on the ESP32 and ESP8266

today

The photo timer for the Nikon

The forefather of this project dates back to 2013, when I had programmed an AT-Tiny2313 with assembler to drive an IR LED with exactly the same signals as the original Nikon RC does. Of course the timer function was already integrated.

Figure 1: Nikon Timer

Image 1: Nikon Timer

How to get from the first measurements to the finished product, I show today with an ESP32S. But the program can be realized just as well with an ESP8266 D1 mini and its relatives without any changes, with the exception of the ESP8266-01, because the bug has too few legs.

Hardware

1

D1 Mini NodeMcu with ESP8266-12F WLAN module

or NodeMCU Lua Amica Module V2 ESP8266 ESP-12F

or ESP32 Dev Kit C unsoldered

or ESP32 NodeMCU Module WLAN WiFi Development Board

or NodeMCU-ESP-32S Kit

1

KY-040 Rotary encoder Rotary encoder module

1

KY-005 IR Infrared Transmitter Transceiver Module

1

0.96 inch OLED SSD1306 display I2C 128 x 64 pixel

1

KY-022 Set IR Receiver Infrared Receiver CHQ1838

1

Resistor 180 Ω

various

Jumper cable

1

Minibreadboard or

Breadboard Kit - 3 x 65pcs Jumper Wire Cable M2M and 3 x Mini Breadboard 400 Pins

1

Logic Analyzer

ESP32 or ESP8266 are both equally suitable for this project with one exception. The exception is the ESP8266-01 because it simply has too few GPIO lines leading out.

The software

For flashing and programming the ESP32:

Thonny or

µPyCraft

SALEAE - Logic analyzer software for Windows 8, 10, 11

Used firmware for the ESP8266/ESP32:

MicropythonFirmware

Please choose a stable version

ESP8266 with 1MB Version 1.18 Status: 25.03.2022 or

ESP32 with 4MB Version 1.18 Status: 25.03.2022

The version number is decisive for the implementation of the project.

The MicroPython programs for the project:

oled.py OLED front end

ssd1306.py OLED driver module

rotary.py Driver for angle encoder cross-port

rotary_irq_esp.py Driver for ESP32/ESP8266

ir_ausloeser.py Test program for the trigger sequence

nikon_timer.py Operating software

MicroPython - Language - Modules and programs

For the installation of Thonny you find here a detailed manual (english version). In it there is also a description how the Micropython firmware (state 05.02.2022) on the ESP chip. burned is burned.

MicroPython is an interpreter language. The main difference to the Arduino IDE, where you always and only flash whole programs, is that you only have to flash the MicroPython firmware once at the beginning to the ESP32, so that the controller understands MicroPython instructions. You can use Thonny, µPyCraft or esptool.py to do this. For Thonny, I have described the process here 

Once the firmware is flashed, you can casually talk to your controller one-on-one, test individual commands, and immediately see the response without having to compile and transfer an entire program first. In fact, that's what bothers me about the Arduino IDE. You simply save an enormous amount of time if you can do simple tests of the syntax and the hardware up to trying out and refining functions and whole program parts via the command line in advance before you knit a program out of it. For this purpose I also like to create small test programs from time to time. As a kind of macro they summarize recurring commands. From such program fragments sometimes whole applications are developed.

Autostart

If you want the program to start autonomously when the controller is switched on, copy the program text into a newly created blank file. Save this file as boot.py in the workspace and upload it to the ESP chip. The program will start automatically at the next reset or power-on.

Test programs

Manually, programs are started from the current editor window in the Thonny IDE via the F5 key. This is quicker than clicking on the Start button, or via the menu Run. Only the modules used in the program must be in the flash of the ESP32.

In between times Arduino IDE again?

If you want to use the controller together with the Arduino IDE again later, simply flash the program in the usual way. However, the ESP32/ESP8266 will then have forgotten that it ever spoke MicroPython. Conversely, any Espressif chip that contains a compiled program from the Arduino IDE or the AT firmware or LUA or ... can easily be flashed with the MicroPython firmware. The process is always like here described.

Contacting (Micro)Python

If you have already worked with the Arduino IDE, you may have had the urge to try out a command now and then to investigate its behavior. But there an interactive work with the system is not provided, I have already mentioned this above.

MicroPython as a descendant of the interpreter language C-Python behaves differently. You work in an IDE, an integrated development environment, with a direct line to a Python interpreter. In Python this tool is called REPL. This is an acronym for Read - Evaluate - Print - Loop. You make an input at the terminal, the MicroPython interpreter reads it, evaluates the input, returns a response and waits for the next input. The Windows command prompt, formerly MS-DOS, works according to the same scheme.

There are quite a few IDEs, Thonny, µPyCraft are two of them, Idle and MU are two others. I like to work with Thonny because besides the terminal (REPL) and a comfortable editor for creating and testing programs, it also has 12 wizards, a plotter and a tool for flashing the firmware. With REPL it is easy to test each instruction individually. We will try this out at various points in this manual.

One more thing is different with Python than with C or other compiler languages. There is no type specification when declaring variables or functions. MicroPython figures out the type itself. Let's test that right now. Start Thonny already. Input at the REPL prompt >>> I format as follows bold, the Answers from the system italic.

Identifiers for variables, constants, functions and other objects always start with a letter or an underscore, never with a number. MicroPython is case sensitive, so it is case sensitive. Here I assign the value 129 to the variable x, and the interpreter recognizes the type integer or int, the type of y is float.

 >>> x = 129
 >>> type(x)
 <class 'int'>
>>> y=23.7
>>> type(y)
<class float>

Everything in MicroPython is an object. x is an object of the class int, and y is one of the class float. Strictly speaking, the identifiers x and y are only references to the actual data, i.e. the numerical values in memory. There are quite a few more "secrets" about variables, but that should be enough background information for now.

Of course there are also strings.

>>> t="Hello friends!"
>>> type(t)
<class 'str'>

A very special data type is None. An object of it, also called instance, refers to nothing. You use None whenever you want to declare a variable but not yet set its value.

>>> r=None
>>> type(r)
<class 'NoneType'>

After the first walking tests we create an application that can time trigger a Nikon camera with an ESP8266 or ESP32, a rotary encoder, an IR transmitting diode and an OLED display.

We measure the "original" Nikon remote trigger

If you want to know which signals an IR remote control emits, you build a rudimentary receiver and irradiate it with the signals of the original device. This provides a sequence of pulses of different length. In their sequence the transmitted message is coded. But the matter is not quite that simple. We need a little background information, and that's where we'll start.

If only rectangular pulses were emitted by a RC (Remote Control), then the transmission would be very unstable because of the influence of daylight and room light. Therefore the RC sends so-called bursts, which are packets of a higher frequency carrier, in our case 38kHz. The duration of the bursts is determined by the length of the square wave signals to be transmitted. The pulses of the carrier frequency switch the IR LED on for the short time of about 13µs and off again for the same length of time.

Figure 2: Optical information flow with 38kHz carrier signal

Image 2: Optical information flow with 38kHz carrier signal

Only pulse packets with 38kHz carrier are converted by the receiver back into a square wave signal of the same width with inverted levels. Extraneous light can also be effectively suppressed by the IR pass filter on the receiver module.

With the help of the logic analyzer (LA), we will now determine the signals generated at E and measure them. The circuit is simple, so is the setup.

Figure 3: Nikon remote control signal sampling

Image 3: Signal sampling of the Nikon remote control

Figure 4: Nikon RC readout

Image 4: Nikon RC readout

As operating software for the LA I used the recommended program from SALEAE was used. It addresses the LA via a USB connection. A good description for installation and commissioning can be found in the article by Bernd Albrecht "Logic Analyzer - Part 1: Making I2C signals visible". This is how the pulse diagram of the Nikon RC looks like.

Figure 5: Original signal

Image 5: Original signal

The signal is already demodulated, the high frequency filtered out.

Figure 6: Nikon-RC - Measure pulse diagram

Image 6: Nikon-RC - Measure pulse diagram

The resting state of the receiver signal is 3.3V corresponding to a logic 1. During the LOW pulses the LED of the handheld transmitter fires.

The ESP clone of the handheld transmitter

Now we have to reproduce the pulse diagram. We have to invert the levels, i.e. at the times when the level in Figure 6 is at LOW, our controller has to fire with 38kHz bursts.

To do this, we are helped by a feature that was not yet present in firmware version 1.15 of MicroPython. So in this project, firmware 1.18 upwards is essential for it to work. This concerns both the ESP32 and the ESP8266.

In this release there are in the module machine module contains the function bitstream(), which is not yet included at least in the versions up to and including 1.15. Exactly this function supplies us namely with the 38kHz carrier signal. In figure 2 I have already calculated the period length to approx. 26.32µs = 26320ns. Pulse and pause are of the same length, i.e. 13160ns. Now we have a look at the syntax of the parameter list of the function bitstream() on this basis.

Bitstream(outPin, config, (high_time_0, low_time_0, high_time_1, low_time_1),data)
  • outPin: GPIO pin for clock output
  • config: 0 currently the only selectable
  • data: data bytes to be encoded

The following tuple contains two pairs of timings. 0 and 1 are usually encoded by pulses and pauses of different lengths. The following four values must in no case be understood as HIGH byte and LOW byte (MSB and LSB) of a 16-bit word. The 32-bit integer values give times in nanoseconds (1 - 10-9 s= 0.000000001s).

  • high_time_0: the pulse duration for a 0
  • low_time_0: the pause duration for a 0
  • high_time_1: the pulse duration for a 1
  • low_time_1: the pause duration for a 1

In the data selected by me no 0 occurs between two 1's, at best at the end of the byte sequence after the last 1. The assignment of the 4's tuple is therefore as follows:

(0,0,13160,13160)

The number of 1's in the bytes object data determines the width of the 38kHz burst. 1 byte of the form 0xFF contains 8 ones and therefore stands for 8 periods of the length 26.32µs. So for a width of 2060µs I need

2060µs / 26,32µs = 78,27 1-bits

with 8 bits per byte therefore

78.27 / 8 = 9.78 byte

0.78 byte corresponds to

0.78 - 8 = 6.26 bit

6 ones bits are filled up with 2 zeros and this results in

0b1111 1100 = 0xFC

The control at the DSO showed that this burst was a bit too long. The accuracy is given for the ESP32 or the ESP8266 with +/-30ns. So I shortened the value to 4 1-ns to 0xF0. The following instruction sets a burst of about 2060µs at the output GPIO17:

bitstream(out,0,(0,0,13160,13160),(b'\xff'*9)+b'\xf0')

For the pauses between bursts, I just let the controller sleep for a few microseconds. The sequence for triggering a photo now looks like this:

ir_trigger.py

from machine import Pin, bitstream
from time import sleep_us

out=Pin(17,Pin.OUT,value=0)

bitstream(out,0,(0,0,13160,13160),(b'\xff'*9)+b'\xf0')
sleep_us(27800)
bitstream(out,0,(0,0,13160,13160),(b'\xff'*1)+b'\xfe')
sleep_us(1580)
bitstream(out,0,(0,0,13160,13160),(b'\xff'*1)+b'\xfe')
sleep_us(3480)
bitstream(out,0,(0,0,13160,13160),(b'\xff'*1)+b'\xfe')
sleep_us(63100)

For testing we need a test circuit. This is immensely complex, it consists of just three parts. The anode of the IR emitting diode is connected to S, the cathode to minus. For the test I use GPIO17 as control output, I will change this later.

Figure 7: Nikon IR trigger - test circuit

Image 7: Nikon IR trigger - test circuit

Now load the program into an editor window. Turn on the camera and activate the IR remote trigger. If you point the IR diode at the Nikon's IR sensor, a shot will be triggered when you start the program. Isn't that spooky?

We could already save the program under the name boot.py and send it into the flash of the ESP32/ESP8266. If the circuit is then powered by a button, the program will start automatically and operate the trigger on the camera. We could do that, but we don't, because we have something much better in mind.

The Nikon Timer

It wouldn't be bad either if our IR shutter release could take continuous shots with the help of a timer. Of course, it should be possible to set different time intervals. This could be done with two buttons for up and down, but even better with an angle encoder. These are the parts that look like a potentiometer, but when you turn them you feel a raster. Here no resistance is adjusted, but switching contacts are closed and opened in a special way with a time delay. What comes out at the two connections of the switches in connection with the ground contact is the Gray code of the numbers 0 to 3. The special feature of the Gray code is that always only exactly one bit changes when counting up.

Now, of course, we want to have more than just four states, because we also want to be able to select more than just four time intervals. At this point a MicroPython module called rotary comes to our aid. Through the classes it contains, we get a counter that counts up and down arbitrarily. The module is licensed under the MIT license and can be used free of charge. Two modes are suitable for our purpose.

  • We could set the time intervals to the second by turning the knob. This is usable for times up to about 20s or 30s, but is ruled out for longer times.
  • The other variant, which I have chosen, allows the selection of a time interval from a preset of 24 times in a grid of seconds, minutes and hours.

And so that you can see what was set, I gave the circuit an OLED display. All together it looks like this in the schematic for the ESP32 and the ESP8266.

Figure 8: Nikon timer - complete circuit with ESP32

Image 8: Nikon-Timer - complete circuit with ESP32

Figure 9: Nikon timer - complete circuit with ESP8266

Image 9: Nikon-Timer - complete circuit with ESP8266

In order for the design to require only one program version for both the ESP32 and ESP8266, care had to be taken to ensure that the selected pins were available on both controllers and that they had the same functionality. With the ESP8266 this is not so easy, because different pins have to carry certain levels during the boot phase so that the controller starts. In addition, the GPIO pins must be interrupt-capable for querying the angle encoder. There is not much left for the ESP8266. The table provides information about the pin assignment for the ESP8266 D1 Mini.

Labeling

GPIO

Input

Output

Dimensioning

used as

D0

GPIO16

no IRQ

no PWM,

no bitstream,

otherwise OK

HIGH at boot

Connection with RST to wake up DEEP SLEEP


D1

GPIO5

OK

OK

SCL

I2C

D2

GPIO4

OK

OK

SDA

I2C

D3

GPIO0

pulled up

OK

Open or HIGH at startup,

Flash key against GND

key

D4

GPIO2

Pulled up

OK

HIGH at startup,

is connected via LED and resistor +Vcc

Pulse output

D5

GPIO14

OK

OK

SPI (SCLK)

CLK

D6

GPIO12

OK

OK

SPI (MISO)


D7

GPIO13

OK

OK

SPI (MOSI)

DT

D8

GPIO15

pulled down

OK

SPI (CS),

must be LOW at startup


RX

GPIO3

OK

RX pin

HIGH at startup,

serial REPL


TX

GPIO1

TX pin

OK

HIGH at startup,

serial REPL


A0

ADC0

Analog input

-

analog input up to 3.2V

220kΩ:100kΩ prescaler

As pulse output for the burst signals I chose GPIO2. The connection is via a resistor and a LED on +Vcc = 3.3V. In parallel to this is the resistor of 180 Ohm and with it the IR LED. The blue LED on the D1 board flashes briefly when the IR LED fires, too. This is enough to check the function.

The two switches in the rotary encoder are each pulled to Vcc with a 10kΩ resistor. When one switch closes, the connection led out is connected to GND potential.

Figure 10: Internal circuit of the angle encoder module

Image 10: Internal circuit of the angle encoder module

Clockwise rotation results in the following pulse diagram. The CLK connection is at the top, DT at the bottom.

Figure 11: Clockwise rotation

Figure 11: Clockwise rotation

The modules rotary_irq_esp.py and rotary.py take over the decoding of the direction of rotation and provide a counter whose properties can be set when calling the constructor of the class RotaryIRQ can be changed. These are the modes:

  1. Counting without limits
  2. Counting with lower and upper limit
  3. Stopping when reaching a limit
  4. Reversing the count when reaching a limit

I have decided to use mode 3, because it prevents the index limits of my list from being exceeded. delay is automatically prevented.

Now it is time for the construction of the hardware. It is then best to download the modules already and copy the same into the working directory of Thonny. From there, all four files must be moved into the Flash of the controller. To do this, select the files by holding down the CTRL key, then right-click on one of them and in the context menu select Upload to / click, confirm with OK.

Figure 12: Transfer modules to the flash

Image 12: Transfer modules to the flash

Then it is time to discuss the program nikon_timer.py. We start, as always, with the import business.

# nikon_timer.py
#
import sys
from rotary_irq_esp import RotaryIRQ
from time import sleep_ms,ticks_ms, sleep_us
from machine import SoftI2C, Pin, bitstream
from oled import OLED
from ssd1306 import SSD1306_I2C

rotary_irq_esp loads automatically the module rotary to inherit from it. From time we get some routines for time delay and time recording. The method bitstream() we fetch next to the I2C interface from machine. oled and ssd1306 we need to control the display.

Then we set the type of the controller and assign the variables for setting up the I2C interface accordingly.

chip=sys.platform
if chip == 'esp8266':
   # pin translator for ESP8266 boards
   # LUA pins D0 D1 D2 D3 D4 D5 D6 D7 D8
   # ESP8266 pins 16 5 4 0 2 14 12 13 15
   # SC SD
   SCL=Pin(5) # S01: 0
   SDA=Pin(4) # S01: 2
elif chip == 'esp32':
   SCL=Pin(21)
   SDA=Pin(22)
else:
   raise OSError ("Unknown port")

With the I2C interface set up, we instantiate the OLED display object right away.

i2c=SoftI2C(SCL,SDA)
d=OLED(i2c)

The following is the declaration of the GPIO pins for the button on the rotary encoder, the pulse output for the IR LED and the pulse generators on the encoder.

button=Pin(0,Pin.IN)  # D3
out=Pin(2,Pin.OUT,value=1)  # D4
CLK=14  # D5
DT=13   # D7

The list delay defines the time intervals for the timer in seconds.

delay=[
   86400,
   5,    10,    20,    30,    40,    50,    60,
   90,  120,   180,   240,   300,   360,   480,  600,
   900,1200,  1800,  2400,  3000,  3600,  5400, 7200,
  ]

With the help of the function TimeOut() I create a non-blocking software timer for the interval control. For this I pass the time duration in milliseconds. In the local variable start the current time in milliseconds is stored. TimeOut returns instead of a value a reference to the locally defined function compare() function. compare() is a so-called closure and it causes the variable start and the parameter t are retained even after the surrounding function TimeOut() is exited until further calls to compare(). Below you can see the application. Normally, locally created objects are destroyed after exiting the function, but not so with a closure.

def TimeOut(t):
   start=ticks_ms()
   def compare():
       return int(ticks_ms()-start) >= t
   return compare 

The sequence in the function trigger() we already know. The circuit of the IR-LED in figure 6 is HIGH-active. This means that the LED lights up, albeit invisibly, when the output is logically at 1 and electrically at 3.3V. However, after the burst sequence ends, the output remains at 0. At GPIO2, this would result in the LED on the ESP8266 board being on continuously, so to speak, during pauses. Therefore I changed the circuit of the IR-LED from HIGH-active to LOW-active for the connection to GPIO2. But now after finishing a burst with the output on LOW-potential the IR-LED would stay on. This is bad because then even during the pauses between triggering the camera, the IR LED is on and causes a higher current draw. For this reason I set the output to 1 after each burst. Thus both connections of the LED are on +Vcc and the LED is off, as well as the blue LED on the board. The latter flashes briefly when the IR LED fires as well. That's good!

Continuing with the program, I clear the OLED display and output the startup message.

d.clearAll()
d.writeAt("NIKON-TIMER",2,0,False)
d.writeAt("press button",2,4,False)
d.writeAt("to start",4,5)

It's time to instantiate the encoder object, assign the pins and set the limits. I must have connected the GPIOs the wrong way round, so I say reverse=True, because I don't feel like changing the schematics a fourth time. Turning clockwise counts up now in any case.

I catch up the start value of the encoder indexOld and start the interval timer with the interval time for one day, 86400 seconds. This is necessary so that now() is initialized as a function. The reference to the function compare() to the identifier now to the identifier. If I then now(), I actually call compare(). The return of this function is now as long Falseuntil the time in start t milliseconds have passed. After that the return value True.

indexOld = r.value()
now=TimeOut(delay[0])
while True:
   index = r.value()

   if indexOld != index:
       indexOld = index
       d.clearFT(0,2,d.width-1,2,False)
       d.writeAt("Break:{}s".format(delay[index]),0,2)
   if key.value() == 0:
       now=TimeOut(delay[index]*1000)
       trigger()
       print("photo")
       sleep_ms(1000)
   if now():
       now=TimeOut(delay[index]*1000)
       trigger()
       print("photo")
   sleep_ms(100)

It goes into the main loop and we get a value from the encoder again. If this value is different from the previously remembered one in indexOld, we remember the new one, delete line 2 of the display from beginning to end, read the time value to the new index from the list delay and write it to the display.

If the key on the rotary encoder was pressed, we start the interval timer with 1000 times the value from the list delay, compare() counts in milliseconds. The variable start is set to the current timestamp. A burst sequence is triggered, the terminal reports "photo" and we send the controller to sleep for one second.

The button can also be used to take photos without the timer. So that the timer does not interfere, it is appropriate to set the interval duration in this case to one day = 86400 seconds.

With now() I query the state of the timer. Only when the timer has expired, reports now() reports a True back. Then we reset the timer, trigger a capture and send "Photo" to the terminal.

100 milliseconds general pause and another loop round starts.

Here is the entire program text again in context. You can run the program nikon_timer.py of course also download it. Open it in an editor window of Thonny and start it with the function key F5.

# nikon_timer.py
#
import sys
from rotary_irq_esp import RotaryIRQ
from time import sleep_ms,ticks_ms, sleep_us
from machine import SoftI2C, Pin, bitstream
from oled import OLED
from ssd1306 import SSD1306_I2C

chip=sys.platform
if chip == 'esp8266':
   # pin translator for ESP8266 boards
   # LUA pins D0 D1 D2 D3 D4 D5 D6 D7 D8
   # ESP8266 pins 16 5 4 0 2 14 12 13 15
   # SC SD
   SCL=Pin(5) # S01: 0
   SDA=Pin(4) # S01: 2
elif chip == 'esp32':
   SCL=Pin(21)
   SDA=Pin(22)
else:
   raise OSError ("Unknown port")

i2c=SoftI2C(SCL,SDA)
d=OLED(i2c)

button=Pin(0,Pin.IN)  # D3
out=Pin(2,Pin.OUT,value=1)  # D4
CLK=14  # D5
DT=13   # D7

delay=[
   86400,
   5,    10,    20,    30,    40,    50,    60,
   90,  120,   180,   240,   300,   360,   480,  600,
   900,1200,  1800,  2400,  3000,  3600,  5400, 7200,
  ]
   
def TimeOut(t):
   start=ticks_ms()
   def compare():
       return int(ticks_ms()-start) >= t
   return compare  

def trigger():
   bitstream(out,0,(0,0,13160,13160),(b'\xff'*9)+b'\xf0')
   out(1)
   sleep_us(27800)
   bitstream(out,0,(0,0,13160,13160),(b'\xff'*1)+b'\xfe')
   out(1)
   sleep_us(1580)
   bitstream(out,0,(0,0,13160,13160),(b'\xff'*1)+b'\xfe')
   out(1)
   sleep_us(3480)
   bitstream(out,0,(0,0,13160,13160),(b'\xff'*1)+b'\xfe')
   out(1)
   sleep_us(63100)

d.clearAll()
d.writeAt("NIKON-TIMER",2,0,False)
d.writeAt("press button",2,4,False)
d.writeAt("to start",4,5)

r = RotaryIRQ(pin_num_clk=CLK,
             pin_num_dt=DT,
             min_val=0,
             max_val=24,
             reverse=True,
             range_mode=RotaryIRQ.RANGE_BOUNDED)

indexOld = r.value()
now=TimeOut(delay[0])
while True:
   index = r.value()

   if indexOld != index:
       indexOld = index
       d.clearFT(0,2,d.width-1,2,False)
       d.writeAt("Break:{}s".format(delay[index]),0,2)
   if key.value() == 0:
       now=TimeOut(delay[index]*1000)
       trigger()
       print("photo")
       sleep_ms(1000)
   if now():
       now=TimeOut(delay[index]*1000)
       trigger()
       print("photo")
   sleep_ms(100)

With the rotary encoder, set an interval time of 5 seconds and press the button. Now the blue LED on the ESP8266 D1 mini flashes briefly every 5 seconds and if a Nikon is switched on in the beam of the IR LED and set to remote release, a picture is taken every 5 seconds.

By the way, the Nikon timer took this selfie of himself - OK, OK, I held the camera, but at least he pressed the "button" himself:

Figure 13: Self-protrait Nikon timer

Image 13: Nikon Timer self portrait

View

The other day we had a family party and one of the guests demonstrated his latest achievement - taking pictures with a cell phone. Of course not with the cell phone, everyone can do that, but taking pictures with the SLR by means of the cell phone. This brings us back to the introduction of today's post. Only the pneumatic shutter release is replaced by the more contemporary wireless shutter release. In the next episode, we will use the WLAN property of the ESPs to design a remote shutter release using a cell phone app.

I'm sure you can think of a lot of things you can use a timer for, either manually or via radio control. I'm also thinking, for example, of a timer for exposing photo-coated circuit boards for the production of printed circuits.

But for now, I hope you enjoy experimenting with the rotary encoder and the photo timer.

See you then!

DisplaysEsp-32Esp-8266Projekte für anfänger

4 comments

Jürgen

Jürgen

Hallo, Daniel,
Da ich keine Z50 besitze, auch niemend in meinem Umfeld, kann ich nur eine Vermutung äußern. Ich denke, dass Nikon nicht für jeden Kameratyp eine eigene RC entwickeln wird. Mit hoher Wahrscheinlichkeit also ja, das müsste funktionieren.

Liebe Grüße
Jürgen

Daniel

Daniel

Hallo Jürgen,

funktioniert dieses Projekt auch bei der Z50 von Nikon?

Ganz liebe grüße,
Daniel

Jürgen

Jürgen

Hallo, Martin,

meine “Vorlage” ist keine Original-RC von Nikon, sondern ein Chinanachbau und hat keinen Druckpunkt wie die Kamera, aber das mit dem Scharfstellen klappt trotzdem. Ich denke, die Kamera macht das von sich aus. Ich halte es für unwahrscheinlich, aber es könnte theoretisch auch sein, dass die Entfernungseinstellung mit in der Pulsfolge codiert ist. Mit dem Empfang des IR-Burst stellt die Kamera jedenfalls scharf und etwa eine Sekunde später löst sie aus. Das funktioniert bei der D50, auch bei der D3200, und wohl auch bei den anderen Nikonmodellen.

Viele Grüße
Jürgen

Martin

Martin

Hallo Jürgen!

Großartige Idee, vielen Dank!
Ich werde das Projekt demnächst nachbauen.
Eine Frage habe ich jedoch: in einer Beschreibung des originalen IR-Fernauslösers von NIKON habe ich gelesen, dass der Auslöser einen Druckpunkt hat, genau wie der Auslöser an der Kamera. Damit kann vor dem Auslösen bereits der Autofokus aktiviert werden. Geht das auch mit dem Fernauslöser? Wird dann eine andere Sequenz gesendet?

Herzliche Grüße
Martin

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery