15 C
Hanoi
Thứ Sáu, Tháng Mười Hai 3, 2021
Home LẬP TRÌNH VI ĐIỀU KHIỂN ARDUINO Viết chương trình không sử dụng hàm delay trong Arduino

Viết chương trình không sử dụng hàm delay trong Arduino

Bất lợi khi sử dụng hàm delay

Các bạn có thể quen với việc sử dụng hàm delay() để code Arduino. Kể từ ngày đầu tiên lập trình với Arduino, delay là một trong những hàm bạn sử dụng đầu tiên. Một phần bởi vì nó đơn giản, dễ sử dụng cho việc định thời (timming). Sử dụng hàm delay đơn giản là bạn muốn Arduino dừng hoạt động trong 1 khoản thời gian trước khi nó thực hiện câu lệnh kế tiếp. Đây chính là vấn đề chính của nó. Arduino sẽ không thể thực thi bất kỳ câu lệnh nào khác cho đến khi hàm delay được hoàn thành, kể cả việc người dùng thao tác với nút nhấn hoặc bất kỳ thứ gì hệ thống tương tác. 

Lợi ích khi tránh việc sử dụng hàm delay

Arduino là vi điều khiển chỉ có 1 nhân xử lý nên tại 1 thời điểm chỉ có thể thực hiện 1 tác vụ. Nếu không sử dụng bất kỳ OS – hệ điều hành – nào chạy trên Arduino, bạn sẽ không thể chạy đa nhiệm trên Arduino.

Tuy nhiên có 1 cách giúp các bạn có thể xử lý nhiều tác vụ trên Arduino là sử dụng hàm millis(). Việc sử dụng hàm delay trong các chương trình đa nhiệm sẽ làm Arduino không xử lý được tác vụ khác trong một khoảng thời gian. Bạn nên tránh sử dụng đến hàm này.

Millis() có nhiệm vụ trả về một số – là thời gian (tính theo mili giây) kể từ lúc mạch Arduino bắt đầu chương trình của bạn. Nó sẽ tràn số và quay số 0 (sau đó tiếp tục tăng) sau 50 ngày.

Arduino Sketch with millis() instead of delay() | Programming Electronics  Academy

Ví dụ về sử dụng hàm millis()

Ví dụ in ra giá trị hàm millis() qua Serial Monitor của Arduino IDE

unsigned long time;
void setup(){
  Serial.begin(9600);
}
void loop(){
  Serial.print("Time: ");
  time = millis();
  // in ra thời gian kể từ lúc chương trình được bắt đầu 
  Serial.println(time);
  // đợi 1 giây trước khi tiếp tục in
  delay(1000);
}

Ví dụ về nhấp nháy Led theo chu kỳ 1 giây

  • Chớp nháy LED D2 trên board UnoX bằng sử dụng chân 13 tín hiệu điều khiển.
  • Hiển thị trạng thái LED ON/OFF trên màn hình monitor trên trình biên dịch Arduino-IDE.
#define pinLed 13     // Định nghĩa pinLed là chân số 13

int ledState = LOW;               // khai báo biến lưu trạng thái của LED
unsigned long previousMillis = 0; // Khai báo biến previousMillis = 0
const long interval = 1000;       // Khái báo biến interval = 1000 mili giây = 1s

void setup()
{
  Serial.begin(9600);
  pinMode(pinLed, OUTPUT);
}

void loop()
{
  unsigned long currentMillis = millis();

  // Nếu hàm millis() đếm được 1000 milli giây = 1s thì sẽ thay đổi trạng thái LED
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if(ledState == LOW) {
      ledState = HIGH;            // Đổi trạng thái
      Serial.println("LED ON");   // Hiển thị trạng thái "LED ON" trên monitor
  } else {
      ledState = LOW;             // Đổi trạng thái
      Serial.println("LED OFF");  // Hiển thị trạng thái "LED OFF" trên monitor
  }
  digitalWrite(pinLed, ledState); // Xuất tín hiệu HIGH hoặc LOW để LED sáng hoặc tắt
  }
}

