Как заставить работать реле через millis()
- Войдите на сайт для отправки комментариев
Чт, 11/01/2018 - 14:45
Есть задача включать реле на 50 минут и выключать на 20 минут. Пока что пробую на светодиоде по примеру Блинка без delay(). Для удобства тестирования светится 1 минуту, полминуты отдыхает. Вначале диод включается через положенную 1 минуту, а дальше не гаснет. Никак не могу понять, как довести до ума, без вашей помощи не обойтись мне! Вот код:
unsigned long previousMillis1 = 0; // will store last time LED was updated
unsigned long previousMillis2 = 0;
const long interval_1 = 60000;//3000000;
const long interval_2 = 30000;//900000;
int led = 13;
void setup()
{
pinMode(led, OUTPUT);
}
void loop()
{
unsigned long currentMillis = millis();
{
if (currentMillis - previousMillis2 >= interval_1) {
previousMillis2 = currentMillis;
digitalWrite(led,LOW);
}
delay(1000);
if (currentMillis - previousMillis1 >= interval_2) {
previousMillis1 = currentMillis;
digitalWrite(led, HIGH);
}
}
}
строки 16, 22 и 28 лишние.
Внимательно прочитайте еще раз блинк_без_делай - разве там два Previousmillis ? и два условия? - нет, все делается в одном. - в этом ваша проблема
Гаснет. Но потом сразу включается. Потому что интервалы у вас кратные и события происходят одно за другим. А зажигается светодиод в два раза чаще, чем тушится.
Вот ваш же код:
unsigned long previousMillis1 = 0; // will store last time LED was updated unsigned long previousMillis2 = 0; const long interval_1 = 6000;//3000000; const long interval_2 = 3000;//900000; int led = 13; void setup() { pinMode(led, OUTPUT); } void loop() { unsigned long currentMillis = millis(); { if (currentMillis - previousMillis2 >= interval_1) { previousMillis2 = currentMillis; digitalWrite(led, LOW); } //delay(1000); if (currentMillis - previousMillis1 >= interval_2) { previousMillis1 = currentMillis; digitalWrite(led, HIGH); } } }Светодиод визуально горит? А если поменять интервалы местами?
Код подправил. 2 Previousmillis мне нужны, потому что диод должен быть в потушенном состоянии ~в два раза меньше, чем во включенном состоянии. А как это реализовать через один Previousmillis, ума не приложу.
unsigned long previousMillis1 = 0; unsigned long previousMillis2 = 0; const long interval_1 = 60000;//3000000; const long interval_2 = 30000;//900000; int led = 13; void setup() { pinMode(led, OUTPUT); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis2 >= interval_1) { previousMillis2 = currentMillis; digitalWrite(led,LOW); } if (currentMillis - previousMillis1 >= interval_2) { previousMillis1 = currentMillis; digitalWrite(led, HIGH); } }Светодиод визуально горит? А если поменять интервалы местами?
Да, горит. Если поменять местами, то 3 секунды горит, на 3 с. гаснет.
Код подправил. 2 Previousmillis мне нужны, потому что диод должен быть в потушенном состоянии ~в два раза меньше, чем во включенном состоянии.
Для этого не нужно два Previousmillis. Нужно всего лишь при каждом переключении диода менять интервал следующего переключения, приравнивая его то interval1. то interval2.
А Previousmillis и условие проверки должно быть одно.
b707, спасибо большое, все получилось. Если есть замечания, как улучшить код, удалить возможные подводные камни, буду благодарен!
unsigned long previousMillis = 0; const long interval_1 = 8000;//3000000; const long interval_2 = 3000;//900000; int led = 13; int interv = interval_2; void setup() { pinMode(led, OUTPUT); Serial.begin(9600); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interv) { if (interv == interval_2) interv = interval_1; else interv = interval_2; previousMillis = currentMillis; Serial.println(interv); digitalWrite(led, !digitalRead(led)); } }unsigned long prev = 0; //для тамера int interval = 50; //интервал мин #define led 13 // пин реле void setup() { pinMode (led, OUTPUT); digitalWrite (led,1); } void loop() { if (millis() - prev > (unsigned long)interval*60000UL ){ if (digitalRead(led)) interval = 20; else interval = 50; digitalWrite (led, !digitalRead(led)); prev = millis(); } }MaksVV, протестировал Ваш код. Все замечательно, кроме маленького нюанса, а именно - диод 50 минут не светится, 20 горит. А должно быть наоборот. Заменил единицу на 0 в 8-й строке Вашего кода, теперь вроде сначала горит. Буду тестировать дальше. Спасибо!
Может вы реле уже подключили? У реле обычно логика включения инвертирована. Т.е. если на пине лог. 0 то реле включено.
Да, решил сразу на Аттини13 с подключенным реле испробовать.
Я этого не знал. Это очень странно, и на первый взгляд нелогично. Для меня, новичка, к тому же неудобно. Но что поделаешь, раз так сделали.
После нескольких включений-выключений 20 и 50 минут меняются местами, то есть горит 20 и выключается на 50 минут.
может так
unsigned long prev = 0; //для тамера int interval = 50; //интервал мин #define led 13 // пин реле void setup() { pinMode (led, OUTPUT); digitalWrite (led,0); } void loop() { if (millis() - prev > (unsigned long)interval*60000UL ){ if (!digitalRead(led)) interval = 20; else interval = 50; digitalWrite (led, !digitalRead(led)); prev = millis(); } }У меня на данный момент схожая ситуация, отличие только в том что я планирую управлять двумя реле 1-е вкл/выкл кулера, а 2-е для вкл/выкл прибора.
В идеале должно быть так чтобы с помощью первой тактовой кнопки вводилось время работы прибора (2-го реле), например 25 минут, с помощью 2ой запуск таймеров.
Включение кулера (реле 1), происходит сразу при подаче питания.
Через 3 минуты происходит запуск прибора (2е реле) и по истечии 25 минут, должно оключится.
Выключение кулера (1е реле) происходит через 20 минут после отключения прибора (2го реле).
Пока пробую на светодиодах без кнопок, время ввожу программно. Данный код работает до момента выключения 1го реле и никак не могу заставить его погаснуть в нужное время. нужное время.
Код я писал не сам (взял изи видеуроков). Пожалуйста помогите.
//culler
int ledPin1 = 12; // the number of the LED pin int ledState1 = LOW; // ledState used to set the LED unsigned long previousMillis1 = 0; // will store last time LED was updated long OnTime1 = 0; // milliseconds of on-time long OffTime1 = 2300; // milliseconds of off-time //pribor int ledPin2 = 13; // the number of the LED pin int ledState2 = LOW; // ledState used to set the LED unsigned long previousMillis2 = 0; // will store last time LED was updated long OnTime2 = 300; // milliseconds of on-time long OffTime2 = 300; // milliseconds of off-time int Value = 1000; void setup() { // set the digital pin as output: pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); } void loop() { unsigned long currentMillis = millis(); if((ledState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime1)) { ledState1 = LOW; // Turn it off previousMillis1 = currentMillis; // Remember the time digitalWrite(ledPin1, ledState1); // Update the actual LED } else if ((ledState1 == LOW) && (currentMillis - previousMillis1 >= OffTime1 + Value)) { ledState1 = HIGH; // turn it on previousMillis1 = currentMillis; // Remember the time digitalWrite(ledPin1, ledState1); // Update the actual LED } if((ledState2 == HIGH) && (currentMillis - previousMillis2 >= OnTime2)) { ledState2 = LOW; // Turn it off previousMillis2 = currentMillis; // Remember the time digitalWrite(ledPin2, ledState2); // Update the actual LED } else if ((ledState2 == HIGH) && (currentMillis - previousMillis2 >= OffTime2 + OffTime1 + Value)) { //ledState2 = LOW; // turn it on previousMillis2 = currentMillis; // Remember the time // digitalWrite(ledPin2, ledState2); // Update the actual LED } ledState1 = LOW; }может так
Так работает, спасибо. Почему я не стал использовать delay(). Следующий код работает очень странно. На Аттини13 светится 1 минуту, гаснет на 20 сек. На Ардуино светится где-то 5 мин.:
const int led = 13; #define inter1 50*6000UL #define inter2 20*6000UL //unsigned long inter1 = 3000000UL; // пробовал и так //unsigned long inter2 = 1200000UL; void setup() { pinMode(led, OUTPUT); } void loop() { digitalWrite(led, LOW); delay(inter1); digitalWrite(led, HIGH); delay(inter2); }Пропуйте
#define led1 13 #define led2 12 uint32_t time; uint32_t pausa = 3000; byte(f_vk) = 1; //int led = 13; void setup() { // put your setup code here, to run once: pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); digitalWrite(led1, HIGH); digitalWrite(led2, LOW); //Serial.begin(9600); time = millis(); } void loop() { if(f_vk == 1 && millis()-time >= pausa){ digitalWrite(led2, !digitalRead(led2)); time = millis(); if(digitalRead(led2))pausa = 25000; else pausa = 20000, f_vk = 2; } if(f_vk == 2 && millis() - time >= pausa){ digitalWrite(led1, LOW); f_vk = 0; } }Как то от нечего делать набросал програмку выполняющую функцию часов, считает секунды, минуты, часы. Может чем поможет, покрайней мере ее можно переделать под ваши нужды.
#include <Wire.h> //#include <WolfCrystal.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F, 16, 2); //WolfCrystal WC(&lcd); byte sec = 0; byte minut = 0; byte hor = 0; int timer = 0; int currentSec = 0; void setup() { lcd.init(); lcd.backlight(); // lcd.print(WC.GS("Ардуино")); lcd.print("Timer 1"); // lcd.setCursor(8,1); // lcd.print("LCD 1602"); } void loop() { ///////////////////////// обработка таймера lcd.setCursor(0, 0); lcd.print("Timer 1"); if ((millis() / 1000) - currentSec >= 1) { currentSec = millis() / 1000; sec ++; } if (sec == 60) { sec = 0; // lcd.clear(); minut ++; } if (minut == 60) { minut = 0; hor ++; } if (hor > 99) { hor = 0; } //////////////////////// вывод времяни if (sec == 0) { lcd.setCursor(6, 1); lcd.print("00"); } else { lcd.setCursor(6, 1); if (sec < 10) lcd.print("0"); lcd.print(sec); } lcd.setCursor(2, 1); lcd.print(":"); lcd.setCursor(5, 1); lcd.print(":"); if (minut == 0) { lcd.setCursor(3, 1); lcd.print("00"); } else { lcd.setCursor(3, 1); if (minut < 10) lcd.print("0"); lcd.print(minut); } if (hor == 0) { lcd.setCursor(0, 1); lcd.print("00"); } else { lcd.setCursor(0, 1); if (hor < 10) lcd.print("0"); lcd.print(hor); } }vosara
Проверил ваш код на схеме возникла проблема в том что код работает иначе.
А именно при вкл питания включается первый диод (13ый пин) т.е. время 00:00
Потом включается второй светодиод (12ый пин), первый отключается, время 00:01
После 3-х секунд работы кода оба диода выключены.
далее на 28ой секунде происходит включение второго светодиода (12ый пин), первый выключен.
на 48 секунде включается первый светодиод.
Мой вариант кода предпологал постоянное включенное состояние первого светодиода. Второй должен включиться и выключится в процессе работы первого. А после истечения определенного времени выключается первый.
Возможно ли это из-за светодиода? Я использую 2 RGB
Попробую переписать ваш код
Большое спасибо за помощь!
Проверил в симуляторе, единственное что время уменьшил, ссылку на видео оставляю
https://drive.google.com/open?id=1w0vgJdgvNQo-IsD12zdsyBHwn3xzFtXJ
Ну и код с меньшими цыфрами
#define led1 13 #define led2 12 uint32_t time; uint32_t pausa = 3000; byte(f_vk) = 1; //int led = 13; void setup() { // put your setup code here, to run once: pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); digitalWrite(led1, HIGH); digitalWrite(led2, LOW); //Serial.begin(9600); time = millis(); } void loop() { if(f_vk == 1 && millis()-time >= pausa){ digitalWrite(led2, !digitalRead(led2)); time = millis(); if(digitalRead(led2))pausa = 5000; else pausa = 2000, f_vk = 2; } if(f_vk == 2 && millis() - time >= pausa){ digitalWrite(led1, LOW); f_vk = 0; } }Получилось таки
//culler int ledPin1 = 12; // the number of the LED pin int ledState1 = LOW; // ledState used to set the LED unsigned long previousMillis1 = 0; // will store last time LED was updated long OnTime1 = 3000; // milliseconds of on-time long OffTime1 = 0; // milliseconds of off-time // добавить 0 к 138000 и получим 23 мин, сейчас 2.3 мин // 600 000 это 10 мин //pribor int ledPin2 = 13; // the number of the LED pin int ledState2 = LOW; // ledState used to set the LED unsigned long previousMillis2 = 0; // will store last time LED was updated long OnTime2 = 0; // milliseconds of on-time // добавить 0 к 18000 и получим 3 мин, сейчас 0.3 мин=18 сек long OffTime2 = 10000; // milliseconds of off-time // добавить 0 и получим 20 мин, сейчас 2 мин int Value = 15000; // добавить 0 и получим 10 мин,сейчас 1 мин /* int ledState3 = LOW; // ledState used to set the LED unsigned long previousMillis2 = 0; // will store last time LED was updated long OnTime2 = 2000; // milliseconds of on-time long OffTime2 = 2000; // milliseconds of off-time */ void setup() { // set the digital pin as output: pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); } void loop() { unsigned long currentMillis = millis(); if((ledState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime1)) { ledState1 = LOW; // Turn it off previousMillis1 = currentMillis; // Remember the time digitalWrite(ledPin1, ledState1); // Update the actual LED } else if ((ledState1 == LOW) && (currentMillis - previousMillis1 >= OffTime1 + Value)) { ledState1 = HIGH; // turn it on previousMillis1 = currentMillis; // Remember the time digitalWrite(ledPin1, ledState1); // Update the actual LED } if((ledState2 == HIGH) && (currentMillis - previousMillis2 >= OnTime2)) { ledState2 = LOW; // Turn it off previousMillis2 = currentMillis; // Remember the time digitalWrite(ledPin2, ledState2); // Update the actual LED } else if ((ledState2 == LOW) && (currentMillis - previousMillis2 >= OffTime2 + Value)) { // ledState2 = HIGH; // turn it on previousMillis2 = currentMillis; // Remember the time digitalWrite(ledPin2, HIGH); // Update the actual LED } ledState1= LOW; // digitalWrite(ledPin2, HIGH); }Проверил в симуляторе, единственное что время уменьшил, ссылку на видео оставляю
https://drive.google.com/open?id=1w0vgJdgvNQo-IsD12zdsyBHwn3xzFtXJ
Хм в симуляторе и правда работает.!
Видимо дело в том что RGB светодиоды гаснут при подаче HIGH а включаются LOW, возможно поэтому у меня не работает.
Еще раз большое спасибо за помощь!