Skip to content

Commit e502cb8

Browse files
author
Kevin J Walters
committed
Adding yellow warning colour for impending shutter release 2 seconds before firing for intervalometer mode.
Using right button in manual mode to toggle use of NeoPixels. Halving red NeoPixel colour as it is bright. Minor code re-arranging and docs.
1 parent 42ba1e3 commit e502cb8

File tree

1 file changed

+67
-34
lines changed

1 file changed

+67
-34
lines changed

cpx/cpx-ir-shutter-remote.py

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
### cpx-ir-shutter-remote v1.0
1+
### cpx-ir-shutter-remote v1.1
22
### Circuit Playground Express (CPX) shutter remote using infrared for Sony Cameras
3-
### TODO - describe in more detail
43

54
### copy this file to CPX as code.py
65

@@ -26,6 +25,19 @@
2625
### OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2726
### SOFTWARE.
2827

28+
29+
### This uses the Circuit Playground Express with its onboard infrared LED
30+
### to send the shutter release codes
31+
32+
### If the switch is to the left then the shutter fires when the left button is pressed
33+
### together with a brief flash of Neopixels.
34+
### The right button can be used to toggle the use of NeoPixels.
35+
36+
### If the switch is to the right then the CPX functions as an intervalometer
37+
### with the shutter being fired on a timer after each interval
38+
### The default interval is thirty seconds and this can be changed
39+
### by reduced with the left button and increased with the right button
40+
2941
import time
3042

3143
import pulseio
@@ -34,82 +46,103 @@
3446
from adafruit_circuitplayground import cp
3547

3648

37-
debug = 1
38-
39-
def d_print(level, *args, **kwargs):
40-
"""A simple conditional print for debugging based on global debug level."""
41-
if not isinstance(level, int):
42-
print(level, *args, **kwargs)
43-
elif debug >= level:
44-
print(*args, **kwargs)
45-
46-
47-
### 40kHz modulation (for Sony)
48-
### with 20% duty cycle (13107 out of 65535)
49+
### 40kHz modulation (for Sony) with 20% duty cycle
4950
CARRIER_IRFREQ_SONY = 40 * 1000
5051
ir_carrier_pwm = pulseio.PWMOut(board.IR_TX,
5152
frequency=CARRIER_IRFREQ_SONY,
52-
duty_cycle=13107)
53+
duty_cycle=round(20 / 100 * 65535))
5354
ir_pulseout = pulseio.PulseOut(ir_carrier_pwm)
5455

55-
5656
### Sony timing values (in us) based on the ones in
5757
### https://github.com/z3t0/Arduino-IRremote/blob/master/src/ir_Sony.cpp
5858
### Disabling the addition of trail value is required to make this work
59-
### trail=0 does not work
59+
### trail=0 did not work
6060
ir_encoder = adafruit_irremote.GenericTransmit(header=[2400, 600],
6161
one= [1200, 600],
6262
zero= [600, 600],
6363
trail=None)
6464

65-
SHUTTER_CMD_COLOUR = (16, 0, 0)
65+
def fire_shutter():
66+
"""Send infrared code to fire the shutter.
67+
This is a code used by Sony cameras."""
68+
ir_encoder.transmit(ir_pulseout, [0xB4, 0xB8, 0xF0],
69+
repeat=2, delay=0.005, nbits=20)
70+
71+
72+
SHUTTER_CMD_COLOUR = (8, 0, 0)
73+
IMPENDING_COLOUR = (7, 4, 0)
6674
BLACK = (0, 0, 0)
6775

6876
S_TO_NS = 1000 * 1000 * 1000
6977
ADJ_NS = 20 * 1000 * 1000
78+
IMPENDING_NS = 2 * S_TO_NS
7079
intervals = [5, 10, 15, 20, 25, 30, 60,
7180
120, 180, 240, 300, 600, 1800, 3600]
7281
interval_idx = intervals.index(30) ### default is 30 seconds
7382
intervalometer = False
7483
last_cmd_ns = None
7584
first_cmd_ns = None
85+
pixel_indication = True
86+
impending = False
7687

77-
###encoder.transmit(pulseout, [0x12, 0xB8, 0xF0], nbits=20) ### start video
7888
while True:
79-
if cp.switch: ### switch to left
89+
### CPX switch to left
90+
if cp.switch:
8091
intervalometer = False
8192
if cp.button_a: ### left button_a
82-
cp.pixels.fill(SHUTTER_CMD_COLOUR)
93+
if pixel_indication:
94+
cp.pixels.fill(SHUTTER_CMD_COLOUR)
8395
last_cmd_ns = time.monotonic_ns()
84-
ir_encoder.transmit(ir_pulseout, [0xB4, 0xB8, 0xF0],
85-
repeat=3, delay=0.005, nbits=20) ### shutter
96+
fire_shutter()
8697
if first_cmd_ns is None:
8798
first_cmd_ns = last_cmd_ns
8899
print("Manual", "shutter release at", (last_cmd_ns - first_cmd_ns) / S_TO_NS)
89-
cp.pixels.fill(BLACK)
100+
if pixel_indication:
101+
cp.pixels.fill(BLACK)
90102
while cp.button_a:
91103
pass ### wait for button release
92-
93-
else: ### switch to right
104+
105+
elif cp.button_b:
106+
pixel_indication = not pixel_indication
107+
while cp.button_b:
108+
pass ### wait for button release
109+
110+
### CPX switch to right
111+
else:
112+
if not intervalometer:
113+
last_cmd_ns = time.monotonic_ns()
114+
intervalometer = True
115+
94116
if cp.button_a and interval_idx > 0:
95117
interval_idx -= 1
96118
while cp.button_a:
97119
pass ### wait for button release
120+
98121
elif cp.button_b and interval_idx < len(intervals) - 1:
99122
interval_idx += 1
100123
while cp.button_b:
101124
pass ### wait for button release
102-
125+
126+
### If enough time has elapsed fire the shutter
127+
### or show the impending colour on NeoPixels
103128
now_ns = time.monotonic_ns()
104-
if (not intervalometer
105-
or now_ns - last_cmd_ns >= intervals[interval_idx] * S_TO_NS - ADJ_NS):
106-
intervalometer = True
107-
108-
cp.pixels.fill(SHUTTER_CMD_COLOUR)
129+
interval_ns = intervals[interval_idx] * S_TO_NS
130+
if now_ns - last_cmd_ns >= interval_ns - ADJ_NS:
131+
if pixel_indication:
132+
cp.pixels.fill(SHUTTER_CMD_COLOUR)
109133
last_cmd_ns = time.monotonic_ns()
110-
ir_encoder.transmit(ir_pulseout, [0xB4, 0xB8, 0xF0],
111-
repeat=3, delay=0.005, nbits=20) ### shutter
134+
fire_shutter()
112135
if first_cmd_ns is None:
113136
first_cmd_ns = last_cmd_ns
114137
print("Timer", "shutter release at", (last_cmd_ns - first_cmd_ns) / S_TO_NS)
138+
if pixel_indication:
139+
cp.pixels.fill(BLACK)
140+
impending = False
141+
142+
elif (pixel_indication
143+
and not impending
144+
and now_ns - last_cmd_ns >= interval_ns - IMPENDING_NS):
145+
cp.pixels.fill(IMPENDING_COLOUR)
146+
time.sleep(0.1)
115147
cp.pixels.fill(BLACK)
148+
impending = True

0 commit comments

Comments
 (0)