2015. 8. 26.

부산 태종대

 


왼쪽에 태종대에 있는 등대가 보인다.



졸려서 버스타고 태종대역에서 내리면 바로 보이는 작은 카페에서 차가운 더치커피를 샀다.

  

집으로 가는 길에 하늘이 이뻐서 찍었다.


  날씨가 흐려서 오히려 더 좋았던 태종대. 덥지도 않고 사람도 별로 없었다. 태종대를 다 보고 나오려고 하는데 비가 내렸다. 

꼭 한번 다시 가고 싶은 곳이다.

박수 스위치를 만들어보자 (Clapping switch with arduino)



<건국대학교 호수>
<The lake of Konkuk university>

  살면서 가장 귀찮은 일이 하나 있다면 무엇일까? 토익스피킹을 보기전에 잠깐 시간이 나서 벤치에 앉아 생각을 했다.
  What is the most annoying thing in usual? I just seated on the bench and thought about that before a TOEIC Speaking test.

  생각해보니 나는 자기전에 불을 끄러 가는 것이 그랬다.
  In my case, that is 'turn off the light before go to bed'

  언젠가 박수를 치면 불이 꺼지는 장치를 본 적이 있다. 그걸 한번 만들어보면 어떨까? 물론 블루투스를 이용해서 더 깔끔하게 on/off 제어를 할 수 있겠지만 난 '박수'를 이용해 제어하고 싶었다. 언제 또 스마트폰을 켜서 불을 끄겠는가? 그냥 박수한번이면 꺼져야한다. 전기 배선을 이용해서 깔끔하게 처리할 수 있지만 내 집이 아닌데다가 위험하기도 해서 버튼을 대신 눌러주는 장치를 고안했다.
  Someday, I saw a device that is if someone clap his/her hands then light is off automatically. So, how about do it my self? If I use a Bluetooth, I can make it more clear to control of on/off the light. But I want use a clapping sound from my hands. There is no time to turn on the smartphone and using an application for turn off the light. It has to be done by just a hand clap. I can use my electrical wiring for control but it is too dangerous and my house is not mine at all. So I made a device that just pushing a buttons.


내가 사용한 것은 아래와 같다.
I used it as follows:

1. Sound sensor (DFR0034) x 1
2. Servo motor (SG-90) x 2
3. Arduino x 1






1. 소프트웨어 (Software)


<processing>

  내가 만들 것은 박수소리를 센서가 받아들여, 특정 시간내에 박수소리가 2번만 나게 되면 on/off 제어를 하는 장치를 만들 것이다. 우선 센서를 이용해 박수소리를 processing 이라는 프로그램으로 그려보았다. processing은 데이터를 시각화 처리할 때 많이 쓰는 모양이다. 오픈소스이며 개발환경(IDE)은 아두이노의 그것과 매우매우매우 흡사하다. 아두이노와 연동도 잘 되므로 앞으로 눈여겨 볼 프로그램이다. 내가 쓴 코드는 아래와 같다. (기본적으로 제공하는 코드를 약간만 수정했다.)
  I will make a device that is detect a clapping sound from a sensor and if the clapping sounds is twice in specific time then control on/off the light. First I used a program named 'processing' for drawing a clap sound value. processing is a program that process a value to a visual. It is an opensource program and IDE is very similar to the Arduino IDE. And it is well linked with Arduino. The code I used is shown below. ( I just modify the code from an original provided code.)

 // Graphing sketch
 // This program takes ASCII-encoded strings
 // from the serial port at 9600 baud and graphs them. It expects values in the
 // range 0 to 1023, followed by a newline, or newline and carriage return
 // Created 20 Apr 2005
 // Updated 18 Jan 2008
 // by Tom Igoe
 // This example code is in the public domain.
 import processing.serial.*;
 Serial myPort;        // The serial port
 int xPos = 1;         // horizontal position of the graph
 float easing = 2;
 float easedVal=0;
 void setup () {
 // set the window size:
 size(1200500);        
 // List all the available serial ports
 println(Serial.list());
 // I know that the first port in the serial list on my mac
 // is always my  Arduino, so I open Serial.list()[0].
 // Open whatever port is the one you're using.
 myPort = new Serial(this, Serial.list()[0], 9600);
 // don't generate a serialEvent() unless you get a newline character:
 myPort.bufferUntil('\n');
 // set inital background:
 background(0);
 }
 void draw () {
 // everything happens in the serialEvent()
 }
 void serialEvent (Serial myPort) {
 // get the ASCII string:
 String inString = myPort.readStringUntil('\n');
 if (inString != null) {
 // trim off any whitespace:
 inString = trim(inString);
 // convert to an int and map to the screen height:
 float inByte = float(inString); 
 float inByteColor = map(inByte, 010230255);
 //Graph color
 if (inByte > 200)
   stroke((250+inByteColor)/2+12734255);
 else if (inByte > 100 && inByte < 200)
   stroke((100+inByteColor)/2+12734255);
 else if (inByte > 50 && inByte < 100)
   stroke((50+inByteColor)/2+12734255);
 else
   stroke(127,34,255);
 inByte = map(inByte, 010230, height);
 float targetVal = inByte;
 easedVal = (targetVal) * easing;
 // draw the line:
 line(xPos, height, xPos,  height-inByte);
 // at the edge of the screen, go back to the beginning:
 if (xPos >= width) {
 xPos = 0;
 background(0); 
 } 
 else {
 // increment the horizontal position:
 xPos++;
 }
 }
 }
