본문 바로가기

ESP32

ESP32 터치 버튼 시작하기 [코드 및 배선 다이어그램 포함]

반응형

 

 

ESP32 터치 버튼 시작하기 [코드 및 배선 다이어그램 포함]

 

ESP32 기반 보드에는 내장된 "터치 버튼"이 있습니다. 터치 버튼은 기계적 스위치 없이 작동하므로 마모되지 않으며 구매할 다른 구성 요소가 없습니다! 터치 버튼은 "정전 용량"을 사용하여 손가락과 같은 것이 특정 ESP32 핀이나 핀에 연결된 것에 가까이 다가가거나 터치할 때를 감지합니다.

 

Arduino touchRead() 함수는 이 정전 용량을 읽고 GPIO 핀이 터치될 때를 확인할 수 있습니다.

 

이 수업에서는 간단한 Arduino 코드로 이러한 ESP32 터치 버튼을 사용하는 방법을 정확히 알아봅니다.

 

정전 용량 터치란?

 

이것은 ESP32 터치 버튼을 사용하는 실용적인 접근 방식이 될 것이지만, 약간의 맥락이 영혼에 좋다고 생각합니다...

 

정전 용량은 전기 구성 요소가 전하 형태로 전기를 저장하는 능력입니다.

 

환경은 구성 요소의 정전 용량뿐만 아니라 구성 요소 주변의 전기 "필드"를 방해하거나 교차하거나 접촉하는 모든 것에 영향을 미칩니다. ESP32가 일부 핀을 정전식 터치 버튼으로 사용할 수 있게 해주는 것은 이러한 정전 용량 변조입니다.

 

터치 버튼은 손가락이 핀에 가까이 다가가거나 터치할 때와 같이 GPIO 핀의 정전 용량에서 발생하는 미세한 변화를 감지합니다.

 

터치 버튼은 얇은 보호 커버나 방수 케이스와 같은 다른 물체를 통과할 수 있습니다! 이러한 속성 덕분에 터치 버튼은 방수 사용자 인터페이스, 숨겨진 버튼, 움직이는 부품이 없는 저렴한 PCB 키패드(부수어야 할 것이 적음 😀)와 같은 고유한 애플리케이션에 적합합니다.

 

Apple에서 정전식 터치를 사용하고 있습니다... 여러분도 사용할 수 있습니다! 정전식 터치 버튼(전 세계 인구의 대부분이 사용!)의 가장 보편적인 애플리케이션은 스마트폰 터치 스크린입니다.

 

스마트폰은 보이지 않는 전선과 패드를 사용하여 정전식 터치 버튼 매트릭스를 만듭니다. 이 매트릭스는 사람이 화면에서 어디를 터치했는지와 얼마나 세게 눌렀는지 감지하는 데 사용됩니다.

 

터치 감지 GPIO는 단순히 "켜짐/꺼짐" 또는 "터치됨/터치되지 않음" 값을 등록하는 것이 아니라, 시간이 지남에 따라 커패시턴스가 어떻게 변하는지에 따라 범위를 읽습니다. 이것이 스마트폰이 터치 시 "압력"과 같은 것을 판단할 수 있는 방법입니다.

 

ESP32 터치 버튼 활성화 핀

 

ESP32 제품군에는 터치가 가능한 여러 GPIO 핀이 있습니다. ESP32 개발 보드에 따라 이러한 모든 커패시티브 터치 핀에 액세스할 수도 있고 그렇지 않을 수도 있습니다. 아래의 "일반" WROOM 핀아웃을 참조하세요.

 

 

 

 

터치 활성화 핀은 ESP32-DevKitC에서 주황색으로 강조 표시됩니다.

 

이 문서에서 참조하는 Arduino Nano ESP32는 ESP32 프로세서에 NORA-W106 모듈을 사용합니다. NORA 모듈은 다음과 같은 터치 버튼 기능을 제공합니다.

 

