개인 프로젝트에서 사용하려고 주문한 Adafruit 5채널 터치 센서 모듈 AT42QT1070 이라는 모듈이 도착했다.


[그림 1] 센서 모듈 (제품 홈페이지)


사용법은 정말 간단한데 전원(1.8V~5.5V)을 연결한 후 입력 핀에 (전도성) 터치 패드를 연결하면 출력 핀에 터치 여부에 따라서 디지털 출력이 나오게 된다. I2C 통신 같은 기능 없이 이렇게만 사용할 수 있다. 도전 패드의 최소 크기는 6x6mm 이다.


 간단하게 VDD에 3.3V를 인가하고 GND도 연결하고 입력 쪽 핀들을 터치해 보니 출력쪽의 LED가 반응하는 것을 볼 수 있다. 각 출력에 LED가 달려 있어서 디지털 출력 신호를 눈으로도 확인할 수 있었다.


 이 모듈의 치명적인 단점은 한 번에 하나의 입력만 감지한다는 것이다. 즉, 동시에 여러 개의 터치를 처리하지 못한다. 여러 개를 터치해도 오직 하나의 출력만 나온다. 이것은 상당히 치명적인 단점이므로 프로젝트에서 사용할 때 이 부분을 고려해야 한다.




Posted by 살레시오

댓글을 달아 주세요

 아두이노의 디지털핀 두 개와 저항 하나로 터치 센서를 구현할 수 있는데 관련 객체를 제공하는 것이 바로 Capacitance Sensing Library 이다.

기본 개념과 구성 회로

정전용량식 터치 센서의 개념도는 아래 그림과 같다.

[그림 1] 정전용량식 터치 센서의 개념도


이 개념도를 보면 두 개의 핀을 사용하는데 하나는 발신 핀(send pin) 이고 다른 하나는 수신 핀(receive pin)이다. 이 두 핀을 저항으로 연결하고 수신 핀에 터치할 도체(foil)를 연결한다. 만약 이 도체를 터치를 하면 수신 핀 단의 정전용량이 틀려지고 발신 핀에서 신호를 보낼 때(즉 발신 핀이 on되었을 때) 수신 핀이 기립 시간(rising time, 발신 핀이 on 된 후 수신핀이 on이 되는데 걸리는 시간 간격)이 변하게 된다. 이 변화를 감지하여 터지가 되었는지 안 되었는지를 판단하는 것이다.

해당 라이브리리 설치와 사용법

 이 기능을 아두이노에서 사용하려면 먼저 라이브러리를 다운로드 받아서 설치해야 한다. 아래와 같은 절차를 따른다.


  1. 소스를 다운로드 받는다.( CapacitiveSensor04.zip )

  2. 압축을 푼 후 그 안의 CapacitiveSensor 폴더를 복사해서 Arduino/libraries/ 폴더에 붙인다.

  3. 아두이노 IDE에서 Sketch>Import Library>CapacitiveSensor 메뉴를 선택한다.


위와 같이 했다면 IDE에 다음과 같이 헤더파일이 인클루드 된다.


#include <CapacitiveSensor.h>


이 라이브러리에서는 CapacitiveSensor라는 클래스가 있는데 이것의 인스턴스는 다음과 같이 초기화 할 수 있다.


CapacitiveSensor CapacitiveSensor(byte sendPin, byte receivePin);

 

여기서 sendPin과 receivePin 은 저항이 연결된 두 개의 디지털 핀을 지정해주면 된다. 이제 이 인스턴스의 메소드(함수)로 다음과 같은 것들이 있다.

long capacitiveSensorRaw(byte samples)


이 함수는 감지된 정전용량 값을 반환이며 반환값은 무단위이다. 입력으로 주어지는 samples 는 (byte형이므로 0-255 사이의 값) 샘플링 횟수를 지정해 주는 것이다. 이 값이 커지면 리턴값의 분해능이 커지는 대신 속도가 느려지게 되므로 적당한 값을 선택해야 한다. 리턴값은 각각의 샘플링에서 얻어진 값을 모두 더한 값이며 평균값이 아니다.


long capacitiveSensor(byte samples)


이 함수 역시 감지된 정전용량 값을 반환이며 반환값은 무단위이다. 앞의 함수와 다른 점은 터치가 안 되었을 때의 값(기본값)을 추적하여 현재 감지된 값에서 그 값을 뺀 다음 반환한다. 따라서 터지가 안 된 상태라면 0에 가까운 작은 값을 반환하고 터치가 되었다면 그것 보다는 큰 숫자를 반환한다.


 기본값(터치가 안 되었을 때의 정전용량 값)은 CS_Autocal_Millis 라는 상수에 저장된 시간 마다 자동으로 조정된다. 초기값은 20000 밀리초 (20초)이다. 이 갱신 시간은 set_CS_Autocal_Millis() 함수를 이용해서 변경할 수 있다.


void set_CS_Autocal_Millis(unsigned long autoCal_millis);


자동 갱신 기능을 끄려면 매우 큰 값(0xFFFFFFFF)으로 지정하면 된다.


 만약 즉시 기본값을 조정하려면 다음 함수를 호출하면 된다.


void reset_CS_AutoCal()


그리고 사용 빈도는 낮지만 다음 함수는 capacitiveSensor()함수나 capacitiveSensorRaw()함수의 타임아웃 시간을 지정해주는 함수도 있다.


void set_CS_Timeout_Millis(unsigned long timeout_millis);


이 함수는 CS_Timeout_Millis 내부 변수를 변경하는 함수인데 초기값은 2000 밀리초(2초)이다. 타임아웃시간이란 발신핀이 on 되었는데도 수신핀이 on이 되지 않을 경우 언제까지 기다려야 하는가를 정하는 것이다. 타임아웃 시간이 지나도 수신핀이 on이 되지 않으면 -2를 반환한다.

