Viet Dev

Cover image for Arduino - Timer - Interrupt
Tuan for Unicloud Group

Posted on

Arduino - Timer - Interrupt

Arduino - Timer - Interrupt

Trong bài viết này chúng ta sẽ tìm hiểu:

  • Các khái niệm về Interrupt, Timer/Counter.

  • Tại sao và khi nào cần sử dụng Interrupt, Timer/Counter.

  • Cách sử dụng Interrupt, Timer/Counter.

Interrupt

Giới thiệu

Trong quá trình làm việc, bỗng nhiên bạn nhận được một yêu cầu gấp, cần
phải thực hiện ngay lập tức. Lúc này, bạn buộc phải dừng công việc hiện
tại để thực hiện yêu cầu đó và chỉ có thể tiếp tục công việc đang dở
dang khi hoàn thành song yêu câu. Tương tự vậy, trong lập trình, chúng
ta có một khái niệm, đó chính là ngắt (Interrupt).

Ngắt

Ngắt là khi một tín hiệu khẩn cấp được gửi tới bộ xử lý, yêu cầu bộ
xử lý tạm dừng tức khắc các hoạt động hiện tại để nhảy đến một nơi khác
thực hiện một nhiệm vụ khẩn cấp nào đó, nhiệm vụ này được gọi là trình
phục vụ ngắt - ISR (Interrupt Service Routine). Sau khi kết thúc trình
phục vụ ngắt - ISR, bộ đếm chương trình sẽ trả về giá trị trước đó để bộ
xử lý quay về thực hiện chương trình đang dang dở.

Vì sao cần sử dụng ngắt

Quay trở lại ví dụ về button đã đề cập ở phần Hello world, chúng ta
phải liên tục đọc trạng thái của nút nhấn bằng hàm digitalRead() trong
chương trình loop.

void loop() {
  // Đọc trạng thái của nút nhấn
  buttonState = digitalRead(buttonPin);

  // Kiểm tra nếu nút được nhấn, tức buttonState ở trạng thái LOW:
  if (buttonState == LOW) {
    // Bật LED
    digitalWrite(ledPin, HIGH);
  } else {
    // Tắt LED
    digitalWrite(ledPin, LOW);
  }
}
Enter fullscreen mode Exit fullscreen mode

Điều này sẽ cực kì khó khăn khi số lượng các câu lệnh trong chương trình
loop tăng lên, lúc này tốc độ đáp ứng của chương trình khi chúng ta
nhấn nút sẽ không còn nhanh nữa bởi vì chương trình loop phải thực
hiện song tất cả các lệnh rồi mới quay trở lại đọc trạng thái nút nhấn.
Ngắt sẽ giải quyết những vấn đề này cho bạn. Lúc này, chương trình
vẫn chạy liên tục những lệnh có trình chương trình loop và chỉ khi có
ngắt xảy ra khi ta ấn nút nhấn thì chương trình mới thực hiện các lệnh
trong chương trình phục vụ ngắt và sau đó quay trở lại thực hiện tiếp
chương trình trong loop.

Điều này sẽ giúp tốc độ đáp ứng của chương trình đối với các thao tác
của bạn được nhanh hơn và việc quản lý chương trình của bạn được dễ dàng
và hiệu quả hơn.

Vector ngắt

Trong thực tế trên mỗi bộ xử lý đều có rất nhiều ngắt khác nhau, vậy
điều gì sẽ xảy ra khi cùng một lúc có hai ngắt xuất hiện? Cũng như ví dụ
đầu bài, nhưng bây giờ bạn nhận đến 2 yêu cầu cần thực hiện gấp, vậy bạn
sẽ thực hiện yêu cầu nào? Tất nhiên là sẽ ưu tiên yêu cầu cấp thiết
nhất, sau khi hoàn thành thì mới thực hiện yêu cầu tiếp theo và cuối
cùng là trở lại công việc đang làm dở. Cũng như trong lập trình, mỗi
ngắt đều được quy định một mức ưu tiên khác nhau, được gọi là vector
ngắt (vector ngắt có giá trị càng nhỏ thì độ ưu tiên càng cao), Reset là
ngắt có mức ưu tiên cao nhất.

Ngắt trong Arduino

