Программа мигания светодиодами. Вопрос по таймерам и функции прерывания.
- Войдите на сайт для отправки комментариев
Чт, 04/12/2014 - 14:00
Доброго всем!
Имеется задача: 1. Разработать программу управления 5-ю светодиодными индикаторами (СД) с помощью двух кнопок, по следующему алгоритму: при нажатии на первую кнопку («Старт») (через каждые 5 сек) зажигаются СД, при этом каждый предыдущий СД не гаснет при включении последующего. Гашение СД происходит одновременно через 5 сек после того как будут гореть все 5 СД. Прекращение работы происходит только после нажатия на кнопку («Стоп»).
Я подключил к цифровым выводам с 5-9 диоды, на pin 2,3 кнопки.
int x=1;
void setup()
{
pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT);
attachInterrupt(0, blink, CHANGE); // привязываем 0-е прерывание к функции blink(). Это будет кнопка стоп pin 2
}
void loop() {
if (x==1)
{
digitalWrite(5, HIGH);
delay(5000);
digitalWrite(6, HIGH)
delay(5000);
digitalWrite(7, HIGH);
delay(5000);
digitalWrite(8, HIGH);
delay(5000);
digitalWrite(9, HIGH);
}
else
{
digitalWrite(5,LOW);
digitalWrite(6, LOW)
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
}
}
void blink()
{
x = 0; // Должно выключить все диоды
}
Этот кусок программы работает, но не по заданию. При нажатии на кнопку х=о, но пока цикл загорания всех светодиодов не завершится они не тухнут.
Знакомый предложил сделать таймер не через delay, а просто создать какой-то цикл и подсчитать время одного цикла тогда программа будет при каждом цикле проверять условие if (x==1) и при его не выполнении сразу же выключать все диоды.
А подскажите, может как-то более точно можно реализовать это или есть еще какие-то внутренние таймеры. Заранее благодарен за помощь. Просто даже нет мыслей в каком направлении смотреть.
как только нажата кнопка старт поочередно начинают загоратся светодиоды, в любой момент принажатии стоп все светодиоды гаснут
[code] bool _tim1I = 0; bool _tim1O = 0; unsigned long _tim1P = 0UL; bool _trgs1 = 0; bool _tim2I = 0; bool _tim2O = 0; unsigned long _tim2P = 0UL; bool _tim3I = 0; bool _tim3O = 0; unsigned long _tim3P = 0UL; bool _tim4I = 0; bool _tim4O = 0; unsigned long _tim4P = 0UL; bool _bounseInput2S = 0; bool _bounseInput2O = 0; unsigned long _bounseInput2P = 0UL; bool _bounseInput3S = 0; bool _bounseInput3O = 0; unsigned long _bounseInput3P = 0UL; void setup() { pinMode(2, INPUT); pinMode(3, INPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); _bounseInput2O = digitalRead(2); _bounseInput3O = digitalRead(3); } void loop() { bool _bounceTmp2 = (digitalRead (2)); if (_bounseInput2S) { if (millis() >= (_bounseInput2P + 40)) {_bounseInput2O= _bounceTmp2; _bounseInput2S=0;} } else { if (_bounceTmp2 != _bounseInput2O ) {_bounseInput2S=1; _bounseInput2P = millis();} } bool _bounceTmp3 = (digitalRead (3)); if (_bounseInput3S) { if (millis() >= (_bounseInput3P + 40)) {_bounseInput3O= _bounceTmp3; _bounseInput3S=0;} } else { if (_bounceTmp3 != _bounseInput3O ) {_bounseInput3S=1; _bounseInput3P = millis();} } if(_bounseInput2O) _trgs1 = 1; if(_bounseInput3O) _trgs1 = 0; if (_trgs1) { _tim1O = 1; _tim1I = 1; } else { if (_tim1I) { _tim1I = 0; _tim1P = millis(); } else { if (_tim1O) {if ( _isTimer(_tim1P, 5000)) _tim1O = 0; } } } if (_tim1O) { _tim2O = 1; _tim2I = 1; } else { if (_tim2I) { _tim2I = 0; _tim2P = millis(); } else { if (_tim2O) {if ( _isTimer(_tim2P, 5000)) _tim2O = 0; } } } if (_tim2O) { _tim3O = 1; _tim3I = 1; } else { if (_tim3I) { _tim3I = 0; _tim3P = millis(); } else { if (_tim3O) {if ( _isTimer(_tim3P, 5000)) _tim3O = 0; } } } if (_tim3O) { _tim4O = 1; _tim4I = 1; } else { if (_tim4I) { _tim4I = 0; _tim4P = millis(); } else { if (_tim4O) {if ( _isTimer(_tim4P, 5000)) _tim4O = 0; } } } digitalWrite(5, _trgs1); digitalWrite(6, _tim1O); digitalWrite(7, _tim2O); digitalWrite(8, _tim3O); digitalWrite(9, _tim4O); } bool _isTimer(unsigned long startTime, unsigned long period ) { unsigned long endTime; endTime = startTime+period; return (millis() >= endTime); } [/code]Спасибо. Буду разбираться, что тут написано. может пойму.
Для понимания упростил и добавил комментарии, поищите в нете что такое RS триггер и таймер с задержкой включения.
[code] bool Q_RS = 0; // выход RS триггера bool _tim1I = 0; bool Q_tim_1 = 0; // выход таймера №1 unsigned long _tim1P = 0UL; bool _tim2I = 0; bool Q_tim_2 = 0; // выход таймера №2 unsigned long _tim2P = 0UL; bool _tim3I = 0; bool Q_tim_3 = 0; // выход таймера №3 unsigned long _tim3P = 0UL; bool _tim4I = 0; bool Q_tim_4 = 0; // выход таймера №4 unsigned long _tim4P = 0UL; void setup() { // тут всё понятно pinMode(2, INPUT); pinMode(3, INPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); } void loop() { if( (digitalRead (2))) Q_RS = 1; // проверяем состояние кнопки пин 2 if( (digitalRead (3))) Q_RS = 0; // проверяем состояние кнопки пин 3 if (Q_RS) // если состояние Q_RS истинно начинаем выполнять: запуск первого таймера; также Q_RS служит для выхода пин 5 (см внизу кода) { Q_tim_1 = 1; _tim1I = 1; } else { if (_tim1I) { _tim1I = 0; _tim1P = millis(); } else { if (Q_tim_1) {if ( _isTimer(_tim1P, 5000)) Q_tim_1 = 0; // сравниваем миллес Q_RS - истинна через 5 сек Q_tim_1 истинна, до этого лож } } } if (Q_tim_1)// если состояние Q_tim_1 истинно начинаем выполнять: запуск второго таймера; также Q_tim_1 служит для выхода пин 6 (см внизу кода) { Q_tim_2 = 1; _tim2I = 1; } else { if (_tim2I) { _tim2I = 0; _tim2P = millis(); } else { if (Q_tim_2) {if ( _isTimer(_tim2P, 5000)) Q_tim_2 = 0; } } } if (Q_tim_2) { Q_tim_3 = 1; _tim3I = 1; } else { if (_tim3I) { _tim3I = 0; _tim3P = millis(); } else { if (Q_tim_3) {if ( _isTimer(_tim3P, 5000)) Q_tim_3 = 0; } } } if (Q_tim_3) { Q_tim_4 = 1; _tim4I = 1; } else { if (_tim4I) { _tim4I = 0; _tim4P = millis(); } else { if (Q_tim_4) {if ( _isTimer(_tim4P, 5000)) Q_tim_4 = 0; } } } digitalWrite(5, Q_RS); digitalWrite(6, Q_tim_1); digitalWrite(7, Q_tim_2); digitalWrite(8, Q_tim_3); digitalWrite(9, Q_tim_4); } bool _isTimer(unsigned long startTime, unsigned long period ) { unsigned long endTime; endTime = startTime+period; return (millis() >= endTime); } [/code]спасибо!
Здравствуйте, Вовчик!
Я не могу реализовать программу по управлению машинкой с использованием эхолокационного дальномера.
Думаю, что дело в delay. Если встретит препятствие, то должно повернуть.
Не могли бы вы мне сделать набросок программы?
Модет сначало распиновку, какие девайсы задействованы и вашу програмку.
vov4ik, может быть сможете подсказать по моей программе. Программа управления двумя светодиодными индикаторами (СД1 и СД2)с помощью 2х кнопок, по следующему алгоритму: Кнопка нажата – СД1 и СД2 переключаются попеременно через 20 сек, отпускание кнопки не приводит к прекращению работы СД. СД гаснут только при нажатии второй кнопки.
У меня получилось написать программу, время между диодами заменил на 5сек. Первый вариант программы получился таким, используется вн.таймер, при нажатии на кнопку старт есть пауза в 5 секунд потом загораются свеодиоды. При нажатии на кнопку стоп все диоды тухнут.
Теперь есть одна проблема, хотел сделать так чтоб при нажатии на кнопку Старт, диод начал гореть 5 секунд без всяких пауз. Добавил в цикл условие, если y==1 оно выполнится один раз после нажатия на кнопку и далее будет отсчитвыться 5 секунд и менять состояние диодов на противоположное. Сейчас ни как не могу понять, почему из этого цика не выходится ни как. при нажатии на кн. стоп программа не останавливается.
// Вар.12 Программа управления двумя светодиодными индикаторами (СД1 и СД2)с помощью 2х кнопок, // по следующему алгоритму: Кнопка нажата – СД1 и СД2 переключаются попеременно через 20 сек, // отпускание кнопки не приводит к прекращению работы СД. СД гаснут только при нажатии второй кнопки. int ledPin1 = 10; // LED подсоединен к выводу 10 int ledPin2 = 9; // LED подсоединен к выводу 9 unsigned long currentTime; // Текшее время unsigned long loopTime; // Время цикла int state = 0; // Статус LED. 1-переменно мигают, 0-не горят void setup() { pinMode(ledPin1, OUTPUT); // устанавливаем вывод 10 как выход pinMode(ledPin2, OUTPUT); // устанавливаем вывод 9 как выход pinMode(1, OUTPUT); currentTime = millis(); // считываем время, прошедшее с момента запуска программы loopTime = currentTime; attachInterrupt(0, button1, CHANGE); // привязываем 0-е прерывание к функции blink(). Кнопка Старт. Pin2. При нажатии выполняется функция button1 attachInterrupt(1, button2, CHANGE); // привязываем 1-е прерывание к функции blink(). Кнопка Стоп. Pin3 } void loop(){ if (state==1) // проверка была ли нажата кнопка старт { currentTime = millis(); // считываем время, прошедшее с момента запуска программы if(currentTime >= (loopTime + 5000)){ // сравниваем текущий таймер с переменной loopTime + 5 секунд digitalWrite(ledPin1, !digitalRead(ledPin1)); digitalWrite(ledPin2, !digitalRead(ledPin1)); // включаем/выключаем LED loopTime = currentTime; // в loopTime записываем новое значение } } else { digitalWrite(ledPin1, LOW); digitalWrite(ledPin2, LOW); } } void button1() { state=1; // условие для зажигания диодов } void button2() { state=0; }Вот код с добавленным условием
// Вар.12 Программа управления двумя светодиодными индикаторами (СД1 и СД2)с помощью 2х кнопок, // по следующему алгоритму: Кнопка нажата – СД1 и СД2 переключаются попеременно через 20 сек, // отпускание кнопки не приводит к прекращению работы СД. СД гаснут только при нажатии второй кнопки. int ledPin1 = 10; // LED подсоединен к выводу 10 int ledPin2 = 9; // LED подсоединен к выводу 9 unsigned long currentTime; // Текшее время unsigned long loopTime; // Время цикла int state = 0; // Статус LED. 1-переменно мигают, 0-не горят int y = 0; void setup() { pinMode(ledPin1, OUTPUT); // устанавливаем вывод 10 как выход pinMode(ledPin2, OUTPUT); // устанавливаем вывод 9 как выход pinMode(1, OUTPUT); currentTime = millis(); // считываем время, прошедшее с момента запуска программы loopTime = currentTime; attachInterrupt(0, button1, CHANGE); // привязываем 0-е прерывание к функции blink(). Кнопка Старт. Pin2. При нажатии выполняется функция button1 attachInterrupt(1, button2, CHANGE); // привязываем 1-е прерывание к функции blink(). Кнопка Стоп. Pin3 } void loop(){ if (state==1) // проверка была ли нажата кнопка старт { currentTime = millis(); // считываем время, прошедшее с момента запуска программы if(currentTime >= (loopTime + 5000) || y==1){ // сравниваем текущий таймер с переменной loopTime + 5 секунд digitalWrite(ledPin1, !digitalRead(ledPin1)); digitalWrite(ledPin2, !digitalRead(ledPin1)); // включаем/выключаем LED loopTime = currentTime; // в loopTime записываем новое значение y=0; } } else { digitalWrite(ledPin1, LOW); digitalWrite(ledPin2, LOW); } } void button1() { state=1; // условие для зажигания диодов y=1; } void button2() { state=0; }Вот нравится вам кидать программу туда сюда, ведь написал как работает RS триггер
if( (digitalRead (2))) Q_RS = 1;// проверяем состояние кнопки пин 2if( (digitalRead (3))) Q_RS = 0;// проверяем состояние кнопки пин 3сдесь всё просто приоритет у кнопки 3, в вашем случае при нажатии одновременно двух кнопок что будет выполнено button1() или button2()
простая мигалка
boolean v1 = 1;boolean v2 = 0;boolean v3 = 0;unsigned long v4 = 0; boolean v5(unsigned long v6,unsigned long v7){unsigned long v8;v8=v6+v7; return (millis()>=v8);} void setup() { pinMode(13, OUTPUT); } void loop() { if (v1){if(!v2){v2=1;v3=1;v4=millis();}}else{v2=0;v3=0;}if(v2){if(v3){if(v5(v4,500)){v4=millis();v3=0;}} else{if(v5(v4,500)){v4=millis();v3=1;}}}digitalWrite(13,v3); }в вашем случае мигалку поставить под истинность Q_RS, digitalWrite(13,v3); заменить на digitalWrite(10,v3); с инверсией digitalWrite(9,!v3); 500 заменить на ваши 20000
Спасибо, я разобрасля) у меня вылетел провод от кнопки и я случайно воткнул его не туда и данные с кнопки давали имели случайный характер. отладил прогу с помощью консоли.