Задать вопрос
mrusklon
@mrusklon
Не получается? Яростно гугли!

Почему таймер milis ардуино не работает 2 раза?

Предыстория: есть у меня свет на улице и в доме, на улице свет включаю кнопочкой или датчиком геркона если на улице темно, захотелось мне добавить в дом датчик движения на включение света, для этого пришлось отказаться от delay потому что тормозило весь код на период включения , написал вот такой код, но он работает не корректно, время не так считает как надо, а самое главное работает только 1 раз

потыкайте носом пожалуйста 6zNm7NR.png
#define knopka 2  // кнопка
#define rele_dom 3    // пин реле в доме
#define rele_ul 4    // пин реле на улице
#define dsveta 5     // пин датчика света 
#define gerkon 7  // геркон 
#define green_1 A0
#define green_2 A1
#define green_3 A2
#define green_4 A3


unsigned long previousMillis_dom = 0;        // храним время последнего переключения
unsigned long previousMillis_ul = 0;
bool rele_dom_on = false;
bool rele_ul_on = false;

void setup() {
  pinMode(green_1, OUTPUT);
  pinMode(green_2, OUTPUT);
  pinMode(green_3, OUTPUT);
  pinMode(green_4, OUTPUT);

  pinMode(rele_dom, OUTPUT);
  pinMode(rele_ul, OUTPUT);

  digitalWrite(rele_dom, HIGH); // выключаем реле по умолчанию
  digitalWrite(rele_ul, HIGH);

  pinMode(dsveta, INPUT);
  pinMode(gerkon, INPUT);
  pinMode(knopka, INPUT);


}

void loop()
{
  unsigned long currentMillis = millis(); // переменная для таймеров

  // индикация светодиодами
  if (digitalRead(dsveta) == 1) {
    digitalWrite(green_1, HIGH);
  } else {
    digitalWrite(green_1, LOW);
  }

  if (digitalRead(ddvij) == 1) {
    digitalWrite(green_2, HIGH);
  } else {
    digitalWrite(green_2, LOW);
  }

  if (digitalRead(gerkon) == 1) {
    digitalWrite(green_3, HIGH);
  } else {
    digitalWrite(green_3, LOW);
  }

  if (digitalRead(knopka) == 1) {
    digitalWrite(green_4, HIGH);
  } else {
    digitalWrite(green_4, LOW);
  }
  //

  // принудительный свет на улице от кнопки
  if (!rele_ul_on && (digitalRead(knopka) == 1)) {
    digitalWrite(rele_ul, LOW); // включить
    rele_ul_on = true; // запомнить состояние
    previousMillis_ul = currentMillis; // запомнить момент включения
  }
  if (rele_ul_on && currentMillis - previousMillis_ul > 5000) { // время в милисекундах

    digitalWrite(rele_ul, HIGH); // прошло больше N секунд - выключаем
    rele_ul_on = false;
  }
  //

  // включение света на улице от геркона и датчика света
  if (digitalRead(gerkon) == 0 && digitalRead(dsveta) == 1) {
    digitalWrite(rele_ul, LOW); // включить
    rele_ul_on = true; // запомнить состояние
    previousMillis_ul = currentMillis; // запомнить момент включения
  }
  if (rele_ul_on && currentMillis - previousMillis_ul > 7000) { // время в милисекундах
    digitalWrite(rele_ul, HIGH); // прошло больше N секунд - выключаем
    rele_ul_on = true;
  }
}
  • Вопрос задан
  • 606 просмотров
Подписаться 1 Простой 5 комментариев
Решения вопроса 1

millis()

Возвращает количество миллисекунд с момента начала выполнения текущей программы на плате Arduino.
Это количество сбрасывается на ноль, в следствие переполнения значения, приблизительно через 50 дней.


Возможно, у вас возникают проблемы из-за переполнения, плюс вы переопределяйте
unsigned long currentMillis = millis(); // переменная для таймеров
переменную currentMillis
с началом каждого прохода void loop(). Также советую вам пересмотреть

// включение света на улице от геркона и датчика света
  if (digitalRead(gerkon) == 0 && digitalRead(dsveta) == 1) {
    digitalWrite(rele_ul, LOW); // включить
    rele_ul_on = true; // запомнить состояние
    previousMillis_ul = currentMillis; // запомнить момент включения
  }


, так как

previousMillis_ul = currentMillis; // запомнить момент включения

будет присваивать время старта loop.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы