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)
Như đã giới thiệu ở bài viết trước, hàm này sẽ giúp chúng ta khai báo sử dụng chức năng GPIO cho chân đã được lựa chọn.

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
}
DOWNLOAD CODETại đây!!!

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
}
DOWNLOAD CODETại đây!!!

VIDEO HƯỚNG DẪN CHI TIẾT

Nhận xét

  1. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO12);
    Nhầm chỗ này rồi bạn, MTDI_U mới đúng

    Trả lờiXóa

Đăng nhận xét

Bài đăng phổ biến từ blog này

Dòng điện, điện áp 1 chiều và các định luật cơ bản

Dòng điện 1 chiều (DC) là gì ?

Các cách mắc điện trở

Dòng điện xoay chiều

Biến áp, Triết áp, Phân loại điện trở