터치 센서를 직접 만들고 싶을 때 유용한 모듈, MPR121 터치센서 모듈입니다. 터치를 이용한 각종 인터페이스 장치를 만드는데 아주 유용합니다.

hqdefault

MPR121은 정전 용량 터치(Capacitive Touch Sensor) 센서 모듈입니다. Capacitive(Capacitance) 란 의미는 전하를 저장하는 물체라는 뜻입니다. 즉, 센서가 일정량의 전하를 저장하고 있다가 외부 접촉에 의해 이 값이 바뀔 경우 터치를 인식하는 원리입니다.

MPR121 터치센서 모듈은 한 모듈 당 최대 12개의 터치를 인식할 수 있습니다. 인식된 결과는 I2C 통신으로 읽어올 수 있으며, IRQ 인터럽트 핀을 지원하기 때문에 터치 상태가 바뀔 때 알려줄 수도 있습니다.

상세한 스펙은 아래 문서를 참고하세요.

 

 

연결 방법

 

아래처럼 I2C의 기본 연결 방법대로 연결하면 됩니다. IRQ 핀은 터치의 변화가 감지되었을 때 알려주는 인터럽트 핀입니다. 따라서 필요한 경우 IRQ 를 아두이노 우노 기준 D2 또는 D3 인터럽트 핀에 연결해서 사용해도 됩니다. loop() 반복함수를 빠르게 돌면서 터치 입력을 계속 체크하는 경우 인터럽트 핀(IRQ)은 사용하지 않아도 됩니다.

mpr121_wiring

 

 

스케치

 

라이브러리 없이 사용도 가능한데.. 코드가 좀 복잡해집니다. 아래 링크에서 소스코드를 받아 사용하면 됩니다.

라이브러리는 아래 링크에서 받을 수 있습니다.

라이브러리에는 MPR121test.ino 파일이 들어있습니다. 이 스케치를 열어보면 사용법을 알 수 있습니다.

#include <Wire.h>
#include "Adafruit_MPR121.h"

// You can have up to 4 on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap = Adafruit_MPR121();

// Keeps track of the last pins touched
// so we know when buttons are 'released'
uint16_t lasttouched = 0;
uint16_t currtouched = 0;

void setup() {
  while (!Serial);        // needed to keep leonardo/micro from starting too fast!

  Serial.begin(9600);
  Serial.println("Adafruit MPR121 Capacitive Touch sensor test"); 
  
  // Default address is 0x5A, if tied to 3.3V its 0x5B
  // If tied to SDA its 0x5C and if SCL then 0x5D
  if (!cap.begin(0x5A)) {
    Serial.println("MPR121 not found, check wiring?");
    while (1);
  }
  Serial.println("MPR121 found!");
}

void loop() {
  // Get the currently touched pads
  currtouched = cap.touched();
  
  for (uint8_t i=0; i<12; i++) {
    // it if *is* touched and *wasnt* touched before, alert!
    if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
      Serial.print(i); Serial.println(" touched");
    }
    // if it *was* touched and now *isnt*, alert!
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
      Serial.print(i); Serial.println(" released");
    }
  }

  // reset our state
  lasttouched = currtouched;

  // comment out this line for detailed data from the sensor!
  return;
  
  // debugging info, what
  Serial.print("\t\t\t\t\t\t\t\t\t\t\t\t\t 0x"); Serial.println(cap.touched(), HEX);
  Serial.print("Filt: ");
  for (uint8_t i=0; i<12; i++) {
    Serial.print(cap.filteredData(i)); Serial.print("\t");
  }
  Serial.println();
  Serial.print("Base: ");
  for (uint8_t i=0; i<12; i++) {
    Serial.print(cap.baselineData(i)); Serial.print("\t");
  }
  Serial.println();
  
  // put a delay so it isn't overwhelming
  delay(100);
}

 

가장 중요한 부분은 I2C 통신을 이용해 현재 터치 값을 읽어오는 부분이겠죠. 아래 코드가 여기에 해당합니다.

  currtouched = cap.touched();
  
  for (uint8_t i=0; i<12; i++) {
    // it if *is* touched and *wasnt* touched before, alert!
    if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
      Serial.print(i); Serial.println(" touched");
    }
    // if it *was* touched and now *isnt*, alert!
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
      Serial.print(i); Serial.println(" released");
    }
  }

여기서 currtouched, lasttouched 변수는 2바이트 정수형 변수입니다. 2바이트이기 때문에 16개의 비트를 저장할 수 있습니다. 즉, 이 변수에 12개의 터치 값의 변화가 0 또는 1로 기록됩니다.

만약 12개의 터치 모두 인식된 상태라면, 센서에서 읽어온 현재 터치값 currtouched 변수는 [0000 1111 1111 1111] 값을 가집니다. lasttouched 는 이전 터치값을 저장하는 변수입니다. 따라서 두 개의 변수 currtouched, lasttouched 를 이용하면 터치 인식 여부를 알 수 있습니다.

말이 좀 어려운데… 그냥 위 코드를 적당히 변형해서 사용하면 됩니다.


 

여러개의 MPR121 모듈 연결

 

MPR121 모듈을 추가해서 인식 가능한 터치의 수를 늘릴 수 있습니다. (최대 4개 모듈 연결 가능) 그러기 위해서는 MPR121 모듈의 I2C 주소를 모두 다르게 설정해줘야 합니다. MPR121 모듈은 I2C default address 값이 0x5A로 세팅되어 있습니다.

ADD(어드레스) 핀을  VSS, VDD, SDA, SCL 핀과 연결하면 I2C address 값이 0x5A, 0x5B, 0x5C, 0x5D 로 바뀝니다. 상세한 내용을 datasheet와 아래 링크들을 참고한 뒤 시도하세요.