Arduino Nano ESP32 터치 가능 핀

 

Arduino Nano ESP32 Touch Capable pins

NORA-W106 Module pin # Arduino Nano ESP32 Pin #
GPIO14 A7
GPIO13 A6
GPIO4 A3
GPIO9 D6
GPIO1 A0
GPIO7 D4
GPIO6 D3
GPIO12 A5
GPIO11 A4
GPIO10 D7
GPIO2 A1
GPIO8 D5
GPIO5 D2
GPIO3 A2

 

 

여기에서 Nano ESP32 치트 시트를 참조하세요. Arduino Nano ESP32 또는 일반 WROOM 모듈을 사용하지 않는 경우 특정 모듈에 대한 유사한 핀아웃 다이어그램을 찾을 수 있습니다.

 

ESP32 터치 버튼 Arduino 기능

 

Arduino 내장 라이브러리 코드는 내장 함수 touchRead()를 통해 터치 버튼 기능에 대한 액세스를 제공합니다.

 

touchRead(TOUCH_PIN); //TOUCH_PIN은 A2, D2, D3와 같은 표준 Arduino PIN#입니다. . .

 

. touchRead() 함수는 GPIO 핀 번호를 허용하는 단일 인수를 사용합니다. 이 인수는 터치 값/커패시턴스를 읽을 PIN입니다.

 

터치 버튼에서 값을 읽으려면 두 단계가 필요합니다.

 

먼저 프로세서에 입력으로 핀을 사용하겠다고 알려야 합니다.

 

pinMode(TOUCH_PIN, GPIO_MODE_INPUT); // setup() 함수 내부에 넣습니다. 그런 다음 touchRead() 함수를 사용하여 "터치 값"을 읽습니다.

 

//TOUCH_PIN의 현재 터치 값을 읽습니다.

 

touch_value_t touchValue = touchRead(TOUCH_PIN); // loop() 함수 내부에 넣습니다.

 

touchRead() 함수는 부호 없는 정수(touch_value_t)를 반환합니다. 이는 0과 약 40억 정도의 정말 큰 숫자 사이의 값을 표현하는 멋진 방법입니다.

 

Arduino Nano ESP32에서 touchRead() 함수는 터치를 나타내는 큰 숫자와 해제를 나타내는 작은 숫자를 반환합니다. 이것은 다른 Arduino 설명서와 다른 것 같으므로 Arduino의 실수일 수 있지만 다른 보드와 코드를 사용할 때는 터치 임계값이나 비교 값을 적절히 조정해야 할 수 있습니다.

 

"터치 버튼"을 작동시키려면 어떻게 해야 하나요?

 

이 예제에서는 다음이 필요합니다.

 

  • ESP32 개발 보드(Arduino ESP32 Nano를 사용 중입니다)
  • 납땜이 없는 브레드보드(선택 사항이지만 편리함)
  • 단일 점퍼 와이어(선택 사항이지만 편리함)

 

먼저 ESP32 개발 보드를 컴퓨터에 연결하고 Arduino IDE를 엽니다.

 

Arduino IDE 드롭다운 목록에서 "Arduino Nano ESP32"를 선택하거나 Nano ESP32를 사용하지 않는 경우 다른 보드를 선택합니다.

 

이 시점에서 이전에 ESP32 보드를 사용한 적이 없다면 IDE에서 계속 진행하는 데 필요한 파일과 드라이버를 다운로드하여 설치하라는 메시지가 표시되므로 아직 설치하지 않았다면 계속 진행하세요. 다음은 Arduino ESP가 아닌 보드를 설정하는 방법에 대한 지침입니다.

 

여기에 표시된 대로 테스트를 위해 GPIO 핀에 연결된 와이어로 보드를 연결할 수도 있습니다.

 

 

IDE가 준비되면 맨 끝/피복이 벗겨진 "점퍼 케이블"을 개발 보드에 추가하여 터치 기능을 테스트합니다. 이제 코드로 넘어가겠습니다!

 

