2015. 12. 20.

TEWDA 로고 - Calligraphy ver.


요즘 캘리그라피 수업을 듣고 있다.

내가 쓴건 아니고 부탁해서 만든 TEWDA 로고이다. (선생님의 캘리그라피 제작 -> 민수의 포토샵 처리)


배우는 과정이 너무 재미있고 활요도가 높은 분야이다. 추후에 내가 직접 저런 글씨를 쓸 수 있게 되면 여기저기 많이 꾸며야지!

2015. 10. 13.

DIY 3axis gimbal - 1 ( MPU 6050 Sensor로 3축 각도 알아내기 )

<구글에서 '3 axis gimbal'을 검색한 결과>
<Search result for '3-axis gimbal' on Google>

 동영상을 흔들림 없이 촬영하려면 어떻게 해야 할까? 물론 사람이 조심조심하면서 촬영할 수 있겠지만 힘들것이다. 그러나 3축 짐벌이라는 도구를 사용하면 흔들림 없이 깨끗한 촬영이 가능하다. 액션캠이 대중화 되면서 3축 짐벌 또한 수요가 증가하고 있다. 나 역시 깨끗한 촬영을 하고 싶었고 3축 짐벌의 가격을 찾아보았다. 하지만 3축 짐벌은 그 가격이 매우 비싸다...

 How do we shoot a video without shaking? Of course, you can shoot a video by your hands. But it will be very hard. However, you can easily shoot video without shaking by using a tool called  '3-axis gimbal'. As the action cam's popularity has increased, 3-axis's demand has increased too. I also wanted a clear video and search a price of 3-axis gimbal. However, the price was very very expensive...

그럼 내가 만들면 되지 뭐.

Well.. Maybe D.I.Y is better.



<나만의 목표>

1. 먼저 목표 가격은 인건비를 제외하고 재료비만 20만원 아래로 할 것이다. 
2. 모터는 서보모터를 이용한다.
3. MPU 6050 센서를 이용하므로 100만원대 제품 정도의 정밀도는 아니지만 가격대비 좋은 성능을 내도록 만든다.  

<My own goal>

1. Price of material is lower than 173 dollars.
2. Using digital servo motor
3. MPU 6050 is very cheap sensor. So I will do my best for good performance.


<MPU 6050 sensor>

 MPU 6050은 3축 가속도 센서+자이로 센서로 이루어진 센서로 2가지 값을 센싱할 수 있다. 

▲ 가속도 센서는 중력가속도를 기반으로 X,Y,Z축에 대한 직선 가속도를 측정한다. 외력에 의해 측정값이 왜곡될 수 있지만 시간이 흘러도 오차가 커지지 않는 다는 장점이 있다. 

▲ 자이로 센서는 X,Y,Z축의 각속도 변화량을 측정한다. 그런데 각도의 미분값 = 각속도이므로 각도를 알기 위해서는 이 값을 적분해줘야 한다. 그런데 적분을 하게 되면 누적오차가 쌓이기 마련이다. 가속도 센서보다는 실제 센서의 움직임과 같은 값을 내지만 누적 오차 때문에 시간이 흐를 수록 오차가 커지게 된다.

 따라서 필터를 이용해 이 둘의 장점만을 따오는 식으로 사용한다. 즉 실제 센서의 움직임과 같으면서 누적오차가 없는 결과가 나오게 되는 것이다. 보통 계산 주기 때문에 계산량이 상대적으로 가볍고 만들기 쉬운 상보필터를 많이 쓰는데, 칼만필터를 적용한다면 더 좋다고 한다. (여기서 다시 확인하는 칼만필터의 위력) 그러나 칼만필터는 계산량이 많아 계산 주기가 길어지기 때문에 Arduino Uno와 같은 보드로는 실시간제어가 힘들다는 문제가 있다. 어찌되었든 코드를 찾는게 문제였다.

 MPU 6050 is a sensor that made of 3-axis acceleration sensor and 3-axis gyro sensor. So MPU 6050 can measure acceleration and gyro together.

The acceleration sensor is based on gravity. It measure an acceleration from each X,Y,Z axis. An acceleration value may be distorted by an external force, but acceleration sensor has an advantage that the error does not increase overtime.

