Информация из этого урока справедлива для AVR Arduino (UNO, Nano, Mega). На других платформах функция yield
может иметь другое назначение, см. документацию
Разработчики Arduino позаботились о том, чтобы функция delay()
не просто блокировала выполнение кода, но и позволяла выполнять другой код во время этой задержки. Данный "костыль" получил название yield()
и работает следующим образом: если объявить функцию
void yield() {
// ваш код
}
то расположенный внутри неё код будет выполняться во время работы задержки delay()
. Это решение хоть и кажется нелепым, но в то же время позволяет быстро и без написания лишних костылей и таймеров реализовать пару параллельно выполняющихся задач. Это вполне соответствует идеологии Arduino - максимально простая и быстрая разработка прототипа.
Рассмотрим простой пример - стандартный мигающий светодиод, но с опросом кнопки:
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
void yield() {
// а тут можно опрашивать кнопку
// и не пропустить нажатия из за delay!
}
Таким же образом можно опрашивать энкодер или другие железки, которые требуют максимально частого опроса. Не менее жизненным будет пример со сценарием движения шагового мотора или плавного движения сервопривода, которые требуют частого вызова "функций движения".
Рассмотрим абстрактный пример движения мотора по нескольким заданным точкам, функция вращения мотора должна вызываться как можно чаще (так сделано почти во всех библиотеках для шаговых моторов):
void setup() {}
void loop() {
// задать целевой угол №1
delay(1000);
// задать целевой угол №2
delay(120);
// задать целевой угол №3
delay(2000);
// задать целевой угол №4
delay(250);
// задать целевой угол №5
delay(600);
}
void yield() {
// вращать мотор
}
Таким образом мы быстро и просто расписали "траекторию" движения для шагового мотора по времени, не используя какие-то таймеры и библиотеки. Для более сложных программ, например с движением двух моторов, такой фокус уже может не пройти и будет проще работать с таймером.