Ví dụ nhấp nháy cùng lúc 2 đèn led, mỗi đèn có chu kì nháy sáng khác nhau

Đoạn chương trình dưới đây có chức năng kiểm tra các biến thời gian time1, time2 so với giá trị của hàm millis(). Nếu vượt quá thời gian quy định 1000ms với biến time1 và 300ms với biến time2 thì sẽ thay đổi trạng thái đèn led.

byte led1 = 5;
byte led2 = 6;
unsigned long time1 = 0;
unsigned long time2 = 0;

void setup()
{
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
}

void loop()
{
    if ( (unsigned long) (millis() - time1) > 1000 )
    {
        if ( digitalRead(led1) == LOW )
        {
            digitalWrite(led1, HIGH);
        } else {
            digitalWrite(led1, LOW );
        }
        time1 = millis();
    }
    
    if ( (unsigned long) (millis() - time2) > 300  )
    {
        if ( digitalRead(led2) == LOW )
        {
            digitalWrite(led2, HIGH);
        } else {
            digitalWrite(led2, LOW );
        }
        time2 = millis();
    }
}

Lưu ý quan trọng về hàm thời gian millis()  

Các hàm về thời gian trong Arduino gồm millis() và micros() sẽ bị tràn số sau 1 thời gian sử dụng. Với hàm millis() là khoảng 50 ngày. Tuy nhiên, do là kiểu số nguyên không âm (unsigned long) nên ta dễ dàng khắc phục điều này bằng cách sử dụng hình thức ép kiểu.

unsigned long time;
byte ledPin = 10;
void setup()
{
    // khởi tạo giá trị biến time là giá trị hiện tại
    // của hàm millis();
    time = millis();
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, LOW);
}
void loop() 
{
    // Lưu ý các dấu ngoặc khi ép kiểu
    // đoạn chương trình này có nghĩa là sau mỗi 1000 mili giây
    // đèn Led ở chân số 10 sẽ thay đổi trạng thái
    if ( (unsigned long) (millis() - time) > 1000)
    {
            // Thay đổi trạng thái đèn led
        if (digitalRead(ledPin) == LOW)
        {
            digitalWrite(ledPin, HIGH);
        } else {
            digitalWrite(ledPin, LOW);
        }
        
        // cập nhật lại biến time
        time = millis();
    }
}

Thông thường, nếu ta có 2 số A, B và B lớn hơn A ( B > A) thì phép trừ thu được A-B là một số âm. Nhưng khi ép kiểu unsigned long là kiểu số nguyên dương, không có số âm nên giá trị trả về là 1 số nguyên dương lớn.

Ví dụ: kết quả của phép trừ:

unsigned long ex = (unsigned long) (0 - 1); 

là 4294967295, con số này chính là giá trị lớn nhất của kiểu số unsigned long. 

2 COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Tắt kính lúp hình vuông trong Altium

Tắt kính lúp của sổ PCB  trên Altium Sử dụng phím tắt: Shift+M Tham khảo thêm một số phím tắt khác trên phần mềm Altium Designer: Thiết...

Tổng hợp trang web liên quan thiết kế phần cứng điện tử

4 trang web tải thư viện SCH/PCB và 3D https://www.ultralibrarian.com/ https://componentsearchengine.com/ https://octopart.com/ https://www.snapeda.com/ https://componentsearchengine.com/ 2 trang tìm 3D cho thư viện của các bạn bao gồm: https://www.3dcontentcentral.com/ https://grabcad.com/library 4 trang cung cấp các...

Mạch đóng ngắt Relay sử dụng Transistor

Giới thiệu về Relay Rơ le (Relay) là một công tắc chuyển đổi hoạt động bằng điện. Dòng điện chạy qua cuộn dây của rơ...

Nạp Bootloader cho Arduino Pro Micro

Bootloader là một chương trình nhỏ được nạp sẵn vào chip vi điều khiển trên Arduino, nhờ đó bạn lập trình cho Arduino một...

Recent Comments