Сохранение значения ИК-датчика не работает

Я впервые работаю над Arduino для своего проекта и столкнулся с проблемой. Я пытаюсь сделать очень простой торговый автомат. Монета или любое препятствие проходит перед ИК-датчиком, и в зависимости от этого пользователь может нажать кнопку 1 или 2, и в зависимости от этого двигатель 1 или 2 заработает соответственно.
Общая логика работает именно так, как я хочу, проблема, с которой я столкнулся, заключается в том, что переменная (sensorStatus), хранящая значение ИК-датчика, работает неправильно. Независимо от того, проходит ли что-то перед ним или нет, он все равно позволяет мне нажимать кнопки, и мотор начинает работать.

void loop() {

  int sensorStatus;

  //вот тут у меня проблема
  if (digitalRead(inSensor) == LOW) sensorStatus = LOW;

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);
  
      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
      }
    
      buttonStatus2 = digitalRead(inButton2);
    
      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
      }

      sensorStatus = HIGH;
   }
}

Если я не использую эту логику и сохраняю значение датчика непосредственно в переменной (sensorStatus), вся программа работает до тех пор, пока перед датчиком не появится препятствие. непрерывно. Я не хочу, чтобы это произошло, я хочу, чтобы это работало таким образом, чтобы, когда препятствие проходит перед датчиком, значение сохранялось (даже после того, как препятствие исчезло) до тех пор, пока не будет нажата кнопка, и после этого он избавляется от значения, чтобы повторить процесс еще раз. Кажется, это проблема с логикой кода, но я не могу понять логику, стоящую за этим.

Мой полный исходный код:

const int relayControl1_1 = 13; // реле 1 из 1 (вход 1)
const int relayControl1_2 = 12; // реле 1 из 2 (вход 2)
const int relayControl2_1 = 11; // реле 2 из 1 (вход 3)
const int relayControl2_2 = 10; // реле 2 из 2 (вход 4)

const int inButton1 = 9; // кнопка ввода 1
const int inButton2 = 8; //кнопка ввода 2

int buttonStatus1 = 0;
int buttonStatus2 = 0;

const int inSensor = 7;

void setup() {
  Serial.begin(9600);
  pinMode(relayControl1_1, OUTPUT);
  pinMode(relayControl1_2, OUTPUT);
  pinMode(relayControl2_1, OUTPUT);
  pinMode(relayControl2_2, OUTPUT);

  pinMode(inButton1, INPUT_PULLUP);
  pinMode(inButton2, INPUT_PULLUP);

  pinMode(inSensor, INPUT_PULLUP);
  
}

void loop() {

  int sensorStatus;

  //вот тут у меня проблема
  if (digitalRead(inSensor) == LOW) sensorStatus = LOW;

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);
  
      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
      }
    
      buttonStatus2 = digitalRead(inButton2);
    
      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
      }

      sensorStatus = HIGH;
   }
}

, 👍0

Обсуждение

Сделать SensorStatus «статическим» и присвоить ему значение по умолчанию?, @Majenko

Кажется, что это не позволяет ему принимать значение мусора и заставлять его работать без ввода с датчика, устанавливая его как `static int sensorStatus = HIGH;`, но это останавливает его от того, как я хочу, чтобы он работал. Я хочу, чтобы он мог сохранять значение, пока я не нажму кнопки двигателя, даже если препятствие от датчика исчезло. Установка его как статического приводит к тому, что он работает только до тех пор, пока у меня есть препятствие перед датчиком, когда препятствие исчезает, кажется, что оно теряет значение., @Moeed Rehman Masood

Итак, измените статус датчика обратно на ВЫСОКИЙ *только при нажатии кнопки*?, @Majenko

Я установил `sensorStatus` в HIGH сразу после `digitalWrite(relayControl1_1, HIGH)` в остальной части условных операторов buttonStatus`. Кажется, это работает так, но мотор продолжает работать, пока я не прерву его, поставив препятствие перед ИК-датчиком. Я исправил это, добавив `delay(2000); digitalWrite(relayControl1_1, LOW);`` после этого и работает именно так, как я хочу. Большое спасибо за помощь, добрый незнакомец., @Moeed Rehman Masood

@Majenko, можете ли вы опубликовать свой комментарий в качестве ответа, чтобы ОП мог его принять? Как и сейчас, мне пришлось прочитать вопрос и 4 комментария, чтобы понять, что проблема уже решена., @Duncan C

Я разместил ответ, но могу принять его как ответ только через 2 дня., @Moeed Rehman Masood


1 ответ


Лучший ответ:

1

Благодаря помощи @Majenko♦ мне удалось решить проблему.

1 – int sensorStatus; должно быть установлено в static int sensorStatus = HIGH;, чтобы программа запомнила значение датчика.

2 - sensorStatus = HIGH; должен был быть сразу после digitalWrite(relayControl1_1, HIGH); в условной части buttonStatus else, чтобы сделать программа правильно установила для sensorStatus значение HIGH.

3 – Независимо от опубликованного вопроса, выполнение вышеуказанных шагов заставляло программу запускать двигатели непрерывно, если только они не были остановлены препятствием от ИК-датчика. Это было исправлено добавлением delay(2000); digitalWrite(relayControl1_1, LOW); после sensorStatus = HIGH;, упомянутого на втором шаге.

Исходный код после исправления:

const int relayControl1_2 = 12; // реле 1 из 2 (вход 2)
const int relayControl2_1 = 11; // реле 2 из 1 (вход 3)
const int relayControl2_2 = 10; // реле 2 из 2 (вход 4)

const int inButton1 = 9; // кнопка ввода 1
const int inButton2 = 8; //кнопка ввода 2

int buttonStatus1 = 0;
int buttonStatus2 = 0;

const int inSensor = 7;

void setup() {
  Serial.begin(9600);
  pinMode(relayControl1_1, OUTPUT);
  pinMode(relayControl1_2, OUTPUT);
  pinMode(relayControl2_1, OUTPUT);
  pinMode(relayControl2_2, OUTPUT);

  pinMode(inButton1, INPUT_PULLUP);
  pinMode(inButton2, INPUT_PULLUP);

  pinMode(inSensor, INPUT_PULLUP);

}

void loop() {

  static int sensorStatus = HIGH;

  if (digitalRead(inSensor) == LOW) {
    sensorStatus = LOW;
  }

  if(sensorStatus == LOW) {
      buttonStatus1 = digitalRead(inButton1);
  
      if(buttonStatus1 == HIGH) {
        digitalWrite(relayControl1_1, LOW);
      } else {
        digitalWrite(relayControl1_1, HIGH);
        sensorStatus = HIGH;
        delay(2000);
        digitalWrite(relayControl1_1, LOW);
      }
    
      buttonStatus2 = digitalRead(inButton2);
    
      if(buttonStatus2 == HIGH) {
        digitalWrite(relayControl2_1, LOW);
      } else {
        digitalWrite(relayControl2_1, HIGH);
        sensorStatus = HIGH;
        delay(2000);
        digitalWrite(relayControl2_1, LOW);
      }
   }
}
,

пара замечаний... похоже, что ваш код не работает так, как описано... вы сказали "препятствие проходит перед ИК-датчиком"... ваш код никогда не проверяет датчик прохождения препятствия, он проверяет только датчик блокировки препятствия ....... программная строка digitalWrite(relayControl1_1, LOW); вызывается независимо от состояния buttonStatus1 ... поместите digitalWrite(relayControl1_1, LOW); после блока if .. .. то же самое в другом блоке if, @jsotola

код был бы понятнее, если бы sensorStatus был логическим именем coin или paid, @jsotola