2014년 5월 21일 수요일

좀 걱정스러운 휴대폰의 지문정보 및 생체정보 관리

아이폰의 TouchID http://support.apple.com/kb/HT5883?viewlocale=ko_KR&locale=ko_KR

스마트폰 지문 인식. 선택이 아닌 필수가 될까? http://review.cetizen.com/5595/view/23/5595/rview/special

삼성 보급형에도 지문 인식 http://gigglehd.com/zbxe/11484009#1

삼성전자, 홍채인식 가능한 스마트폰 선보인다 http://news1.kr/articles/1419752

바야흐로 몇몇 대기업들(skt, samsung, 등등)이 거의 모든 국민 (산간 도서 지역 거주자 및 찌져지게 가난한 몇몇 계층을 제외한)의 지문정보와 생체정보를 구축할 수 있는 환경이 모두 갖추어 졌다.
 앞으로 휴대폰의 저 구석탱이에 있는 다음과 같은 메시지는 대부분 보지 못할 것이다.

............
진단 및 사용내용
 ............
 자동으로 보냄



2014년 4월 9일 수요일

새로운 논문을 위한 아이디어 노트

사과의 품종을 정하고 현재 규정되어 있는 등금에 따른 표준 구형 모델을 제작
혹은, 설정이 고정된 영상 시스템에서 크기별로 영상을 획득하고 그 영상들의 평균 영상을 추려내는 방식으로 사과 영상에 대한 표준화 과정을 거친다.

이러한 표준 영상을 기반으로 구형 모양의 사과에서 발생하는 난반사를 줄이는 정규화 방법을 모색해 보자.


2014년 3월 21일 금요일

아두이노에 마우스 센서 갖다 붙이기

로지텍 마우스에 붙어 있는 마우스 센서를 사용하기 위해서 우선 열어 보았다. 센서 같이 보이는 칩의 상단에 표기된 봐로는 H2000이라고 되어 있지만, 실제로 정확한 마우스 센서의 이름은 HDNS 2000이다. 저렴한 마우스를 직접 이용하는 것이 손 쉬은 것은 필요한 부품은 일일이 구하로 다닐 필요 없이 약간의 기판 쪼가리만 가지고 있으면 아두이노와 연결 할 수 있다는 점이다.

실제로 작업에 들어 가기에 앞서 HDNS 2000의 데이터 시트를 살펴보자. 아래의 회로는 데이터 시트에서 추천하는 인터페이스 회로이다. 두 개를 제안하고 있지만, 내가 사용하고자하는 용도에는 다음의 회로가 적합하다.


 위의 회로에서 Cypress사의 Cyxxxx라는 것은 무시하고 HDNS2000과3.3V용 레귤레이터 그리고 다섯개의 신호선만 사용할 것이다. 실제로 로지텍 마우스를 열어 보면 거의 동일하다. 다섯개의 신호선중 NRESET이라는 신호선은 실제로 사용하지 않아도 무관한 신호선이다. 그냥 내버려 두어도 무관한다. 나중에 아두이노에서 때때로 센서를 초기화 해야 할 경우가 발생하면 그 때 가서 연결해보 무방하다. 아무튼 지금은 간단하기 네 개의 신호선 XA, XB, YA, YB만 사용할 것이다. 이 네 신호선에 대한 설명도 데이터 시트를 살펴보면 복잡하다. 예전에 마이크로 마우스를 건드려 본 경험이 있거나, 모터를 만지작 해 보았다면 encoder라는 것을 들어 보았을 것이다. HDNS2000은 아주 간단히 설명하자면 X축과 Y축 방향으로 encoder가 하나씩 들어 있는 칩으로 보면 정확할 것이다. 실제로 코드도 encoder를 다루는 방식으로 접근한다.

 

XA, XB, YA, YB 핀은 각각 아두이노의 D8, D9, D10, D11핀에 연결한다. 보면 알겠지만, 아쉽게도 외부 인터럽트 핀은 INT0, INT1으로 두개 밖에 지원하지 않는다.












간단히 이야기 하자면 HDNS 2000 센서는 X축과 Y축을 위해 각각 두 개의 엔코더 신호선을 제공한다. 아쉽게도 직접 영상을 얻어 올 수 있는 통로는 제공되지 않는다. 아무튼 총 4 신호선을 외부 인터럽트로 다루기 위해서 코드가 복잡해 진다. 그래서 이미 만들어 져 있는 코드를 아두이노 IDE에 외부 라이브러리 형태로 설치해야 한다. 다음의 누리집에 가면 pinchangeint라는 라이브러리를 받아 볼 수 있다.

 http://code.google.com/p/arduino-pinchangeint/downloads/list  

