Следует ли использовать цикл вместо оператора If?

У меня есть простой скетч, который проверяет входные сигналы с двух датчиков касания и выходные сигналы на два реле (при касании датчика срабатывает соответствующее реле без фиксации). Получилось, мягко говоря, непривычно. Возможно, нужно настроить задержки или чувствительность датчиков касания, но, думаю, код можно сделать эффективнее. Будет ли лучше использовать цикл WHILE или DOWHILE, чем оператор IF? Похоже, есть проблема синхронизации между реле и датчиком. При касании датчика реле срабатывает немедленно, но не отключается сразу. Кроме того, если оба датчика срабатывают одновременно, я вижу только одно срабатывание реле или ни одного. Я пытаюсь исключить этот код из списка возможных ошибок . Код выводится на последовательный монитор и выводит сообщение «Датчик 1 коснулся» или «Датчик 2 коснулся», и иногда это срабатывает один раз, а иногда — несколько.

int touchPin1 = 2; // Датчик касания 1
int touchPin2 = 4; // Датчик касания 2
int val_1 = 0; 
int val_2 = 0; 
int relayPin1 = 8; //Реле 1
int relayPin2 = 9; //Реле 2

void setup() 
{
  Serial.begin(9600);
  pinMode(touchPin1, INPUT); 
  pinMode(touchPin2, INPUT);
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);

}

void loop() {
  digitalWrite(relayPin1, LOW);
  digitalWrite(relayPin2, LOW);
  val_1 = digitalRead(touchPin1);
  val_2 = digitalRead(touchPin2);  
  if(val_1 ==1)
  {
  Serial.println("Pad 1 Touched");
  digitalWrite(relayPin1, HIGH);
  }
  if(val_2 ==1)
  {
  Serial.println("Pad 2 Touched");
  digitalWrite(relayPin2, HIGH);
  }
  delay(100);
  //Serial.println();
}

По сути, я спрашиваю, есть ли более эффективный способ закодировать это.

Датчики касания: Автономный емкостный датчик касания Adafruit, разъем для подключения. Номер детали Adafruit: 1374

Реле: Модуль реле SunFounder для Arduino и Raspberry Pi, 5 В постоянного тока, триггер HIGHLO (HIGH Trigger)

, 👍0

Обсуждение

Поскольку у нас нет хрустального шара, мы не можем помочь вам отладить код, которого не видим., @Edgar Bonet

Чтобы мы могли вам помочь, вам необходимо предоставить свой код. Мы не можем рекомендовать ту или иную стратегию, не зная, что делает ваш код, какие датчики вы используете и как он работает. Вам необходимо будет добавить свой код вместе с чертежом вашей установки (схемой) или, по крайней мере, фотографией макетной платы или любого другого используемого вами устройства к вашему вопросу (используйте кнопку «Изменить» под вашим вопросом)., @Majenko

Какое поведение вы хотите получить? Пока сенсорная панель нажата, реле активируется, а как только вы отпускаете её, реле замыкается? Потому что я не понимаю, почему вы всегда используете digitalWrite(relayPin1, LOW); в каждой итерации loop, а затем (в зависимости от val_1) сразу же снова устанавливаете его в состояние HIGH., @Maximilian Gerhardt

Как вы и сказали, я хотел бы, чтобы сенсорная панель активировала реле, пока сенсорная панель находится в контакте, и выключалась при прекращении касания. В идеале я хотел бы, чтобы каждое реле могло активироваться максимум на 1 секунду и не могло активироваться повторно в течение той же секунды., @Matthew Paulin

это не то, что делает ваш код... цикл () повторяется 10 раз в секунду из-за задержки в конце... внимательно посмотрите на свой код и определите, что делает каждая строка вашего кода... вы увидите, что он делает не то, что вы думаете, @jsotola

Задержка необходима для учёта времени, необходимого для переключения реле. Если задержки нет, весь процесс прерывается. Если я помещу задержку в условные операторы, реле не смогут сработать одновременно. Команда цифровой записи LOW необходима для того, чтобы реле стали кратковременными, как датчики касания. В противном случае они будут постоянно замыкаться на нормально разомкнутом контакте. У меня есть некоторый опыт в электронике и программировании, но я новичок в Arduino. Не привык писать код в условиях принудительного активного цикла., @Matthew Paulin

Вас никто не «обязателен» использовать loop, знаете ли. Просто оставьте его пустым, если хотите, и поместите весь код в setup. По сути, это то же самое, что делает любая другая среда программирования: у вас есть main, которая делает то, что вам нужно (возможно, выполняя цикл внутри себя и вызывая другие функции)., @Nick Gammon


1 ответ


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

2

Чего вам не хватает, так это концепции else:

  • Если нажата сенсорная панель, то
    • Включите реле
  • иначе
    • Выключите реле

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

Это можно записать так:

val_1 = digitalRead(touchPin1);

if(val_1 ==1)
{
  Serial.println("Pad 1 Touched");
  digitalWrite(relayPin1, HIGH);
} else {
  digitalWrite(relayPin1, LOW);
}

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

static uint8_t oldVal1 = LOW;

uint8_t val1 = digitaRead(touchPin1);

if (val1 != oldVal1) {
    oldVal1 = val1;
    if (val1 == HIGH) {
        Serial.println("Pad 1 Touched");
        digitalWrite(relayPin1, HIGH);
    } else {
        Serial.println("Pad 1 Released");
        digitalWrite(relayPin1, LOW);
    }
}
,