저항값의 선택

저항값은 다음과 같은 기준으로 선택한다.

  • 1 MΩ (혹은 이것보다 다소 작은 용량) : 완전히 터치되었을 때에만 반응시키고자 할 때

  • 10 MΩ : 4~6인치 정도 떨어진 곳에서도 반응시킬 때

  • 40 MΩ : 12~24인치 정도 떨어진 곳에서도 반응시킬 때 (도체의 크기에 따라 가변적임)


즉, 저항값이 커지면 감도도 높이지고 반응 속도는 느려진다. 또한 터치부가 노출된 금속판이라면 발신부에서서 on 신호를 발생시키지 못 할 가능성도 있다. 수신핀을 작은 용량의 커패시터 (100 pF ~ 0,01uF) 를 통해서 접지시키면 센서의 안정도를 개선시킬 수 있다.

실제 예제 프로그램

 회로도는 다음과 같다. 아두이노 우노와 1MΩ 저항 하나로 구성한다.

[그림 2] 실험 회로도


다음 프로그램을 실행하면 D3핀 쪽의 리드선을 터치할 때 LED가 켜진다.


#include <CapacitiveSensor.h>
#define LED 13
CapacitiveSensor cs23 = CapacitiveSensor(2,3);
void setup() {
   pinMode(LED, OUTPUT);
   cs23.set_CS_Autocal_Millis(0xFFFFFFFF);
   Serial.begin(9600);
}
void loop() {
   long start = millis();
   long total1 = cs23.capacitiveSensor(30);
   (total1>10) ? digitalWrite(LED, HIGH):digitalWrite(LED, LOW);
}



Posted by 살레시오

댓글을 달아 주세요

 이번에는 터치 센서를 한 번 터치하면 LED가 켜지고 다시 터치하면 LED가 꺼지도록 동작하는프로그램을 작성하도록 하겠다. 여러 방법이 있겠지만 인터럽트(interrupt)를 이용하는 것이 가장 일반적이다.


 다음 프로그램은 우노의 11번 핀에 부저가 달렸고 3번 핀에 터치센서가 달렸다고 가정하고 작성한 예제이다.


#define TS 3
#define BUZ 11
void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
   pinMode(BUZ, OUTPUT);
   pinMode(TS, INPUT);
   attachInterrupt(INT1, toggleLed, RISING);
}
void loop() {
   digitalWrite(BUZ, HIGH);
   delay(50);
   digitalWrite(BUZ, LOW);
   delay(450);
}
void toggleLed() {
   digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN) );
}


 setup()함수에서 attachInterrupt(INT1, toggleLed, RISING) 를 수행하여 INT1 핀(3번 핀)에 toggleLed()함수를 붙였다. 이 ISR 함수는 rising edge 에서 호출된다.


 그리고 loop() 함수에서는 부저를 0.5초마다 한 번씩 울리는 일 외에는 하지 않는다. 터치센서의 값을 읽는 코드는 어디에도 없다는 것에 주목해야 한다. 터치 센서의 출력값이 0에서 1로 변하는 순간 함수 toggleLed()가 (하드웨어적으로) 자동으로 호출된다. 그러면 main()함수에서 빠져나와서 toggleLed()함수를 수행한 후 다시 돌아와서 계속 수행하게 된다.


아두이노 강좌 전체 목록 (TOP) >>>

C++ 언어 전체 강좌 목록 >>>

c{ard},n{ad016}

Posted by 살레시오

댓글을 달아 주세요

 여기에서는 터치센서를 이용하여 디지털 입력 값을 받는 실험을 진행해보도록 하겠다. 시중에서 구할 수 있는 터치센서 모듈의 외형은 다음 그림과 같다.


[그림 1]  터치센서 모듈


터치센서의 금속판을 터치할 때 출력 신호가 바뀐다. 즉, 터치시에 HIGH를 아닐 때는 LOW 신호를 내보낸다.


 이 모듈은 선이 세 가닥이 있다. 두 가닥은 전원선이고 나머지 하나는 신호선이다. 이 신호선을 아두이노의 디지털 핀에 연결하면 되는데 예를 들어서 3번 핀에 연결한다면 다음과 같다.

[그림 2] 터치센서 모듈을 우노의 3번 핀에 에 연결한 모양


 이 모듈의 동작은 간단하다. 터치가 안 되어 있다면 신호선으로 LOW 신호가 나오고 터치가 되었다면 HIGH 신호가 나온다. 따라서 이 디지털 신호를 읽으면 터치 패널에 터치가 되었는지 아닌 지를 판별할 수 있다.


 단순하게 터치가 된 상태라면 LED가 켜진 상태를 유지하고 아니라면 LED도 꺼진 상태를 유지하는 매우 간단한 프로그램을 작성해 보도록 하겠다.


#define TS 3 // 터치센서에 연결된 핀 번호
void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
   pinMode(TS, INPUT);
}
void loop() {
   int iTouched = digitalRead(TS);
   digitalWrite(LED_BUILTIN, iTouched);
}


이것을 더 간단하게 줄이면 다음과 같이 iTouched 변수를 생략할 수 있다.


#define TS 3 // 터치센서에 연결된 핀 번호
void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
   pinMode(TS, INPUT);
}
void loop() {
   digitalWrite(LED_BUILTIN, digitalRead(TS));
}


이 프로그램이 실행되면 터치 상태를 계속 읽어들여서 터치되었다면 LED를 켠다.


아두이노 강좌 전체 목록 (TOP) >>>

C++ 언어 전체 강좌 목록 >>>

c{ard},n{ad009}


Posted by 살레시오

댓글을 달아 주세요