티스토리 뷰

Processing

[Kinect with processing] Feedback From Arduino

생각많은 소심남 2012. 8. 25. 16:39

이전 포스트까지는 컴퓨터에서 아두이노로 데이터를 줘서 표현하는 방식을 했었습니다. 이제는 반대로, 아두이노로부터 데이터를 받아서 컴퓨터에 뿌려주는 것을 해보고자 합니다. 물론 이런 정보 교환이 이뤄져야 컴퓨터는 아두이노가 접해있는 환경에 대한 정보를 알 수 있을 것이고 그에 대한 반응을 표현할 수 있을겁니다. 이런 걸 일종의 피드백이라고 합니다. 

 사람도 꾹 찌르면 반응이 옵니다. 그리고 그에 대한 반응을 상대방에게 돌려줍니다. 물론 이런건 자연스런 현상이지만 기계의 세상에서는 이 피드백이라는 것을 정의하지 않는 한,사용자의 입력에 대한 반응을 내보이지 않습니다. 보통 이런 입력을 감지하는데 있어서 많이 사용하는 것이 스위치라는 겁니다. 스위치는 두가지 입력값을 줄 수 있습니다. 하나는 켜졌다는 의미의 1, 다른 하나는 꺼졌다는 의미의 0을 줄 수 있는 겁니다. 

물론 이런 입력정보를 두개만 줄수도 있고, 지난 포스트에 잠깐 나왔던 potentiometer 같은 경우는 항상 불이 켜져있는 상태에서 저항의 크기를 제어하고 그에 대한 반응을 표현하는 것 역시 어떻게 보면 사용자가 어떻게 보면 입력을 부여하고 그에 대한 피드백으로 LED의 밝기를 볼수 있었던 거지요. 

 이번 프로젝트에서는 이렇게 값을 가변적으로 줄수 있는 스위치 중 조도센서를 사용해서 제어를 해보고자 합니다. 또 하나의 회로를 구성해야 되겠군요.



그중에 눈여겨봐야 할 것이 바로

 


조도센서입니다. 우리가 사용하는 스마트폰에도 하나씩 들어가 있는 소자입니다. 물론 이렇게 생긴게 아니지요. 참고로 이 소자의 정확한 명칭은 Light Dependent Resistor(LDR) 즉 저항입니다. 즉 이 저항의 값에 따라서 흐르는 전류가 틀려질 것이고 결국 그 전류가 외부 환경에 대한 피드백이 되는 것입니다. 이걸 관찰하기 위한 회로도는 다음과 같습니다.



기존의 LED 부분은 앞 포스트에서 보셨으니까 아실거고 새롭게 등장하는게 LDR과 저항 부분일텐데요.저항이 왜 달렸을까 궁금하시지는 않으신가요? 일종의 전압분배의 개념으로 생각하시면 됩니다.


키르히호프의 전압법칙(KVL)에 따르면 전체 전압은 나머지 소자에 가한 전압의 합과 같습니다. 이말은 즉 저항과 LDR 전체에 걸린 전압은 각각에 걸린 전압의 합과 같다는 뜻입니다. 그런데 만약 앞의 저항이 없다면 전체 전압은 LDR에 걸리는 전압과 같게 됩니다. 앞에서 말했다시피 LDR은 빛에 따라서 저항값이 바뀌는 소자인데 어느 순간인가에는 그 저항값이 0이 되는 구간도 발생하겠지요. 이 때 쇼트현상이 발생하는 겁니다. 이런 현상을 막기 위해서 앞단에 저항을 달아주는 겁니다. 이게 계속 나오는 개념인 풀업 저항이라는 겁니다. 반대로 접지부분에 저항이 달려있으면 풀다운 저항이 되는 것이겠지요. 

 두개의 차이는 소자에 확실한 0의 값을 줄 것인가 1의 값을 줄것인가의 차이인데 물론 디지털로직을 사용할 때에는 중요한 개념으로 작용합니다만, 지금은 별 필요가 없을겁니다. 


 자 회로를 작성했으니까 본격적으로 아두이노에 프로그램을 넣어야겠지요. 그런데 기존 내용과 거의 차이가 없습니다. 차이가 있다면 이번에 입력으로 넣을 AnalogIn에 대한 값을 읽어오는 부분이 추가되는 것이겠지요. 