가장 최신의 것을 다운로드하고 윈도우 시스템의 경우 다음의 경로에

 C:\Users\Anonymous\Documents\Arduino\libraries  

압축을 해제하고, 다음의 코드를 컴파일하자.


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <PinChangeInt.h>
//#include <PinChangeIntConfig.h>
        
#define ledPin (13)
#define encoderXPinA (10)
#define encoderXPinB (11)
#define encoderYPinA (8)
#define encoderYPinB (9)

volatile unsigned int encoderXPos = 0;
volatile unsigned int encoderYPos = 0;
unsigned int lastReportedXPos = 1;
unsigned int lastReportedYPos = 1;
static boolean rotatingX = false;
static boolean rotatingY = false;

boolean XA_set = false;
boolean XB_set = false;
boolean YA_set = false;
boolean YB_set = false;

// the setup routine runs once when you press reset:
void setup() {                
  Serial.begin(9600);
  Serial.println("hello");

  pinMode(ledPin, OUTPUT);
  pinMode(encoderXPinA, INPUT);
  pinMode(encoderXPinB, INPUT);
  pinMode(encoderYPinA, INPUT);
  pinMode(encoderYPinB, INPUT);
  
  //digitalWrite(encoderXPinA, HIGH);
  //digitalWrite(encoderXPinB, HIGH);
  //digitalWrite(encoderYPinA, HIGH);
  //digitalWrite(encoderYPinB, HIGH);
  
  // Attach pin change interrupt service routines from the Wiegand RFID readers
  PCintPort::attachInterrupt(encoderXPinA, doEncoderXA, CHANGE); // attach a PinChange Interrupt to our pin on the rising edge
  PCintPort::attachInterrupt(encoderXPinB, doEncoderXB, CHANGE); // attach a PinChange Interrupt to our pin on the rising edge
  PCintPort::attachInterrupt(encoderYPinA, doEncoderYA, CHANGE); // attach a PinChange Interrupt to our pin on the rising edge
  PCintPort::attachInterrupt(encoderYPinB, doEncoderYB, CHANGE); // attach a PinChange Interrupt to our pin on the rising edge

}

// the loop routine runs over and over again forever:
void loop() {
  //rotatingX = true; // reset the debouncer
  //rotatingY = true; // reset the debouncer
  
  if (lastReportedXPos != encoderXPos ||
      lastReportedYPos != encoderYPos) {
    Serial.print("X:");
    Serial.print(encoderXPos, DEC);
    lastReportedXPos = encoderXPos;
    Serial.print(" Y:");
    Serial.println(encoderYPos, DEC);
    lastReportedYPos = encoderYPos;
  }
  
  digitalWrite(ledPin, HIGH);
  delay(200);
  digitalWrite(ledPin, LOW);
  delay(200);               // wait for a second
}

// Interrupt on A changing state
void doEncoderXA(void)
{
  // debounce
  if (rotatingX) delay (1);  // wait a little until the bouncing is done
  // Test transition, did things really change? 
  if (digitalRead(encoderXPinA) != XA_set) {  // debounce once more
    XA_set = !XA_set;
    // adjust counter + if A leads B
    if (XA_set && !XB_set) encoderXPos += 1;
    rotatingX = false;  // no more debouncing until loop() hits again
  }
}

// Interrupt on B changing state, same as A above
void doEncoderXB(){
  if (rotatingX) delay (1);
  if (digitalRead(encoderXPinB) != XB_set) {
    XB_set = !XB_set;
    //  adjust counter - 1 if B leads A
    if (XB_set && !XA_set) encoderXPos -= 1;
    rotatingX = false;
  }
}

// Interrupt on A changing state
void doEncoderYA(void)
{
  // debounce
  if (rotatingY) delay (1);  // wait a little until the bouncing is done
  // Test transition, did things really change? 
  if (digitalRead(encoderYPinA) != YA_set) {  // debounce once more
    YA_set = !YA_set;
    // adjust counter + if A leads B
    if (YA_set && !YB_set) encoderYPos += 1;
    rotatingY = false;  // no more debouncing until loop() hits again
  }
}

