Включить реле на некоторое время непрерывным входом

У меня есть проект, имеющий два входных статуса

  • во первых вход не является непрерывным выходное реле зуммера будет включено в течение 10 секунд а затем выключено или оно может быть выключено непосредственно кнопкой

  • второе состояние если вход непрерывный то выходное реле зуммера будет включено в течение 10 секунд а затем выключено или оно может быть выключено непосредственно кнопкой

Я сделал этот код, но он не работает, может ли кто-нибудь предложить редактирование без использования millis (), потому что он выйдет из строя через 49 дней и без использования функции задержки.

Обратите внимание, что устройство будет работать 24 часа / 365 дней.

const int input1 = 19;
const int input2 = 36;
const int relay1 = 10;
const int relay2 = 21;
const int reset = 40;
const int buzzerreset = 45;
const int buzzerrelay = 46;

int buttonState1 = 0;    //для input1
int buttonState2 = 0;    //для input2
int buttonState3 = 0;    //для кнопки
int buttonState4 = 0;    //для сброса зуммера
int b4 = 0;              // для сброса зуммера

void setup() {
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(buzzerrelay, OUTPUT);
  pinMode(input1, INPUT);
  pinMode(input2, INPUT);
  pinMode(reset, INPUT);
  pinMode(buzzerreset, INPUT);

  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(buzzerrelay, LOW);
}

void loop() {
  buttonState1 = digitalRead(input1);
  if (buttonState1 == HIGH) {
    digitalWrite(relay1, HIGH);
    digitalWrite(buzzerrelay, HIGH);
    //задержка (10000);
    //digitalWrite (зуммер, НИЗКИЙ УРОВЕНЬ);
  }

  buttonState3 = digitalRead(reset);
  if (buttonState3 == HIGH) {
    digitalWrite(relay1, LOW);
    //digitalWrite (зуммер, НИЗКИЙ УРОВЕНЬ);
  } else {
    buttonState4 = digitalRead(buzzerreset);

    if ((buttonState4 == HIGH || buttonState1 == HIGH) && b4 == LOW) {
      digitalWrite(buzzerrelay, LOW);
    }
    // while (digitalRead(input1) == HIGH);
    // digitalWrite (buzzerrelay, НИЗКИЙ);

    (buttonState2 = digitalRead(input2));
    if (buttonState2 == HIGH) {
      digitalWrite(relay2, HIGH);
      digitalWrite(buzzerrelay, HIGH);
      //задержка (10000);
      //digitalWrite (зуммер, НИЗКИЙ УРОВЕНЬ);
    }

    buttonState3 = digitalRead(reset);
    if (buttonState3 == HIGH) {
      digitalWrite(relay2, LOW);
      //digitalWrite (зуммер, НИЗКИЙ УРОВЕНЬ);
    } else {
      buttonState4 = digitalRead(buzzerreset);
      if (buttonState4 == HIGH) {
        digitalWrite(buzzerrelay, LOW);
      }
      //while (digitalRead(input2) == HIGH);
      //digitalWrite (buzzerrelay, НИЗКИЙ);
    }
  }
}

, 👍0

Обсуждение

миллис не падает через 50 дней. Он просто переполняется и возвращается к нулю. Это проблема только в том случае, если вы сравниваете две временные метки. Вы можете обойти эту проблему все вместе, вычислив разницу двух временных меток. Затем вы можете проверить, не превышает ли разница 10000ms в вашем случае. Например if( millis()-buzzerStartTime> 10000){/*stop buzzer*/}, @Gerben

Не могли бы вы подробнее остановиться на части это не работает? Что происходит, когда вы запускаете свой код? Как вы ожидаете, что произойдет, когда вы запустите свой код?, @Gerben

почему вы беспокоитесь о штатах? ... в вашем описании говорится , что зуммер делает одно и то же в обоих состояниях ... все, что вам нужно сделать, это нажать на зуммер в течение 10 секунд, @jsotola

когда я запускаю код, если вход не спорный, нет никаких проблем с таймером, но когда вход спорный, зуммер также спорный, и это проблема, я хочу, чтобы зуммер работал в течение 10 секунд каждый раз, когда один из входов идет ВЫСОКО (у меня есть 25 входов), даже вход спорно это или нет . – Gerben, @eng.hamza