cs




<박수 신호>
<Signal of clapping sounds>

  아무런 처리 없이 박수신호를 그려보면 위 사진과 같이 나온다. 그러나 약간 노이즈가 있는 것을 알 수 있다. 그래서 아두이노 홈페이지에 있는 smoothing라는 방법을 이용해 아날로그 신호를 좀 더 부드럽게 해봤다. 
  Without any processing, the graph is like above. But there is a noise. So I used a 'smoothing' from Arduino website.


<부드럽게 처리한 박수 신호>
<Signal of clapping sounds after smoothing>

  그 결과 노이즈가 어느정도 사라지고 부드럽게 표시가 되는 것을 알 수 있다. 여러차례 테스트를 해보고 적정한 타이밍과 값을 찾아냈다. 아래는 최종적으로 사용한 아두이노 코드이다.
  As a result, there are just little noise and smooth graph. I used a 'try and error' method for searching an appropriate value and timing. Below is the Arduino code, using the final.



#include <Servo.h> //header for servo motor
//This is for average
const int numReadings = 10;
int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
//This is for clap switch 
int servoPin1 = 4, servoPin2 = 6//servo1, servo2 pin
int soundSensorPin = A0;
int claps = 0//count of clap
long detectionSpanInitial = 0
long detectionSpan = 0;
boolean lightState = false
Servo servo1, servo2; 
void setup() {
  Serial.begin(9600);
  servo1.attach(servoPin1); 
  servo2.attach(servoPin2);
  servo1.write(95); //Set the servo1 angle ( middle angle )
  servo2.write(70); //Set the servo2 angle ( middle angle )  
  //Set for get an average
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;
}
void loop() {
  
  //////////////////////////////////////////////////
  //I used a code for get an average value from   //
  // https://www.arduino.cc/en/Tutorial/Smoothing //
  //////////////////////////////////////////////////
  
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(soundSensorPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;
  // if we're at the end of the array...
  if (readIndex >= numReadings)
    // ...wrap around to the beginning:
    readIndex = 0;
  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  //////////////////////////////////////////////////
  
  //Now, I will use this average value. Because just the original anlaog value has a noise.
  //////////////////////////////////////////////////////////////////////////////////
  // I used a code from here.                                                     //
  // http://en.code-bude.net/2014/12/08/how-to-build-a-clap-switch-using-arduino/ //
  //////////////////////////////////////////////////////////////////////////////////
  
  if (average >= 120// detect clap
  {
    if (claps == 0// If it is first clap,,
    {
      detectionSpanInitial = detectionSpan = millis(); // reset detectionSpanInitial, detectionSpan time
      claps++
    }
    else if (claps > 0 && millis()-detectionSpan >= 200// minimum Span is 100 millisec.
    {
      detectionSpan = millis(); // update detectionSpan
      claps++;
    }
  }
  if (millis()-detectionSpanInitial >= 500// Maximum Span is 400 milisec.
  {
    if (claps == 2// If clap counts is 2, turn on or off the light.
    {
      if (!lightState) 
        {
          lightState = true// change state and turn on the light
          servo1.write(135); 
          servo2.write(110);  
          delay(500); //delay for pushing the button
          servo1.write(95);
          servo2.write(70);  
        }
        else if (lightState)
        {
          lightState = false// change state and turn off the light
          servo1.write(55); 
          servo2.write(30);  
          delay(500); //delay for pushing the button
          servo1.write(95);
          servo2.write(70);  
        }
        delay(1000); //delay after change state
    }
    claps = 0//reset clap count
    
  }  
  Serial.println(average,DEC);
  //////////////////////////////////////////////////////////////////////////////////
}
cs







2. 하드웨어 (Hardware)


자 이제 소프트웨어는 끝났다. 이제 하드웨어를 만들어보자.
Well, software is done. Let's make a hardware.


<높이 측정>
<Measuring height>

  우선 나는 실제 버튼을 눌러줄 장치를 만들 것이기 때문에 그에 맞는 하드웨어를 제작해야 했다.
First, I will use a device that pushing the button. So the device has to fit my environment.





 그 후에 간단한 도면을 그리고 서보모터가 움직일 공간과 메커니즘을 생각했다.
After that I drew simple drawings and thought about servo motor mechanism and space for servo motor.







  그리고 박스를 이용해 제작을 하기 시작했다. 서보모터가 움직여서 버튼을 누를 수 있게 제작하였다. 아래는 메커니즘을 보여주는 프로토타입 동영상이다.
  And I made it using a boxes. I made it that servo motor can push the button. Below is a prototype video that showing how it works.





<prototype>

  영상을 보면 실시간으로 processing을 이용해 그래프도 그려지는 것을 알 수 있다. 
박수소리를 들으면 서보모터가 스위치를 켜거나 끄는 메커니즘이다.
As you can see in this video, you can see the graph is drawn by processing in real-time.
The mechanism is just pushing on/off button when a clapping sounds is detected.




<전선 정리>
<Cleaning wires>


<센서 고정>
<Fixing a sensor>


<받침대 부분 제작>
<Make a stand>


<완성된 모습>
<Finished>

  음.. 원래는 전기테이프로 다 감으려고 한게 아닌데, 방수의 문제도 있고 붙이다보니 차라리 다 붙이는게 깔끔해보여서 저렇게 다 감아버렸다. 위에 봉은 고정용으로 해논 것이고 원할때는 탈부착이 가능하다. 받침대 왼쪽으로는 전원선이 들어가는 구멍이 있다.
  Well.. there is no plan that all the device is wrapped by an electrical tape. But there is an issue of waterproof and it is more clean then wrapped only a parts. A little pillar above a device is for fixing. And it is detachable. Left of a stand has a hole for power line.



<시현 영상>
<Video of demonstration>

잘 작동되는 것을 알 수 있다.
You can see that a device works well.





<방열판을 부착한 Arduino Due>
<Arduino Due with heat sink>

  나중에 Arduino Uno나 더 값싼 MCU를 구한다면 교체할 생각이다. 저기에 8만원 정도의 고스펙을 가진 Due를 쓰기에는 너무 아깝기 때문이다.
  If I buy an Arduino Uno or more cheaper then Due, I will change a MCU. It is waste that using an Arduino Due( Expensive and has a high degree of specification )







출처(Reference) :

아두이노 코드 참고 ( Arduino code )
http://en.code-bude.net/2014/12/08/how-to-build-a-clap-switch-using-arduino/

아두이노 smoothing 참고 ( Arduino smoothing )
https://www.arduino.cc/en/Tutorial/Smoothing

아두이노의 아날로그 신호를 processing으로 그리는 코드 참고 ( Draw a graph using processing )
https://www.arduino.cc/en/Tutorial/Graph



P.S.
코드는http://colorscripter.com 을 이용해서 포스팅하였습니다.