Trong khuôn khổ của Arduino và mục tiêu của sách là đơn giản hóa mọi vấn
đề để các bạn mới bắt đầu dễ dàng tiếp cần thì chúng ta sẽ không đi sâu
vào vấn đề này.

Trong Arduino, chúng ta được hỗ trợ 2 loại ngắt như sau:

  • Ngắt số 0 được nối với chân số 2.

  • Ngắt số 1 được nối với chân số 3.

Để sử dụng ngắt chúng ta cần phải kết nối nút nhấn hoặc cảm biến vào hai
chân này để tạo tín hiệu ngắt cho bộ xử lý.

Tùy thuộc vào vi điều khiển trên board mà mỗi dòng Arduino có số lượng
các ngắt khác nhau. Bạn có thể tham khảo bảng sau:

Board Int.0 Int.1 Int.2 Int.3 Int.4 Int.5
Uno. Ehternet 2 3 . . . .
Mega2560 2 3 21 20 19 18
Leonardo 2 3 0 1 7 .

Số lượng ngắt trên các Board Arduino

Arduino hỗ trợ 2 lệnh giúp ta khai báo và hủy một ngắt bất kì một cách
dễ dàng đó là attachInterrupt()detachInterrupt().

Lệnh attachInterrupt()

  • Mục đích: Giúp khai báo một ngắt.

  • Cú pháp lệnh: attachInterrupt(interrupt, ISR, mode).

  • Các đối số:

    • interrupt: Lựa chọn ngắt mà bạn muốn dùng, với Arduino Uno
      có 2 lựa chọn là:

      • 0: Ứng với ngắt số 0 trong Arduino (chân số 2).
      • 1: Ứng với ngắt số 1 trong Arduino (chân số 3).
    • ISR: Chương trình phục vụ ngắt. Chương trình này sẽ được
      thực hiện khi có ngắt xảy ra.

    • mode: Kiểu kích hoạt ngắt:

      • LOW: Ngắt sẽ được kích hoạt khi trạng thái chân ở mức thấp.
      • HIGH: Ngắt sẽ được kích hoạt khi trạng thái chân ở mức cao.
      • CHANGE: Ngắt khi có sự thay đổi trạng thái trên chân ngắt (trạng thái thay đổi từ mức điện áp thấp lên mức điện áp cao hoặc ngược lại, từ mức điện áp cao xuống mức điện áp thấp.
      • RISING: Ngắt sẽ được kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp thấp sang mức điện áp cao.
      • FALLING: Ngắt sẽ được kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp cao sang mức điện áp thấp.
Trong mode LOW và HIGH, chương trình ngắt sẽ được gọi liên tục khi chân digital vẫn còn giữ ở mức điện áp thấp hoặc cao.
  • Giá trị trả về: Không có giá trị trả về

Lệnh detachInterrupt()

  • Mục đích: Tắt ngắt hiện tại.

  • Cú pháp lệnh: detachInterrupt(pin).

  • Các đối số:

    • pin: Lựa chọn ngắt mà bạn muốn tắt, dùng board Arduino Uno
      có 2 lựa chọn là:

      • 0: Tắt ngắt số 0 trong Arduino ( chân số 2).
      • 1: Tắt ngắt số 1 trong Arduino ( chân số 3).
  • Giá trị trả về : Không có giá trị trả về.

Ví dụ

Yêu cầu

Thiết kế hệ thống tự động bật sáng đèn khi trời tối.

Linh kiện cần dùng

  • Board Arduino Uno

  • Cảm biến ánh sáng quang trở

  • Module Relay 5V 1 kênh

Cảm biến ánh sáng quang trở

Cảm biến ánh sáng quang<br>
trở

Relay

Module Relay 5v 1<br>
kênh.

Relay là công tắc chuyển mạch (có thể đóng cắt điện áp DC và AC) được
điều khiển bằng tín hiệu DC. Đây là linh kiện thụ động rất thường gặp
trong các mạch điện tử.

Relay có hai dạng phổ biến: Relay đóng mức thấp và đóng mức cao. Để hiểu
thêm nguyên lý hoạt động của Relay, Module relay và cách sử dụng.

Phân tích chương trình:

  • Chúng ta sẽ dùng chân DO (Digital Output) của quang trở kết nối với
    ngắt số 0 (chân số 2). Trong điều kiện có ánh sáng, chân DO sẽ xuất
    ra mức 0 và ngược lại khi không có ánh sáng sẽ xuất ra mức 1.

  • Chúng ta sẽ khai báo ngắt số 0 (chân số 2) với kiểu kích hoạt là LOW
    (ngắt khi trạng thái chân số 2 ở mức thấp) và chương trình phục vụ
    ngắt là turnOffRelay (để tắt Relay).

  • Chương trình chính sẽ thực hiện việc bật Relay.

  • Khi môi trường có ánh sáng, chân DO của cảm biến sẽ xuất mức LOW,
    lúc này ngắt xảy ra và Relay sẽ tắt (đèn tắt).

Kết nối

Arduino Uno Relay
5V 5V
GND GND
A0 IN

Bảng đấu nối board Arduino Uno và Relay

Arduino Uno Cảm biến ánh sáng
5V 5V
GND GND
2 DO

Bảng đấu nối board Arduino Uno và Cảm biến ánh sáng

Hình ảnh kết nối cảm biến ánh sáng quang trở và Relay với board<br>
Arduino<br>
Uno

Source code

int relay = A0;               // khai báo chân relay là chân Ao

void turnOffRelay()
{
    digitalWrite(relay, LOW); // Tắt relay khi xảy ra ngắt.
}

void setup()
{
   pinMode(relay, OUTPUT);
   pinMode(2, INPUT_PULLUP);  // khai báo chân số 2 là ngõ vào sử dụng điện trở kéo lên.
   attachInterrupt(0, turnOffRelay, LOW);
   // khai báo ngắt số 0, xảy ra khi chân số 2 ở mức thấp
   // chương trình turnOffRelay được gọi khi ngắt xảy ra.
}

void loop()
{
  digitalWrite(relay, HIGH);  // bật relay
}
Enter fullscreen mode Exit fullscreen mode

Trong ví dụ sử dụng Relay đóng mức cao. Khi sử dụng Relay đóng mức thấp
thì cần phải đảo tín hiệu điều khiển.

Timer/Counter

Giới thiệu

Timer/Counter là một trong những ngoại vi hoạt động độc lập và không thể
thiếu trong bất kì vi điều khiển nào. Thực chất, Timer/Counter chỉ là
một bộ đếm xung clock (có thể là xung nhịp nội bên trong vi điểu khiển
hoặc xung clock bên ngoài). Nó tương tự như việc đếm giờ, thay vì ngồi
canh đồng hồ và đếm từng giây thì chúng ta có thể đặt báo thức và làm
những công việc khác, việc đếm thời gian thì giao cho đồng hồ xử lý.

Quá trình hoạt động của Timer/Counter được quản lý bởi thanh ghi, chúng
gồm thanh ghi chứa giá trị Timer/Counter đếm được và thanh ghi điều
khiển các hoạt động đếm của nó.

Trong khuôn khổ của sách này, chúng ta sẽ không tìm hiểu sâu về thanh
ghi, nếu bạn có nhu cầu tìm hiễu rõ hơn có thể truy cập vào đường dẫn:
arduino.vn/bai-viet/411-timercounter-tren-avrarduino.

Timer/Counter được sử dụng rất nhiều trong các ứng dụng định thời, đếm
sự kiện, tạo xung PWM,…​

Timer/Counter trong Arduino

Một số định nghĩa mà các bạn cần lưu ý trong khi sử dụng Timer/Counter:

  • BOTTOM: Giá trị nhỏ nhất mà Timer/Counter có thể đạt được. Mặc định
    giá trị này bằng 0.

  • MAX: Giá trị lớn nhất mà thanh ghi giá trị của Timer/Counter có thể
    chứa được. Tùy thuộc vào độ rộng của thanh ghi giá trị mà chúng ta
    có được giá trị MAX khác nhau. Ví dụ như Timer/Counter 0 là bộ timer
    8 bit tức là giá trị tối đa (MAX) của nó là 28-1=255 và
    đối với timer 16 bit là 216-1=65535.

  • TOP: Giá trị mà khi Timer/Counter đạt đến nó sẽ thay đổi trạng thái,
    giá trị này phải bé hơn hoặc bằng 255 (đối với timer 8 bit) và 65535
    (đối với timer 16 bit). Ví dụ: Trong Timer/Counter 0 chúng ta sẽ có
    giá trị MAX là 255, nếu không không thiết lập giá trị TOP thì timer
    sẽ đếm từ 0 đến 255 và sau đó quay trở lại 0, nếu chúng ta thiết lập
    giá trị TOP thì timer sẽ đếm từ 0 đến giá trị TOP và quay về 0.

  • Ngắt Timer: Bất cứ khi nào Timer đếm đến giá trị TOP hoặc Timer bị
    tràn (đếm đến giá trị MAX) thì đều xảy ra ngắt.

Chip ATMega328p (vi điều khiển của board Arduino Uno) bao gồm các
Timer/Counter sau:

  • Timer/Counter 0: Là bộ timer 8 bit được sử dụng nhiều trong các hàm
    delay(), millis(), micros(). Chúng ta nên hạn chế sử
    dụng bộ timer này vì rất dễ gây ảnh hưởng đến những hàm trên.

  • Timer/Counter 1: Là bộ timer 16 bit được sử dụng trong thư viện
    servo.

  • Timer/Counter 2: Là một bộ timer 8 bit tương tự như Timer/Counter 0
    và được sử dụng trong hàm tone().

Khi sử dụng bộ Timer/Counter nào thì chúng ta cần lưu ý đến những hàm hoặc thư viện sử dụng bộ Timer/Counter đó nhằm tránh việc chương trình bị xung đột hoặc chạy không chính xác.

Thư viện TimerOne

Trên nền tảng Arduino và mục tiêu của eBook là đơn giản hóa cho những
bạn mới tiếp cận, vì vậy chúng ta sẽ không điều khiển trực tiếp Timer
bằng thanh ghi mà thay vào đó sẽ sử dụng thư viện TimerOne để tiếp
cận với Timer/Counter.

Đúng như tên gọi, thư viện sẽ sử dụng bộ Timer/Counter 1 (16 bit), ngoài
ra nếu bạn muốn tìm hiểu rõ hơn về cách sử dụng cũng như quá trình hoạt
động của tất cả Timer trong board Arduino Uno, bạn có thể tham khảo bài
viết sau: arduino.vn/bai-viet/411-timercounter-tren-avrarduino.

Các hàm cần chú ý trong thư viện:

  • initialize(microseconds): Khởi động ngắt Timer với một chu kì
    xác định.

    • Các đối số:

      • microseconds: chu kỳ ngắt của Timer (tính bằng micro giây). Mặc định giá trị microseconds = 1 000 000 tương ứng với 1s.
  • start(): Khởi động lại Timer sau quá trình thay đổi, chỉnh sửa.

  • startBottom(): Cho Timer đếm lại từ 0 (giá trị BOTTOM).

  • read(): Đọc giá trị Timer đếm được ở thời điểm hiện tại.

  • stop(): Dừng Timer.

  • attachInterrupt(): Thêm chương trình phục vụ ngắt khi xảy ra sự
    kiện ngắt Timer.

  • detachInterrupt(): Hủy hàm ngắt Timer.

  • pwm(pin, duty): Xuất xung PWM ra một chân xác định.

    • Các đối số:

      • pin: Lựa chọn chân xuất PWM.
      • duty: Chu kì xung PWM.
  • disablePwm(char pin): Hủy băm xung PWM.

    • Các đối số:

      • pin: Lựa chọn chân để hủy PWM.

Một số ví dụ

Điều khiển LED

Yêu cầu

Sử dụng Timer để điều khiển LED trên board nháy sau mỗi 0,15s và hiển
thị số lần LED sáng lên OLED.

Linh kiện cần dùng

  • Board Arduino Uno

  • OLED SSD1306

Phân tích:

  • Chúng ta sẽ khai báo một Timer để định thời gian là 0,15s. Cứ sau
    0,15s Timer sẽ ngắt, thực hiện chương trình blinkLED và đếm lại từ
    đầu.

  • Chương trình blinkLED sẽ thực hiện việc đảo trạng thái của đèn LED
    từ sáng thành tắt và ngược lại, đống thời đếm số lần đèn LED sáng.

  • Vòng lặp loop() sẽ thực hiện việc hiển thị số lần LED sáng lên màn
    hình OLED SSD1306.

Thư viện

  • Đầu tiên, chúng ta cần download thư viện TimerOne của PaulStoffregen cho Arduino. Link download.

Sau khi tải thư viện về, bạn mở phần mềm arduino, chọn Sketch → Import
Library…​ → Add Library…​. Sau đó chọn file .zip mà bạn vừa tải về để có
thể sử dụng thư viện.

Source code

#include <TimerOne.h> //thư viện cho Timer1
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

const int led = LED_BUILTIN;  // LED BUILD chính là LED mặc định trên BOARD

void setup(void)
{
  pinMode(led, OUTPUT);
  Timer1.initialize(150000); //Khởi động ngắt Timer1 tràn mỗi 0.15s
  Timer1.attachInterrupt(blinkLED); // blinkLED to run every 0.15 seconds
  setUpOLED(); // thiết lập OLED
}

void setUpOLED()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
}

