Xử lý nhiều mẫu cùng một lúc chắc chắn là có thể với một nền tảng như Arduino, và có một số cách bạn có thể đi về nó.
Một phương pháp tôi sẽ xem xét là viết các hàm đại diện hiệu quả cho từng mẫu theo toán học. Cho đến nay, bạn chỉ cần vượt qua tổng thời gian đã trôi qua trong chương trình của mình và nó sẽ thực hiện hành động thích hợp cho thời điểm cụ thể đó. Nó sẽ trở lại ngay lập tức sau đó (không chậm trễ hoặc bất cứ điều gì).
Để làm điều đó, trước tiên bạn cần biết một chu kỳ của mẫu sẽ kéo dài bao lâu. Sau đó, bạn có thể sử dụng toán tử modulo để tìm hiểu xem bạn đang ở đâu trong chu kỳ hiện tại. Từ đó, tất cả những gì bạn cần làm là có một số if
điều kiện để xác định những việc cần làm tại bất kỳ thời điểm nào.
Đây là giao diện của mẫu "5 giây bật, tắt 5 giây" của bạn:
function pattern5on5off(unsigned long totalTime)
{
// Calculate how far through the current cycle we are
const unsigned long cycleTime = totalTime % 10000;
// If we're in the first 5 seconds of the cycle then turn the light on.
// Otherwise, turn it off.
if (cycleTime < 5000)
digitalWrite(3, HIGH);
else
digitalWrite(3, LOW);
}
Phải thừa nhận rằng, liên tục gọi điện digitalWrite()
khi bạn không cần kỹ thuật là không hiệu quả. Nó không gây ra bất kỳ tác hại nào, và khá dễ dàng để tối ưu hóa nếu cần thiết.
Để sử dụng ví dụ trên trong một bản phác thảo, bạn chỉ cần gọi nó vào loop()
và chuyển số bạn nhận được từ millis()
; ví dụ:
void loop()
{
const unsigned long totalTime = millis();
pattern5on5off(totalTime);
// call other patterns here...
}
Các mẫu khác sẽ phức tạp hơn, nhưng theo cùng một nguyên tắc. Bạn chỉ cần sử dụng các if
tuyên bố thích hợp để thể hiện logic của bạn.
Điều quan trọng cần nhớ là chức năng đại diện cho một thời điểm cụ thể. Nó không bao giờ nên tạm dừng hoặc trì hoãn chương trình, nếu không nó sẽ ngăn các mẫu khác chạy.
Chỉnh sửa: Thời gian trên chu kỳ đầu tiên
Như jfpoilpret đã lưu ý trong các nhận xét, chu kỳ đầu tiên sẽ bắt đầu tại một điểm ngẫu nhiên. Điều này là do lần đầu tiên bạn gọi millis()
đến loop()
, nó sẽ không bắt đầu từ 0 (thiết bị sẽ chạy trong một thời gian ngắn trước khi loop()
được gọi). Thật dễ dàng để giải quyết, nếu cần thiết.
Bạn sẽ làm điều đó bằng cách bù đắp totalTime
giá trị bằng bất kỳ giá trị nào bạn nhận được trong lần đầu tiên loop()
. Ví dụ:
unsigned long g_startTime = 0;
void loop()
{
unsigned long totalTime = 0;
if (g_startTime == 0) {
// This is the first cycle.
// Store the start time so we can compensate later.
g_startTime = millis();
} else {
// This is not the first cycle.
// Compensate for the start time.
totalTime = millis() - g_startTime;
}
pattern5on5off(totalTime);
// etc..
}