ESP32 정전식 터치 버튼 코드

 

아날로그 핀 A2가 좋은 선택입니다(위 이미지 참조). 프로그램에 하드 코딩하는 대신 핀 번호에 변수를 사용하는 것이 좋습니다. 이렇게 하면 나중에 여러 줄의 코드를 편집하지 않고도 핀을 변경할 수 있습니다. 다음과 같습니다.

 

const uint8_t TOUCH_PIN = A2; // 이 변수를 모든 함수 외부에 배치합니다. 전역 변수입니다.

 

그러면 코드의 어느 곳에서나 "A2" 대신 "TOUCH_PIN" 변수를 사용할 수 있습니다. 그런 다음 TOUCH_PIN의 핀 모드를 GPIO_MODE_INPUT으로 설정해야 합니다. 이렇게 하면 ESP32에 이 GPIO 핀을 정전식 터치 핀으로 활성화하라고 알립니다.

 

pinMode(TOUCH_PIN, GPIO_MODE_INPUT); // setup() 함수 내부에 배치합니다.

 

이 작업이 끝나면 터치 버튼 값을 읽는 일만 남았습니다. 다음과 같습니다(다음 코드를 loop() 함수 내부에 배치합니다).

 

//use a variable threshold for the touch input, adjust this as needed to get the sensitivity required for your project
touch_value_t threshold = 100000;

//read the current touch value of the TOUCH_PIN
touch_value_t touchValue = touchRead(TOUCH_PIN);

//check if touchValue is greater than the threshold
if(touchValue >= threshold){

  //turn on the Green LED when a touch is detected
  digitalWrite(LED_GREEN, LOW);

}else{

  //turn off the Green LED when a touch is NOT detected.
  digitalWrite(LED_GREEN, HIGH);
}

 

 

그게 다입니다! 위의 코드를 사용하면 터치 버튼을 누르면 녹색 LED가 켜지고 놓이면 꺼집니다. 필요에 따라 더 많은 버튼에 대해 설정 및 if 문을 추가할 수 있습니다. 위의 코드는 단일 임계값을 사용하여 LED를 켜고 끕니다. 다른 LED를 토글하거나 터치를 WiFi 또는 BLE로 보내 인터넷이나 스마트폰과 상호 작용하도록 수정할 수 있습니다.

 

다음은 직렬 모니터에 "touchValue"를 보고하는 간소화된 스케치입니다.

 

//use a const for the TOUCH_PIN so we can change the pin as needed without having to update multiple locations in code
const uint8_t TOUCH_PIN = A2; //A2 corresponds to the A2 pin on the board, Analog Pin 2

//everything inside the setup() function runs once at the start of the program
void setup() {

  //enable input mode for the TOUCH_PIN
  pinMode(TOUCH_PIN, GPIO_MODE_INPUT);

  //enable the serial port at 115200 speed (baud rate)
  Serial.begin(115200);

  //spit out a start message so we know things are working.
  Serial.println("ESP32 Capacative Touch");
}

//everything in the loop() function happens in order over and over as fast as possible
void loop() {

  //read the current touch value of the TOUCH_PIN
  touch_value_t touchValue = touchRead(TOUCH_PIN);

  //debug the touchValue on the serial port
  Serial.println(touchValue);

  //wait 1 seconds before we loop so we don't flood the serial port
  delay(1000);

  //loop() again...
}

 

 

정전식 터치 버튼에 인터럽트 사용

 

loop() 함수를 사용하여 touchRead()를 통해 "touchValue"를 가져오는 것은 대부분 애플리케이션에서 작동합니다. 그러나 loop()에서 다른 작업을 많이 수행하는 경우 혼란스러울 수 있으며 코드의 다른 부분 간의 타이밍을 조정하기가 매우 어려울 수 있습니다.

 

"인터럽트"를 입력합니다...

 