int ledState = LOW;
volatile unsigned long blinkCount = 0; //biến đếm số lần Led sáng

void blinkLED(void)
{
  if (ledState == LOW) {
    ledState = HIGH;
    blinkCount = blinkCount + 1;  // Tăng biến đếm mỗi khi LED sáng
  } else {
    ledState = LOW;
  }
  digitalWrite(led, ledState);
}

void loop(void)
{
  unsigned long blinkCopy;  // biến linkCopy được dùng để copy số lần LED từ biến blinkCount
  //tắt ngắt nhằm tránh trường hợp biến blinkCount thay đổi (do ngắt timer xảy ra) trong quá trình copy.
  noInterrupts();
  blinkCopy = blinkCount;
  interrupts();

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("So Lan Sang:" + String(blinkCopy));
  display.display();
  delay(1000);
}
Enter fullscreen mode Exit fullscreen mode

Từ khóa volatile được dùng cho những biến sử dụng trong chương trình
phục vụ ngắt và các chương trình khác.

Điều khiển tốc độ quạt

Yêu cầu

Điều khiển tốc độ quạt sử dụng băm xung PWM.

Thực tế chúng ta vẫn có thể điều khiển tốc độ quạt bằng hàm
analogWrite (), nhưng vấn đề đặt ra là hàm analogWrite() chỉ xuất ra
xung PWM với tần số mặc định khoảng 490Hz đến 3920Hz trong khi một số
quạt hiện nay yêu cầu xung PWM có tần số trong khoảng từ 21kHz đến
28kHz. Vì vậy chúng ta sẽ phải sử dụng Timer/Counter đề điều chế xung
PWM.

