Следящий фокус для зеркалки. Raspberry Pi + HC-SR04 + SG90 servo +17


Данный пост описывает как за один вечер из говна и палок был сделан следящий фокус для зеркали. Видео того что получилось:


Предисловие


Малина здесь избыточна, бесспорно. Но если речь идет о более сложном устройстве у которого следящий фокус является лишь одной из функций, то почему нет.

Я не придумал ничего нового, просто взял и сделал за один вечер. Результат мне понравился, поэтому хочу поделиться с сообществом.

Механика, крепление


Для меня всегда камнем преткновения является механика. Найти говно и палки под руками, которые совместимы друг с другом, при этом позволят добиться поставленной цели — бывает сложно. Но в этот раз мне повезло.

Выглядит прототип примерно так:



В качестве шестерни на оси сервака я использовал крышку от коробки молока на которую приклеил остаток хомута-шестерни для объектива зеркалки. Крышка от молока в моем случае оказалась оптимального диаметра для регулировки у 50мм объектива. «Шестерню» приклеил с помощью цианоакрилата с содой к одному из коромысел идущих в комплекте к серво и прикрутил винтом. Для крепления конструкции к зеркалке надо винт с дюймовой резьбой, такой у меня нашелся от штатива-осьминога.

В общем, конструкция как-то сама собой воплотилась в реальность:



Без стяжек нынче сложно. Синяя изолента закончилась и пришлось крепить датчик на бумажный скотч.

Электроника


В качестве мозгов у меня выступает Raspberry Pi 3. Серво запитываю отдельным блоком питания на 24VDC с DC-DC Step Down преобразователем на LM2596 микросхеме на выходе которого 7.2В.
Алгоритм работы прост до безобразия. Есть обратная связь по расстоянию до объекта от ультразвукового дальномера HC-SR04, которая преобразуется в угол поворота сервы SG-90. На оси сервы закреплена «шестеренка» которая вращает объектив через хомут-шестерню устанавливая фокусное расстояние.

Код


Подключение ультразвукового датчика описано здесь. Управление сервой сделано с помощью аппаратного ШИМа, настройку брал здесь.

Код получился весьма скромный, но это лишь начало и нет предела совершенству.

#Libraries
import RPi.GPIO as GPIO
import time
from subprocess import call

from RPIO import PWM
servo = PWM.Servo()

#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)
 
#set GPIO Pins
GPIO_TRIGGER = 18
GPIO_ECHO = 24
 
#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
 
def distance():
    # set Trigger to HIGH
    GPIO.output(GPIO_TRIGGER, True)
 
    # set Trigger after 0.01ms to LOW
    time.sleep(0.00001)
    GPIO.output(GPIO_TRIGGER, False)
 
    StartTime = time.time()
    StopTime = time.time()
 
    # save StartTime
    while GPIO.input(GPIO_ECHO) == 0:
        StartTime = time.time()
 
    # save time of arrival
    while GPIO.input(GPIO_ECHO) == 1:
        StopTime = time.time()
 
    # time difference between start and arrival
    TimeElapsed = StopTime - StartTime
    # multiply with the sonic speed (34300 cm/s)
    # and divide by 2, because there and back
    distance = (TimeElapsed * 34300) / 2
 
    return distance
 
if __name__ == '__main__':
    try:
        while True:
            dist = distance()
            if dist <=40:
                focus = 900
            elif dist <= 70:
                focus = 900+int(dist-40)*20
            else:
                focus = 2000
            servo.set_servo(23, focus) 
            print ("Measured Distance = %.1f cm, focus = %3i" % (dist, focus))
            time.sleep(0.1)
 
        # Reset by pressing CTRL + C
    except KeyboardInterrupt:
        print("Measurement stopped by User")
        servo.stop_servo(23)
        GPIO.cleanup()


Для определения соответствия угла поворота серво фокусному расстоянию я сделал несколько калибровочных измерений, в результате получил линейную зависимость на интересующем участке (40-70см), остальное принял за фокус в бесконечность.

Заключение


На мой взгляд, даже самые дешевые серваки SG-90 на многое способны, 1.2кг/см штока для такой малютки, да еще и с такой скоростью — это круто, тем более за цену в 1.5 бакса. То же самое касается и ультразвукового дальномера.

П.С. Серваком можно управлять и отдельно от датчика, например делать быстрые переходы от одного объекта до другого с разным фокусным расстоянием. Также для улучшения работы системы можно дописать фильтр, который будет компенсировать недостатки измерения ультразвукового датчика.




К сожалению, не доступен сервер mySQL