우선 이부분은 익숙할 겁니다. 추가된게 있다면 sensorValue라는 변수인데 이걸 LDR에서 받아오는 값을 넣는 역할로 하겠습니다.loop에서 그걸 코드로 구현하면 되겠지요.


이 다음은 기존 코드와 동일합니다.


이렇게 해놓으면 Serial Console을 통해서 LDR을 통해서 받은 값이 출력될 겁니다. 이제 프로세싱을 통해서는 과연 어느 조건에서 어떤 결과를 내놓을 것인가만을 결정지으면 되겠지요. 


 그래서 기존 코드에서도 수정되는것이 거의 없습니다. LDR을 통해서 어떤 값을 넘었을때의 결과와 미달했을 때의 결과를 다르게만 해주면 그걸로 우리가 보고자 하는 결과는 나오는 겁니다. 예제상에서는 그 값의 결과를 각각 ColorStream과 DepthStream이 나오게 하는 것으로 해놓았습니다. 한번 보시지요.


일단 아가 앞에서 받은 값을 받아놓을 변수가 필요합니다. 

그리고 setup에서 RGBImage를 활성화시키고 draw에서 그 조건문을 구현하면 됩니다.




그런데 뭔가 잊은거 없나요?

분명 photoVal이란 변수는 만들어놨는데 이 정보를 정의하는 부분이 없습니다. 시리얼통신을 통해서 아두이노 상의 정보를 키넥트로 표현해야 되는데 그에 대한 언급이 전혀 없는 것이지요. 그래서 그걸 해결하기 위한 방안이 하나의 이벤트로 만들어서 처리하는 방안입니다.그걸 다루는 메서드가 바로 serialEvent라는 겁니다. 당연히 앞에서 선언한 시리얼 변수가 인자로 포함되어 있어야 해당 포트에 대한 정보를 받아올 수 있을겁니다.

사실 시리얼 통신을 통해서 ASCII 코드로 구성된 데이터들이 넘어가는데 이 데이터 안에는 당연히 여기서는 LDR을 통해서 제어되는 전압 값들이 전달될겁니다. 하지만 이게 하나의 Stream을 이루면서 계속 전달이 되고 있기 때문에 하나의 데이터안에 이전값들도 포함되어 있습니다. 그래서 이걸 구분지을만한 무언가가 필요합니다. 다행히 값이 전달되면서 중간중간에 newline이 포함되어 있기에 그걸 토대로 분리를 할 수 있습니다. 우선 이렇게 구분한 값을 버퍼에 놓고 그 버퍼값으로 연산하는 과정을 setup에서 구현해줘야 합니다. 그래서 마지막에 한 줄을 더 붙입니다.



이렇게 해놓으면 \n(newline)이 있는 부분까지만 뚝 떼어서 그걸 가지고 SerialEvent를 돌릴 수 있게 됩니다. 다시 내려와서 그 부분까지의 데이터를 스트링형 변수에 집어넣습니다.



그 후에 이데이터를 분석하면 되겠지요. 그래서 데이터가 있을 경우에만 딱 처리를 해주면 되겠습니다.


여기서 잠깐 나오는 trim이라는 메서드는 그냥 빈곳 없이 채워주는 겁니다. 보통 SSD 쓰시는 분이라면 트리밍이라고 많이 들어보셨을텐데 중간중간의 빈 여백을 채워서 효율성을 높이는 기능이었지요. 여기서도 trim이라는게 바로 데이터가 쭉 있을때 여백없이 그냥 채운다는 뜻입니다. 여기까지 하고 한번 결과를 볼까요?


보이시나요? 스탠드불을 켰다껏다 하면서 스크린상에 나타나는 이미지가 RGB냐 Depth로 달라지고 있습니다. 당연히 어두우니까 photoVal값이 작아서 RGB이미지를 내보내고 있을 것이고 스탠드를 켜서 밝아지면 그 조건문에 따라서 Depth를 내보내고 있습니다. 물론 그와 별개로 지난 포스트에서 구현했던 LED 제어는 계속 동작되는 것도 볼 수 있었지요.

https://dl.dropbox.com/u/96808368/processing/SerialKinect.zip

간단하게 시리얼통신을 통해서 아두이노와 키넥트를 연결해보았습니다. 키넥트로 다른 기기를 제어하는 것. 조금씩 가까워짐을 느낍니다. 여러분들도 해보면서 직접 느껴보셨으면 좋겠네요.


댓글