DIY 캐논 카메라 리모컨 및 수신기 만들기

2014. 11. 26. 19:082018년 이전 관심사/개발관련

반응형

DIY 캐논 카메라 리모컨 및 수신기 만들기

본 포스팅에서는 원격에서 캐논 카메라를 제어하기 위한 리모컨과 수신기를 만드는 방법을 설명한다.
리모컨은 Focus와 Shutter 기능을 지원하며 수신기와 스마트폰은는 Wi-Fi 통신을 사용한다.

시스템 구성

본 프로젝트의 구성 요소는 아래와 같다.

  • Camera

    • Receiver와 2.5pi Audio Cable을 이용하여 연결
  • Receiver

    • Arduino Uno(MCU) + WizFi250 (Wi-Fi Module)
    • WizFi250의 AP 기능을 사용 ( 별도의 유/무선 공유기 없이 스마트폰과 다이렉트로 연결 )
  • Remote Controller

    • Smart Phone ( LG G2 )
    • Simple Android App 구현

Camera + Receiver H/W 구성

캐논 카메라를 제어 할 수 있는 방법은 두가지가 있다.

  1. 2.5파이 오디오 잭을 이용하는 방법
  2. USB를 이용하는 방법

2번 방법은 캐논 카메라의 SD Card에 있는 사진을 불러 온다거나 설정 값들을 변경 할 수 있는 다양한 기능을 제어 할 수 있다.
하지만 내가 필요한 기능은 사진을 찍는 간단한 동작만 되면 되기 때문에 1번 방법을 사용하여 구현 하였다.

1번 방법은 아래 그림과 같이 오디오 잭의 모서리 금속과 마지막 금속을 접지 시키면 캐논 카메라의 Shutter가 눌려지는 동작을 하는 원리 이다.
또한 두번째 금속과 마지막 금속을 접지 하면 캐논 카메라가 포커스를 잡는다.

오디오 잭의 피복을 벗기면 빨강, 흰색, 금색 선을 볼 수 있다. ( 이 부분은 오디오 잭에 따라 다를 수 있으니 테스터기를 가지고 어느 선과 연결되어 있는지 확인 하는 것을 추천 한다.)

본 프로젝트에 사용된 오디오 잭은 빨간 석은 Shutter, 흰색 선은 Focus로 사용 할 수 있으며, 각각 Arduino Board의 D7번과 D6번에 연결 하였다.
아래는 Arduino Board와 WizFi250-EVB를 결합한 보드에 오디오 잭을 연결한 사진이다.

위와 같은 구성을 마치고 오디오 잭을 캐논 카메라에 연결하면 Camera와 Receiver의 H/W 구성은 끝이다.
(아래 사진과 같이 표시된 부분에 오디오 잭을 연결)

Receiver S/W 구성

본 프로젝트에서는 WizFi250의 AP 기능을 사용하려고 한다. WizFi250은 일반적인 유/무선 공유기에 접속하여 통신하는 Station 모드 이외에 AP 기능을 지원한다. WizFi250이 지원하는 AP 기능은 제한적이기 하지만 Device 2~3대 정도가 통신하기에는 적합하다.

아래는 Recevier S/W 구현으로 설정한 네트워크 환경을 나타내는 그림이다.

구현한 Arduino Code는 아래와 같다. 스마트폰과의 통신은 TCP를 이용하였고 프로토콜은 보는 것과 같이 아주 간단하다.
스마트폰으로 부터 ‘S’를 받으면 사진을 찍고 ‘F’를 받으면 Focus를 잡는다.

#include <Arduino.h>
#include <SPI.h>
#include <IPAddress.h>
#include "WizFi250.h"
#include "WizFi250_tcp_server.h"


#define SSID    "600D_AP"
#define KEY        "123456789"
#define AUTH    "WPA2"

#define FOCUS        6
#define SHUTTER        7
#define REMOTE_PORT    5000
#define LOCAL_PORT    5000

WizFi250    wizfi250;
IPAddress    ip(192,168,12,1);
IPAddress    subnet(255,255,255,0);
IPAddress    gateway(192,168,12,1);

void pinSetup();
void PushFocus();
void ReleaseFocus();
void PushShutter();
void ReleaseShutter();

boolean Wifi_setup = false;
WizFi250_TCP_Server myServer(LOCAL_PORT);

String str;

void setup()
{
    Serial.begin(9600);
    Serial.println("\r\nSerial Init");

    wizfi250.init();
    wizfi250.setDebugPrint(4);
    wizfi250.hw_reset();
    pinSetup();

    wizfi250.sync();

    wizfi250.setDhcp(ip,subnet,gateway);

    if( wizfi250.begin(SSID,KEY,AUTH,1) == RET_OK )
    {
        Wifi_setup = true;
    }

}

void loop()
{
    char cmd;

    if( Wifi_setup )
    {
        wizfi250.RcvPacket();

        if( myServer.isListen() != true )
        {
            myServer.listen();
        }

        if( myServer.available() )
        {
            cmd = myServer.recv();

            if( cmd == (uint8_t)'S')
            {
                ReleaseFocus();
                PushShutter();
                delay(500);
                ReleaseShutter();
            }
            else if( cmd == (uint8_t) 'F')
            {
                ReleaseShutter();
                PushFocus();
            }
            cmd = NULL;
        }
    }
}

void pinSetup()
{
    pinMode(FOCUS, OUTPUT);
    pinMode(SHUTTER, OUTPUT);

    digitalWrite(FOCUS, HIGH);
    digitalWrite(SHUTTER, HIGH);
}

void PushFocus()
{
    digitalWrite(FOCUS, LOW);
}

void ReleaseFocus()
{
    digitalWrite(FOCUS, HIGH);
}

void PushShutter()
{
    digitalWrite(SHUTTER, LOW);

}

void ReleaseShutter()
{
    digitalWrite(SHUTTER, HIGH);
}

스마트폰 S/W

스마트 폰 역시 Shutter 버튼과 Focus 버튼만 있는 아주 간단한 형태로 구현하였으며, 아래는  소스 코드 이다.

package com.example.canonremotecontrol;

import android.support.v7.app.ActionBarActivity;
import android.os.*;
import android.util.Log;
import android.view.*;
import android.widget.*;

import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.*;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnFocus = (Button)findViewById(R.id.focus_btn);
        btnFocus.setOnClickListener(new Button.OnClickListener(){
            public void onClick(View v){

                ConnectThread thread = new ConnectThread("192.168.12.1");
                thread.SetAction("F");
                thread.start();
            }
         });

        Button btnTake = (Button)findViewById(R.id.shutter_btn);
        btnTake.setOnClickListener(new Button.OnClickListener(){
            public void onClick(View v){
                ConnectThread thread = new ConnectThread("192.168.12.1");
                thread.SetAction("S");
                thread.start();
            }
        });
    }


    class ConnectThread extends Thread{
        String hostname;
        String m_action;

        public ConnectThread(String addr){
            hostname = addr;
        }

        public void SetAction(String action){
            m_action = action;
        }

        public void run(){
            try{
                int port = 5000;

                Socket sock = new Socket(hostname, port);
                OutputStream out = sock.getOutputStream();
                out.write(m_action.getBytes());
                out.flush();
                sock.close();
            } catch(Exception ex){
                ex.printStackTrace();
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
} 








반응형