// Interrupt on B changing state, same as A above
void doEncoderYB(){
  if (rotatingY) delay (1);
  if (digitalRead(encoderYPinB) != YB_set) {
    YB_set = !YB_set;
    //  adjust counter - 1 if B leads A
    if (YB_set && !YA_set) encoderYPos -= 1;
    rotatingY = false;
  }
}

코드를 테스트 하기위해서 렌즈와 뚜껑을 덥고,  아두이노 IDE에서 실행 이미지를 다운로드 하여 실제로 마우스 처럼 굴러가는 지 확인해 보았다.













 아직은 정확도를 확인해 보지는 못하였다.


참고 자료
http://photonicsguy.ca/_media/projects/electronics/opticalmouse/h2000.pdf
http://www.pighixxx.com/pgdev/Temp/Arduino_uno_Pinout.pdf
http://playground.arduino.cc/Main/RotaryEncoders#.UysL-IUmk7k
http://forum.arduino.cc/index.php?topic=84040.0
http://code.google.com/p/arduino-pinchangeint/
http://arduino.cc/en/Guide/Libraries#.UysE2IUmk7k
http://codeformatter.blogspot.com/
http://hilite.me/

2014년 2월 28일 금요일

[작업중] 555타이머를 이용한 전원 지연 회로

555타이머를 이용한 전원 지연회로는 진공관 앰프를 제작할때 많이 사용한다. 진공관 앰프는 특성상 예열 과정이 필요하다. 진공관 앰프에 전원을 인가할때 동시에 스피커에도 전원이 인가되면 '퍽 퍽' 하는 굉음이 발생하기도 한다. 이러한 전원 인가시 발생하는 굉음을 차단하기 위해서 전원 지연회로를 사용한다. 일반적으로 전원 지연회로로 알려져 있지만 실제로는 스피커 지연연결회로가 되겠다.

원리는 555에 저항(R)과 캐패시터(C)에 의해 결정되는 시간 이후에 555타이머의 출력이 발생되게 하는 것이다. 로직은 555타이머가 담당하고 있지만, 실제로 전원연결이나 스피커 신호를 연결하는 것은 Relay가 맏고 있다.  Relay는 전기 신호로 유도되는 전자기힘으로 동작하는 물리적인 스위치이다. 그래서 전기신호가 인가 되었을때 스위치가 켜지게 설정할 것인지 아니면 전기 신호가 인가 되었을때 스위치가 단선 되도록 할 것인지는 용도에 따라 고민해 보아야 하는 문제이다. 각각 장단점을 가지고 있다.

Relay에 전원이 인가 되었을때 스위치가 연결되도록 한 설정에서는 회로에 전원이 혹은 스피커에 음성 신호가 연결되어 정상 동작하는 동안 Relay에는 항상 전원을 공급해 주어야 한다. 이 경우에 원래의 회로에서 소모되는 전력 이외에 추가적인 전력 소비가 아무래도 발생한다. 그리고 반대의 경우 전원이 인가 되지 않을때 스위치가 연결되도록 한 설정에서는 회로가 정상 동작할때 발생하는 추가적인 전력 소비가 없다 하지만, 다음과 같은 단점이 존재한다. relay 전원이 인가 되지 않을때 심지어는 전체 전원이 인가되지 않았을 경우에도 스위치는 연결된 상태로 남아 있게 된다. 그러다 전체 전원이 인가될 때 relay에 동시에 전원이 인가되어 순식간에 스위치가 단선되고 일정 시간이 지난 후에 다시 스위치가 연결되는 과정을 거친다. 요약 하자면 스위치는 연결된 상태 였다가 전원이 인가되면 단선되고 일정 시간이 지난 후에 다시 연결된다. 이 상태에서 불가피하게 초기에 전원이 인가된 동안 순간적인 스위치 연결은 피할 수 없다. 이 부분은 적당한 용량의 캐패시터를 사용해서 해결 가능하지만, 아무래도 순간적인 오작동에도 민감한 회로의 경우 특히 명심해 두어야 한다.

아래는 555타이머를 이용한 시지연 회로이다.


렐리이에 전원이 인가 될 시 동작하는 회로

렐리에 전원이 인가 되지 않을 때 동작하는 회로


2014년 2월 15일 토요일

자전거의 휠 사이즈 700c와 26"