Linh kiện sử dụng

  • Board Arduino Uno

  • OLED SSD1306

  • Quạt mini (Fan)

FAN

FAN nói chung hoặc quạt tản nhiệt nói riêng thông thường sẽ có 3 chân,
chân (+) màu đỏ, chân GND màu đen và chân còn lại là chân điều khiển tốc
độ.

Kết nối

Arduino Uno FAN
5V 5V
GND GND
4 Xanh dương

Bảng đấu nối board Arduino Uno và quạt mini

Hình ảnh kết nối quạt mini với board Arduino<br>
Uno

Source code

#include <TimerOne.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

const int fanPin = 4; //khai báo chân điều khiển tốc độ quạt

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

void setup(void)
{
  Timer1.initialize(40);  // thiết lập timer1 với chu kì 40us tương ứng 25kHz.
  setUpOLED(); // thiết lập OLED
}

void setUpOLED()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
}

void loop(void)
{
  for (float dutyCycle = 30.0; dutyCycle < 100.0; dutyCycle++)
  {
    Timer1.pwm(fanPin, (dutyCycle / 100) * 1023);
    display.clearDisplay();
    display.setCursor(32, 0);
    display.println("PWM Fan");
    display.setCursor(0, 15);
    display.println("Duty Cycle = " + String(dutyCycle));
    display.display();
    delay(500);
  }
}
Enter fullscreen mode Exit fullscreen mode

