Menangani beberapa pola pada saat yang bersamaan tentu dimungkinkan dengan platform seperti Arduino, dan ada sejumlah cara untuk melakukannya.
Salah satu metode yang akan saya pertimbangkan adalah fungsi menulis yang secara efektif mewakili setiap pola secara matematis. Anda baru saja melewatkannya total waktu yang telah berlalu dalam program Anda sejauh ini, dan itu akan melakukan tindakan yang sesuai untuk momen spesifik waktu itu. Ini akan segera kembali setelah itu (tidak ada penundaan atau apa pun).
Untuk melakukan itu, pertama-tama Anda harus tahu berapa lama satu siklus pola berlangsung. Anda kemudian dapat menggunakan operator modulo untuk mengetahui seberapa jauh siklus Anda saat ini. Dari sana, yang perlu Anda lakukan adalah memiliki beberapa if
kondisi untuk menentukan apa yang harus dilakukan pada waktu tertentu.
Inilah yang mungkin terlihat untuk pola "5 detik aktif, 5 detik nonaktif" Anda:
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);
}
Memang, terus-menerus menelepon digitalWrite()
ketika Anda tidak perlu secara teknis tidak terlalu efisien. Seharusnya tidak menyebabkan bahaya, dan cukup mudah untuk dioptimalkan jika perlu.
Untuk menggunakan contoh di atas dalam sketsa, Anda hanya perlu memanggilnya loop()
, dan meneruskan nomor yang Anda dapatkan millis()
; misalnya:
void loop()
{
const unsigned long totalTime = millis();
pattern5on5off(totalTime);
// call other patterns here...
}
Pola lain akan lebih kompleks, tetapi mengikuti prinsip yang sama. Anda hanya perlu menggunakan if
pernyataan yang sesuai untuk mengekspresikan logika Anda.
Yang penting untuk diingat adalah bahwa fungsi tersebut mewakili momen tertentu dalam waktu. Seharusnya tidak pernah menghentikan atau menunda program, jika tidak maka pola lainnya tidak akan berjalan.
Sunting: Waktu pada siklus pertama
Seperti jfpoilpret mencatat dalam komentar, siklus pertama akan dimulai pada titik acak. Hal ini karena pertama kali Anda menelepon millis()
di loop()
, itu tidak akan dimulai dari 0 (perangkat akan sudah telah berjalan untuk waktu yang singkat sebelum loop()
dipanggil). Sangat mudah untuk diselesaikan, jika perlu.
Anda akan melakukannya dengan mengimbangi totalTime
nilai dengan nilai apa pun yang Anda dapatkan pada saat pertama kali loop()
. Sebagai contoh:
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..
}