The gyro sensor measure a angular speed from each X,Y,Z axis. However, because of angular speed is differential of angle, we have to integrating this value. But the problem is because of integration, there is an accumulated error. The gyro sensor could measure almost corrected value from real movement. But it still have an accumulated error.

 So we have to use a filter for taking each advantage from 2 sensors. If we use a filter, we can always get a correct value from MPU 6050. Kalman filter is a popular filter. But it could heavy to arduino. So I have to find another solution from internet.



하지만 언제나 Google에는 해결책이 있다..!!

But there is always a solution in Google!!




 아래는 MPU 6050과 관련된 자료를 찾다가 발견한 사이트이다. 이는 아두이노 공식 홈페이지에서도 추천하는 방법이다.

 먼저 i2cdevlib 를 다운 받는다. 그리고 그 폴더안에 Arduino라는 폴더가 있다. Arduino 폴더 안에 있는 'MPU6050' 폴더와 'I2Cdev' 란 폴더를 원래 아두이노가 설치된 폴더의 libraries 폴더 안에 복사한다. 라이브러리를 추가하기 위함이다. 
 그리고 예제코드인 MPU6050_DMP6.ino 를 다운받아 컴파일을 해본다. 오류 없이 잘 된다면 일단 소프트웨어는 준비가 완료되었다. 이 예제코드는 센서안에 있는 DMP(Digital Motion Processor)로 부터 가속도와 자이로값을 토대로 쿼터니안값을 계산하고 이것을 이용해 원하는 값으로 변환하여 내뱉는 코드이다. Jeff Rowberg란 사람이 i2cdevlib란 라이브러리를 만들어 놓아서 그걸 이용해 만들었다고 한다. 

 코드 내용을 보면 쿼터니안 값, 오일러 각도 값, 가속도 각도 값, yaw pitch roll 값 등을 출력하는 부분이 있으니 필요한 부분을 쓰면 될 듯 하다. 나는 3축짐벌을 만들어야 하므로 yaw, pitch, roll 값을 오일러 값으로 출력하는 부분을 이용했다. 아래는 내가 수정한 부분이다. 

 Below is the link that I found. That solution is recommended by Arduino website.

 First, we have to add some libraries. Download i2cdevlib. And there is a folder named 'Arduino'. In 'Arduino' folder, there is 'MPU6050' folder and 'I2Cdev' folder. Copy 'MPU6050','I2Cdev' folder and paste in 'libraries' folder that is inside your installed arduino IDE folder. 
 And download an example code MPU6050_DMP6.ino and compile. If there is no an error, the basic thing is done. 

 In this example code, you can select output value by #define part. You can get quaternion, euler angle, yaw pitch roll value, etc.. And I use yaw pitch roll value from an example code. And below is edited part.



