Shutter Speed

This experiment deals with how to determine the shutter speed of foto cameras. The code that I will use is not new. It is from the Faster Counter experiment. So if you want to understand why this code looks so strange and how it counts read this and its predecessor Fast Counter as well.

However if you just want to learn how to determine the shutter speed of your camera you may safely ignore both experiments and just copy the code.

//
//  www.blinkenlight.net
//
//  Copyright 2012 Udo Klein
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program. If not, see http://www.gnu.org/licenses/


#define COUNT_1                asm volatile ("out 0x09, r20");
#define COUNT_3    COUNT_1;    asm volatile ("out 0x09, r21"); COUNT_1;
#define COUNT_7    COUNT_3;    asm volatile ("out 0x09, r22"); COUNT_3;
#define COUNT_15   COUNT_7;    asm volatile ("out 0x09, r23"); COUNT_7;
#define COUNT_31   COUNT_15;   asm volatile ("out 0x09, r24"); COUNT_15;
#define COUNT_63   COUNT_31;   asm volatile ("out 0x09, r25"); COUNT_31;
#define COUNT_127  COUNT_63;   asm volatile ("out 0x09, r26"); COUNT_63;
#define COUNT_255  COUNT_127;  asm volatile ("out 0x09, r27"); COUNT_127;
#define COUNT_511  COUNT_255;  asm volatile ("out 0x03, r20"); COUNT_255;
#define COUNT_1023 COUNT_511;  asm volatile ("out 0x03, r21"); COUNT_511;
#define COUNT_2047 COUNT_1023; asm volatile ("out 0x03, r22"); COUNT_1023;
#define COUNT_4095 COUNT_2047; asm volatile ("out 0x03, r23"); COUNT_2047;

void count_8191() { COUNT_4095; asm volatile ("out 0x03, r24"); COUNT_4095; }

#define COUNT_16383  count_8191(); asm volatile ("out 0x03, r25"); count_8191();
#define COUNT_32767  COUNT_16383;  asm volatile ("out 0x06, r20"); COUNT_16383;
#define COUNT_65535  COUNT_32767;  asm volatile ("out 0x06, r21"); COUNT_32767;
#define COUNT_131071 COUNT_65535;  asm volatile ("out 0x06, r22"); COUNT_65535;
#define COUNT_262143 COUNT_131071; asm volatile ("out 0x06, r23"); COUNT_131071;
#define COUNT_524287 COUNT_262143; asm volatile ("out 0x06, r24"); COUNT_262143;
#define COUNT_524288 COUNT_524287; asm volatile ("out 0x06, r25");

#define TWICE(a) a a

void setup() {
    DDRD = 0b11111111; // set digital  0- 7 to output
    DDRB = 0b00111111; // set digital  8-13 to output
    DDRC = 0b00111111; // set digital 14-19 to output (coincidences with analog 0-5)

    // ensure we do not get interrupted during prescaler manipulation
    cli();

    // set clock prescaler as desired to slow down the timer
    // const uint8_t clock_prescaler_1   = 0;
    // const uint8_t clock_prescaler_2   = 1;
    // const uint8_t clock_prescaler_4   = 2;
    // const uint8_t clock_prescaler_8   = 3;
    // const uint8_t clock_prescaler_16  = 4;
    // const uint8_t clock_prescaler_32  = 5;
    // const uint8_t clock_prescaler_64  = 6;
    // const uint8_t clock_prescaler_128 = 7;
    const uint8_t clock_prescaler_256 = 8;

    // prepare to set clock prescaler: write CLKPCE bit to one and all the other to zero
    CLKPR = 1<<CLKPCE;
    // set clock prescaler immediately after preparing to do so
    CLKPR = clock_prescaler_256;

    // do not enable interrupts back again because we do not want
    // interrupts to slow us any down
}

void loop() {
     asm volatile ("ldi	r20, 0x01");
     asm volatile ("ldi	r21, 0x02");
     asm volatile ("ldi	r22, 0x04");
     asm volatile ("ldi	r23, 0x08");
     asm volatile ("ldi	r24, 0x10");
     asm volatile ("ldi	r25, 0x20");
     asm volatile ("ldi	r26, 0x40");
     asm volatile ("ldi	r27, 0x80");

    l0:
        TWICE(TWICE(TWICE(TWICE(TWICE(COUNT_524288)))));
    goto l0;
}

The important part here is that this code will blink the LEDs of the Blinkenlight Shield at different speeds like summarized in the table below (for a prescaler of 256). With other words the this code turns the Blinkenlight Shield into a display of a kind of digital stop watch.

LED Frequency [Hz] Period
0 15610.03 64.71 μs
1 7805.01 129.42 μs
2 3902.51 258.84 μs
3 1951.25 517.68 μs
4 975.63 1.04 ms
5 487.81 2.07 ms
6 243.91 4.14 ms
7 121.95 8.28 ms
8 60.98 16.57 ms
9 30.49 33.13 ms
10 15.24 66.26 ms
11 7.62 132.53 ms
12 3.81 265.05 ms
13 1.91 530.10 ms
14 0.9528 1.06 s
15 0.4764 2.12 s
16 0.2382 4.24 s
17 0.1191 8.48 s
18 0.0595 16.96 s
19 0.0595 33.93 s

So now how can this applied used to determine the shutter speed of a camera? After all this thing just blinks as you can see in the video.

The Trick is to take a picture of the Blinkenlight Shield while moving it in front of the camera. Or to take a picture of the shield while moving the camera. This will then result in a picture like this.

Shutter Speed Measurement

Shutter Speed Measurement

The green marks were added by me afterwards with a graphics editor. The point here is that there are exactly 8*4 = 40 ticks of LED 3 in this picture. Since LED 3 blinks with a period length of ~517.68μs it follows that this picture had an exposure time of 40*517.68μs = 20.70ms. Please notice that this is at the limit of the picture resolution so I may be ~1 tick off the mark. If you look at LED 4 you see only 19 blinks with a period length of ~1.04ms which implies 19.74ms. It follows that this picture was exposed 20ms (+/- 1ms) which matches the camera setting of 1/50s.

The same technique can also be used for speed measurements. Below is a picture with considerably longer exposure time. This time my goal was not to measure the shutter speed but to measure the speed of the Blinkenlight Shield moving in front of the camera. In order to infer the speed I need a time reference (the blinking LEDs) and a length reference. As it turns out the outermost edges of LED 0 and LED 19 delimit a distance of 5cm.

So I inverted a rectangle in the picture (this is the white thing on the left), rotated it by 90 degrees and pasted it back. Then I added the green markers. The “time distance” of the green markers is 10 ticks of LED 1 or 1.2942ms. Thus the 5cm pass by in about 128 ticks or 16.565ms. Thus the speed was 5cm/16.565ms = 3,018m/s = 10,87km/h = 6,75mph.

Speed Measurement

Speed Measurement


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s