Игнорирование первого высокого выходного сигнала датчика

Если датчик вибрации с Arduino обнаруживает два высоких входа в течение 1 минуты, я хочу, чтобы светодиод мигал в течение одной секунды.

Моя способность писать код Arduino очень низка; я попытался использовать millis(), но не смог.

Я хочу, чтобы он игнорировал первый высокий вход.

Спасибо вам за всю информацию, которую вы мне дадите.

const byte sensor = 7;
const byte LED = 13;
unsigned long sensorMillis;
unsigned long ledTurnedOnAt;
unsigned long high_1 = 60000UL;
bool ledState = false;

void setup() {
  pinMode(sensor, INPUT);
  pinMode(13, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if (digitalRead(sensor) == HIGH) {
    sensorMillis = currentMillis;
    ledstate = true;
  }

  if (ledstate == HIGH) && ((unsigned long)(currentMillis - ledTurnedOnAt) <= high_1) {
    digitalWrite(8, HIGH);
    delay (1000);
    digitalWrite(8, LOW);
  }

  ledstate = false;
}

, 👍1

Обсуждение

Это работает лучше, если вы задаете вопрос о * конкретной * вещи, на которой вы застряли., @timemage

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

Я хочу, чтобы он игнорировал первый высокий входной сигнал, я хочу, чтобы светодиод мигал сразу при втором высоком входном сигнале., @Sabri73

это не вопрос ... это описание того, как вы хотите, чтобы программа вела себя, @jsotola

Возможно, вы захотите прочитать о [Конечном автомате] (https://majenko.co.uk/blog/finite-state-machine )., @Edgar Bonet

спасибо вам, Эдгар Бонет, @Sabri73

Попробуйте найти значение high в setup, затем оно будет проигнорировано вашим циклом., @Gil


3 ответа


1
const int sensor = 7;
const int LED = 13;
unsigned long sensorMillis;
unsigned long ledTurnedOnAt;
unsigned long high_1 = 60000UL;
bool ledState = false;
void setup() {
  pinMode(sensor, INPUT);
  pinMode(LED, OUTPUT);
  delay(1000); // Время прогрева
}

void loop() {
  unsigned long currentMillis = millis();

  if (digitalRead(sensor) == HIGH) {
    sensorMillis = currentMillis;
    ledstate = true;
  }

  if (ledstate == HIGH) && ((unsigned long)(currentMillis - ledTurnedOnAt) <= high_1) {
    digitalWrite(8, HIGH);
    delay (1000);
    digitalWrite(8, HIGH);
  }

  ledstate = false;
}

Я не проверял это, потому что у меня нет своего оборудования. Однако я добавил задержку в 1 секунду в настройку в качестве времени прогрева. Это теоретически должно игнорировать первый максимум. Надеюсь, это помогло.

,

"N0m4d " Большое вам спасибо за ваше внимание и помощь, @Sabri73


0

Или как насчет добавления еще одного глобального логического значения;

bool firstTime = true;

а затем измените код loop() следующим образом;

if (digitalRead(sensor) == HIGH) {
    if (firstTime) firstTime = false;
    else {
        sensorMillis = currentMillis;
        ledstate = true;
    }
  }
,

спасибо, Роб У. Я постараюсь, @Sabri73


2

Одним из простых решений может быть:

Начните с того, что заметьте, что в первый раз вы получаете ВЫСОКИЙ входной сигнал с помощью простого оператора if:

if (digitalRead(sensor) == HIGH) {
}

где датчик - это номер PIN датчика в соответствии с вашим кодом.

Когда это утверждение истинно, вы заинтересованы в том, чтобы оставаться здесь до тех пор, пока не произойдет одно из двух:

  • либо вы прерываете какой-то цикл с другим ВЫСОКИМ входом,
  • или время, которое вы установили, прошло.

Одним из способов узнать прошедшее время будет функция millis(), которая возвращает миллисекунды с момента начала работы платы. Мы должны получить прошедшее время при первом входе в цикл:

if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
}

Затем, как я уже сказал, мы должны остаться здесь на определенное время. Мы могли бы использовать цикл while, но какое условие должно быть истинным?

Итак, у нас есть время начала, скажем, x, и вам нужно оставаться в цикле, скажем, y миллисекунд. Это то же самое, что сказать, что вы хотите оставаться в цикле до тех пор, пока мы не войдем в цикл и определенное количество миллисекунд, x + y. Когда функция millis() дает нам большее число, мы должны выйти из цикла:

if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+1000))
// ^ Второй, который вас интересует, - 1000 миллисекунд.
}

Теперь мы должны проверить, есть ли еще одно прерывание в течение этого времени, используя тот же оператор начала:

if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+1000)) {
    if (digitalRead(sensor) == HIGH) {
      // 2 прерывания менее чем за 1000 миллисекунд!
    }
  }
}

Подводя итог, лучше объявить глобальный с конкретным временем, которое мы хотим, вместо значения 1000, которое мы используем сейчас:

const long maxTimeInterval = 1000;

И меняем его в нашем коде (то есть внутри цикла ()).

if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+maxTimeInterval)) {
    if (digitalRead(sensor) == HIGH) {
      // 2 прерывания менее чем за 1000 миллисекунд!
      digitalWrite(LED, HIGH);
    }
  }
}

Надеюсь, это поможет!

,

> `Начните с того, что заметьте, что в первый раз, когда вы получаете высокий ввод с помощью простого оператора if", вы не можете видеть, как ваш код делает это., @DataFiddler

@DataFiddler У меня все завернуто внутри if (digitalRead(sensor) == HIGH) { ... }, @Juan CA

Большое вам спасибо. @Хуан КА, ты великолепен. код работает хорошо., @Sabri73

@хуан , Калифорния .Я спрашивал многих людей, но никому это не удалось. Вы легко добились успеха. Ты просто чудо. Если бы вы были близки, я бы хотел сделать вам подарок., @Sabri73

Огромное спасибо всем администраторам сайта, @Sabri73