* 700c 혹은 ISO 622mm
로드 자전거, 투어링, 레이싱 그리고 산악 자전거와 로드 바이크의 이종 결합 형태인 cyclo-cross 에서 널리 사용된다. 림의 지름이 622mm으로 대부분의 자전거의 명칭이 유럽에서 처음 사용되어져서 인치로 표기되는 산악 자전거의 명칭과 혼동을 잃으킨다. 700이라는 수치는 림과 타이어를 포함한 지름이 700mm 정도가 되는 휠을 일컫는 말로 추정된다. 그리고 "29er" 타입의 (산악용 자전거의 휠사이즈인 29"?) 림 사이즈와 동일하기 때문에 이런 스타일의 자전거가 많이 사용된다.

* 26" 혹은 ISO 559mm
산악 자전거에 많이 사용되고 그 기원은 미국의 초기 산악 자전거 개척자들에 의해서 수립되었다. 26" 휠의 일반적인 림의 지름은 559mm으로 22"이고 여러가지 요인들로 인해 요새는 29"나 27.5"의 휠도 산악 자전거에 많이 사용되고 있다.

참고

http://en.wikipedia.org/wiki/Bicycle_wheel
http://en.wikipedia.org/wiki/29er_%28bicycle%29
http://piaarang.com/311

2014년 2월 13일 목요일

[작업중] Swing Arm 방식의 노트북 스탠드

예전에 탁상용 백열등 스탠드 중에서 스프링으로 지지되는 방식이 있었는데 이것을 활용하면 노트북 스탠드로써 아주 편리할 것 같다는 생각이 문득 들었다(http://www.amazon.com/Boston-Harbor-TL-WK-134E-WH-3L-Swing-White/dp/B0026KLI6C/ref=sr_1_2?s=hi&ie=UTF8&qid=1392230944&sr=1-2&keywords=boston+harbor+architect+swing+arm+desk+lamp). 그리고 Kickstarter에서 한번 본적있는 로봇 팔도 이 생각을 구체화하는데 도움이 될 것 같았다(https://www.kickstarter.com/projects/ufactory/uarm-put-a-miniature-industrial-robot-arm-on-your?ref=live).

인터넷에서 swing arm lamp로 검색을 해보면 많은 것들을 참고 삼아 볼 수 있다. 아마도 스프링 방식으로 되어있는 것들이 여전히 많이 보이는 것이 이방식이 가장 안정 적인 방식이 아닌가 싶다. 다른 기타 방식 베이링 방식이나 각 관절을 조여서 고정하는 방식은 그 수명과 편리성 적인 측면에서 문제가 있어 보인다.


swing arm 방식의 백열등 (출처: www.amazon.com)
 



해당 제품의 구체적인 사진들
 (출처 : http://www.amazon.com/Boston-Harbor-WK-618E-3L-Swing-Holder/dp/B002ZKHZC4/ref=sr_1_7?s=hi&ie=UTF8&qid=1392235016&sr=1-7)




그럼 기본 바탕은 swing arm lamp방식으로 하되  헤드 부분에 노트북 받침이 들어가야 하기 때문에 이 부분에 대한 수정이 이루어 져야 한다. 이 부분에 대한 수정과 위에서 살펴본 로봇 팔의 모터 부분을 자동차 트렁크나 창문 고정에 사용되는 실린더방식을 사용하여도 훌룡한 것이 나올 것 같기도 하다. 문제는 돈이지만 말이다.


네개의 자유도를 가진 로봇팔 (출처: www.kickstarter.com)

이 세상에는 새로운 것이 없는 것 같다. 찾아 보니 이미 이와 같은 개념의 제품이 나왔다(http://www.laptopdesk.net/ipad-swing-arm-mount.html). 항상 이럴때 김이 세지만.  뭐 사람 생각이 거기서 거기라는 생각이 든다. 아래의 그림은 해당 제품의 구체적인 도면쯤 되겠다.

swing arm ipad mount 도면 (출처: http://www.laptopdesk.net/ipad-swing-arm-mount.html)
이렇게 된거 이 제품에서 좀 더 개선할 점이 없는지 살펴 보아야 겠다.



2014년 2월 12일 수요일

애플이 삼성을 초토화 시킬 수 있는 유일한 방법

삼성 본사가 있는 땅 값 비싼 강남 말구

삼성의 핵심 연구 부서가 몰려 있는 수원에 더도 말고 덜도 말고

미국 현지와 같은 노동 조건의 캠퍼스를 짓고

몇 년만 유지하고 신나게 연구 인원 빨아 들이면 된다.

안되면 말구 ㅋㅋ.