Сделал простую плату выбора режима работы для будущего устройства. Плата состоит из 2 кнопок и 6 светодиодов Написал скетч. При запуске программы должно происходить следующее - поочередно зажигаются шесть светодиодов и плата переходит в режим ожидания, горит 1-й светодиод Если нажать на кнопку 2 происходит переключение режима с одновременной индикацией режима соответствующим светодиодом. Вопрос. Хотел избавится от функции delay () в нижеуказанной части кода /* Устанавливаем выводы, к которым подключены светодиоды платы режимов, в OUTPUT. Далее зажигаем и гасим светодиоды с интервалом в 0.5 сек для проверки их работы */ for (vmode = 0; vmode < 6; vmode = vmode + 1) { pinMode(vledpins[vmode], OUTPUT); digitalWrite(vledpins[vmode],HIGH); delay (500); digitalWrite(vledpins[vmode], LOW); } * Устанавливаем выводы, к которым подключены светодиоды платы режимов, в OUTPUT. Далее зажигаем и гасим светодиоды с интервалом в 0.5 сек для проверки их работы */ for (vmode = 0; vmode < 6; vmode = vmode + 1) { pinMode(vledpins[vmode], OUTPUT); digitalWrite(vledpins[vmode], ledpin); } и заменить ее на millis(), но не получается. После запуска программы горит только первый светодиод. Помогите разобраться. Спасибо. Код (Text): // Плата управления режимами работы // Заносим в массив номера выводов контроллера, к которым подключены светодиоды // платы выбора режимов работы робота const int vledpins[6]={2,3,4,5,6,7}; int ledpin = LOW; // предыдущее состояние светодиода long previousMillis = 0; // здесь будет храниться время последнего изменения состояния светодиода long interval = 2000; // интервал мигания в миллисекундах // Создаем переменную для сохранения режима работы int vmode; // Создаем переменную для сохранения предыдущего режима работы int vmodeprev = -1; // Заносим в массив номера вывода контроллера, к которым подключены кнопки // платы выбора режимов работы робота const int vbtn[2]={8,9}; void setup() { /* Инициализируем выводы контроллера, к которым подключены кнопки, в INPUT. */ pinMode(vbtn[0], INPUT); pinMode(vbtn[1], INPUT); if (millis() - previousMillis > interval) { previousMillis = millis(); // запоминаем текущее время // если светодиод был выключен – включаем и наоборот :) if (ledpin == LOW) ledpin = HIGH; else ledpin = LOW; } /* Устанавливаем выводы, к которым подключены светодиоды платы режимов, в OUTPUT. Далее зажигаем и гасим светодиоды с интервалом в 0.5 сек для проверки их работы */ for (vmode = 0; vmode < 6; vmode = vmode + 1) { pinMode(vledpins[vmode], OUTPUT); digitalWrite(vledpins[vmode],HIGH); //digitalWrite(vledpins[vmode], ledpin); delay (500); digitalWrite(vledpins[vmode], LOW); } // Устанавливаем значение первого режима работы робота vmode = 0; } //ИСПОЛНЯЕМЫЙ ПРОГРАММНЫЙ МОДУЛЬ void loop() { /* Исполняемый программный модуль переключения режимов работы робота */ // Кнопка переключения на следующий режим - BTN1 if (digitalRead(vbtn[0]) == HIGH) { vmode = vmode + 1; vmodeprev = vmode - 1; if (vmode > 5) { vmode = 0; vmodeprev = 5; } } // Кнопка переключения на предыдущий режим - BTN2 if (digitalRead(vbtn[1]) == HIGH) { vmode = vmode - 1; vmodeprev = vmode + 1; if (vmode < 0) { vmode = 5; vmodeprev = 0; } } // Засвечиваем светодиод текущего режима работы digitalWrite(vledpins[vmode], HIGH); // Гасим светодиод предыдущего режима работы if (vmodeprev > -1) { digitalWrite(vledpins[vmodeprev], LOW); } /* Выбор режима работы */ switch (vmode) { case 0: // Режим 0 break; case 1: // Режим 1 break; case 2: // Режим 2 break; case 3: // Режим 3 break; case 4: //Режим 4 break; case 5: // Режим 5 break; } }
setup() - запускается 1 раз, при запуске программы. loop() - крутится вечно. В setup нет смысла избавляться от delay, там она уместна. В setup мы производим настройку портов модулей и т.д., но не пишем программу, поэтому задержка с использованием delay не критична. Да и уйти от delay таким способом в setup нельзя, так как принцип проверки через millis, требует цикла loop, а setup выполняется только раз. Программу мы пишем в loop и там delay, бывает критичен, так как команда delay почти полностью останавливает контролер. Пока программа ожидает завершения delay, нельзя работать с портами и т.д., подробнее тут. Подробно о таймерах без delay на русском тут.
Коллеги, хотел бы понять все таки, как в указанном скетче заменить delay на millis и чтобы он работал. При запуске мигает только 1-й светодиод, подключенный к выводу 2, а остальные не зажигаются. То есть при включении не наблюдается "дорожка" из светодиодов как собственно указано в программе и она работает с функцией delay
Не понимаю, что именно не понятно. Но иногда, проще написать код, может он прояснит Код (Text): // Плата управления режимами работы // Заносим в массив номера выводов контроллера, к которым подключены светодиоды // платы выбора режимов работы робота const int vledpins[6]={2,3,4,5,6,7};//{2,3,4,5,6,7}; int ledpin = 13; // предыдущее состояние светодиода long previousMillis = 0; // здесь будет храниться время последнего изменения состояния светодиода long interval = 2000; // интервал мигания в миллисекундах // Создаем переменную для сохранения режима работы int vmode; // Создаем переменную для сохранения предыдущего режима работы int vmodeprev = -1; // Заносим в массив номера вывода контроллера, к которым подключены кнопки // платы выбора режимов работы робота const int vbtn[2]={8,9}; int allLedShow = 0; // Индекс цикла boolean ledShow = 0; // Пока 0, зажигаем и гасим светодиоды с интервалом в 0.5 сек boolean led13Show = 0; // Пока 0, зажигаем и гасим светодиод 13 long previousShowMillis = 0; // Здесь будет храниться время последнего изменения состояния светодиодов long intervalShow = 500; // Интервал мигания в миллисекундах светодиодов void setup() { /* Инициализируем выводы контроллера, к которым подключены кнопки, в INPUT. */ pinMode(vbtn[0], INPUT); pinMode(vbtn[1], INPUT); pinMode(ledpin, OUTPUT); /* Устанавливаем выводы, к которым подключены светодиоды платы режимов, в OUTPUT. Далее зажигаем и гасим светодиоды с интервалом в 0.5 сек для проверки их работы */ for (vmode = 0; vmode < 6; vmode++) { pinMode(vledpins[vmode], OUTPUT); /*digitalWrite(vledpins[vmode],HIGH);*/ /*delay (500); digitalWrite(vledpins[vmode], LOW);*/ } // Устанавливаем значение первого режима работы робота vmode = 0; Serial.begin(9600); previousMillis = millis(); // запоминаем текущее время для led13 } //ИСПОЛНЯЕМЫЙ ПРОГРАММНЫЙ МОДУЛЬ void loop() { /* Исполняемый программный модуль переключения режимов работы робота */ if (!led13Show) { if (millis() - previousMillis > interval) { previousMillis = millis(); // запоминаем текущее время // если светодиод был выключен – включаем и наоборот :) digitalWrite(ledpin, !digitalRead(ledpin)); // После того как светодиод 13 будет выключен, прерываем мигание if (!digitalRead(ledpin)) { led13Show = 1; } } } // Убеждаемся, что ledShow == 0 if (!ledShow) { // Убеждаемся, что previousShowMillis == 0 + millis() > 0 if (!previousShowMillis && millis()) { digitalWrite(vledpins[allLedShow],HIGH); previousShowMillis = millis(); Serial.print("1 step - index array: "); Serial.print(allLedShow); Serial.print(" pin: "); Serial.print(vledpins[allLedShow]); Serial.print(" value pin: "); Serial.println(digitalRead(vledpins[allLedShow])); } // Убеждаемся, что previousShowMillis > 0 проверяем что прошло необходимое время if ((previousShowMillis > 0) && (millis() - previousShowMillis > intervalShow)) { digitalWrite(vledpins[allLedShow],LOW); Serial.print("2 step - index array: "); Serial.print(allLedShow); Serial.print(" pin: "); Serial.print(vledpins[allLedShow]); Serial.print(" value pin: "); Serial.println(digitalRead(vledpins[allLedShow])); previousShowMillis = 0; // Увеличиваем на 1, значения индекса allLedShow++; // Прерываем мигание if (allLedShow == 6) { ledShow = 1; Serial.println("Finish"); } } } // Кнопка переключения на следующий режим - BTN1 if (digitalRead(vbtn[0]) == HIGH) { vmode = vmode + 1; vmodeprev = vmode - 1; if (vmode > 5) { vmode = 0; vmodeprev = 5; } } // Кнопка переключения на предыдущий режим - BTN2 if (digitalRead(vbtn[1]) == HIGH) { vmode = vmode - 1; vmodeprev = vmode + 1; if (vmode < 0) { vmode = 5; vmodeprev = 0; } } // Засвечиваем светодиод текущего режима работы digitalWrite(vledpins[vmode], HIGH); // Гасим светодиод предыдущего режима работы if (vmodeprev > -1) { digitalWrite(vledpins[vmodeprev], LOW); } /* Выбор режима работы */ switch (vmode) { case 0: // Режим 0 break; case 1: // Режим 1 break; case 2: // Режим 2 break; case 3: // Режим 3 break; case 4: //Режим 4 break; case 5: // Режим 5 break; } } Если хотим именно в setup, хоть это не логично, можно и так, читаем задержки в AVR. Удачи.