인터럽트를 사용하면 프로세서가 이벤트가 발생할 때 수행 중인 작업을 일시 중지하고 이벤트를 처리한 다음 이벤트 전에 수행 중이던 작업으로 돌아갈 수 있습니다.

 

인터럽트는 ESP32와 같은 단일 프로세서 또는 단일 코어 컴퓨터에서 "멀티태스킹"을 허용하는 주요 기능입니다. 인터럽트는 실리콘 시대의 시작부터 이 목적으로 사용되었습니다.

 

ESP32는 루프에서 폴링(변경 사항을 계속 확인)하는 대신 터치 버튼 입력이 인터럽트를 트리거하도록 허용합니다. 단서로는 (현재) 터치 인터럽트는 "터치 안 함"에서 "터치됨"까지의 "활성" 터치에 대해서만 발생한다는 것입니다. 예를 들어, 인터럽트로 버튼을 눌렀는지 놓았는지 알 수 없고, 터치되었는지만 알 수 있습니다.

 

버튼을 눌렀는지 놓았는지 확인해야 하는 경우 루프에서 touchRead()를 사용하는 것이 아마도 가장 좋은 방법일 것입니다.

 

touchAttachInterrupt()

 

인터럽트가 작동하려면 이벤트가 프로세서에 등록되어야 하며 이벤트가 발생할 때 호출할 함수도 함께 등록되어야 합니다.

 

표준 인터럽트의 경우, 함수인 attachmentInterrupt()가 사용되지만, 터치 인터럽트의 경우 터치 임계값을 인수로 사용하는 보다 구체적인 함수가 있습니다.

 

이 함수는 touchAttachInterrupt()라고 하며, touchAttachInterruptArg()라는 대체 함수도 있습니다.

 

함수 touchAttachInterrupt()는 임계값을 기반으로 기본 터치 인터럽트를 등록합니다. 대체 함수인 touchAttachInterruptArg()는 약간 더 진보되어 있으며 인터럽트 함수에 전달할 다른 인수를 포함할 수 있습니다.

 

일반적으로 인터럽트 함수는 "콜백 함수" 또는 콜백이라고 합니다. "연결 인터럽트 함수"는 프로세서에 콜백을 등록하여 특정 인터럽트나 이벤트가 발생할 때 무엇을 해야 하는지 알 수 있도록 합니다.

 

인터럽트를 활성화하려면 먼저 setup() 또는 loop() 함수 외부에 콜백 함수를 만들어야 합니다. 예를 들어:

 

//use a bool to store the last touch value

bool touch1detected = false;

//create a callback function to run when the touch event happens
//you don’t want to do a lot of processing in the callback function 
//as this delays the processor from getting back to its normal loop

void touchInterrupt1(){

  //update the variable
  touch1detected = true;
}

 

 

그런 다음 setup()에 콜백 함수를 등록해야 합니다.

 

touchAttachInterrupt(TOUCH_PIN, touchInterrupt1, threshold); //put this in the setup() function

 

그런 다음 loop()에서 "touch1detected" 상태를 처리합니다. 

 

void loop(){

//check if a touch interrupt happened
 if(touch1detected){

   //reset the touch state and print out a message
   touch1detected = false;

   Serial.println("Touch 1 detected");
 }
}

 

전체 터치 버튼 인터럽트 예제는 Arduino IDE의 파일 메뉴에서 ESP32 예제를 통해 찾을 수 있습니다. 파일 > 예제 > ESP32 > 터치 > TouchInterrupt.

 

 

ES32 터치 인터럽트 예제를 선택하는 Arduino IDE 파일 메뉴 드롭다운

 

 

로봇 스킨 및 기타 터치 버튼 애플리케이션

 

터치 버튼으로 할 수 있는 일은 많습니다. Arduino Nano ESP32에는 숫자 키패드를 만들기에 충분한 버튼 입력이 있습니다.

 

