Здраствуете! Уважаемые участники форума. В работе с проэктом возникла необходимость разобраться как работать с таймером. Только прошу не пинайте ссылками на короткие примеры которых куча прочитаны, там мне не все понятно а что понятно того нет для понимания этого примера. Вопрос вот в чем, к примеру есть три светодиода красный синий и зеленый #define Red_DiodPIN 6 #define Blue_DiodPIN 7 #define Green_DiodPIN 8 #define PIN_Button 5 Для управления их работой задается кучка параметров каждый параметр будет регулироваться в меню //пауза между включением светодиодов unsigned long next_red = 200; unsigned long next_blue = 150; unsigned long next_green = 300; // время свечения светодиодов unsigned long ligth_time_red = 500; unsigned long ligth_time_blue = 700; unsigned long ligth_time_green = 800; свечение должно быть пульсирующим с регулировкой количества импульсов // количество импульсов unsigned long Pulse_red = 3; // будет регулироваться от 1 до 5 unsigned long Pulse_blue = 1; unsigned long Pulse_green = 4; так же присутствует интервал между импульсами //интервал пульсаций unsigned long Pulse_time_red = 50; // задержка между импульсов unsigned long Pulse_time_blue = 60; unsigned long Pulse_time_green = 80; Нажали на кнопку пауза (next_red) загорелся красный светодиод на заданное время (ligth_time_red), погас совсем если количество (Pulse_red) импульсов равно 0, или погас на время (Pulse_time_red). Повторил работу на установленое (Pulse_red) количество раз. Прошло время паузы (next_blue) в работу вступает синий светодиод. Загорелся на на заданное время (ligth_time_blue), погас совсем если количество (Pulse_blue) импульсов равно 0, или погас на время (Pulse_time_blue) Повторил работу на установленное (Pulse_blue) количество раз. Точно так же и зеленый... Если вам не трудно приведите пример работы описанной логики, я поизучаю если какие моменты не понятны то спрошу.
Как-то так Код (Text): #include <TimerOne.h> #define Red_DiodPIN 6 #define Blue_DiodPIN 7 #define Green_DiodPIN 8 #define PIN_Button 5 enum LED_COLOR { RED = 0, BLUE = 1, GREEN = 2 }; enum STATE { LIGHT_LED = 0, PULSE = 1 }; byte currentState = 0; byte currentLed = 0; byte currentPulse = 0; byte ledPin[] = { Red_DiodPIN, Blue_DiodPIN, Green_DiodPIN }; //пауза между включением светодиодов int nextLedTime[] = { 200, 150, 300 }; // время свечения светодиодов int lightTime[] = { 500, 700, 800 }; // количество импульсов будет регулироваться от 1 до 5 byte pulseCount[] = { 3, 1, 4 }; //интервал пульсаций int pulseInterval[] = { 50, 60, 80 }; //unsigned long time; void setup() { // put your setup code here, to run once: for (byte i = 0; i < 3; ++i) { pinMode(ledPin[i], OUTPUT); } Timer1.initialize(100000); // set a timer of length 100000 microseconds (or 0.1 sec - or 10Hz => the led will blink 5 times, 5 cycles of on-and-off, per second) Timer1.attachInterrupt( timerIsr ); // attach the service routine here // time = millis(); } void loop() { // put your main code here, to run repeatedly: /* //тупо и «в лоб» for (byte i = 0; i < 3; ++i) { for (byte pulse = 0; pulse < pulseCount[i]; ++pulse) { digitalWrite(ledPin[i], HIGH); delay(lightTime[i]); digitalWrite(ledPin[i], LOW); delay(pulseInterval[i]); } delay(nextLedTime[i]); } */ } void timerIsr() { unsigned long nextTime; switch (currentState) { case LIGHT_LED: digitalWrite(ledPin[currentLed], HIGH); nextTime = lightTime[currentLed]; currentState=PULSE; break; case PULSE: digitalWrite(ledPin[currentLed], LOW); if (currentPulse < pulseCount[currentLed]) { nextTime = pulseInterval[currentLed]; ++currentPulse; } else { currentPulse=0; currentState=LIGHT_LED; nextTime = nextLedTime[currentLed]; if (currentLed==GREEN) { currentLed=RED; } else { ++currentLed; } } currentState=LIGHT_LED; break; } Timer1.initialize(nextTime*1000); }
Почему то начинает работать сразу и не ждет нажатия кнопки.... Что то я совсем ничего не понял А попроще для начинающего нет варианта? С библиотеками еще не работал, кроме LiquidCrystal_I2C и debounce У меня настройки используются с помощью case типа такого if (flightTim < 1000) flightTim ++; Которая находится в void(loop) с неё вызываются исполняющие коды вроде такого if (debounce (Button_START)) { PulseLght(); } else if (debounce(Button_PLUS)) { mode = SELECT; } else if (debounce(Button_SET)) { mode = STOP; } } Мне теперь не понятен это момент как мне настраивать по отдельности параметры int lightTime[] = { 500, 700, 800 }; И второй вопрос если я вместо void loop() заменю PulseLght() Будет работать так же?
Можно вариант наподобие этого здесь то я как бы понимаю что происходит Правда он не полностью рабочий Код (Text): #define Red_DiodPIN 6 #define Blue_DiodPIN 7 #define Green_DiodPIN 8 #define Button_START 5 // абсолтюное время unsigned long time; unsigned long timepuls; // каждый параметр будет регулироваться // интервал между включением unsigned long next_red = 200; unsigned long next_blue = 150; unsigned long next_green = 300; // время свечения unsigned long ligth_time_red = 500; unsigned long ligth_time_blue = 700; unsigned long ligth_time_green = 800; // количество пульсаций unsigned long Pulse_red = 3; // будет регулироваться от 1 до 5 unsigned long Pulse_blue = 1; unsigned long Pulse_green = 4; //интервал пульсаций unsigned long Pulse_time_red = 100; // задержка между импульсами unsigned long Pulse_time_blue = 150; unsigned long Pulse_time_green = 200; void setup() { pinMode(Red_DiodPIN, OUTPUT); pinMode(Blue_DiodPIN, OUTPUT); pinMode(Green_DiodPIN, OUTPUT); digitalWrite(Red_DiodPIN, LOW); digitalWrite(Blue_DiodPIN, LOW); digitalWrite(Green_DiodPIN, LOW); pinMode(PIN_BTN_START, INPUT); } void loop() { if (digitalRead (Button_START)) { // сохраняем время на момент нажатия кнопки time = millis(); timepuls = millis(); // флаг, указывающий что цикл закончен boolean flag = false; while (!flag) { // если текущее время - сохраненое время меньше время свечения if (millis() - time <= ligth_time_red) digitalWrite(Red_DiodPIN, HIGH);// то выполняется условие Red_DiodPIN, HIGH // мне кажеться что сожранять новое время нужно после каждого действия //if (timepuls() - time <= ((ligth_time_red ++ Pulse_time_red) //digitalWrite(Red_DiodPIN, LOW); // включился выключился на заданное кличество раз Pulse_red else // инче Red_DiodPIN, LOW digitalWrite(Red_DiodPIN, LOW); if (millis() - time >= next && millis() - time <= next_blue + ligth_time_blue ) digitalWrite(Blue_DiodPIN, HIGH); else digitalWrite(Blue_DiodPIN, LOW); if (millis() - time >= next_green && millis() - time <= next_green + ligth_time_green ) digitalWrite(Green_DiodPIN, HIGH); else digitalWrite(Green_DiodPIN, LOW); // выходим из цикла if (millis() - time <= next_green + ligth_time_green) flag = true; } } }
lightTime[RED]=52; - например так можно менять таймеры Подредактировал код чуть - он был немного не того. Теперь того. Кнопку можете добавить сами) Там есть два варианта - один тупой (закомментированный в loop), второй с таймером. Вам нужен был пример работы - вот он. Если выберете тупой метод - удалите всё, что относится к Timer1. По поводу вашего кода с millis() - можно и так)
Что то не могу понять что происходит попытался сделать так lightTime[RED]=52; ошибку выдает И еще можете мне объяснить вот это для чего вернее что сдесь происходит я не могу понять если не сложно обьясните пожалуйста построчно. enum LED_COLOR { RED = 0, BLUE = 1, GREEN = 2 }; enum STATE { LIGHT_LED = 0, PULSE = 1 }; byte currentState = 0; byte currentLed = 0; byte currentPulse = 0; byte ledPin[] = { Red_DiodPIN, Blue_DiodPIN, Green_DiodPIN }; Код (Text): #include <TimerOne.h> #define Red_DiodPIN 6 #define Blue_DiodPIN 7 #define Green_DiodPIN 8 #define PIN_Button 5 enum LED_COLOR { RED = 0, BLUE = 1, GREEN = 2 }; enum STATE { LIGHT_LED = 0, PULSE = 1 }; byte currentState = 0; byte currentLed = 0; byte currentPulse = 0; byte ledPin[] = { Red_DiodPIN, Blue_DiodPIN, Green_DiodPIN }; //пауза между включением светодиодов int nextLedTime[] = { 200, 150, 300 }; // время свечения светодиодов int lightTime[RED]=500; int lightTime[BLUE]=750; int lightTime[GREEN]=800; // количество импульсов будет регулироваться от 1 до 5 byte pulseCount[] = { 3, 1, 4 }; //интервал пульсаций int pulseInterval[] = { 50, 60, 80 }; //unsigned long time; void setup() { // put your setup code here, to run once: for (byte i = 0; i < 3; ++i) { pinMode(ledPin[i], OUTPUT); } // time = millis(); } void loop() { for (byte i = 0; i < 3; ++i) { for (byte pulse = 0; pulse < pulseCount[i]; ++pulse) { digitalWrite(ledPin[i], HIGH); delay(lightTime[i]); digitalWrite(ledPin[i], LOW); delay(pulseInterval[i]); } delay(nextLedTime[i]); } }
Пожалуйста если не трудно покажите как это сделать с millis() так хоть мне больше всего понятней будет. Я сам плохо разбираюсь еще только учусь мне не как было не заставить работать свой код так как я еще неопытен в программировании.
http://wiki.amperka.ru/программирование:конечный-автомат?s[]=millis Почитайте эту статью - будет очень полезно для вашего проекта
Спасибо статья полезная кое чем помогла скретив ваш код и свой я разобрался как заставить мигать красный светодиод, Вот ту то и пошла загвоздка подскажите пожалуйста как delay() заменить на milis() чтобы в этот момент управлять остальными диодами статья типа Blink без Delay мне не помогла как записать выражение что пора выключить светодиод? Вот такой код у меня получился он работает но только на красный светодиод мне нужно чтобы синий и зеленый запускались в момент нажатия кнопки у каждого своя пауза перед запуском свой интервал и своя длительность свечения С delay это не подходит так как следущий диод будет ждать пока не закончит красный... С библиотекой TimerOne мне никак не разобраться... Код (Text): #define RED_PIN 6 #define BLUE_PIN 7 #define GREEN_PIN 10 #define PIN_BTN_START 5 // абсолтюное время unsigned long time; unsigned long timepuls; // каждый параметр будет регулироваться // пауза перед работой после старта unsigned long next_red = 200; unsigned long next_blue = 150; unsigned long next_green = 300; // длительность свечения unsigned long ligth_time_red = 500; unsigned long ligth_time_blue = 700; unsigned long ligth_time_green = 800; // количество сколько раз мигнуть byte Pulse_red = 2; // будет регулироваться от 1 до 5 byte Pulse_blue = 1; byte Pulse_green = 4; //интервал между миганием unsigned long pulseIntervalRed = 100; // задержка между импульсами unsigned long pulseIntervalBlue = 150; unsigned long pulseIntervalGreen = 200; // флаг статуса кнопки boolean btn_flag = false; void setup() { pinMode(RED_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); digitalWrite(RED_PIN, LOW); digitalWrite(BLUE_PIN, LOW); digitalWrite(GREEN_PIN, LOW); pinMode(PIN_BTN_START, INPUT); } void loop() { if ((digitalRead (PIN_BTN_START)) && !btn_flag) { btn_flag = true; // флаг отработки свечения диодов boolean flag = false; // текущее системное время long time = millis(); while(!flag) { // если текущее время - сохраненое время меньше время свечения if (millis() - time <= next_red) { for (byte pulse = 0; pulse < Pulse_red; ++pulse) { digitalWrite(RED_PIN, HIGH); delay(ligth_time_red); digitalWrite(RED_PIN, LOW); delay(pulseIntervalRed); } delay(next_red); flag = true; } } if (!(digitalRead (PIN_BTN_START)) && btn_flag) { btn_flag = false; delay(100); } } }
Я так делал но проблема в том что следующие светодиоды ждут когда закончит работать красный, delay портит всю картину мне нужно что бы работа трех диодов была независима...Вот примерно попытался изобразить
Я думал мне помогут а тут реально только издеваются над новичками Спасибо конечно я то и не догадался....
Вам код типа такого нужно сделать: Код (Text): bool active = false; long int time = 0; void loop() { if (digitalRead(PIN_BTN_START)) { active = true; time = millis(); } if (active) { long int rt = millis() - time; // timer event 1 if ((rt>=TIME_START_RED) && (rt<TIME_STOP_RED)) { digitalWrite(PIN_LED_RED, HIGH); } if (rt>=TIME_STOP_RED) { digitalWrite(PIN_LED_RED, LOW); } // timer event 2 if ((rt>=TIME_START_GREEN) && (rt<TIME_STOP_GREEN)) { digitalWrite(PIN_LED_GREEN, HIGH); } if (rt>=TIME_STOP_GREEN) { digitalWrite(PIN_LED_GREEN, LOW); } // timer event 3 if ((rt>=TIME_START_BLUE) && (rt<TIME_STOP_BLUE)) { digitalWrite(PIN_LED_BLUE, HIGH); } if (rt>=TIME_STOP_BLUE) { digitalWrite(PIN_LED_BLUE, LOW); } if (rt>=TIME_STOP_ALL) { active = false; } } }