Giải thích source code:

  • Đầu tiên khai báo Timer để định thời gian là 40 micro giây (tương
    ứng với tần số PWM là 1/40 µs = 25kHz ) bằng lệnh
    Timer1.initialize(40).

  • Trong chương trình loop(), chúng ta dùng một vòng lặp for để tăng
    tốc độ của quạt bằng cách tăng đối số duty của hàm pwm (duty
    tăng dần theo vòng lặp for).

Điều khiển động cơ Servo bằng biến trở

Servo là gì?

Khác với những dạng động cơ thông thường chỉ quay liên tục khi cấp nguồn
điện, Servo là dạng động cơ điều khiển được góc quay bằng xung PWM. Trên
thị trường có rất nhiều loại động cơ Servo với kích thước, khối lượng,
cấu tạo khác nhau, từ những loại Servo kích thước nhỏ gọn (dùng cho máy
bay mô hình) đến những loại sỡ hữu moment xoắn cực lớn (vài chục N/m).

Để điều khiển được góc quay Servo (trong khoảng từ 0o -
180o ) chúng ta sẽ dùng xung PWM như sau:

Hình điều khiển<br>
Servo

Biến trở

Biến trở là linh kiện điện tử mà giá trị điện trở có thể thay đổi được.
Chúng có thể được sử dụng trong các mạch điện để điều chỉnh hoạt động
của mạch điện.

