บทความนี้กล่าวถึงการใช้งาน GPIO ของ ESP32 เพื่อทำหน้าที่เป็นการนำเข้าสัญญาณดิจิทัล โดยใช้วงจรของคีย์แพดที่เป็นสวิตช์จำนวน 8 ตัวที่ทำมาต่อให้เป็นเหมือนเกมแพ็ดดังภาพที่ 1
โครงสร้างของโครงงาน
โครงสร้างของโครงงานของ ESP-IDF เป็นดังภาพที่ 2 คือ ในไดเร็กทอรีหรือโฟลเดอร์ของโครงงานจะมีไฟล์ CMakeList.txt และ sdkconfig กับไดเร็กทอรีชื่อ main สำหรับเก็บรหัสต้นฉบับของโครงงาน โดยในไดเร็กทอรีดังกล่าวมีไฟล์ภาษา C และ CMakeLists.txt
จากโครงสร้างในภาพที่ 2 ต้องสร้างโค้ดของไฟล์ CMakeLists.txt ดังนี้ ซึ่งเนื้อหาในโค้ดได้กำหนดรุ่นขั้นต่ำของโปรแกรม cmake และกำหนดค่าการใช้งานของ cmake เบื้องต้นตามจ้นฉบับที่มากับ ESP-IDF พร้อมทั้งตั้งชื่อโครงงานเป็น ep05
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ep05)
สิ่งที่เขียน main/CMakeLists.txt เป็นดังต่อไปนี้ เพื่อกำหนดรายการไฟล์ที่จะต้องคอมไพล์ ซึ่งกำหนดไว้เป็น main.c และกำหนดไดเร็กทอรีที่เก็บไฟล์ส่วนหัวเอาไว้เป็นค่าว่างซึ่งหมายถึงที่เดียวกับ main.c หรือในไดเร็กทอรี main
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "")
เมื่อสร้างโครงสร้างได้เหมือนดังภาพที่ 2 ให้สั่งเลือก target ของระบบเป็น ESP32 ดังนี้
idf.py set-target esp32
ส่วน sdkconfig เกิดจากการเรียกใช้คำสั่งต่อไปนี้ idf.py menuconfig
idf.py menuconfig
จากหน้าจอกำหนดการตั้งค่าให้เข้าไปที่ Component Config –> FreeRTOS และกำหนด Tick rate (Hz) เป็น 1000 ดังภาพที่ 3 หลังจากนั้นบันทึกและออกจากการตั้งค่า
คำสั่ง
การใช้งาน GPIO จะต้องนำเข้าไฟล์ส่วนหัวชื่อ gpio.h ซึ่งอยู่ในโฟลเดอร์ย่อย driver ของ ESP-IDF ซึ่งสามารถนำเข้าดั้วยคำสั่ง include ดังนี้
#include <driver/gpio.h>
การเลือกใช้ขาต้องระบุด้วยคำสั่งต่อไปนี้
gpio_pad_select_gpio( หมายเลขขา )
คำสั่งสำหรับกำหนดหน้าที่การทำงานของขา มีรูปแบบดังนี้ โดยโหมดของขาเป็น GPIO_MODE_INPUT หรือ GPIO_MODE_OUTPUT
gpio_set_direction( หมายเลขขา, โหมดของขา )
คำสั่งสำหรับอ่านค่าสัญญาณดิจิทัลจากหมายเลขขาที่ระบุมีรูปแบบของคำสั่งดังนี้
ระดับสัญญาณดิจิทัล = gpio_get_level( หมายเลขขา )
สุดท้าย คำสั่งสำหรับกำหนดรูปแบบของขานำเข้าสัญญาณในกรณีที่เป็น PULL UP จะใช้คำสั่งดังนี้
gpio_pullup_en( หมายเลขขา )
ถ้าต้องการยกเลิก PULL UP ให้เรียกใช้ gpio_pullup_dis() ดังนี้
gpio_pullup_dis( หมายเลขขา )
กรณีที่ต้องการใช้งาน GPIO แบบอื่น ๆ สามารถเข้าไปอ่านบทความต่าง ๆ ดังต่อไปนี้เพิ่มเติม
ตัวอย่างโปรแกรม
วงจรแอลอีดีที่ใช้ในการทดลองครั้งนี้เป็นดังภาพที่ 4 อุปกรณ์ที่ใช้ในการทดลองได้แก่
- บอร์ด esp32
- บอร์ดทดลอง
- สวิตช์
- ตัวต้านทาน
ดังตัวอย่างโปรแกรมต่อไปนี้
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define swC 35
#define swD 34
#define swA 33
#define swB 32
#define keL 19
#define keU 18
#define keD 17
#define keR 16
gpio_num_t keys[] = {keL, keU, keD, keR, swC, swD, swA, swB};
void app_main(void)
{
printf("Ep.05 Keypad\n");
for (int i=0; i<8; i++) {
gpio_pad_select_gpio(keys[i]);
gpio_pullup_en(keys[i]);
if (gpio_set_direction(keys[i], GPIO_MODE_INPUT) == ESP_OK) {
printf("GPIO%02d ... Success.\n",keys[i]);
} else {
printf("GPIO%02d ... Parameter error.\n",keys[i]);
}
}
vTaskDelay( 1000/portTICK_PERIOD_MS );
while(1) {
printf("%d:%d:%d:%d %d-%d %d-%d\n",
gpio_get_level(keys[0]),
gpio_get_level(keys[1]),
gpio_get_level(keys[2]),
gpio_get_level(keys[3]),
gpio_get_level(keys[4]),
gpio_get_level(keys[5]),
gpio_get_level(keys[6]),
gpio_get_level(keys[7])
);
vTaskDelay( 100/portTICK_PERIOD_MS );
}
}
คอมไพล์และอัพโหลด
ทำการคอมไพล์ หลังจากนั้น flash ลงชิพ และเข้าโปรแกรม Serial Monitor สั่งงานดังนี้
idf.py -p /dev/ttyUSB0 build flash monitor
ตัวอย่างผลลัพธ์ของโปรแกรมที่แสดงผลจะเป็นดังภาพที่ 5
idf.py -p /dev/ttyUSB0 flash
สรุป
จากบทความนี้จะพบว่า การนำเข้าสัญญาณดิจิทัลนั้นทำด้วยการใช้คำสั่ง gpio_get_level() และเมื่อใช้วงจรแบบมี pull up ให้เรียกคำสั่ง gpio_pullup_en() และยกเลิกด้วยคำสั่ง gpio_pullup_dis() สุดท้ายขอให้สนุกกับการเขียนโปรแกรมครับ
ท่านใดต้องการพูดคุยสามารถคอมเมนท์ได้เลยครับ
แหล่งอ้างอิง
- ESP-IDF : GPIO & RTC GPIO
(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-10-09, 2021-12-22