Реле времени на функции millis

Roman2344
Offline
Зарегистрирован: 09.09.2015

Нужен код по которому по ЮАРТу я присылаю число допустим 60000, потом нужно когда это число пришло чтобы отработала функция времени в кторой включен один раз 5-й выход ардуины нано, на время которое я прислал по ЮАРТу на ардуино нано, после этого времени 5 вывод должен находится в лог. 0, но потом как снова прийдет число по ЮАРТу, должен опять 1 раз 5 вывод ардуины быть включен на то время которое пришло по ЮАРТу, то есть реле времени, задержки будут от 1мин(то есть 60000, до 12ч., то есть 43200000). Точность большая мне не нужна, поэтому часы реального времени применять не хочу.

Набросал код, но не работает

int out=5;
char data;
int loopTime=0;
int i=0;
void setup() {
  pinMode(out, OUTPUT);
  Serial.begin(9600);

}

void loop() {
  digitalWrite(out, 0);
   if (Serial.available() > 0 ) {
    data = Serial.read();
    i=0;
    }
  loopTime=data;
 unsigned long currentMillis = millis();
 while(i<1)
  {
while(millis()-currentMillis<=loopTime)
  {

   digitalWrite(out, 1);
 }
 i++;
}


}

 

Logik
Offline
Зарегистрирован: 05.08.2014

Очплохо. Как соотносится диапазон знаяений int с ожидаемым 43200000? Ищите в форуме про прием чисел с serial. Магию с переменной i вобще непонял. И не надо "долбить" порт в стр.24 (и 12 тоже) он понимает с одного раза. Оба цикла ненужные и даже вредные.

Roman2344
Offline
Зарегистрирован: 09.09.2015

LoopTime назначил как unsigned long, это я для примера по быстрому набросал, просто код большой, а это так для примера. А последовательный порт я всегда так пишу и читаю, и все было впорядке. Переменная i для того чтобы цикл когда на 5 выводе лог.1 выполнялся один раз после прихода числа по серийному порту.

int out=5;
char data;
 unsigned long loopTime=0;
int i=0;
void setup() {
  pinMode(out, OUTPUT);
  Serial.begin(9600);

}

void loop() {

   if (Serial.available() > 0 ) {
    data = Serial.read();
    i=0;
    }
  loopTime=data;
 unsigned long currentMillis = millis();
 while(i<1)
  {
while(millis()-currentMillis<=loopTime)
  {

   digitalWrite(out, 1);
 }
 i++;
}


}

 

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Roman2344 пишет:

LoopTime назначил как unsigned long, это я для примера по быстрому набросал, просто код большой, а это так для примера. А последовательный порт я всегда так пишу и читаю, и все было впорядке. Переменная i для того чтобы цикл когда на 5 выводе лог.1 выполнялся один раз после прихода числа по серийному порту.

int out=5;
char data;
 unsigned long loopTime=0;
int i=0;
void setup() {
  pinMode(out, OUTPUT);
  Serial.begin(9600);

}

void loop() {

   if (Serial.available() > 0 ) {
    data = Serial.read();
    i=0;
    }
  loopTime=data;
 unsigned long currentMillis = millis();
 while(i<1)
  {
while(millis()-currentMillis<=loopTime)
  {

   digitalWrite(out, 1);
 }
 i++;
}


}

 

Работать не будет.

Вставьте после 14 строчки Serial.println(data); и посмотрите что выдаст в терминал.

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Можно сделать примерно так:

int out = 5;
unsigned long loopTime = 0;
byte i = 0;

void setup() {
  pinMode(out, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  if (Serial.available() > 0 ) {
    loopTime = Serial.parseInt() * 1000 + millis();
    digitalWrite(out, 1);
    if (loopTime > millis())
      i = 1;
    else
      i = 2; //переход через ноль millis()
  }
  if (i == 2 && loopTime > millis()) //переход через ноль millis()
    i = 1;

  if (millis() >= loopTime && i == 1) {
    digitalWrite(out, 0);
    i = 0;
  }
}

Время только задается теперь в секундах.

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Nosferatu пишет:
//переход через ноль millis()
:) тебе целочисленную арифметику не мешало бы подучить...

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Andy пишет:

Nosferatu пишет:
//переход через ноль millis()
:) тебе целочисленную арифметику не мешало бы подучить...

Подправил. Если где ещё ошибки, не обессудьте, ухожу.

fogary
Offline
Зарегистрирован: 05.03.2016

Roman2344 пишет:

LoopTime назначил как unsigned long, это я для примера по быстрому набросал, просто код большой, а это так для примера. А последовательный порт я всегда так пишу и читаю, и все было впорядке. Переменная i для того чтобы цикл когда на 5 выводе лог.1 выполнялся один раз после прихода числа по серийному порту.

