위즈네트 아카데미

TUTORIAL

튜토리얼

Home  > 튜토리얼

Wireless WizFi250 활용 캐논 카메라 리모콘 및 수신기 만들기

WIZnet Academy 2014.12.12 13:29 조회 수 : 21

위즈네트의 연구원 곽동은 마스터가 WizFi250 을 활용하여 캐논 카메라용 무선 리모콘 시스템을 제작하여, 그 방법을 소개합니다.

시스템 구성


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

  • 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 구현
    Canon_4


Camera + Receiver H/W 구성


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

  • 2.5파이 오디오 잭을 이용하는 방법

  • USB를 이용하는 방법


USB를 이용하는 방법은 캐논 카메라의 SD Card에 있는 사진을 불러 온다거나 설정 값들을 변경 할 수 있는 다양한 기능을 제어 할 수 있습니다. 하지만 여기서 필요한 기능은 사진을 찍는 간단한 동작만 되면 되기 때문에 '2.5파이 오디오 잭을 이용하는 방법'을 사용하여 구현 하였습니다. 즉 아래 그림과 같이 오디오 잭의 모서리 금속과 마지막 금속을 접지 시키면 캐논 카메라의 Shutter가 눌려지며 동작을 합니다. 또한 두번째 금속과 마지막 금속을 접지 하면 캐논 카메라가 포커스를 잡습니다.
Canon_5

오디오 잭의 피복을 벗기면 빨강, 흰색, 금색 선을 볼 수 있습니다. (이 부분은 오디오 잭에 따라 다를 수 있으니 테스터기를 가지고 어느 선과 연결되어 있는지 확인 필요)
본 프로젝트에 사용된 오디오 잭은 빨간 선은 Shutter, 흰색 선은 Focus로 사용 할 수 있으며, 각각 Arduino Board의 D7번과 D6번에 연결 하였습니다. 아래는 Arduino Board와 WizFi250-EVB를 결합한 보드에 오디오 잭을 연결한 사진입니다.
Canon_2

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

Receiver S/W 구성


본 프로젝트에서는 WizFi250의 Soft AP 기능을 활용할 예정입니다. WizFi250은 일반적인 유/무선 공유기에 접속하여 통신하는 Station 모드 이외에 AP 기능을 지원하는데 기능이 제한적이기 하지만 Device 2~3대 정도가 통신하는데는 문제 없습니다.
아래는 Receiver S/W 구현으로 설정한 네트워크 환경을 나타내는 그림입니다.
Canon_7
구현한 Arduino Code는 아래와 같습니다. 스마트폰과의 통신은 TCP를 이용하였고 프로토콜은 아래와 같이 아주 간단합니다.
스마트폰으로 부터 ‘S’를 받으면 사진을 찍고 ‘F’를 받으면 Focus를 잡습니다.

[sourcecode language="plain"]
#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("rnSerial 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);
}
[/sourcecode]

스마트폰 S/W


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

[sourcecode language="plain"]
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);
}
}
[/sourcecode]

데모 영상입니다.

출처 : 카이젠의 임베디드 DIY