Arduino:Хакинг/Почему в работе с Arduino необязательно всегда использовать функцию delay()
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Почему в работе с Arduino необязательно всегда использовать функцию delay()[1]
Первый раз работая с Arduino, вы, возможно, сделали что-то вроде этого:
- Подключили светодиод к Arduino
- Загрузили скетч «Blink», каждую секунду включающий/выключающий этот светодиод
Этот пример – «Привет, мир!» из мира скетчей Arduino. Он показывает, как при помощи всего нескольких строчек кода создать нечто, способное выполнять задачи в реальном мире.
В этом примере используется функция delay(). С ее помощью задаются интервалы между включением/выключением светодиода.
Но дело вот в чем. Хотя delay() удобна и хорошо работает с простыми скетчами, при создании более-менее серьезных проектов от ее использования лучше воздержаться. И вот почему.
Как работает функция delay()
Функция delay() работает очень просто.
Ее единственным аргументом является целочисленное значение, и оно означает время (в миллисекундах), которое скетч должен подождать перед тем, как перейти к следующей строчке кода.
Таким образом, если вписать в скетч delay(1000), это остановит работу Arduino на 1 секунду.
Функция delay() – это блокирующая функция. Блокирующие функции не дают скетчу делать ничего, кроме одной единственной задачи, которая выполняется в данный момент.
То есть если вы хотите, чтобы ваш скетч выполнял одновременно несколько задач (к примеру, если он постоянно считывает и сохраняет данные, приходящие через входные контакты), от использования delay() нужно попросту отказаться. К счастью, ее есть чем заменить.
Функция millis() спешит на помощь
Будучи вызванной, функция millis() возвращает количество миллисекунд, прошедших с запуска скетча.
Окей. Но чем она полезна?
При помощи millis() и небольших расчетов вы можете определять временные интервалы, не блокируя остальные строчки кода.
Код ниже демонстрирует, как создать скетч-пример «Blink», но с millis() вместо delay(). Он включает светодиод, 1000 миллисекунд держит его во включенном состоянии, а потом выключает. Но другой код при этом не блокируется.
/*
Пример «Blink» без функции delay()
Отсюда: arduino.cc/en/Tutorial/BlinkWithoutDelay
*/
// константы – это значения, которые не меняются;
// задаем константу, чтобы задать номер контакта:
const int ledPin = 13; // номер контакта со светодиодом
// переменные – это значения, которые меняются:
int ledState = LOW; // для хранения статуса светодиода
// как правило, для переменных, хранящих данные о времени,
// тип данных «unsigned long» не используется;
// но в данном случае значение будет очень быстро увеличиваться
// и не поместится в типе данных «int»:
unsigned long previousMillis = 0; // для хранения данных о том,
// когда светодиод был переключен
// в последний раз
// значения в константах не меняются:
const long interval = 1000; // интервал для мигания (мс)
void setup() {
// выставляем цифровой контакт в режим OUTPUT:
pinMode(ledPin, OUTPUT);
}
void loop() {
// здесь пишем код, выполнение которого будет постоянно повторяться;
// проверяем, пришло ли время моргнуть светодиодом;
// оно пришло, если разница между текущим временем и временем,
// когда произошло последнее моргание, больше интервала,
// который вы задали в константе «interval»:
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// сохраняем время, когда вы в последний раз мигнули светодиодом:
previousMillis = currentMillis;
// если светодиод выключен, включаем его, и наоборот:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// задаем статусу светодиода значение из переменной «ledState»:
digitalWrite(ledPin, ledState);
}
}
Этот скетч можно найти по этой ссылке. В его основе лежат очень простые расчеты: вы просто вычитаете из текущего времени (currentMillis) время, когда светодиод был переключен в последний раз (previousMillis). Если остаток будет выше заданного интервала (в данном случае – 1000 миллисекунд), скетч обновит previousMillis на текущее время, а затем либо включит, либо выключит светодиод.
И поскольку это неблокирующая функция, любой код, находящийся вне оператора if(), должен работать безо всяких проблем и задержек.
Таким образом, вы можете добавить в блок loop() какие-то другие задачи, и скетч будет по-прежнему мигать светодиодом раз в секунду.
Так какую функцию использовать?
Итак, мы научились двум разным способам того, как обращаться со временем в скетчах Arduino. Если delay() особо никаких усилий не требует, то millis() нужны дополнительные расчеты, но зато ваши скетчи будут многозадачными.
См.также
Внешние ссылки
Arduino продукты | |
---|---|
Начальный уровень | Arduino Uno • Arduino Leonardo • Arduino 101 • Arduino Robot • Arduino Esplora • Arduino Micro • Arduino Nano • Arduino Mini • Arduino Starter Kit • Arduino Basic Kit • MKR2UNO • TFT-дисплей Arduino |
Продвинутые функции | Arduino Mega 2560 • Arduino Zero • Arduino Due • Arduino Mega ADK • Arduino Pro • Arduino Motor Shield • Arduino USB Host Shield • Arduino Proto Shield • MKR Proto Shield • MKR Proto Large Shield • Arduino ISP • Arduino USB 2 Serial Micro • Arduino Mini USB Serial Adapter |
Интернет вещей | Arduino Yun • Arduino Ethernet • Arduino MKR1000 • Arduino WiFi 101 Shield • Arduino GSM Shield V2 • Arduino WiFi Shield • Arduino Wireless SD Shield • Arduino Wireless Proto Shield • Arduino Ethernet Shield V2 • Arduino Yun Shield • Arduino MKR1000 Bundle |
Носимые устройства | Arduino Gemma • Lilypad Arduino Simple • Lilypad Arduino Main Board • Lilypad Arduino USB • LilyPad Arduino SimpleSnap |
3D-печать | Arduino Materia 101 |
Устаревшие устройства | - |
Примеры Arduino | |
---|---|
Стандартные функции | |
Основы |
|
Цифровой сигнал |
|
Аналоговый сигнал |
|
Связь |
|
Управляющие структуры |
|
Датчики |
|
Дисплей |
Примеры, объясняющие основы управления дисплеем:
|
Строки |
|
USB (для Leonardo, Micro и Due плат) |
В этой секции имеют место примеры, которые демонстрируют использование библиотек, уникальных для плат Leonardo, Micro и Due.
|
Клавиатура |
|
Мышь |
|
Разное |