<Servo motor SETUP> - 서보모터 셋업

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================
int servoPin1 = 3, servoPin2 = 5, servoPin3 = 11;
Servo servo1, servo2, servo3;
void setup() {
        servo1.attach(servoPin1); 
        servo2.attach(servoPin2);
        servo3.attach(servoPin3);
        servo1.write(0); //Init the servo1 angle to 0
        servo2.write(0); //Init the servo2 angle to 0
        servo3.write(0); //Init the servo2 angle to 0
cs



<Control Servo motor> - 각 각도값에 따라 서보모터 컨트롤

        #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            Serial.print("ypr\t");
            Serial.print(ypr[0* 180/M_PI);
            servo1.write(map(ypr[0* 180/M_PI, -1801800180)); //Control servo1
            Serial.print("\t");
            Serial.print(ypr[1* 180/M_PI);            
            servo2.write(map(ypr[1* 180/M_PI, -90900180)); //Control servo2
            Serial.print("\t");
            Serial.println(ypr[2* 180/M_PI);
            servo3.write(map(ypr[2* 180/M_PI, -90900180)); //Control servo3
         
        #endif
cs



<Yaw, Pitch, Roll angle, from wikipedia > 

  그런데 ypr[0] (=Yaw)는 -180~+180이 되는데, ypr[1], ypr[2] (=Pitch, Roll)는 -90~+90 밖에 측정이 되지 않으므로 이에 맞게 서보모터가 움직일 수 있도록 map()을 사용하였다. 

 ypr[0] (=Yaw) can measure -180~+180. But ypr[1], ypr[2] (=Pitch, Roll) is only -90~90. So I used map().




<MPU 6050 핀 연결>

<MPU 6050 pin map>

▲ 5V <->VCC (You can also connect with 3.3V)
▲ GND <-> GND
▲ A5 <-> SCL
▲ A4 <-> SDA
▲ Digital pin 2 <-> INT (interrupt)

※나머지 핀은 연결하지 않는다.
※The remaining pins are not connected.


<dccDuino>

 Arduino Uno의 클론 보드인 dccDuino 이다. 마이크로 칩을 사용했다는 것과 암컷핀이 수컷핀으로 확장되어 암,수 핀이 모두 연결가능하며 전원핀도 확장되 었다는 것이 차이점이다. 인터넷에서 할인하여 5천원대에 구매했다. (정품의 약 1/6가격.. 그러나 성능은 동일하다. 왜 그런지는 밑에 나올 동영상을 보면 알게 될 것이다.) 다만 입력 전원이 조금 낮다는 점과 전용 드라이버를 다운받아야 PC에서 인식이 된다. 드라이버는 인터넷에서 쉽게 구할 수 있다. 귀찮으면 아래 링크로 다운로드 받자.








<데모 영상>


<MPU 6050 센서로 서보모터 컨트롤 하기>
<Servo motor control with MPU 6050 sensor>

 영상을 촬영하기 전 Yaw값이 steady state가 될 때까지 기다린 후 촬영하였다.(30초 정도 소요) 한번 steady state가 되면 그 이후로는 안정적인 값을 출력한다. Arduino Uno급 보드로도 충분히 정밀한 제어가 가능하다는 것을 알 수 있다.

 Before taking this video, I waited for Yaw value until steady state.(It takes maybe 30 seconds) In this video, we can sufficient accurate control with arduino-level board.
















<번외편>

<Extra>


<Hot Hand USB Wireless MIDI Controller>

 위 제품 영상중 2:02초 부터 나오는 장면을 보면 각축의 기울기에 따라 mapping된 knob값이 변경되는 것을 볼 수 있다. 
 저걸 보자마자 드는 생각..

 In that video from 2:02 seconds, the product control knobs by each axis angle.



저거 나도 충분히 가능한거 아냐?!

I think I can make like that!




  결론적으로 말하자면 가능하다. 물론 무선통신을 하는 건 블루투스 모듈이나 Xbee 모듈이 있어야 하므로 나중에 만들더라 치더라도 일단 기울기로 knob값 조절 기능은 가능하다.

 In conclusion, it is possible.



<MIDI Control>

        #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            //Serial.print("ypr\t");
            //Serial.print(ypr[0] * 180/M_PI);
            midiControl(0xB01, map(ypr[0* 180/M_PI, -1801800127));
            delay(10);
            //Serial.print("\t");
            //Serial.print(ypr[1] * 180/M_PI);
            midiControl(0xB02, map(ypr[1* 180/M_PI, -90900127));
            delay(10);
            //Serial.print("\t");
            //Serial.println(ypr[2] * 180/M_PI);
            midiControl(0xB03, map(ypr[2* 180/M_PI, -90900127));
            delay(10);            
        #endif
cs

 위에서 Yaw, Pitch, Roll 값을 이용해 서버모터를 제어하던 부분에 'midiControl' 이란 함수로 변경하였다. 각각 PC 프로그램에서 1,2,3 채널로 인식이 되어 control 값이 입력이 된다. control 값은 0~127사이의 값을 가져야한다.

 Instead of controlling the server motor using Yaw, Pitch, and Roll values, I changed the function to 'midiControl'. It have 1,2,3 channel and input control value to computer. control value should 0~127.

<midiControl function>

void midiControl(int st, int cc, int val) {
  Serial.write(st);
  Serial.write(cc);
  Serial.write(val);
}
cs

  midiControl function은 MIDI 규격으로 출력하게 해주는 역할이며 첫째 인자는 보내는 값이 음인지 컨트롤 값인지를 구분하는 것이고 두번째 인자는 각 음의 높이 혹은 컨트롤 채널을 의미하며 마지막 인자는 음일 경우 속도를, 컨트롤일 경우 값을 의미한다. 그러나 USB를 이용해 PC와 serial 통신으로 MIDI 값을 전송하는 것이기 때문에 중간에 2 가지 프로그램이 필요하다.

 'midiControl function' make a MIDI serial data. 'st' is distinguish whether sending data is key or control. 'cc' is key level or control channel. 'val' is velocity or control value. But arduino uno use a usb for serial communication with computer. So we need 2 more program.






 첫째로는 아두이노와 같은 디바이스로 부터 받은 serial 값을 MIDI 통신 값으로 전달하는 다리 역할을 하는 프로그램이다.
'hairless-midiserial'이란 프로그램이며 리눅스, 맥, 윈도우 버젼이 있다.

First program is 'hairless-midiserial'. It change serial data to MIDI data. 
This program is available for Linux, Mac, and Windows versions.





Link : loopmidi

 두번째로는 가상 midi port 역할을 하는 'loopmidi'란 프로그램이다. 윈도우버젼만 있다.

Second program is 'loopmidi'. It is a virtual midi port. Mac does not need a virtual midi port.(Because Mac support this thing)





자, 신호가 가는 순서를 정리하자면 이렇다.
Well, the signal flow like below.

MPU6050  ->  Arduino  ->  hairless-midiserial  ->  loopmidi  ->  Abletonlive



<데모 영상> - Demo

<MPU 6050 센서로 Abletonlive 입력하기>
<Control Abletonlive with MPU 6050>

각 축에 따라 노브값이 바뀌는 것을 알 수 있다.
Abletonlive의 임의의 knob와 MIDI 신호를 mapping 하는 것은 youtube에 많이 나와 있다.
아두이노에서 보내는 MIDI 신호 값을 Abletonlive에서 mapping 시키는 작업은 필수이다. 

It can be seen that this knob value is changed by each axis angle.
How to mapping of a knob with MIDI signals are a lot of on youtube.
In Abletonlive, it is necessary to map the MIDI signal values sent by Arduino.

2015. 10. 1.

성곽길


<성곽길>
<성곽길>


 2주년을 맞이하여 다녀온 성곽길.
성곽길이 혜화문부터 시작한다고 쓰여있지만.. 사실은 그 건너편에서 출발해야 한다.

너무나 맑고 쾌청한 가을하늘이었다. 언덕이 많았지만 성벽 때문에 생긴 그늘 덕분에 덥지않았다.

2015. 9. 22.

NVIDIA GPU Technology Conference (GTC) - 나이트리컨벤션


   오늘 한국 최초로 NVIDIA에서 GPU Technology Conference를 열었다. 종각역 근처의 나인트리컨벤션에서 개최된 이 행사는 NVIDIA의 GPU를 이용한 많은 응용과 기술들에 대한 콘퍼런스였다. 지인들과 함께 사전등록을 하고 방문을 하였다. 그곳에서는 GE, HP, NAVER 등 다른 업체들도 미니부스를 운영하고 있었다.



1. 미니부스


<GE Intelligent Platforms 미니 부스>

<GE 에서 만든 보드>
GE Intelligent Platforms 미니 부스에서는 NVIDIA에서 하드웨어를 제공 받아 만든 임베디드용 보드가 있었다. 
-40 ~ +70 ºC 에서도 견디며 크기는 작지만 성능은 굉장한 보드라고 하며 여기에 안드로이드를 포팅하여 전시하고 있었다. 
군사용으로도 쓰인다고 한다.


<NVIDIA 그래픽카드를 이용한 3D 모델>


< 실시간으로 계산하여 모니터에 출력하는 연기모양의 형상>



2. 기조 연설


<일찍 가서 사진상 아직 사람이 많지 않지만 이날 총 2000여명이 오셨다.>


<이용덕 한국 지사장 환영사>


<NVIDIA 솔루션 아키텍쳐 및 엔지니어링 부사장>
한국 지사장님의 환영사 후에는 외국 부사장님의 기조연설이 있었는데, 
물론 저번 GE Innovation Forum 2015 처럼 동시통역 서비스가 제공 되었다. 
간단하게 GPU 시장의 중요성과 그 파급효과에 대해 들을 수 있었다.

<KAIST 권인소 교수>
다음으로는 KAIST의 권인소 교수님이 로봇 '휴보'에 대해 설명을 했다.
어떤식으로 대회가 진행되었고 또 어떻게 준비를 했는지 그 과정과 결과에 대해 알 수 있었다.
그 이후에 다음소프트 송길영 CTO의 기조연설도 있었으나 촬영이 금지되었다. 


3. 점심 식사


<제공된 도시락>
먼저 선착순으로 도착한 사람에게는 위의 도시락을, 나머지 선착순 인원은 옥토버훼스트에서 식사를 했다. ( 정말 맛있음... )


4. Deep Learning

  점심식사 후에는 여러 섹션으로 나뉘어져서 각 시간마다 준비된 발표를 들을 수 있었는데 나는 애초에 딥러닝 때문에 참여를 한 것이기 때문에 계속해서 딥러닝만 들었다. 그 중에 기억에 남는 것이 2개 있었다. 하나는 의료진단이고 또 다른 하나는 음성 인식이었다.


1. 의료 진단


<위 3줄은 놔둬도 되는 종양, 아래는 유방암으로 발전 가능한 종양이다.  눈으로구분이 가능한가?>
유방암이나 결핵 검사를 위해 X-ray 혹은 채취한 세포 조직 등을 직접 사람이 보고 눈으로 판단해야 했던 부분을 
딥러닝을 통해 컴퓨터가 찾아내는 기술이다.


<종양의 심지어 위치도 알려준다.>
딥러닝을 이런 의료진단에 사용하는 이유는 기본적으로 의사에 의한 오진률을 최소화 하자는게 그 목적이다. 
물론 위험하지도 않은데 위험할 수 있다고 표현을 한다면 불필요한 검사를 해야하기 때문에 
사용자가 싫어할 수 있다는 변수까지 고려한다고 한다.
앞으로는 컴퓨터나 로봇이 대신 진단하는 것이 더 안전한 시대가 올지도 모르겠다.
이미 무인자동차의 경우 가까운 미래에 '사람이 운전하는 것이 불법인 시대'가 온다고 하는 말도 있다.


2. 음성 인식


<언어 인식과 이미지 인식을 함께.>
음성 인식에도 딥러닝이 사용된다. 물론 들은 언어를 쪼개서 단어와 단어간의 의미를 파악하고 
그들간의 관계를 넘어 내포된 의미까지 파악한다. 위 사진은 문장에서 단어를 인식할 때 실제로 이미지에서도 
그 단어가 의미하는 곳을 중점적으로 컴퓨터가 본다는 것을 보여준다.


<과거의 기억을 토대로 유추를 한다.>
잘은 모르겠지만 인간의 기억과 같이 근접한 과거에 대해 영향을 받아 입력된 단어를 기억속에서 그 의미를 유추해 낸다고 한다.
딥러닝이 음성인식에 활용되고 있다는 것은 머지않아 지금처럼 답답한 음성인식이 아니라 정말 정확하게 내가 말하는 의미를 파악하고 그에 맞는 결론을 도출해내주는 것들이 나올 가능성이 아주 높다는 것을 의미한다.


<직접 해볼 수 있다. http://deeplearner.fz-qqq.net/>
어떤 문장에서 단어를 인식하는 과정에서 그 단어의 '벡터화'가 필요하다고 하다.
쉽게말하자면 특징을 잡아내는 것이라고 생각하면 된다.
위 사이트를 들어가면 딥러닝을 체험해볼 수 있다. (체험형 같은 것이라 그런지 안되는 조합도 있다.)
3가지의 단어를 입력하면 그들의 공통된 특징을 출력하거나 그와 관련된 특징을 출력해낸다.


<기념품>
기념품이다. 선착순 200명에게 주는 스마트 충전usb와 기본 기념품인 노트북가방을 받았다.
둘다 정말 필요했는데!



  이번 컨퍼런스도 정말 많이 배우고 얻은게 많은 자리였다. 기술적인 것 뿐만아니라 좋은 연설들과 어떤 행사를 진행하는 과정도 배울 수 있었다. 앞으로 전시회도 많이 남아있는데 나머지도 모두 시간을 내어 꼭 참가하고 싶다.





감시카메라를 만들어보자(Let's make a cctv using a raspberry pi) - 2

  자, 저번에는 vnc서버를 이용해서 라즈베리파이에 원격 접속하는 것을 했다.
이번에는 cctv를 만들기에 앞서 무선랜을 설정하는 방법을 먼저 설명하겠다. 무선랜을 설정하기 위해서는 무선랜카드가 있어야한다.
 Well, the last time, we connected with RPi2 using a VNC server.
This time, before make a cctv, I explain how to use a wlan. We need a wlan card to use a wlan.


1. 무선랜 설정 (wlan setting)


  
1. lsusb 명령어를 이용하여 무선랜카드가 인식되는지 확인한다.
1. Input a lsusb command to check a wlan card has been recongized.

2. iwconfig 명령어를 이용하여 wlan이 잡히는지 확인한다. 처음에는 아무것도 연결되지 않았을 것이다.
2. Input a iwconfig command to check wlan has been detected. Maybe at first, there is no wlan.

3. iwlist 를 이용하여 주변 공유기를 검색한다. 이때 원하는 공유기의 SSID(ESSID) 와 IP주소(Address)를 기억해둔다.
3. Input iwlist command to find wlan signal. And remember your SSID and IP address.

4. /etc/wpa_supplicant/wpa_supplicant.conf 에 아래를 vi 등을 이용하여 추가한다.
4. Add the following lines by using the vi editor or any editor in /etc/wpa_supplicant/wpa_supplicant.conf

network={                
    ssid="SSID"                
    psk="PASSWARD"
}

cs

  물론 이렇게만 해놓으면 누가 라즈베리파이를 뒤져서 공유기 비밀번호를 알아낼 수 있다.
설마 그것이 꺼림칙하다면 인터넷에 암호화 하는 방법이 있으니 참고하시길.
 Of course, it can easy to be found by someone.
If you want to further strengthen security, just find on the internet how to do that.


5. 이제 라즈베리파이를 껏다 켜도 자동으로 무선랜이 연결되도록 하자. 아래의 명령어를 입력하자.
5. Now, let's make RPi2 that automatically connect with wlan even it was rebooted. Input the following lines.

cd /etc/ifplugd/action.d/
sudo mv ifupdown ifupdown.original
sudo cp /etc/wpa_supplicant/ifupdown.sh ./ifupdown
sudo reboot
cs


6. 이제 vnc로 무선랜을 통해 라즈베리파이에 접속하려면 할당된 라즈베리파이의 무선랜 IP주소를 이용해 접속하면 된다.
6. Now, if you want connect RPi2 using wlan then just use an wlan IP address.


이제 무선랜으로 원격접속이 가능하니 거리의 제약이 많이 없어졌다! 야호!

Now we can access to RPi with wlan. So there are not much a constraint for distance! Yay!


2. cctv 코드(code)


1. Basic code


#import
import os
import RPi.GPIO as GPIO
import datetime
import time
#set GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN)
#program start
print "Start!!"
#check a door is opened
try:
    while True:
        timeNow = datetime.datetime.now() #set timeNow value
        if GPIO.input(18== 1#if a door is opened, activate below
            print "\n-------------------------------------------------------------------"
            print "Door is opened!! - Taking a picture!!!!!"
            print timeNow #print timeNow value
            print "-------------------------------------------------------------------\n"
            os.system("raspistill -t 500 -vf -hf -o /home/pi/Desktop/images/$(date +\"%Y-%m-%d_%T\").jpg -w 960 -h 720") #taking a picture
        if GPIO.input(18== 0#if a door is not opened, activate below
                print "Door is closed..."
        time.sleep(1) #delay 1s
except KeyboardInterrupt:      
    GPIO.cleanup()
cs

  간단히 설명하자면 1초마다 문이 열렸는지 확인을 하다가 문이 열리면 외부명령어를 실행하는 os.system을 이용하여 사진을 찍는다.
이때 raspistill이라는 명령어로 사진을 찍게 되는데 몇가지 옵션이 있다.
  To explain briefly, This code just check 'the door is opened?' in every 1s. Then if the door is opened, use an external command 'os.system' to take a picture.
At that time, we used raspistill. And here is some option for raspistill.


1. -t 500 : 500ms 후에 찍는다
2. -vf : 수직반전
3. -hf : 수평반전
4. -o /home/pi/Desktop/images/$(date +\%Y-%m-%d_%T\").jpg  : /home/pi/Desktop/images 경로에 찍는 순간의 '년, 월, 일, 시간' 을 이름으로 하는 .jpg 확장자를 가진 이미지를 저장
5. -w 960 : 사진 폭
6. -h 720 : 사진 높이

1. -t 500 : take a picture after 500ms 
2. -vf : Vertical reverse
3. -hf : Horizontal reverse
4. -o /home/pi/Desktop/images/$(date +\%Y-%m-%d_%T\").jpg  : Save a '.jpg' picture file that name is 'Year, Month, Day, Time' at that moment. And the path is /home/pi/Desktop/images
5. -w 960 : Width of picture
6. -h 720 : Height of picture


2. With SMS code


-*- coding: utf8 -*-
"""
Copyright (C) 2008-2014 NURIGO
http://www.coolsms.co.kr
"""
#import
import os
import RPi.GPIO as GPIO
import datetime
import time
import sys
sys.path.append("..")
import coolsms
#Set GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN)
#Define sms method
def sms():
    api_key = 'INSURT YOUR API_KEY'
    api_secret = 'INSURT YOUR API_SECRET'
    to = 'INSERT NUMBER'
    sender = 'INSERT NUMBER'
    message = 'INSERT MESSAGE'
    cool = coolsms.rest(api_key, api_secret)
        status = cool.send(to,message,sender)
        print status
    
    return None
#Start program
print "Start!!"
#Set flag for sending sms
flag = True
#Check a door is opened
try:
    while True:
        timeNow = datetime.datetime.now() #set timeNow value
        if GPIO.input(18== 1#if a door is open, activate below
            print "\n-------------------------------------------------------------------"
            print "Door is opened!! - Taking a picture!!!!!"
            print timeNow #print timeNow value
            print "-------------------------------------------------------------------\n"
            os.system("raspistill -t 500 -vf -hf -o /home/pi/Desktop/images/$(date +\"%Y-%m-%d_%T\").jpg -w 960 -h 720") #taking a picture
            #sending sms once
            if flag is True:
                sms() 
                    flag = False
        if GPIO.input(18== 0#if door is not opened, activate below
                print "Door is closed..."
        time.sleep(1) #delay 1s
except KeyboardInterrupt:      
    GPIO.cleanup()
cs


  sms코드는 문이 열렸을 때 sms를 지정된 번호로 보내는 코드를 추가하였다. 이 서비스를 이용하려면 coolsms 홈페이지에서 제공하는 coolsms.py를 다운로드 받아서 cctv 코드와 가은 경로에 저장되어 있어야 한다. 서비스는 유료이며 회원가입시 기본금을 공짜로 준다. 연습삼아 쓰기에는 충분한 양을 준다.
 다른 방법으로는 웹사이트를 만들어서 실시간으로 확인하게 할 수 있으나 자취방의 공유기 설정을 바꿔야하기 때문에 포기했다..
 This sms code is just sending a sms to user when the door is opened. If you want this service, you have to download a coolsms.py file on coolsms homepage and save it in the same path with cctv code. This service is not free. But you can get a basic amount when you sign up. And that is enough for practice.
 Alternatively, it may be checked in real-time by creating a website. But I can not change my building's router port settings. So I just gave up..



3. 도어센서 설치 (Install a door sensor)


<라즈베리파이와 라즈베리카메라>
<A RPi2 and a RPi camera>


<도어센서>
<A door sensor>


<일단 전기테이프로 부착했다.>
<As a temporary solution, I just attached with electrical tape.>


<선 정리. 도와준 현수, 민수에게 감사를.>
<Clean lines. Thanks for hsjoe's and minsoo's help.>


<데모 영상>
<Demonstration video>


<문 열기 전 찍은 모습>
<A picture before the door is opened.>


<문을 열고 나서 자동으로 찍힌 모습>
<A picture after the door is opened.>


 이제 무선으로 원격접속이 가능하니 나중에 시간이 나면 문 앞쪽에 라즈베리파이를 설치해야 겠다.
 Now, I can wireless remote access to RPi so if I have a time, I will reinstall a RPi in front of the door.


참조(References)

-coolsms 홈페이지

-coolsms.py 다운로드 링크