GPIO 핀에 연결된 전극의 속성에 따라 터치 입력은 물리적 터치 대신 근접을 감지할 수도 있습니다. 예를 들어 유리 또는 플라스틱 판을 통해 터치를 감지할 수 있습니다. 이는 방수 사용자 인터페이스를 만드는 데 유용합니다.

 

또한 접착 금속 테이프를 통해 피부 또는 외골격 아래에 여러 개의 터치 버튼을 설치하여 로봇 스킨을 만드는 데 사용할 수도 있습니다. 이를 사용하여 피부를 통해 터치를 감지할 수 있습니다.

 

저는 사람들이 터치 버튼 GPIO에서 과일과 같은 것에 점퍼 와이어를 꽂는 것을 본 적이 있는데, 과일을 만졌을 때 감지할 수 있었습니다.

 

터치 버튼은 "바디"가 터치 전극에 얼마나 가까운지에 따라 가변 범위를 반환합니다. 이 속성은 제스처 감지에 사용할 수 있으며 손가락이나 손이 터치 버튼을 향해 움직이는지 멀어지는지 확인할 수 있습니다. 이를 사용하여 음표를 구부리거나 LED의 강도를 변경할 수 있습니다.

 

터치 버튼의 일반적인 용도는 손가락 터치이지만 다른 용도도 있습니다. 예를 들어 터치 버튼은 커패시턴스나 "커패시티브 태그"가 추가되어 다양한 객체를 저렴하게 식별하는 데 사용할 수도 있습니다. 로봇이나 장난감과 상호 작용하기 위한 객체를 식별하는 데 사용할 수 있습니다.

 

이러한 응용 프로그램 아이디어 중 일부에 매료되기를 바라지만, 저와 비슷하다면 이러한 터치 핀이 "후드 아래"에서 어떻게 작동하는지 궁금할 것입니다.

 

터치 버튼은 "후드 아래"에서 어떻게 작동합니까?

 

앞서 언급했듯이 터치 버튼은 전기적 속성인 정전용량을 사용하여 작동합니다.

 

전자 기기의 대부분과 마찬가지로 실제로 작동하게 하는 요소는 보이지 않으며 정전용량도 다르지 않습니다! 이것이 전자 기기가 혼란스러운 이유일 것입니다. 많은 부분이 보이지 않기 때문입니다 👻.

 

정전용량은 전자 소자가 전하를 저장하는 능력으로, 전자가 표면에 축적되어 전기장을 생성합니다. 정전용량 소자는 전선, 금속판 또는 인체일 수 있습니다.

 

전자 기기의 모든 것에는 어떤 종류의 정전용량이 있습니다. 회로 기판의 트레이스, MOSFET의 접합부, 두 회로를 연결하는 전선. 대부분의 응용 분야에서 이 "기생" 정전용량은 무시할 수 있습니다.

 

그러나 주요 기능이 전하를 저장하는 전자 부품이 있는데, 이를 (우연이 아니라) 커패시터라고 합니다. 커패시터에는 여러 유형이 있습니다. 각 유형은 전하를 저장하는 데 다른 방법을 사용합니다.

 

완벽한 커패시터는 전하를 저장하지만 완전히 충전된 후에는 전류가 흐르지 않습니다. 거의 완벽한 커패시터는 두 금속판을 실제로 접촉하지 않고 가능한 한 서로 가깝게 유지하여 얻을 수 있습니다.

 

이렇게 하면 전자가 판에 축적되어 그 사이에 전기장이 생성되지만 전류는 판 사이로 흐르지 않습니다. 라이덴 병이나 전해 커패시터는 거의 완벽한 커패시터의 좋은 예입니다.

 

커패시터는 표면적 및 사용된 재료와 같은 물리적 특성에 따라 알려진 양의 전하를 저장합니다. 커패시터로 가는 회로의 저항량을 감안할 때 커패시터를 특정 전압으로 충전하는 데 걸리는 시간은 정확히 알려져 있습니다.

 