int out=5;
char data;
 unsigned long loopTime=0;
int i=0;
void setup() {
  pinMode(out, OUTPUT);
  Serial.begin(9600);

}

void loop() {

   if (Serial.available() > 0 ) {
    data = Serial.read();
    i=0;
    }
  loopTime=data;
 unsigned long currentMillis = millis();
 while(i<1)
  {
while(millis()-currentMillis<=loopTime)
  {

   digitalWrite(out, 1);
 }
 i++;
}


}

 

Если показанный код именно то, что Вы хотите заставить работать, то зачем Вам тут millis()? Замените на delay(), программа будет проще, а функционировать будет точно так же. Вот например (без исправления Ваших неточностей):

void loop() {
  if (Serial.available() > 0 ) {
    data = Serial.read();
    digitalWrite(out, 1);
    delay(data);
    digitalWrite(out, 0);
  }
}

 

Nosferatu
Offline
Зарегистрирован: 04.11.2012

fogary пишет:

void loop() {
  if (Serial.available() > 0 ) {
    data = Serial.read();
    digitalWrite(out, 1);
    delay(data);
    digitalWrite(out, 0);
  }
}

Serial.read() считывает только 1 байт.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Цитата:
Если показанный код именно то, что Вы хотите заставить работать, то зачем Вам тут millis()? Замените на delay(), программа будет проще, а функционировать будет точно так же. Вот например (без исправления Ваших неточностей):

Код большой, это веб-сервер, на котором есть функция таймера, делей не вариант, так как остальной код в это время работать не будет.

Спасибо Nosferatu, работает почти как нужно, пытаюсь под себя сделать, и тестирую, я почти так и делал до этого, только не проверял отдельно кусок кода.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Добрый день!.

Тема наверное давно загнулась, но влез чтоб лишний раз неперегружать форум новыми темами:

Искал простейшего реле времени на ардуино и здесь и вгугле, чего-то не нашел. Простейшее подразумеваю что в нем несколько переменных резисторов и пару перемычек дя изменения функционала. Переменных резисторов изначально 2- интервал high и интервал low хотя бы для одного канала управления. Ну и перемычки на выносе 1-60 сек. 1-60мин.1-60 часов а также последовательно перемычка с резистором для канала LOW типа  например (для одноразового срабатывания) .  Если есть что-то подобное, подскажите пожалуйста! Не, то придется что-то придумать. Хотелось именно без кнопок и экранов, простенько, для производства чтоб под рукой валялось всегда. На 555 можно конечно но бедноват функционал выходит. Да и на микроконтроллере сейчас проще все делать.

denis@davt.kz
Offline
Зарегистрирован: 24.10.2019

Добрый день!

нужна помощь с реле временем,

задумка следущия ставим на дверь геркон, дверь открылась через три минуты если дверь не закрыть сработает серена 

то есть для того чтобы дверь не держали открыто 

написал скейч 

 
 
 
 
 
 
 
 
 
 
все работает, но есть нюанс, когда дверь закрыта 3 минуты или дольше серена срабатывает мгновенно, подскажите в чем может быть проблема 
BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Ну давай на код посмотрим, для начала )

denis@davt.kz
Offline
Зарегистрирован: 24.10.2019
#define gerkon 2
#define relay 3

unsigned long timer;
unsigned long timerb;
int gerkonstate=0;



void setup() {
  Serial.begin (9600);
  pinMode (gerkon, INPUT_PULLUP);
  pinMode (relay, OUTPUT);
  digitalWrite (relay, LOW);  //HIGH
}

void loop() {

if (digitalRead (gerkon)==HIGH&&gerkonstate==0)
{gerkonstate=1;
timer = millis();}

 if (millis() - timer > 60000) 
 digitalWrite (relay, HIGH);
 
if (digitalRead (gerkon)==LOW)
{
gerkonstate=0;
digitalWrite (relay, LOW);    //HIGH
}

 if (millis() - timerb > 1000) 
 { timerb=millis();
Serial.println ("Gerkon:");
Serial.println (digitalRead(gerkon));
Serial.println ("Relay:");
Serial.println (digitalRead(relay));  }

}

 

