Управляющие реле с ИК-подсветкой и кнопкой

Что у меня есть:

  • 1 х 8 канальное реле
  • 1 х ИК-приемник
  • 1x Arduino Uno
  • 1x мгновенный переключатель
  • 1x макетная плата
  • 1x 10K резистор

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

Просто несколько ошибок, которые мне нужно исправить.

Цель состояла в том, чтобы включить/выключить только 2 реле (на данный момент) с помощью проводного переключателя и индивидуально переключить реле а с помощью ИК-пульта дистанционного управления.

Как я уже сказал, это работает...

Если я нажму мгновенную кнопку, она действительно переключит оба реле...да! затем, пока 2 реле переключаются в положение on мгновенным переключателем, я могу переключать каждое реле с помощью кнопок на пульте дистанционного управления.

Однако если я выключу реле мгновенной кнопкой, то не смогу включить их с помощью пульта дистанционного управления. Кроме того, если я выключу одно из реле с помощью пульта дистанционного управления, а затем нажму мгновенный переключатель, он будет чередовать переключатель между 2 реле, а не просто выключать другое.

Я использую различные примеры скетчей, чтобы достичь всего этого, и просто пытаюсь сшить их вместе как можно лучше, но что-то подсказывает мне, что этот подход ошибочен и что мне, возможно, следует изучить логическое значение?

Надеюсь, вы сможете пролить свет на это для меня.

#include <IRremote.h>
#define irPin 8
IRrecv irrecv(irPin);
decode_results results;
const int buttonPin = 2;
const int relay1 = 13;
const int relay2 = 12;
int relay1State;
int relay2State;
int buttonState;
int lastButtonState;
long lastDebounceTime = 0;
long debounceDelay = 50;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(buttonPin, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
}

void loop() {
  if (irrecv.decode(&results)) {
    switch (results.value) {
      case 0xFF30CF:
        Serial.println("Button 1 Pressed");
        relay1State = ~relay1State;
        digitalWrite(relay1, relay1State);
        delay(250);
        break;
      case 0xFF18E7:
        Serial.println("button 2 pressed");
        relay2State = ~relay2State;
        digitalWrite(relay2, relay2State);
        delay(250);
        break;
    }
    irrecv.resume();
  }

  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == HIGH) {
        relay1State = !relay1State;
        relay2State = !relay2State;
      }
    }
  }

  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
  lastButtonState = reading;
}

, 👍4

Обсуждение

Добро пожаловать, Майкл. Во-первых, просто предложение: в строках 30 и 36 измените " ~ "на"!`. Теперь просто проясните нам одну вещь. Предположим, вы запускаете arduino и один раз нажимаете кнопку. Вы включаете оба реле. Теперь с помощью пульта дистанционного управления вы выключаете реле 1. Таким образом, текущее состояние relay1 выключено и relay2 ВКЛЮЧЕНО. Теперь вы снова нажимаете на кнопку. Какими вы хотите видеть новые состояния реле? (не то, что происходит прямо сейчас, а то, чем вы собираетесь стать), @brtiberio

Спасибо! Эти изменения решили одну проблему-возможность включать реле с пульта дистанционного управления, находясь сначала в выключенном состоянии с помощью кнопки. Чтобы ответить на ваш вопрос: я надеялся выключить или включить оба реле с помощью кнопки (например, all on all off switch/override), которая работает, когда оба включены или выключены, но если одно включено, а другое выключено, они переключаются друг напротив друга, так что я думаю, что это так то, что говорит ему код, просто не так, как я хочу. Я хочу, чтобы тот, который остался включенным, выключился с помощью кнопки, а затем, когда я снова нажму кнопку, оба включатся. Спасибо!, @Michael Sinclair

Это потому, что вы говорите ему "relay1State = !relay1State;". Т. е. инвертировать состояние реле при нажатии кнопки. Если вы хотите, чтобы они оба включались и выключались вместе, вам нужна дополнительная переменная, чтобы сохранить, хотите ли вы включить или выключить кнопку при следующем нажатии. Поэтому пусть кнопка перевернет эту переменную, а затем, какое бы значение эта переменная ни имела, отправьте его реле. Также вверху "int relay1State;" должно быть "int relay1State=0;", потому что в вашей настройке вы отправляете это состояние в relay1, не определяя его сначала. К счастью, это все равно работает., @Greenaum

Кроме того, я должен добавить, что включение И выключение кнопки немного сбивает с толку! Если один включен, а другой выключен, то в какое состояние вы хотите, чтобы они оба перешли, когда вы нажмете его? Я полагаю, что если у вас есть только одна кнопка, вы немного ограничены этим. Лучший дизайн предполагал бы покупку еще одной кнопки! Тогда у вас будет один ВКЛЮЧЕН, а другой ВЫКЛЮЧЕН. И пользователь будет знать, чего ожидать, где, если в настоящее время у вас есть одно реле в каждом состоянии, должна ли кнопка включать или выключать их? Может быть, светодиод или что-то еще могло бы сообщить об этом пользователю, но дополнительная кнопка была бы лучше, я думаю., @Greenaum


1 ответ


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

3

Итак, согласно вашим комментариям, это должен быть код, если не было допущено никакой ошибки

#include <IRremote.h>
#define irPin 8
IRrecv irrecv(irPin);
decode_results results;
const int buttonPin = 2;
const int relay1 = 13;
const int relay2 = 12;
int relay1State = 0;
int relay2State = 0;
int masterState = 0;
int buttonState;
int lastButtonState;
long lastDebounceTime = 0;
long debounceDelay = 50;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(buttonPin, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
}

void loop() {
  if (irrecv.decode(&results)) {
    switch (results.value) {
      case 0xFF30CF:
        Serial.println("Button 1 Pressed");
        relay1State = !relay1State;
        digitalWrite(relay1, relay1State);
        delay(250);
        break;
      case 0xFF18E7:
        Serial.println("button 2 pressed");
        relay2State = !relay2State;
        digitalWrite(relay2, relay2State);
        delay(250);
        break;
    }
    irrecv.resume();
  }

  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == HIGH) {
        masterState = !masterState;
        relay1State = masterState;
        relay2State = masterState;
      }
    }
  }

  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
  lastButtonState = reading;
}

то, что я сделал, - это создал masterState, который изменяется только всякий раз, когда вы нажимаете кнопку buttonPin, и, нажав на нее, вы также измените оба реле на значение new masterState независимо от их фактического состояния.

Еще один совет: плохая практика - не инициализировать переменные перед использованием, потому что при объявлении не гарантируется, что они автоматически равны нулю.

,

Вы, сэр, очень помогаете! Это решило мои проблемы! Я еще не уверен, что полностью понимаю, как работает моя программа, но она постепенно погружается в нее. Но я могу сказать, что научился гораздо большему и быстрее, просто застряв в небольших проектах и попробовав их, а не просто читая книгу за книгой или просматривая учебник за учебником. Программу учить, а не учиться программировать, я думаю, они говорят:) Еще раз спасибо за вашу помощь. Это была настоящая царапина в голове-э-э для меня! Думаю, теперь я мог бы запустить в смесь фоторезистор ... Почему бы и нет, а? Это весело! :D, @Michael Sinclair

Продолжай, Майкл. Продолжайте проверять вещи. Чтобы помочь вам понять ваш исходный код, вы инвертировали текущее состояние реле, когда нажимали на кнопку. ! дает вам логическое не переменной. Поэтому, если var равен 1, true, использование ! даст отрицание этого var. Вот почему вам нужно было главное состояние, чтобы делать то, что вы хотите. Продолжайте практиковаться! Счастливого кодирования, @brtiberio