Используем функции delay() и millis() в Arduino IDE

Автор Deny, 23:08:36

« предыдущая - следующая »

0 Пользователей и 1 гость просматривают эту тему.

Deny

[h=1]1. Использование DELAY[/h]Основная ошибка новичков при написании скетчей для Arduino – чрезмерное использование функции delay().Эта функция, (см. официальную документацию) останавливает выполнение программы. Рассмотрим пример: подключим к Arduino кнопку и светодиод; нажимаем на кнопку, светодиод должен зажечься на 3 секунды.Скетч может выглядеть примерно следующим образом (несолько модифицированная версия из оффициального туториала):


[COLOR=#000000][FONT=Lato_medium]const int buttonPin = 2;[/FONT][/COLOR]const int ledPin = 4;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop() {
if (digitalRead(buttonPin) == HIGH) {
digitalWrite(ledPin, HIGH);
delay(3000);
digitalWrite(ledPin, LOW);
}
[COLOR=#000000][FONT=Lato_medium]}[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]Добавим вторую [URL=http://arduino-diy.com/arduino-knopka-i-seriynyy-monitor-v-IDE]кнопку[/URL] и второй [URL=http://arduino-diy.com/arduino-miganiye-vstroyennym-na-platu-svetodiodom]светодиод[/URL],  обновляем скетч, чтобы управлять двумя светодиодами, при этом используем функцию delay():[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]const int button1Pin = 2;[/FONT][/COLOR]const int button2Pin = 3;
const int led1Pin = 4;
const int led2Pin = 5;
void setup() {
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(button1Pin, INPUT);
pinMode(button2Pin, INPUT);
}
void loop(){
if (digitalRead(button1Pin) == HIGH) {
digitalWrite(led1Pin, HIGH);
delay(3000);
digitalWrite(led1Pin, LOW);
}
if (digitalRead(button2Pin) == HIGH) {
digitalWrite(led2Pin, HIGH);
delay(3000);
digitalWrite(led2Pin, LOW);
}
[COLOR=#000000][FONT=Lato_medium]}[/FONT][/COLOR]


Схема подключения с использованием breadboard'a в данном случае выглядит так:ПРОБЛЕМА!!! Когда один светодиод включен, то не включается второй! Причина простая: когда первый светодиод включен, скетч останавливает свою работу и, соответственно, не может проверить состояние второй кнопки...

2. Используем MILLIS
Для решения этой проблемы можно использовать функцию millis(): она возвращает количество милисекунд, которое прошло с момента запуска скетча.Если надо узнать, когда прошло заданное время, можно:сохранить в переменной начальное время, то есть момент времени, когда включили светодиод.Периодически проверять (например, в теле цикла loop), разницу между начальным временем и фактическим на данный момент.

Ниже приведен новый скетч:




const int button1Pin = 2;
const int button2Pin = 3;
const int led1Pin = 4;
const int led2Pin = 5;
unsigned long led1OnTime;
unsigned long led2OnTime;bool led1On;[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]bool led2On;[/FONT][/COLOR]void setup() {[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR]pinMode(led1Pin, OUTPUT);pinMode(led2Pin, OUTPUT);[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]pinMode(button1Pin, INPUT);[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]pinMode(button2Pin, INPUT);[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]led1On = false;[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]led2On = false;[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]}[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]void loop(){[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]if (digitalRead(button1Pin) == HIGH) {[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]digitalWrite(led1Pin, HIGH);[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]led1On = true;[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]led1OnTime = millis();[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]}[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]if (digitalRead(button2Pin) == HIGH) {[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]digitalWrite(led2Pin, HIGH);[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]led2On = true;[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]led2OnTime = millis();[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]}[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]if(led1On)[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]if(millis() - led1OnTime > 30000) {[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]digitalWrite(led1Pin, LOW);[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]led1On = false;[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]}[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]if(led2On)[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]if(millis() - led2OnTime > 30000) {[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]digitalWrite(led2Pin, LOW);[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]led2On = false;[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]}[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium][/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]}[/FONT][/COLOR][COLOR=#000000][FONT=Lato_medium]


Введено две новые переменные: две (led1OnTime и led2OnTime), чтобы сохранить значения времени, когда светодиоды включаются и две (led1On и led2On), чтобы оценивать текущий статус светодиодов (вкл. или выкл. (on/off) или в булевом типе — true/false).[/FONT][/COLOR]Когда кнопка нажата, скетч заставляет светодиод включится, сохраняет текущее время и меняет значение в переменной статуса.Если светодиод горит (переменная состояния равна true), скетч периодечески проверяет длительность состояния вкл. (30 секунд, то есть 30000 милисекунд): если период превышает допустимый (30 секунд 30000 миллисекунд), то это значит, что светодиод выключен.
​Не говорите, если это не изменит тишину к лучшему.