오렌지보드 WiFi

Posted by 카이젠8501 카이젠8501
2016.11.24 17:17 IoT/Wi-Fi Module

(주)위즈네트와 (주)네패스가 콜라보레이션 해서 만든 오렌지보드 WiFi를 소개 한다. 아두이노 Uno에 WizFi250(Wi-Fi 모듈)을 연결해서 하나의 보드로 만든 보드이며, 당연히 아두이노 Uno와 완벽 호환하며  아두이노에서 Wi-Fi를 사용하기 위한 WizFi250 Library를 제공한다.


구성품은 아래와 같이 오렌지보드WiFi 1개, 확장 안테나 1개, USB 케이블 1개로 되어 있다.


오렌지 보드를 만드는 과정 중, WizFi250 Library를 구현하기 위해 조금 고생하였지만, (주)네패스를 통해 다양하고 유익한 컨텐츠들이 많이 생성되고 있어 보람을 느끼고 있다.


아래 링크들은 오렌지보드 WiFi를 학습하기 위한 학습 가이드이며 자세한 내용은 아래 링크를 참고 하기 바란다.

http://www.kocoafab.cc/product/orangewifi

 

1Wiznet라이브러리 설치와 WebClient 예제 사용하기
2WebServer 예제 사용하여 조도센서 값 웹브라우저에 출력하기
3OpenWeatherMap API를 사용하여 날씨데이터 받아오기
4OrangeBoard WiFi와 Ubidots를 연동하여 사용하기
5OrangeBoard WiFi와 Ubidots를 연동하여 사용하기2
6OrangeBoard WiFi와 Thingspeak를 연동하여 사용하기
7OrangeBoard WiFi와 Dweet.io를 연동하여 사용하기
8OrangeBoard WiFi의 AP모드 사용하기
9OrangeBoard WiFi, 조이스틱 센서 쉴드로 RC카 제어해보기


저작자 표시
신고
이 댓글을 비밀 댓글로

DIY Projects using WizFi250 or WizFi210

Posted by 카이젠8501 카이젠8501
2016.10.10 10:50 IT 개발/DIY 프로젝트

본 포스팅은 WIZnet의 Wi-Fi Module인 WizFi250과 WizFi210을 활용한 DIY 프로젝트들을 소개한다.

To Make Canon DSLR’s Remote controller using  WizFi250

본 프로젝트에서는 Canon Camera를 제어하기 위한 Wi-Fi Remote Controller를 만드는 방법에 대해 설명한다.

 해당 장치를 위해서는 아래와 같은 구성 요소가 필요하다.

  • Camera
    • Receiver와 2.5pi Audio Cable을 이용하여 연결
  • Receiver
    • Arduino Uno(MCU)+WizFi250 (Wi-Fi Module)
    • WizFi250의 AP 기능을 사용 ( 별도의 유/무선 공유기 없이 스마트폰과 다이렉트로 연결 )
  • Remote Controller
    • Smart Phone
    • Simple Android App

Wiznet Museum : http://wiznetmuseum.com/portfolio-items/to-make-canon-dslrs-remote-controller-using-wizfi250/

Author’s Blog(KOR) : http://kaizen8501.tistory.com/86

Author’s Blog(ENG) : http://www.life4iot.com/2015/01/18/to-make-canon-dslrs-remote-controller-using-wizfi250/?lang=en

 

WiFi Electric Skateboard using WIZwiki-W7500ECO + WizFi250

본 프로젝트에서는 WIZwiki-W7500ECO MCU Board와 WizFi250 Wi-Fi Module을 이용하여 전동 스케이트 보드를 만드는 방법에 대해 설명한다.

필요한 구성 요소는 아래와 같다. 해당 구성 요소에 대한 구입을 원하는 경우, 아래 구성 요소들의 이름을 클릭하여 구매 사이트로 이동하면 된다.

 

Wiznet Museum : http://wiznetmuseum.com/portfolio-items/to-make-canon-dslrs-remote-controller-using-wizfi250/

Author’s Blog(KOR) :

http://kaizen8501.tistory.com/112

http://kaizen8501.tistory.com/113

http://kaizen8501.tistory.com/114

Author’s Blog(ENG) :

- http://www.life4iot.com/2015/10/29/electric-skateboard-1-material/

http://www.life4iot.com/2015/10/29/electric-skateboard2-servo-motor-test/

http://www.life4iot.com/2015/10/29/electric-skateboard3-wi-fi-receiver-and-controller/

 

Hedgehog - Educational Robotics Controller

Hedgehog는 Robot을 이용하여 교육 및 연구를 하기 원하는 사람들을 위한 프로젝트이다. 본 프로젝트는 2015년에 KickStarter에 게시 되었지만 펀딩에는 실패 하였다. 하지만 로봇 동작 원리 및 임베디드 디바이스의 동작 원리를 쉽고 간단하게 학습 하기 좋은 프로젝트로 판단 되어 본 포스팅에서 소개 하게 되었다. 참고로 Hedgehog의 Wi-Fi 통신에는 WizFi210 Wi-Fi Module이 탑재되어 있다.

본 프로젝트의 자세한 내용은 아래 링크를 참고 하기 바란다.

Wiznet Museum : http://wiznetmuseum.com/portfolio-items/hedgehog-educational-robotics-controller-2/

KickStarter : https://www.kickstarter.com/projects/priarobotics/hedgehog-educational-robotics-controller


Drainage tank of water purifier IoT

본 프로젝트는 정수기를 사용하면서 한번 쯤 필요하다고 생각한 아이디어를 실제로 구현하고 구현 방법을 정리 하였다.
저자는 Arduino와 WizFi250(Wi-Fi Module)을 이용하여, 정수기 배수통에 물을 비워야 하는지 확인하고 배수통에 물이 일정 높이 이상 차면 등록된 E-mail로 알려주는 장치를 구현하였다.