vrd
Offline
Зарегистрирован: 20.01.2022
#define gerkon 2
#define relay 3
unsigned long timer;
unsigned long timerb;
#define sek = 1000;
#define mi = 60000;
void setup() {
  Serial.begin (9600);
  pinMode (gerkon, INPUT_PULLUP);
  pinMode (relay, OUTPUT);
  digitalWrite (relay, LOW);  //HIGH
}
void loop() {
  if (digitalRead (gerkon) == HIGH) {
    timer = millis();
  }
  if (millis() - timer >= (mi * 3)) {
    digitalWrite (relay, HIGH);
  } else {
    digitalWrite (relay, LOW);
  }
  if (millis() - timerb >= sek) {
    timerb = millis();
    Serial.println ("Gerkon:");
    Serial.println (digitalRead(gerkon));
    Serial.println ("Relay:");
    Serial.println (digitalRead(relay));
  }
}

Как-то так.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

1. Код из #14 не компилируется.

2. Код из #13 компилируется.

Рассматриваем рабочий вариант (#13).

3. Почём сейчас скобки, что Вы на них экономите? Не завезли чтоль? Мошт отгрузить?

Приводим к читабельному виду и добавляем комментарии:

#define gerkon 2
#define relay 3

unsigned long timer;    // Какие-то "таймеры"? Какие?
unsigned long timerb;   // А этот?
int gerkonstate = 0;    // Что это значит? А если будет 15 - тогда что???



void setup() {
  Serial.begin (9600);
  pinMode (gerkon, INPUT_PULLUP);
  pinMode (relay, OUTPUT);
  digitalWrite (relay, LOW);  //HIGH                        // ЗАНИМАТЕЛЬНО! ДАЖЕ ЗАЛИПАТЕЛЬНО !!! )))
}

void loop() {

  if (digitalRead (gerkon) == HIGH && gerkonstate == 0) {   // Если пин геркона ЧТО? И что за состояние???
    gerkonstate = 1;                                        // Меняем состояние на ЧТО?
    timer = millis();
  }

  if (millis() - timer > 60000) {                           // Ну тут хоть догадаться можно
    digitalWrite (relay, HIGH);
  }

  if (digitalRead (gerkon) == LOW) {                        // А теперь пин геркона "не такой как раньше"? Какой?
    gerkonstate = 0;
    digitalWrite (relay, LOW);    //HIGH
  }

  if (millis() - timerb > 1000) {                           // Об этом пока думать не хочу...
    timerb = millis();
    Serial.println ("Gerkon:");
    Serial.println (digitalRead(gerkon));
    Serial.println ("Relay:");
    Serial.println (digitalRead(relay));
  }
}

Я надеюсь намек понятен? А потом продолжим.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

denis@davt.kz Наша песня хороша, начинай сначала #58  

Задача решается через автомат с тремя состояниями. Дверь закрыта, дверь открыта, дверь открыта и сирена.  

Все остальное это хождение по битому стеклу.

BOOM. Лучше этот код не править, а сразу слить в унитаз

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

qwone пишет:

denis@davt.kz Наша песня хороша, начинай сначала #58  

Задача решается через автомат с тремя состояниями. Дверь закрыта, дверь открыта, дверь открыта и сирена.  

Все остальное это хождение по битому стеклу.

BOOM. Лучше этот код не править, а сразу слить в унитаз

Мой посыл был не о коде, а начать думать головой (и код писать понятный). Но qwone есть qwone, ладно...

denis@davt.kz
Offline
Зарегистрирован: 24.10.2019

не судите строго в программирование полный ноль 

код заказывал, что сделали то сделали, собрал схемку залил код вроде все работает но вот глюки бы убрать. 

я только учусь помогите чем сможете избавится от глюков 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

1. Почему исполнитель (который и писал код) его не "допиливает"?

2. Если код не вами писан, то как же вам помочь? Ну разве что сделать ЗА ВАС? Это в платном разделе делается "Ищу исполнителя".

3. "я только учусь" - это не оправдание. Если действительно учитесь (хотите учиться) - тогда #15

b707
Offline
Зарегистрирован: 26.05.2017

denis@davt.kz пишет:

код вроде все работает но вот глюки бы убрать.

который код, из #13?

Непонятно, о этом ли коде речь,  в коде задержка минута, а вы пишете - три...

 

denis@davt.kz
Offline
Зарегистрирован: 24.10.2019

if (millis() - timer > 60000) это для теста так то будет стоять 180000

b707
Offline
Зарегистрирован: 26.05.2017

чтобы "убрать глюки" измените эту строчку так:

 if ((millis() - timer > 60000) &&(gerkonstate == 1))

напишите. поможет или нет

denis@davt.kz
Offline
Зарегистрирован: 24.10.2019

b707 пишет:

чтобы "убрать глюки" измените эту строчку так:

 if ((millis() - timer > 60000) &&(gerkonstate == 1))

напишите. поможет или нет

большое спасибо!!! помогло, глюк вроде ушел.