Biến<br>
trở

Yêu cầu

  • Chúng ta sẽ đọc giá trị analog từ biến trở (sử dụng biến trở để tăng
    giảm mức điện áp từ 0V đến 5V tương ứng với góc quay từ
    0o đến 180o).

  • Sau đó, chúng ta xuất ra xung PWM tương ứng ra chân số 9.

Sơ đồ kết nối

Arduino Uno Servo Motor
5V Màu Đỏ
GND Màu nâu
9 Màu Vàng

Bảng đấu nối board Arduino Uno với động cơ Servo

Arduino Uno Biến trở
5V 1
GND 3
A7 2

Bảng đấu nối board Arduino Uno với Biến trở

Hình ảnh kết nối biến trở và động cơ Servo với Arduino<br>
Uno

Thư viện

Trong ứng dụng này, chúng ta sẽ sử dụng thư viện servo.h

Thư viện servo.h sử dụng bộ Timer/Counter 1, đóng vai trò quan
trọng nếu bạn muốn làm về dự án robot. Nó cung cấp cho bạn một phương
thức cực kì đơn giản để điều khiển động cơ Servo. Đồng thời, thư viện đã
được tích hợp sẵn trong arduino IDE nên bạn không cần phải tải thêm thư
viện khi sử dụng.

Một số hàm cần chú ý như:

  • myservo.attach(pin): Khai báo ngõ ra điều khiển Servo.

    • pin: lựa chọn chân ngõ ra điều khiển Servo.
  • myservo.write(deg): Điểu khiển góc quay Servo.

    • deg: giá trị góc mà bạn muốn quay (0o đến 180o).

Source code

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Servo.h>      // Thư viện điều khiển servo

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

// Khai báo đối tượng myservo dùng để điều khiển servo
Servo myservo;

int bientro = A0;       // Khai báo chân analog đọc biến trở điều khiển servo
int servoPin = 9;       // Khai báo chân điều khiển servo

void setup ()
{
   // Cài đặt chức năng điều khiển servo cho chân servoPin
   myservo.attach(servoPin);
   setUpOLED();
}
void setUpOLED()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
}

void loop ()
{
   int value = analogRead(bientro);// Đọc giá trị biến trở

   // Chuyển giá trị analog (0-1023) đọc được từ biến trở sang số đo độ (0-180độ)
   // dùng để điều khiển góc quay cho servo
   int servoPos = map(value, 0, 1023, 0, 180);

   // Cho servo quay một góc là servoPos độ
   myservo.write(servoPos);
   display.clearDisplay();
   display.setCursor(20, 0);
   display.println("Control Servo");
   display.setCursor(0, 15);
   display.println("Goc quay = " + String(servoPos));
   display.display();
   delay(50);
}
Enter fullscreen mode Exit fullscreen mode

Summary

Qua chương này, chúng ta đã tìm hiểu được những khái niệm cơ bản về
ngắt (Interrupt)Timer/counter, lý do tại sao chúng ta cần sử
dụng nó trong các ứng dụng. Đồng thời chúng ta biết được thêm thư viện
TimerOne giúp ta dễ dàng tiếp cận và làm chủ bộ Timer/Couter trên
board Arduino Uno.

Đối với những ví dụ đơn giản, khó có thể không nhận thấy sự khác biệt
khi sử dụng ngắt (Interrupt) và Timer/Counter. Nhưng khi thực hiện những
ví dụ phức tạp, cần khai thác tối ta khả năng xử lý của vi điều khiển
thì đây sẽ là trợ thủ đắc lực cho bạn.

Oldest comments (0)