BÀI 3: ĐIỀU KHIỂN GPIO ESP8266 NONOS SDK VỚI CHỨC NĂNG INPUT
Ở bài viết trước, mình đã hướng dẫn các bạn sử dụng chức năng GPIO OUTPUT của ESP8266. Trong bài viết này, chúng ta sẽ tiếp tục thao tác với chức năng GPIO INPUT - đọc giá trị nút nhấn hay nói cách khác là đọc dữ liệu.
LINH KIỆN CẦN CHUẨN BỊ
- Nút nhấn 4 chân hoặc 2 chân
![]() |
Hình 1. Nút nhấn 4 chân và cấu tạo của nó |
- Điện trở giá trị từ 220 Ohm - 10k Ohm
![]() |
Hình 2. Điện trở và ký hiệu |
- Led
![]() |
Hình 3. Các dạng LED đơn |
- Dây cắm và Test Board
![]() |
Hình 4. Dây cắm và Test board |
- ESP8266 Board và dây micro USB
![]() |
Hình 5. Board ESP8266 D1 mini |
MẠCH NGUYÊN LÝ - SCHEMATIC
![]() |
Hình 6. Các cách mắc điện trở để đọc giá trị từ nút nhấn |
Có hai cách mắc linh kiện dùng để đọc dữ liệu từ nút nhấn:
- Dùng điện trở kéo lên (Pull-up method).
- Dùng điện trở kéo xuống (Pull-down method).
Tùy vào mục đích sử dụng của từng project, chúng ta sẽ chọn cách mắc cho phù hợp. Thông thường, người lập trình sẽ chọn sử dụng phương pháp điện trở kéo lên. Hai cách mắc mạch nguyên lý để đọc được giá trị từ nút nhấn tương đối giống nhau, chỉ khác nhau một điểm như sau:
- Dùng điện trở kéo lên
- Khi không nhấn nút nhấn, giá trị đọc được tại chân GPIO là mức cao (VCC).
- Khi nhấn nút, giá trị đọc được sẽ là 0 (GND).
- Dùng điện trở kéo xuống
- Khi không nhấn nút, giá trị đọc được sẽ là 0 (GND).
- Khi nhấn nút, giá trị đọc được sẽ là 1 (VCC).
CÁC HÀM HỖ TRỢ CHỨC NĂNG INPUT GPIO
PIN_FUNC_SELECT(PIN_NAME, FUNC)
GPIO_DIS_OUTPUT(gpio_no)
Chức năng: không sử dụng chức năng OUTPUT GPIO => không sử dụng output thì sẽ là INPUT.Tham số truyền vào: uint8 gpio_no (với giá trị từ 0 - 16, xem trong cột gpio của hình esp8266 pin list).
Ví dụ: GPIO_DIS_OUTPUT(12); // sử dụng chức năng gpio input cho chân GPIO 12.
GPIO_INPUT_GET(gpio_no)
Chức năng: Đọc giá trị trạng thái của chân GPIO được lựa chọn.Tham số truyền vào: uint8 gpio_no (với giá trị từ 0 - 16, xem trong cột gpio của hình esp8266 pin list).
Giá trị trả về: uint32 bitmask (Xem tại dòng 28 //Register Bits{{ file eagle_soc.h - thư mục include của SDK).
Ví dụ: uint32 data = GPIO_INPUT_GET(12); // đọc giá trị input tại chân GPIO 12 rồi sau đó lưu vào trong biến data.
ESP8266EX có 17 chân GPIO có thể sử dụng với nhiều chức năng. Mỗi chân của nó có thể cấu hình sử dụng điện trở kéo lên hoặc kéo xuống (Chi tiết tại trang 17/29, mục 4.1 tài liệu ESP8266EX Datasheet). Thay vì phải sử thêm một điện trở bên ngoài, chúng ta có thể cấu hình để sử dụng điện trở bên trong của ESP8266 bằng hai hàm dưới đây:
PIN_PULLUP_EN(PIN_NAME)
Chức năng: Sử dụng điện trở kéo lên cho chân GPIO được lựa chọn.Tham số truyền vào: PIN_NAME là chuỗi "PERIPHS_IO_MUX_" kết hợp với tên trong cột Inst Name(xem trong cột Inst Name của hình esp8266 pin list).
Ví dụ: PIN_PULLUP_EN(PERIPHS_IO_MUX_MTDI_U); // sử dụng điện trở kéo lên cho chân GPIO 12.
PIN_PULLUP_DIS(PIN_NAME)
Chức năng: Bỏ sử dụng chức năng điện trở kéo lên cho chân được lựa chọn.Tham số truyền vào: PIN_NAME là chuỗi "PERIPHS_IO_MUX_" kết hợp với tên trong cột Inst Name(xem trong cột Inst Name của hình esp8266 pin list).
Ví dụ: PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); // tắt sử dụng điện trở kéo lên cho chân GPIO 12.
Version SDK hiện tại - V3.0.0, SDK chưa hỗ trợ sử dụng chức năng điện trở kéo xuống (PIN_PULLDWN) chi tiết xem tại: https://bbs.espressif.com/viewtopic.php?f=5&t=481.
CODE MẪU
Hình 7. Schematic sử dụng trong code mẫu |
1. ĐỌC GIÁ TRỊ NÚT NHẤN VỚI CHỐNG DỘI PHÍM (Read push button with debounce)
os_timer_t check_button_timer; bool led_stt = false; uint32 btn_data = 0; uint8 count = 0; // check push button function void check_button(){ btn_data = GPIO_INPUT_GET(13); // read button value at gpio 12 pin if (btn_data == 0){ os_delay_us(10000); // wait for debounce btn_data = GPIO_INPUT_GET(13); // read button value at gpio 12 pin if (btn_data == 0) { led_stt = !led_stt; GPIO_OUTPUT_SET(12, led_stt); // controll led at pin gpio 13 count += 1; // if push button => count = count + 1 os_printf("button push %d\n", count); // debug count } } while (GPIO_INPUT_GET(13) == 0); // wait to unpush button } void ICACHE_FLASH_ATTR user_init(void) { PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO12); // select function gpio for gpio 13 pin GPIO_OUTPUT_SET(12, 0); // set gpio 13 is output and pulldown GND PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO13); // select function gpio for gpio 12 GPIO_DIS_OUTPUT(13); // use gpio 12 as input os_timer_setfn(&check_button_timer, (os_timer_func_t *) check_button, NULL); // set callback timer to check button os_timer_arm(&check_button_timer, 100, true); // 100 ms callback to function check_button_timer }
2. ĐỌC GIÁ TRỊ NÚT NHẤN VỚI CHỐNG DỘI PHÍM VÀ ĐIỆN TRỞ KÉO LÊN BÊN TRONG (Read push button with debounce and internal resistor pullup)
os_timer_t check_button_timer; bool led_stt = false; uint32 btn_data = 0; uint8 count = 0; // check push button function void check_button(){ btn_data = GPIO_INPUT_GET(13); // read button value at gpio 12 pin if (btn_data == 0){ os_delay_us(10000); // wait for debounce btn_data = GPIO_INPUT_GET(13); // read button value at gpio 12 pin if (btn_data == 0) { led_stt = !led_stt; GPIO_OUTPUT_SET(12, led_stt); // controll led at pin gpio 13 count += 1; // if push button => count = count + 1 os_printf("button push %d\n", count); // debug count } } while (GPIO_INPUT_GET(13) == 0); // wait to unpush button } void ICACHE_FLASH_ATTR user_init(void) { PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO12); // select function gpio for gpio 13 pin GPIO_OUTPUT_SET(12, 0); // set gpio 13 is output and pulldown GND PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO13); // select function gpio for gpio 12 PIN_PULLUP_EN(PERIPHS_IO_MUX_MTDI_U); // use internal pullup for gpio 12 GPIO_DIS_OUTPUT(13); // use gpio 12 as input os_timer_setfn(&check_button_timer, (os_timer_func_t *) check_button, NULL); // set callback timer to check button os_timer_arm(&check_button_timer, 100, true); // 100 ms callback to function check_button_timer }
VIDEO HƯỚNG DẪN CHI TIẾT
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO12);
Trả lờiXóaNhầm chỗ này rồi bạn, MTDI_U mới đúng