Skip to content

Concept Modeling

This phase is all about figuring out the DNA of the product and core technologies that will be elemental to the design.

Objectives

The objective is to explore potential solutions to creating interesting photography effects in the form factor of a DSLR lens hood. For the initial exploration, the focus will be to create a device that will fit on the Sony SEL50F18 50mm F/1.8 lens that I use with my Sony A7 body. This is a lens that I am familiar with and has the low aperture setting that can take advantage of the effects I am trying to produce.

SEL50 Lens

Prototype

CAD Exploration and Initial Layout

I started by creating a CAD model of the lens and lens hood to use as reference for the design. For the lens, I found a silhouette CAD image of the cross section of the lens. So I brought that into SolidWorks and traced with with lines and splines and revolved it to form the shape. I then mated that in an assembly to a rough CAD model of a Sony A7 series camera. Since I am not building anything onto the camera, the camera body is just for aesthetics of the model.

LensCad

CAD of the SEL50 lens

I then created a CAD surface of the lens hood and used that as the basis for the component layout. I inserted downloaded CAD of the XIAO board as that may be the ultimate controller device, roughed in a PCB for LEDs that would create the ring light as well as a ring of SK6812 side-emmitting addressable LEDs that would illuminate the lens hood extension. I then roughed in a back cover, a lens, and a lens hood extension. I also made a ring for a strip of 5050 addressable LEDs to slide over the hood extension that would simulate light injection from the side emitting LEDs, as I do not have any to experiment with currently. I also roughed in the shape of a curved LiPo battery for a potential power source.

Hood CM CAD

Concept model CAD and layout exploration

Lens Hood Geometry

I wanted to explore injecting light into the lens hood. So I focussed on making printable CAD for a replacement hood. I used calipers and 2D printer bed scan to extract the geometry of the locking mechanism for the hood. Then I created the geometry in CAD and made a few iterations of just the locking mechanism until I was able to get it to work.

Paint

I used paint pen to highlight the locking geometry areas of the factory lens hood before scanning

Scanning

Scanning the lens hood on a bed scanner

Scan CAD

Tracing the scanned geometry to create the lens hood locking geometry.

Hood Comparison

Comparison of 3 iterations of the locking ring geometry. The green ones were done first. I added some small cutouts to allow the tab to flex for the grey one and that made it work.

Vignette Hood Build

Once I figured out the locking mechanism I went ahead and finished the CAD for the lens hood. I then made a cylindrical protrusion of the hood that going forward would be a flexible component and may have accordion geometry to fold down. As I wanted to add a string of addressable LEDs, I added a ring around the hood extension to hold the LEDs around the outside diameter but allow moving them axially to test. I 3D printed all of the components and did a mechanical fit on the parts.

Adding Electronics

I wanted a way to drive the LEDs strip without having to change the code to modify the color output. I had a couple of Adafruit Circuit Playground Bluefruit boards and I found a sample project using the Bluefruit Connect app to change the colors and effects of an addressable LED strip. So, I used this as a jumping off point.

As my boards were pretty old, the device firmware on them was old, so I had to first use the Arduino IDE to flash from version 0.2 to 0.9. Then I was able to upload the Circuit Python code to the devices. I soldered up a string of 15 WS2812 addressable LEDs to pin A1 and tested the code with the app.

sBluetooth Controlled Room Lights Code
# SPDX-FileCopyrightText: 2020 Kattni Rembor for Adafruit Industries
# SPDX-FileCopyrightText: 2020 Erin St Blaine for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
Bluetooth Controlled Room Lights using a Circuit Playground Bluetooth
   Scroll between 7 modes and control brightness with your smartphone via Bluetooth
   Full tutorial: https://learn.adafruit.com/easy-no-solder-bluetooth-controlled-room-lights/overview
Code by Kattni Rembor & Erin St Blaine for Adafruit Industries
Adafruit invests time and resources to bring you this code! Please support our shop!
"""

# pylint: disable=attribute-defined-outside-init
# pylint: disable=too-few-public-methods

import board
import neopixel
from adafruit_led_animation.animation.solid import Solid
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.rainbow import Rainbow
from adafruit_led_animation.animation.rainbowcomet import RainbowComet
from adafruit_led_animation.animation.sparkle import Sparkle
from adafruit_led_animation.animation.sparklepulse import SparklePulse
from adafruit_led_animation.sequence import AnimationSequence
from adafruit_led_animation.group import AnimationGroup
from adafruit_led_animation.animation import Animation
from adafruit_led_animation.sequence import AnimateOnce
from adafruit_led_animation.color import (
    AMBER,
    ORANGE,
    WHITE,
    RED,
    BLACK,
    colorwheel,
)


from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.button_packet import ButtonPacket
from adafruit_bluefruit_connect.color_packet import ColorPacket

NUM_LEDS = 240                   # change to reflect your LED strip
NEOPIXEL_PIN = board.A1        # change to reflect your wiring

# Declare a NeoPixel object on NEOPIXEL_PIN with NUM_LEDS pixels,
# no auto-write.
# Set brightness to max, we'll control it later in the code
pixels = neopixel.NeoPixel(NEOPIXEL_PIN, NUM_LEDS, brightness=1.0,
                           auto_write=False,
                           #pixel_order=(1,0,2,3) #uncomment if using RGBW NeoPixels
                           )


ble = BLERadio()
uart_service = UARTService()
advertisement = ProvideServicesAdvertisement(uart_service)

class RainbowFade(Animation):
    ''' fades the entire strip through the whole spectrum '''
    _color_index = 150 # choose start color (0-255)
    def __init__(self, pixel_object, speed, name): # define animation
        super().__init__(pixel_object, speed=speed, color=WHITE, name=name)

    def draw(self): # draw the animation
        ''' fades the entire strip through the whole spectrum '''
        self.color = colorwheel(self._color_index + 1)
        self._color_index = (self._color_index + 1) % 256
        self.fill(self.color)

# ANIMATION DEFINITIONS --
#    create as many animations as you'd like and define their attributes here.
#    They can be a single line or a group of animations - the groups will play
#    at the same time, overlaid on top of each other.


readingLight = Solid(pixels, color=0xFF7D13) #warm white color HEX code
brightWhite = Solid(pixels, color=(150, 150, 150))
rainbow = Rainbow(pixels, speed=0.1, period=10, step=0.5)
rainbowfade = RainbowFade(pixels, speed=0.4, name="rainbowfade")
powerup = RainbowComet(pixels, speed=0, tail_length=50, bounce=False)
off = Solid(pixels, color=BLACK)

#startup animation will play just once
startup = AnimateOnce(powerup)

#starrynight and fire are animation groups with layered effects.
starrynight = AnimationGroup(
    SparklePulse(pixels, speed=0.01, color=(0, 0, 150), period=1),
    Comet(pixels, speed=0, tail_length=8, color=(150, 150, 150), bounce=False),)

fire = AnimationGroup(
    Comet(pixels, speed=0, tail_length=1, color=BLACK),
    Sparkle(pixels, speed=0.05, num_sparkles=10, color=AMBER),
    Sparkle(pixels, speed=0.05, num_sparkles=10, color=RED),
    Sparkle(pixels, speed=0.05, num_sparkles=20, color=ORANGE),
    Sparkle(pixels, speed=0.05, num_sparkles=5, color=0xFF7D13),
    Sparkle(pixels, speed=0.05, num_sparkles=10, color=BLACK),
    )

# Here is the animation playlist where you set the order of modes

animations = AnimationSequence(
        readingLight,
        fire,
        rainbow,
        starrynight,
        rainbowfade,
        brightWhite,
        auto_clear=True,
        )



MODE = 0

while True:
    if MODE == 0:  # If currently off...
        startup.animate()
        while startup.animate():
            pass
        MODE = 1
    # Advertise when not connected

    elif MODE >= 1:  # If not OFF MODE...
        ble.start_advertising(advertisement)
        while not ble.connected:
            if MODE == 2:
                pass
            elif MODE == 1:
                animations.animate()
    # Now we're connected

    while ble.connected:
        if uart_service.in_waiting:
            packet = Packet.from_stream(uart_service)
            # Color Picker Functionality
            if isinstance(packet, ColorPacket):
                MODE = 2
                # Set all the pixels to one color and stay there.
                pixels.fill(packet.color)
                pixels.show()
            # Control Pad Functionality
            elif isinstance(packet, ButtonPacket):
                if packet.pressed:
                    if packet.button == ButtonPacket.BUTTON_1:
                        MODE = 1
                        animations.activate(1)
                    elif packet.button == ButtonPacket.BUTTON_2:
                        MODE = 1
                        animations.activate(2)
                    elif packet.button == ButtonPacket.BUTTON_3:
                        MODE = 1
                        animations.activate(3)
                    elif packet.button == ButtonPacket.BUTTON_4:
                        MODE = 1
                        animations.activate(4)
                    # change the mode with right arrow
                    elif packet.button == ButtonPacket.RIGHT:
                        MODE = 1
                        animations.next()
                    elif packet.button == ButtonPacket.LEFT:
                        MODE = 4
                        off.animate()
                    #change the brightness with up and down arrows
                    elif packet.button == ButtonPacket.UP:
                        pixels.brightness = pixels.brightness + 0.1
                        pixels.show()
                        if pixels.brightness > 1:
                            pixels.brightness = 1
                    elif packet.button == ButtonPacket.DOWN:
                        pixels.brightness = pixels.brightness - 0.1
                        pixels.show()
                        if pixels.brightness < 0.1:
                            pixels.brightness = 0.1
        if MODE == 1:
            animations.animate()
        if MODE == 4:
            animations.freeze()

Once the board and code was verified, I drilled a couple of holes through the flare hood and mounted the Bluefruit chip. I found a 3xAAA battery box and double sided taped it to power the chip and the LEDs. I slipped the LED ring over the flare hood extension and gave it a test.

Proto

Completed first prototype of the device.

Proto

LEDs on.

Testing

I went ahead and gave it a test. I took a few photos with the device on the camera. The LEDs provided a very nice vignetting effect to the photos. The lens hood protruded into the frame ever so slightly and provided a good frame to the image.

However it did not provide the flaring effect that I was hoping for. So I had to go back to the drawing board for that. I still think the vignetting can be part of the final product so will keep this feature in mind going forward. Espcially if the flare hood is flexible and can manually be manipulated to create custom vignettes.

Sample Pics

Vignette effect of a picture of an orchid.

Sample Pics

Vignette effect of a picture of a 3D printer in the lab.