Вы говорите, что при обнаружении входного сигнала (непрерывного или прерывистого) вы хотите включить зуммер на 10 секунд, а затем снова выключить его. Что должно произойти, когда зуммер снова выключится? Должен ли он иметь период "блокировки", когда он игнорирует входные данные? Или он должен просто ждать другого ввода? После того, как прошло 10 секунд, должен ли он ждать, пока вход не перейдет в состояние off, прежде чем искать новый триггер?, @Duncan C

просто зуммер будет включен на 10 секунд во всех случаях (непрерывный или прерывистый вход) и ждать другого триггера от другого входа, если вход будет высоким, зуммер будет гореть в течение 10 секунд и так далее @DuncanC, @eng.hamza

Что делать, если вход включается и остается включенным в течение 5 минут? Как же тогда должен вести себя зуммер?, @Duncan C

вход может быть включен в течение месяца зуммер должен быть включен в течение 10 секунд а затем выключен и игнорируется состояние ввода до тех пор пока вход не станет НИЗКИМ, @eng.hamza

Именно так я и думал. Вам нужно обновить свой вопрос, чтобы это стало ясно. Мой ответ объясняет, как это сделать. Есть ли только один зуммер, который жужжит, если включается какой-либо из ваших входов, или у каждого входа есть свой собственный зуммер?, @Duncan C

да в цепи есть один зуммер, @eng.hamza


2 ответа


0

Что бы ни делали входы, когда один из них сначала поднимается ВЫСОКО, вы хотите, чтобы звучал зуммер, останавливающийся через 10 секунд или нажатие кнопки, в зависимости от того, что наступит раньше? Тогда вам нужно что-то вроде этого:

if any input is HIGH,
   save millis();
   start the buzzer;

   if button is HIGH
      stop the buzzer;
   else if millis() - saved millis() >= 10*1000 millisec),
      stop the buzzer;
end;
,

спасибо за повтор я попробую это сделать, @eng.hamza

Этот псевдокод будет воспроизводить зуммер непрерывно до тех пор, пока любой входной сигнал будет высоким. ОП хочет, чтобы зуммер воспроизводился только в течение 10 секунд, независимо от того, включен вход или нет. И они сказали, что хотят, чтобы зуммер снова заиграл, только если вход снова опустится, как только зуммер остановится. Там должны быть некоторые переменные состояния, как я предложил в своем ответе., @Duncan C

Да, именно так. :) И psuedo-код отражает постановку проблемы в том виде, в каком она была заявлена до тех пор, пока они не разъяснили ее в ответ на ваше указание на это. Это было через 5 часов после моего поста., @JRobert


1

Я бы предложил иметь состояние buzzerPlaying , состояние oldInput и buzzerOffTime (unsigned long millis, когда вы должны выключить зуммер.

Игнорируйте ввод, если buzzerPlaying == true, и просто проверьте buzzerOffTime. Когда buzzerOffTime пройдет, выключите зуммер, установите buzzerPlaying в false и снова начните проверять вход.

Если зуммер играет == false и вход высокий:

  1. проверьте игру зуммера. Если это правда, ничего не делай.

  2. Если значение buzzerPlaying равно false, проверьте oldInput. Если oldInput высок, ничего не делайте (вход не был сброшен). В противном случае установите buzzerPlaying в true, установите oldInput в high, включите зуммер и рассчитайте buzzerOffTime.

Если buzzerPlaying == false и вход низкий, установите oldInput на низкий (как только зуммер перестал воспроизводиться и вход упал низко, начните искать дополнительные входы).

,

спасибо за повтор, я новичок в arduino, и у меня есть 25 входов и 25 выходов, я не думаю, что смогу справиться с добавлением этих трех статусов в мой код. @, @eng.hamza

25 входов и 25 выходов? Это означает, что вам нужно 50 контактов ввода-вывода. У вас есть Arduino с таким количеством контактов?, @Duncan C

я буду использовать arduino mega 23 input и 23 output и pin для зуммера и pin для сброса зуммера и pin для сброса вывода, который будет 49 i / o, @eng.hamza