해당 장치에 대한 자세한 설명이 필요하면 아래 링크를 참고 하기 바란다.
Wiznet Museum : http://wiznetmuseum.com/portfolio-items/drainage-tank-of-water-purifier-iot/





신고
이 댓글을 비밀 댓글로

Arduino에서 Wi-Fi 기반의 MQTT 사용하기

Posted by 카이젠8501 카이젠8501
2016.09.05 10:44 IT 개발/Arduino

앞 포스팅에서 기술한 것과 같이, WizFi250 Arduino Library가 업데이트 되면서 기존에 ESP8266이나 Ethernet에서 사용하는 예제들을 별도의 수정 없이 그대로 사용 할 수 있게 되었다.

http://www.life4iot.com/2016/07/27/wizfi250-arduino-library/

본 포스팅에서는 업데이트 된 WizFi250 Arduino Library를 이용하여 Arduino에서 Wi-Fi를 사용하고 MQTT 연결 후 데이터를 Publish하고 Subscribe 하는 예제를 구현 하는 방법을 설명 한다.

MQTT란?

mqttorg

MQTT란 경량의 Publish/Subscribe 메시징 프로토콜이다. IoT(Internet of things)나 M2M(machine-to-machine)에서 사용하기 위해 설계 되었으며, 이런 이유로 낮은 전력, 낮은 대역폭 환경에서 사용할 수 있다.

아래 문서를 참고 하면, MQTT에 대한 자세한 내용을 확인 할 수 있다.
MQTT 소개

WizFi250 Library 설치 및 PubSub Client Libary 설치

아두이노 IDE에서는 라이브러리 매니저를 지원한다. 라이브러리 매니저를 이용하면, Arduino에서 사용 할 Library를 편하게 검색하고 설치 할 수 있으며, WizFi250 Library 역시 라이브러리 매니저를 이용하여 설치 할 수 있다.

아두이노 IDE의 메뉴에서 [스케치]-[Include Library]-[Manage Libraries] 선택 후, Library Manager에서 WizFi250을 검색 후 설치 한다.

20160801_140536

20160801_140642

Arduino에서 MQTT를 사용하기 위해서는 PubSubClient Library를 설치 해야 한다. 설치 방법은 WizFi250 Library 설치와 동일하며 검색어만 pubsubclient로 바꿔서 사용하면 된다.

Arduino에서 Wi-Fi 연결 후 MQTT 사용하기

WizFi250 Library에는 MQTT를 사용하기 위한 기본적인 예제를 포함하고 있다. 아두이노 IDE에서 [파일]-[예제]-[WizFi250]-[mqtt_wizfi250]를 열고 Wi-Fi SSID와 Password를 공유기에 맞게 설정하면 그대로 사용 할 수 있으며, broker.mqtt-dashboard.com에 설치되어 있는 broker에 접속해서 데이터를 publish 하고 subscribe 할 수 있다.

20160801_142526

// Update these with values suitable for your network.
const char* ssid = "DIR-815_Wiznet";
const char* password = "12345678";
const char* mqtt_server = "broker.mqtt-dashboard.com";

위 코드에서 mqtt_server 값을 변경하면, broker.mqtt-dashboard.com에 있는 broker 이외의 다른 broker를 이용 할 수 있다.

아래 코드는 WizFi250을 AP에 연결한 후, MQTT Broker에 접속하고 Callback 함수를 등록한다. Callback 함수는 Arduino+WizFi250이 MQTT Broker로 부터 MQTT Message를 수신 하였을 때 처리 하기 위한 내용을 정의 한다.

void setup() {
  pinMode(9, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.init();
  WiFi.begin((char*)ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

본 예제의 callback 함수는 Broker로 부터 Message를 수신하면 “Topic”을 출력하고 “Topic”에 대한 Payload 값을 출력 한다.
그리고 모든 “Topic”에 대하여 Payload 값이 ‘1’이면 9번 핀에 연결되어 있는 LED를 ON하고 ‘0’이면 LED를 OFF 한다.

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(9, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(9, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

Main Loop에서는 MQTT Broker와 연결이 끊어 지면 다시 연결 하고, 2초에 한번씩 “outTopic”이라는 Topic으로 “WizFi250 hello world xxxx” 메시지를 보낸다.

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "WizFi250 hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

MQTT Publish/Subscribe Test

위 예제를 컴파일 하고 아두이노에 업로드 한 후, 예제가 정상적으로 구동 한다면 아래와 같은 로그 메시지를 확인 할 수 있다.

20160801_144011

MQTT Publish Test

PC의 웹브라우저를 이용하여 broker.mqtt-dashboard.com에 접속하면 아래와 같은 화면을 볼 수 있으며, 빨간 박스로 표시된 부분과 같이 “outTopic”에 “WizFi250Hello world #xxxx” 메시지가 출력되면 아두이노에서 메시지를 정상적으로 publish 한 것으로 판단 할 수 있다.

20160801_143851

MQTT Subscirbe Test

PC에 MQTT.fx 툴을 설치 한다. MQTT.fx Download

MQTT.fx의 Connection Profile에 연결할 broker.mqtt-dashboard.com 정보를 입력한 후 Connect 버튼을 누르면 broker.mqtt.dashboard.com에 연결 할 수 있다.

20160801_150203

20160801_150215

아래 그림과 같이 첫번째 박스에 Topic, 두번째 박스에 Message를 입력한 후 Publish 버튼을 누르면, Arduino에서 해당 토픽에 대한 메시지를 로그 메시지로 출력한다. 아래 그림과 같이 출력 되면, 정상적으로 Subscribe가 된다고 판단 할 수 있다.

20160801_150232

20160801_145851

저작자 표시
신고
이 댓글을 비밀 댓글로

Arduino Library Manger에 Library 등록하기

Posted by 카이젠8501 카이젠8501
2016.09.05 10:23 IT 개발/Arduino

Library를 Arduino Library Manager에 등록하는 방법

새로 작성한 라이브러리를 Arduino Library Manager에 등록하기 위해서는 아래 문서에 있는 조건들을 만족해야 한다.
https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ

간단하게 정리하면

  • GitHub에 Library Repository 등록
  • GitHub Repository 폴더 구조는 아래과 같은 구조로 구성
    • examples : 라이브러리 예제
    • src : 라이브러리를 구성하는 전체 소스 파일 (.h, .cpp)
    • README.md : 라이브러리를 설명하는 문서
    • keywords.txt : 아두이노 IDE에서 Highlite 할 문자 표시
    • library.properties : 라이브러리 이름, 버전, 저자, 및 다운로드 url
  • 라이브러리 Tag 생성

20160801_155014

위 조건에 따라 GitHub Repository를 만든 후, https://github.com/arduino/Arduino의 Issues 탭에 GitHub Repository를 등록 해 달라는 이슈를 남기면, 관리자가 검토 후 Arduino Library Manager에 등록 한다.

20160801_155508

20160801_155519

저작자 표시
신고
이 댓글을 비밀 댓글로

WizFi250 Arduino Library

Posted by 카이젠8501 카이젠8501
2016.09.05 10:18 IT 개발/Arduino

기존 WizFi250 Arduino Library 개선 필요

이전에 있던 WizFi250 Arduino Library에 아래와 같은 문제 및 불편한 사항이 있었다.
Old Version WizFi250 Arduino Libary Download link

  1. API 함수들이 표준과 달라서, Arduino 예제들을 그대로 사용 할 수 없음
  2. 구조적으로 버퍼를 많이 사용하고 있어, Arduino Uno와 같이 RAM이 부족한 보드에서는 Memory Overflow가 발생

위와 같은 문제가 있어 WizFi250 Arduino Library를 다시 구현해야 겠다는 생각이 들었으며, 본 포스팅에서는 새로운 WizFi250 Arduino Library를 구현하는 과정과 예제 구동 방법에 대해 설명한다.

개발 환경

Arduino Library를 구현하기 위한 Eclipse 개발 환경 구축을 참고 하기 바란다.

WizFi250 Arduino Library 다운로드 링크

New Version WizFi250 Arduino Library Download link

WizFi250 Arduino Library 참고 사항

WizFi250 Arduino Library는 ESP-8266 기반의 아두이노 라이브러리를 참고 해서 개발하였다.
이미 일반적으로 많이 사용되고 있는 ESP-8266 라이브러리의 함수 포맷을 맞춰서, 이미 만들어져 있는 예제들을 그대로 사용 할 수 있도록 하는 것에 초점을 두고 개발 하였다. 그 결과 WizFi250 Arduino Library 예제에 있는 것과 같이 별도의 큰 수정 없이 MQTT, ThingPlus 및 Ubidot와 같은 클라우드 예제를 사용 할 수 있다.

WizFi250 Arduino Library 폴더 구조

파일및폴더명 내용
examples WizFi250 Library를 활용한 예제(.ino)
utility
WizFi250_spi_drv SPI 인터페이스로 WizFi250을 제어하는 드라이버 구현
WizFiRingBuffer WizFi250에서 사용하는 Ring Buffer 구현
general_parse Parsing을 위한 범용적인 함수들 구현
WizFi250 Wi-Fi 동작을 위한 기능 구현
WizFi250Client TCP Client 동작을 위한 기능 구현
WizFi250Server TCP Server 동작을 위한 기능 구현
WizFi250Udp UDP 동작을 위한 기능 구현
저작자 표시
신고
이 댓글을 비밀 댓글로

Arduino Library를 구현하기 위한 Eclipse 개발 환경 구축

Posted by 카이젠8501 카이젠8501
2016.09.05 10:02 IT 개발/Arduino

Arduino를 설치 하면 Sketch라는 별도의 IDE를 사용해서 코드를 수정, 컴파일 및 다운로드를 한다. 간단한 프로그램을 작성하거나, 사용하고 있는 라이브러리를 내부까지 확인 할 필요가 없는 경우 Sketch 프로그램만 이용해도 대부분의 Arduino의 기능을 사용 할 수 있다.

하지만 나와 같이 Arduino Library를 구현해야 하거나, Arduino Core 및 Library에서 제공하는 함수들의 내부를 확인하고 싶을 때는 Sketch 프로그램의 기능이 한 없이 부족함을 느낀다.

때문에 본 포스팅에서는 Eclipse IDE 환경에서 Arduino Library를 개발 하기 위한 환경 구축하는 방법을 설명한다.

Arduino Library를 구현하기 위한 Eclipse 개발 환경

Download Eclipse

본 포스팅에서는 Eclipse Mars 버전을 사용 하였다.

아래 주소를 이용하면 Eclipse Mars 버전을 다운로드 할 수 있다.

Eclipse IDE for C/C++ Developers

Install Arduino Plugin

Eclipse를 실행 한 후, [Help]-[Eclipse Marketplace]에서 Arduino Eclipse IDE V2를 설치 한다.

20160727_091520

정상적으로 설치가 완료되면, 아래와 같은 메뉴와 아이콘이 생성되는 것을 볼 수 있다.

20160727_092202

Install Arduino IDE

위에서 설치한 Arduino Plugin은 Arduino IDE version 1.6.5 이상을 지원하지 않는다. 때문에 최신 버전의 Arduino IDE 대신, 1.6.5 버전을 설치해야 되며 아래 주소를 이용하면 해당 버전을 다운로드 할 수 있다.

https://www.arduino.cc/en/Main/OldSoftwareReleases#previous

20160727_093141

Configure Arduino Plugin in Eclipse

Arduino IDE 설치가 완료되면, Eclipse에서 Arduino를 컴파일하기 위한 환경 설정이 필요하다. Eclipse에서는 Arduino IDE에 설치된 컴파일러와 다운로드 프로그램을 이용하여 컴파일 및 다운로드를 할 수 있으며, Arduino IDE가 설치 되어 있는 경로를 지정하는 간단한 환경 설정이 필요 하다.

[Window]-[Preferences]-[Arduino]에서 아래 표시되어 있는 정보를 설정하면 된다.

(일반적인 Arduino IDE를 설치 경로는 C:\Program Files (x86)\Arduino 이다.)

또한 개인적으로 사용하고 있는 Library가 있는 경우, 아래 Private Library path 에 설정하면 Arduino에서 지원하는 Library 이외의 개인적인 Library를 사용 할 수 있다.

20160727_093549

Create Arduino Project

새로운 Arduino Project를 생성하기 위해서는, Project Explorer에서 [New]-[Project]-[Arduino]-[New Arduino sketch]를 선택 하고 프로젝트 이름 및 간단한 옵션들을 선택 해야 한다.

20160727_092534 20160727_092606

20160727_094049 20160727_094102

20160727_094122

프로젝트가 정상적으로 만들어 지면 아래와 같은 폴더 구조를 볼 수 있으며, Test_Arduino.cpp 파일에 main 코드를 구현하면 된다.

20160727_094151

Import Library

내가 만든 새로운 라이브러리 혹은 별도의 외부 라이브러리를 사용하기 위해서는 라이브러리를 Import 해야 한다.

Import를 위한 방법은 프로젝트 이름을 선택 한 후, [마우스 우 클릭]-[Import]-[Arduino]-[Import Arduino libraries into the current project]를 선택 해서 원하는 라이브러리를 추가 한다.

20160727_095036

20160727_095149

20160727_095210

Compile and Download

코드를 작성한 후, 아래 표시된 화살표 아이콘을 누르면 컴파일과 다운로드가 동시에 된다. 다운로드가 정상적으로 완료 되면 Console 탭에서 아래와 같은 메시지를 확인 할 수 있다.

20160727_111425

Trouble Shooting

혹시, 컴파일이 안되거나 다운로드시 보드를 찾을 수 없다는 메시지가 나오면 아래와 같이 프로젝트 속성을 확인해서 컴포트 및 보드가 제대로 설정되어 있는지 확인 해야 한다.

20160727_111638

저작자 표시
신고
이 댓글을 비밀 댓글로

[전동 Skateboard 만들기]#3 Wi-Fi 모듈 연결 및 Control 어플 구현

Posted by 카이젠8501 카이젠8501
2015.11.03 09:58 IT 개발/DIY 프로젝트

[전동 Skateboard 만들기]#3 Wi-Fi 모듈 연결 및 Control 어플 구현

Hardware of Wi-Fi Receiver

Wi-Fi 수신기는 스마트폰에서 데이터를 수신하여 스케이트 보드의 속도를 조절하는 장치이며, 하드웨어 구성은 아래와 같다.

20151029_143029

아래 사진은 완성된 하드웨어 사진이다. 배터리나 다른 보드들과의 circuit short를 방지하기 위해 절연 테이트를 부착하여 조금 부족해 보이지만 동작에는 문제가 없다.

오른쪽에 3핀, 2핀이 나와 있는데, 위에 3핀은 PWM,3.3V VCC,GND 핀이고, 아래 2핀은 배터리에서 받아 올 5V VCC, GND 핀이다.

20151030_082315

Wi-Fi Receiver Firmware

Source Code

Wi-Fi Receiver firmware는 아래 그림과 같은 구조로 동작된다. 스마트폰에서 Speed Up 명령을 주면 Wi-Fi Receiver는 속도를 5% 올리고 Speed Down 명령을 주면 속도를 5% 내린다.

20151030_084225

예외 상황에서는 아래 그림과 같이 Motor를 정지 한다. 단 Motor가 정지 되어도 가속도 때문에 스케이트 보드는 계속 움직일 수는 있다.

20151030_085505

Wi-Fi 수신기에 대한 소스코드는 아래 경로에서 다운로드 할 수 있다.
https://developer.mbed.org/users/kaizen/code/Wifi_Electric_Skateboard/

#include "mbed.h"
#include "Servo.h"
#include "WizFi250Interface.h"

#define SECURE WizFi250::SEC_WPA2_MIXED
#define SSID "Kaizen_Skate"
#define PASS "qwertyuiop"

#define SERVER_PORT    5000
#define STOP_MOTOR     50


#if defined(TARGET_WIZwiki_W7500P)
    WizFi250Interface wizfi250(PC_2,PC_3,PC_13,PC_14,PC_12,NC,115200);
    Serial pc(USBTX, USBRX);
    Servo motor_speed(PC_8);      // it used to percentage value ( 0 ~ 1 )
    DigitalOut green_led(LED2);    
    DigitalOut red_led(LED1);
    DigitalOut blue_led(LED3);
#endif

#define START_MSG       "START"
#define END_MSG         "END\n"
#define CONTROL_UP      "UPXX"
#define CONTROL_DOWN    "DOWN"
#define CONTROL_CRUISER "CRUI"
#define CONTROL_STOP    "STOP"

#define STATUS_CMD_OK   "OKXX"
#define STATUS_CMD_FAIL "FAIL"

#define CONTROL_MSG_SIZE    19

// Control Pkt Format : START,CONTROL,SPEED_VALUE,END
//                      START,UPXX,500,END
// Status Pkt Format : START,CONTROL,SPEED_VALUE,STATUS,END

struct control_pkt{
    char start_msg[6];
    char control_msg[5];
    char speed_msg[4];
    char end_msg[4];
};
void parse(char buffer[], int *j, char *string);

int main() {    
    int recv_cnt,j;
    volatile float speed_value = 0.5;
    char recv_control_msg[100];
    char status_msg[100];
    control_pkt control;

    pc.baud(115200);
    green_led = 1; red_led = 1; blue_led = 1;

    wizfi250.init();
    wizfi250.setAntMode(WizFi250::PCB);
    wizfi250.setAddress("192.168.100.2","255.255.255.0","192.168.100.1");
    if ( wizfi250.connect(SECURE, SSID, PASS, WizFi250::WM_AP))
    {
        red_led = 0;
        return -1;
    }
    printf("IP Address is %s\r\n", wizfi250.getIPAddress());
    green_led = 0; red_led = 0; blue_led = 0;

    TCPSocketServer server;
    TCPSocketConnection client;

    while(true)
    {
        if( client.is_connected() == false )
        {
            green_led = 1; red_led = 1; blue_led = 0;            
            client.close();
            server.close();

            if(speed_value == 0.5)
            {
                server.bind(SERVER_PORT);
                server.listen();

                printf("\nWait for new connection...\r\n");
                server.accept(client);
                client.set_blocking(false, 1500);
            }
            else if(speed_value <= 0.4)
            {
                printf("Speed decrease +\r\n");

                speed_value = 0.5;
                motor_speed = speed_value;
            }
            else
            {
                printf("Speed decrease -\r\n");
                speed_value = 0.5;  motor_speed = speed_value;
            }
        }
        else
        {
            motor_speed = speed_value;

            green_led = 0; red_led = 1; blue_led = 1;
            //recv_cnt = client.receive_all((char*)recv_control_msg, sizeof(control)-1);
            recv_cnt = client.receive_all((char*)recv_control_msg, sizeof(control));

            j=0;
            parse(recv_control_msg, &j, control.start_msg);
            parse(recv_control_msg, &j, control.control_msg);
            parse(recv_control_msg, &j, control.speed_msg);
            parse(recv_control_msg, &j, control.end_msg);

            if(recv_cnt > 0)
            {
                if( (strncmp(control.start_msg,START_MSG,sizeof(control.start_msg)) != 0) || 
                    (strncmp(control.end_msg,END_MSG,sizeof(control.end_msg)) != 0) )
                {
                    printf("TEST Error\r\n");
                    sprintf(status_msg,"%s,%03d,%s,%s\n",START_MSG,int(speed_value*100),STATUS_CMD_FAIL,END_MSG);
                    client.send_all((char*)status_msg,strlen(status_msg));
                    continue;
                }

                if( strncmp(control.control_msg,CONTROL_UP,sizeof(control.control_msg)) == 0 )
                {
                    speed_value += 0.05; 
                    motor_speed = speed_value;
                    printf("TEST UP %f\r\n",speed_value); 
                }
                else if( strncmp(control.control_msg,CONTROL_DOWN,sizeof(control.control_msg)) == 0)
                {
                    speed_value -= 0.05; 
                    motor_speed = speed_value;
                    printf("TEST DOWN %f\r\n",speed_value);
                }
                else if( strncmp(control.control_msg,CONTROL_CRUISER,sizeof(control.control_msg)) == 0)
                {
                    printf("TEST CRUISER\r\n"); 
                    speed_value = (float)(atoi(control.speed_msg)) / 100;
                    motor_speed = speed_value;
                }
                else if( strncmp(control.control_msg,CONTROL_STOP,sizeof(control.control_msg)) == 0)
                {
                    printf("TEST STOP\r\n"); 
                    speed_value = 0.5;
                    motor_speed = speed_value;
                }
                else
                {
                    printf("TEST Error 1-2\r\n");
                    sprintf(status_msg,"%s,%03d,%s,%s\n",START_MSG,int(speed_value*100),STATUS_CMD_FAIL,END_MSG);
                    client.send_all((char*)status_msg,strlen(status_msg));
                    continue;
                }

                sprintf(status_msg,"%s,%03d,%s,%s\n",START_MSG,int(speed_value*100),STATUS_CMD_OK,END_MSG);
                client.send_all((char*)status_msg,strlen(status_msg));
            }
            else
            {
                sprintf(status_msg,"%s,%03d,%s,%s\n",START_MSG,int(speed_value*100),STATUS_CMD_OK,END_MSG);
                client.send_all((char*)status_msg,strlen(status_msg));
            }
        }
    }// while
}

void parse(char buffer[], int *j, char *string) {
//extracts next location string data item from buffer
    int i=0;
    for (i=0; i<=strlen(buffer); i++) {  //TOTAL SIZE OF RETURNED DATA
        if ((buffer[*j+i] == ',')||(buffer[*j+i] == '\0' )) { //IF comma or end of string
            //comma is the string field delimiter
            string[i]=0; //SETS END OF SRTRING TO 0
            *j=*j+i+1; //UPDATES to 1 after comma seperated value
            break;
        } else string[i]=buffer[*j+i]; //Keep adding to the string
    }
}

스마트폰 어플

Screenshot_2015-10-29-16-20-25

Source Code

https://github.com/kaizen8501/WiFi_Skateboard

Demo Video


저작자 표시
신고
이 댓글을 비밀 댓글로
    • ㅇㅇ
    • 2016.12.17 21:51 신고
    너무 어렵다.........
    • 안녕하세요^^

      어느 부분이 어려우신지 말씀해 주시면 제가 아는 한도 내에서 자세히 설명 해 드리도록 하겠습니다^^

How to make Geo-location Watch

Posted by 카이젠8501 카이젠8501
2015.10.08 14:54 IT 개발/DIY 프로젝트

How to make Geo-location watch

System Diagram

본 포스팅에서는 WizFi250과 WIZwiki-W7500을 이용하여 Geolocation Server에 접속해서 현재 내 위치를 알아 확인하고, NTP Server를 통해 시간을 가져오는 예제를 설명한다. 시스템 구성은 아래 그림과 같다.

20150626_171106

Materials

WIZwiki-W7500 ( MCU Platform)

wizwiki-w7500_main

WizFi250-EVB ( Wi-Fi Module )

ShopDtl_1203_20140918154919

Sensor Shield

TB2wSGHaFXXXXcLXXXXXXXXXXXX_!!33841454

SSD1306 OLED

  • Features
    • Resolution: 128 x 64 dot matrix panel
    • Power supply
      • VDD = 1.65V to 3.3V for IC logic
      • VCC = 7V to 15V for Panel driving
    • For matrix display
      • OLED driving output voltage, 15V maximum
      • Segment maximum source current: 100uA
      • Common maximum sink current: 15mA
      • 256 step contrast brightness current control
    • Embedded 128 x 64 bit SRAM display buffer
    • Pin selectable MCU Interfaces:
      • 8-bit 6800/8080-series parallel interface
      • 3 /4 wire Serial Peripheral Interface
      • I2C Interface
    • Screen saving continuous scrolling function in both horizontal and vertical direction
    • RAM write synchronization signal
    • Programmable Frame Rate and Multiplexing Ratio
    • Row Re-mapping and Column Re-mapping
  • On-Chip Oscillator
  • Chip layout for COG & COF
  • Wide range of operating temperature: -40°C to 85°C

Hardware Configuartion

WIZwiki-W7500 Board는 UART0 RX/TX/CTS/RTS 핀들로 WizFi250을 제어하고, I2C SDA/SCL 핀을 이용하여 SSD1306 OLED를 제어 한다.

20150626_204959

WizFi250-EVB Sensor Shield WIZwiki-W7500 SSD1306
RX-TX RXD TXD
TX-RX TXD RXD
CTS-RTS CTS D8
RTS-CTS RTS D7
WizFi250-RESET JP10-2 PA12
I2C SCL SCL PA9 SCL
I2C SDA SDA PA10 SDA
VCC VCC VCC
GND GND

Compile WizFi250 Geolocation_NTP Example

아래 주소에 접속하면 WizFi250 Geolocation_NTP Example를 이용할 수 있으며, Example에서 사용하는 라이브러리들은 아래와 같다.

WizFi250 Geolocation_NTP Example

SSD1306 Library

SSD1306 OLED를 사용하기 위해 Adarfruit GFX Library를 사용하였다. 이 라이브러리를 사용하는 중, Display() 함수에 약간의 버그가 있는 거 같아서 수정 후, 원작자에게 Pull Request를 보낸 상태이다. ( 원작자가 반영 해 줄 지는 모르겠다. )

Adafruit_GFX 수정
Adafruit GFX 원본

HTTP Client

HTTP Client Library는 이름에서도 알 수 있듯이, 외부에 있는 웹 서버에 Request와 Response를 송/수신 하기 위해 사용된다.
본 예제에서는 ip-api.com 서버에 접속해서 Geolocation(지리적 위치 코드)를 얻기 위해 사용되며, ip-api.com/csv 주소로 접속하면 csv 형태로 국가 이름, 주소, 위도(latitude), 경도(longitude), TimeZone 등의 정보를 얻을 수 있다.

아래 주소를 클릭하면 HTTP Client Library를 다운로드 할 수 있다.
HTTP Client

NTP Client

NTP Client Library는 UDP 통신을 이용하여 Network Time Server에서 UTC(협정 세계 시각)을 얻기 위해 사용된다. 본 예제에서는 한국의 NTP Server Domain인 kr.pool.ntp.org를 이용한다. NTP Server로 받은 정보는 UTC(협정 세계 시각)이므로, 9시간을 더해야 한국 시간을 알 수 있다.

NTP Client

Example Source Code

WizFi250-Geolocation_NTP

#include "mbed.h"
#include "Adafruit_SSD1306.h"
#include "WizFi250Interface.h"
#include "NTPClient.h"
#include "HTTPClient.h"


#define SECURE WizFi250::SEC_AUTO
#define SSID "wizohp"
#define PASS "wiznet218"


#if defined(TARGET_WIZwiki_W7500)
    #define SDA                  PA_10
    #define SCL                  PA_9
    WizFi250Interface wizfi250(D1,D0,D7,D8,PA_12,NC,115200);
    Serial pc(USBTX,USBRX);
#endif


// an SPI sub-class that provides a constructed default
class I2CPreInit : public I2C
{
public:
    I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
    {
        frequency(100000);
        start();
    };
};

I2CPreInit gI2C(SDA,SCL);
Adafruit_SSD1306_I2c gOled(gI2C,NC,0x78,64,128);
NTPClient ntpClient;
HTTPClient httpClient;
void parse(char buffer[], int *j, char *string); //FUNCTION TO PARSE HTTP GET DATA
char httpGetData[200]; //BUFFER TO HOLD DATA FROM HTTP GET REQUEST


int main()
{
    time_t ctTime; //system time structure
    char success[10]={0};  //success first
    char countryFull[20]={0}; //Full Country Name
    char countryAbrv[5]={0}; //Abbreviated Country Name or country Code
    char stateAbrv[5]={0}; //Abbreviated State or region code
    char stateFull[15]={0}; //Full State Name
    char city[15]={0}; //City Name
    char zip[6]={0}; //ZIP CODE
    char latitude[10]={0}; //latitude
    char longitude[10]={0}; //longitude
    char timeZone[30]={0}; //timeZone
    int j=0, returnCode;

    pc.baud(115200);
    gOled.begin();
    gOled.clearDisplay();

    wizfi250.init();
    returnCode = wizfi250.connect(SECURE, SSID, PASS);

    if ( returnCode == 0 )
    {
        printf(" - WiFi Ready\r\n");
        printf("IP Address is %s\r\n", wizfi250.getIPAddress());
    }
    else
    {
        printf(" - Could not initialize WiFi - ending\r\n");
        return 0;
    }

    //HANDLES THE HTTP GET REQUEST THE WAY THE FUNCTION IS CALLED HERE IS THE FOLLOWING
    // get(DOMAIN_NAME,BUFFER,TIMEOUT_VAL)
    //DOMAIN_NAME= domain name that get request is sent to
    //BUFFER= buffer to store data returned from the server
    //TIMEOUT_VAL= Time before the request times out
    HTTPResult r = httpClient.get("http://ip-api.com/csv",httpGetData,128); //GET GEOLOCATION DATA (CSV)

    if (r==HTTP_OK) { //IF THE DATA WAS RECIEVED
        j=0;
        //parse and display each of the API's location information strings on the LCD
        parse(httpGetData, &j, success); 
        parse(httpGetData,&j,countryFull);
        parse(httpGetData,&j,countryAbrv);
        parse(httpGetData,&j,stateAbrv);
        parse(httpGetData,&j,stateFull);
        parse(httpGetData,&j,city);
        parse(httpGetData,&j,zip);
        parse(httpGetData,&j,latitude);
        parse(httpGetData,&j,longitude);
        parse(httpGetData,&j,timeZone);
        gOled.printf("HTTP Data Received\r\n");
        gOled.display();
    } 
    else { //HTTP GET REQUEST ERRORED
        gOled.printf("HTTP Error %d\r\n", r);
        gOled.display();
        return -1;
    }
    printf("Reading Time...\r\n");
    char* domainName="kr.pool.ntp.org"; //SET TO DOMAIN NAME OF SERVER GETTING TIME FROM
    //GETS THE TIME FROM THE SERVER
    //setTime(DOMAIN_NAME,PORT_NUMBER,TIME_OUT)
    //DOMAIN_NAME= domain name
    //PORT NUMBER=port number (123 for NTP)
    //TIME_OUT= timeout value for request
    ntpClient.setTime(domainName,123,0x00005000);
    printf("Time Set\r\n");
    //Delay for human time to read LCD display
    wait(3.0);

    char buffer[80]; //BUFFER TO HOLD FORMATTED TIME DATA
    gOled.printf("%s, %s %s, %s\r\n",city,stateAbrv,zip,countryAbrv); //PRINT CITY STATE AND ZIP INFORMATION AND COUNTRY
    gOled.printf("LAT:%s\r\nLONG:%s\r\n",latitude,longitude); //PRINT LATITUDE AND LONGITUDE 
    gOled.printf("Timezone:%s\r\n",timeZone); //PRINT TIMEZONE

    wizfi250.disconnect(); //DISCONNECT FROM THE NETWORK 
    while (1) {
        //ctTime = time(NULL)-(3600*4);  //TIME with offset for eastern time US
        ctTime = time(NULL)+(3600*9);  //TIME with offset for eastern time KR
        //FORMAT TIME FOR DISPLAY AND STORE FORMATTED RESULT IN BUFFER
        strftime(buffer,80,"%a %b %d\r\n%T %p %z\r\n %Z\r\n",localtime(&ctTime));
        gOled.printf("Univ Time Clock\r\n%s\r\n", buffer);
        gOled.display();
        gOled.setTextCursor(0,40);
        wait(1);
    }      
}

//SET FOR CSV FORMAT: NEEDS TO BE EDITED IF DIFFERENT FORMAT
void parse(char buffer[], int *j, char *string) {
//extracts next location string data item from buffer
    int i=0;
    for (i=0; i<=strlen(buffer); i++) {  //TOTAL SIZE OF RETURNED DATA
        if ((buffer[*j+i] == ',')||(buffer[*j+i] == '\0' )) { //IF comma or end of string
            //comma is the string field delimiter
            string[i]=0; //SETS END OF SRTRING TO 0
            *j=*j+i+1; //UPDATES to 1 after comma seperated value
            break;
        } else string[i]=buffer[*j+i]; //Keep adding to the string
    }
}

Demo Video


저작자 표시
신고
이 댓글을 비밀 댓글로

How to make Wi-Fi oil checker using Axeda

Posted by 카이젠8501 카이젠8501
2015.10.08 14:50 IT 개발/DIY 프로젝트

How to make WiFi oil check using Axeda cloud

Axeda

Axeda는 세계 각지의 기계와 센서 데이터를 수집하고 체계화하기 위한 IoT 솔루션을 제공하는 기업이다. 150개 이상의 고객사를 향해 매일 수억 개의 규모의 데이터를 처리하고 있으며, 크게 3가지 서비스를 제공하고 있다.

  1. ‘Axeda Machine Cloud Service’는 기기간 통신(M2M) 및 IoT 연결 서비스 소프트웨어 에이전트 툴킷으로 구성되어 있으며, 기업의 제품과 클라우드 보안 연결을 거의 모든 통신 방법(이동통신 네트워크, 인터넷, 무선 LAN, 위선통신 등)에서 제공한다.
  2. ‘Axeda Connected Content Application’은 대량의 연결된 제품에 콘텐츠 전송을 안전하고 확실하고 효율적으로 실현하고 소프트웨어 업데이트 및 보안 패치의 원격 설치를 자동화 한다.
  3. ‘Axeda Connected Service Application’은 PTC의 서비스 라이프 사이클 관리(SLM) 솔루션을 보완하고 Axeda 플랫폼에 연결된 장치의 문제를 원격으로 확인, 진단, 수리하는 다양한 툴과 Web 기반의 그래픽 인터페이스를 현장 서비스 및 기술 지원 부서에 제공한다.

참고 PTC, 액세다(Axeda) 인수 완료…사물인터넷 사업 강화

Go to the staging page on your Axeda Toolbox account

toolbox.axeda.com에 회원 가입 후, 아래 그림과 깉이 AXEDA READY 아이콘을 선택하고 mbed LPC1768 Device를 선택한다.

toolbox_landing_page mbedselect

본 포스팅 예제에서는 WIZwiki-W7500 Board를 사용하지만, 아직 Axeda에는 WizWik-W7500 Board가 없는 관계로 LPC1768의 ToolBox를 사용한다.

원하는 Device Name을 입력하고 Go 버튼을 누르면 아래 그림과 같은 화면을 볼수 있다.
Serial Number는 Axeda Example Code를 수행 할 때 필요하므로 메모장 같은 곳에 복사 해두길 바란다.

yourdevicepage

Materials

아래 하드웨어에 대한 자세한 내용은 아래 링크를 참고 하기 바란다.
Link

WIZwiki-W7500 ( MCU Platform)

wizwiki-w7500_main

WizFi250-EVB ( Wi-Fi Module )

ShopDtl_1203_20140918154919

Sensor Shield

TB2wSGHaFXXXXcLXXXXXXXXXXXX_!!33841454

Hardware Configuartion

20150626_151253

WizFi250-EVB Sensor Shield WIZwiki-W7500
RX-TX RXD TXD
TX-RX TXD RXD
CTS-RTS CTS D8
RTS-CTS RTS D7
WizFi250-RESET JP10-2 PA12

Compile AxedaGo-WizFi250 Example onto Wizwiki-W7500 Board

아래 주소에 접속하면 WizFi250 Axeda Example Code를 이용 할 수 있다.
Link for AxedaGo-WizFi250 Example

20150626_151744

AxedaGo-WizFi250 Example을 컴파일 하기 전, Axeda Tool box 에서 얻은 Serial Number를 아래 코드에 추가한다.

line19serial

코드를 컴파일 한 후, 생성된 바이너리를 WIZwiki-W7500 Board에 Upload 한다.

Source Code

#include <stdio.h>
#include "mbed.h"
#include "WizFi250Interface.h"

#define SECURE WizFi250::SEC_AUTO
#define SSID "ssid"
#define PASS "key"


#if defined(TARGET_WIZwiki_W7500)
    WizFi250Interface wizfi250(D1,D0,D7,D8,PA_12,NC,115200);
    Serial pc(USBTX,USBRX);
#endif

AnalogIn pot1(A0);
TCPSocketConnection sock;

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

int main() 
{
    char *MODEL = "mbed";
    char *SERIAL_NUM = "serial number"; 
    float DEADBAND = 0.03;

    int http_cmd_sz=800;
    char http_cmd[http_cmd_sz];
    int buffer_sz=300;  
    char buffer[buffer_sz];  
    int returnCode = 0;

    led1 = 1;
    led2 = 1;
    led3 = 1;
    led4 = 1;

    pc.baud(115200);

    wizfi250.init();
    returnCode = wizfi250.connect(SECURE, SSID, PASS);

    if ( returnCode == 0 )
    {
        printf(" - WiFi Ready\r\n");
        printf("IP Address is %s\r\n", wizfi250.getIPAddress());
        led1 = returnCode;
    }
    else
    {
        printf(" - Could not initialize WiFi - ending\r\n");
        return 0;
    }

    float oil_level = 0.0;
    float oldPotVal = -2.0;

    while(1) {
        oil_level = pot1.read();

        if ( abs(oil_level - oldPotVal) < DEADBAND)
        {
            continue;   
        }
        else
        {
            oldPotVal = oil_level;
            printf("Sending Value for well1 %.2f\n\r", oil_level);
            sock.connect("toolbox-connect.axeda.com", 80);

            snprintf(http_cmd, http_cmd_sz,  "POST /ammp/data/1/%s!%s HTTP/1.1\r\nContent-Type: application/json\r\nContent-Length: 65\r\n\r\n{\"data\":[{\"di\":{\"oil_level\":%.2f}}]}\r\n\r\n", MODEL, SERIAL_NUM, oil_level);
            sock.send_all(http_cmd, http_cmd_sz-1);

            while ( (returnCode = sock.receive(buffer, buffer_sz-1)) > 0)
            {
                buffer[returnCode] = '\0';
                printf("Received %d chars from server:\n\r%s\n", returnCode, buffer);
            }

            sock.close();
        }
     }
}

Test Result

Send data to the demo application

위 코드를 수행하면, WIZwiki-W7500은 WizFi250을 이용하여 Axeda Tool box에 센싱된 데이터를 송신한다. Axeda Tool box는 Device가 송신한 데이터를 가지고 아래 그림과 같이 Mbed Widget을 만들어 준다. Sensor Shield의 A0의 Switch를 돌리면 Axeda의 mbed Widget도 변하는 것을 확인 할 수 있다.

20150626_16013820150626_154710

Log message on Serial Terminal

[WizFi250: INFO]AT+MMAC=?
[WizFi250: INFO][OK]

[WizFi250: INFO]AT+WSET=0,wizohp
[WizFi250: INFO][OK]

[WizFi250: INFO]AT+WSEC=0,,wiznet218
[WizFi250: INFO][OK]

[WizFi250: INFO]AT+WJOIN
[WizFi250: INFO][OK]

[WizFi250: INFO]AT+WSTATUS
[WizFi250: INFO][OK]

[WizFi250: INFO]IP      : 192.168.13.29
[WizFi250: INFO]Gateway : 192.168.13.1
[WizFi250: INFO]WizFi250 is successfully join to AP
 - WiFi Ready
IP Address is 192.168.13.29
Sending Value for well1 0.54
[WizFi250: INFO]AT+FDNS=toolbox-connect.axeda.com,1000
[WizFi250: INFO][OK]

[WizFi250: DBG]216.34.120.52
[WizFi250: INFO]AT+SCON=O,TCN,216.34.120.52,80,,0
[WizFi250: INFO][OK]

[WizFi250: INFO]AT+SSEND=0,,,799
[WizFi250: INFO][OK]

[WizFi250: INFO]POST /ammp/data/1/mbed!nlr__kaizen8501_gmail_com___6245114 HTTP/1.1
Content-Type: application/json
Content-Length: 65

{"data":[{"di":{"oil_level":0.54}}]}



[WizFi250: DBG]receive readable : 1

Received 36 chars from server:
HTTP/1.1 200 
Content-Length: 0

Demo Video


저작자 표시
신고
이 댓글을 비밀 댓글로

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

Posted by 카이젠8501 카이젠8501
2014.11.26 19:08 IT 개발/DIY 프로젝트

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);
    }
} 








저작자 표시
신고
이 댓글을 비밀 댓글로
    • Dude
    • 2017.06.30 14:56 신고
    선풍기를 핸드폰으로 조작되게 만들려고 찾아봤는데
    이런 좋은 글이.. 참고하겠습니다