21 C
Hanoi
Thứ Hai, Tháng Mười 18, 2021
Home LẬP TRÌNH VI ĐIỀU KHIỂN ARDUINO Hàm millis() trong Arduino

Hàm millis() trong Arduino

Giới thiệu

Hàm 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. 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, micros()sẽ tràn sau khoảng 70 phút. 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. Hai hàm millis()và micros() là các chức năng thực sự tiện dụng để sử dụng khi xử lý các tác vụ thời gian.

Tham số: không

Trả về: một số nguyên kiểu unsigned long là thời gian kể từ lúc thương trình Arduino được khởi động

Thông thường trong chương trình Arduino, khi cần dừng lại để chờ qua 1 khoảng thời gian chúng ta thường sử dụng hàm delay () để thực hiện việc chờ này. Tuy nhiên cách làm này gây hao phí thời gian của CPU một cách vô ích, chúng ta không thể vừa dừng lại để chờ, vừa chạy 1 đoạn chương trình khác được. Kĩ thuật dùng hàm millis() sẽ giúp bạn chạy được nhiều đoạn chương trình song song với nhau.

Ví dụ: Đ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

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();
    }
}

Ép kiểu

if ( (unsigned long) (millis() - time) > 1000)
    {
    /*..............*/    
    }

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); à 4294967295, con số này chính là giá trị lớn nhất của kiểu số unsigned long. Giống như bạn đạp xe 1 vòng và quay về vạch xuất phát vậy.

Ví dụ in ra dòng chữ hello vào serial mỗi 1 giây:

int period = 1000;
unsigned long time_now = 0;
void setup() {
    Serial.begin(9600);
}
void loop() {
    if(<span class="pl-c1">millis</span>() > time_now + period)
    {
        time_now = millis();
        Serial.print("Time: ");
    Serial.print(time_now/1000);
    Serial.print("s - ");
        Serial.println("Hello");
    }
    //Run other code
}

Tại sao sử dụng millis () thay vì delay ()?

Thời gian chính xác: Với millis(), chúng ta có thể đảm bảo rằng vòng lặp chạy thường xuyên như chúng ta muốn, bất kể thời gian thực hiện.
Không chặn:  millis() không chặn các tác vụ đang chạy

Sử dụng hàm millis() với khoảng thời gian lớn

Ví dụ in MESSAGE1 mỗi 5 giây và MESSAGE2 mỗi 7 giây và MESSAGE3 mỗi 9 giây:

#define INTERVAL1 5000
#define INTERVAL2 7000
#define INTERVAL3 9000
 
unsigned long millis_1 = 0;
unsigned long millis_2 = 0;
unsigned long millis_3 = 0;
 
void displayTime(unsigned long);
void setup() 
{
    Serial.begin(9600);
}
void loop() 
{
  if(<span class="pl-c1">millis</span>() > millis_1 + INTERVAL1)
  {
    millis_1 = millis();
    displayTime(millis_1);
    Serial.println("1");
  }
  if(<span class="pl-c1">millis</span>() > millis_2 + INTERVAL2)
  {
    millis_2 = millis();
    displayTime(millis_2);
    Serial.println("2");
  }
  if(<span class="pl-c1">millis</span>() > millis_3 + INTERVAL3)
  {
    millis_3 = millis();
    displayTime(millis_3);
    Serial.println("3");
  }
}
void displayTime(unsigned long time_millis)
{
    Serial.print("Time: ");
    Serial.print(time_millis/1000);
    Serial.print("s - ");
}

Sử dụng millis để tính khoảng thời gian (timer)

Tính thời gian ấn giữ phím nhấn tại chân 2 của Arduino Uno:

/*
tính thời gian phím được giữ
*/
const int switchPin = 2; // nút bấm được nối vào PIN2
long startTime; // giá trị khi nút bắt đầu bấm
long duration; // khoảng thời gian được giữ
void setup()
{
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH); // kéo chân 2 lên mức cao
Serial.begin(9600);
}
void loop()
{
if(digitalRead(switchPin) == LOW) // nếu nút bấm ở mức thấp
{
startTime = millis(); // giá trị ban đầu được gán bằng giá trị hiện tại của millis
while(digitalRead(switchPin) == LOW) ; // đợi cho nút bấm được giữ
long duration = millis() - startTime; // thời gian bằng giá trị hiện tại trừ giá trị ban đầu
Serial.println(duration); //in ra màn hình
}
}

Ví dụ nhấp nháy hai led song song nhau

Mục tiêu của đoạn chương trình này là nhấp nháy cùng lúc 2 đèn led, mỗi đèn có chu kì nháy sáng khác nhau.

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();
    }
}

Đoạn chương trình trên 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. Nếu với cách làm thông thường chúng ta sẽ viết:

void loop()
{
   if ( digitalRead(led1) == LOW )
   {
        digitalWrite(led1, HIGH);
   } else {
        digitalWrite(led1, LOW );
   }
   delay (700); // giảm thời gian để tổng thời gian chờ của led 1 là 700 + 300 = 1000ms
   
   if ( digitalRead(led2) == LOW )
   {
        digitalWrite(led2, HIGH);
   } else {
        digitalWrite(led2, LOW );
   }
   delay (300);
}

Với cách viết thông thường, chương trình sẽ dừng lại ở hàm delay và chờ ở đó. Trong khi với cách viết dùng hàm millis() như ở trên, chúng ta có thể nhấp nháy nhiều led song song với nhau.

Tham khảo:
http://arduino.vn/
http://arduino4everyone.blogspot.com/

2 COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

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...

Một vài lưu ý khi thiết kế sản phẩm đáp ứng EMC

Mỗi bảng mạch in (PCB) phải có thể hoạt động mà không bị gián đoạn do nhiễu từ các thiết bị khác và không...

Recent Comments