터치 버튼의 정전 용량

 

ESP32에 내장된 회로와 같은 터치 버튼 구현에는 GPIO 핀에 연결된 알려진 커패시터 및 저항 회로(RC 회로)가 있습니다. 프로세서는 RC 회로를 지속적으로 충전 및 방전하고 커패시터가 특정 전압에 도달하는 데 걸리는 시간을 측정합니다.

 

인체가 GPIO 핀을 만지는 형태로 회로에 추가된 추가 정전 용량으로 인해 정전 용량이 변경되면 회로의 충전 및 방전 시간도 그에 따라 변경됩니다.

 

touchRead() 함수는 이 충전/방전 시간을 반환합니다. 따라서 이 시간을 읽고 알려진 값과 비교하면 핀이 외부 소스에 의해 터치되었는지 아닌지 확인할 수 있습니다!

 

이 모든 것이 놀랍게 들리지만, 악마는 세부 사항에 있다는 것을 알고 있습니다...

 

무엇이 잘못될 수 있을까요?

 

아무것도 없습니다!... 말하고 싶습니다. 현실에서는 터치 버튼 기능을 방해할 수 있는 많은 것들이 있습니다. 특히 터치 버튼이 사용되는 환경을 완벽하게 제어할 수 없는 경우 더욱 그렇습니다.

 

정전용량은 터치 버튼의 전기장에 들어오는 모든 것의 영향을 받으며, 전기장은 종종 버튼이나 전극의 물리적 한계를 훨씬 넘어 확장됩니다.

 

저는 다른 삶에서 로봇 장난감을 만들었는데, 그 중 많은 장난감이 상호작용을 위해 터치 센서/버튼을 사용했습니다. 이 장난감은 또한 즉석에서 혼합되는 고급 애니메이션을 통합했기 때문에 예측할 수 없었습니다.

 

종종 장난감의 일부가 자체 터치 센서의 전기장으로 이동하여 효과적으로 거짓 트리거를 하는 경우가 있었습니다! 이를 쉽게 해결할 수 없었고 필요한 플레이 패턴에 따라 터치 센서는 특정 애니메이션에 따라 비활성화되어야 했습니다.

 

터치 버튼은 독특하고 흥미로운 인터페이스를 제공하며 종종 전자 장치에 인간과 같은 감각을 제공하지만 거짓 트리거가 발생할 수 있으므로 사용할 때 이 점을 명심하세요. "미션 크리티컬"한 것에는 사용하지 마세요(NASA의 말을 잘 듣고 계시기를 바랍니다!)

 

대사를 연습해 봅시다...

 

ESP32 기반 보드를 통해 터치 버튼을 사용하는 것은 간단합니다. pinMode() 함수를 통해 핀을 설정하고 touchRead() 함수로 터치 값을 읽기만 하면 됩니다.

 

touchRead() 함수는 "터치 양"에 따라 가변 범위를 반환합니다. 이 값을 임계값과 비교하여 무언가를 트리거하는 데 사용합니다.

 

"터치 양"은 환경에 영향을 받을 수 있으므로 잘못된 트리거가 발생할 수 있습니다. 미션 크리티컬한 용도로 사용하려는 경우 이 점을 고려하세요!

 

여기에서 어디로 가야 할까요...

 

이 모든 Arduino 코드는 훌륭하고 충분히 쉬워 보이지만 기본 코드 구조를 이해하는 데 어려움을 겪고 있다면 정말 어려울 수 있습니다.

 

Arduino 교육 프로그램을 확인하는 것을 고려해야 하는 이유입니다. Arduino 프로그래밍에 대해 아무것도 모르는 상태에서 자신의 프로젝트를 만드는 데까지 안내할 수 있습니다. 

 

 

본 글이 참고한 원문을 보시려면 이 링크를 따라가세요. 배움을 멈추지 마세요.

 

읽어주셔서 감사합니다. 

 

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^