Цифровой ввод с помощью кнопки не работает должным образом при ее использовании для управления реле

Я пытаюсь управлять реле как через Bluetooth, так и с помощью переключателя. Проблема в том, что, когда светодиод выключен, я могу включить его с помощью переключателя, но тогда, если я выключу переключатель, реле останется включенным. Что-то не так с моим кодом? Заранее спасибо. Переключатель устанавливается следующим образом: Switch

Вот мой код: Переключатель подключен к контакту 3, а реле подключено к контакту 2.

//bluetooth hc-06
int ledPin = 2; // usamos un pin de salida al LED
int state = 0; // Variable lectrura serial
int interruptor=3;

void setup() {
    pinMode(ledPin, OUTPUT);   //Declara pin de Salida
    pinMode(interruptor, INPUT);
    digitalWrite(ledPin, LOW); //Normalmente Apagado
    Serial1.begin(9600);
    }

void loop() {
  int valor=digitalRead(interruptor);

  if(Serial1.available() > 0){
       state = Serial1.read();
  } // esta parte del código es para solo 1 Carácter o Unidad. 


 if (state == '0'&& valor== LOW) {
    digitalWrite(ledPin, LOW);
    Serial1.println("LED: off");
 }


 else
 if (state == '1' || valor== HIGH) {
     digitalWrite(ledPin, HIGH);
     Serial1.println("LED: on");
 }


}

Новый код:

//bluetooth hc-06
int ledPin = 2; // usamos un pin de salida al LED
int state = 1; // Variable lectrura serial
int interruptor=3;

void setup() {
    pinMode(ledPin, OUTPUT);   //Declara pin de Salida
    pinMode(interruptor, INPUT);
    digitalWrite(ledPin, LOW); //Normalmente Apagado
    Serial1.begin(9600);
    }

void loop() {
  int valor=digitalRead(interruptor);
 //si el modulo ha mandado dato, guardarlo en estado.

  if(Serial1.available() > 0){
       state = Serial1.read();
  } // esta parte del código es para solo 1 Carácter o Unidad. 

 // si el estado es 0 ese sería Apagado “OFF”
 if (valor== LOW) {
    digitalWrite(ledPin, LOW);
    Serial1.println("LED: off");
 }

 // de lo contrario si el estado es 1 ese sería Encendido “ON”
 else
 if (valor== HIGH) {
     if (state== 1){  
     digitalWrite(ledPin, HIGH);
     Serial1.println("LED: on");
     }
     else if (state== 0){
     digitalWrite(ledPin, LOW);
     Serial1.println("LED: off");

     }
 }


}

, 👍2

Обсуждение

Схема работает правильно при использовании команд Bluetooth, на случай, если это поможет., @Daniel Navarro

Должен ли коммутатор работать независимо от команды Bluetooth на реле? В настоящее время вы можете включить его только с состоянием= " 1 "И включить, и вы можете выключить его только с состоянием=" 0 " И выключить. Не совсем ясно, каково желаемое поведение. Пожалуйста, объясните подробнее, что должен делать код., @chrisl

@chrisl: Нет, вы можете включить его с состоянием='1', ИЛИ переключатель закрыт. Вот почему он может включить светодиод с помощью выключателя, но не выключить., @PimV

Хорошо, я изменил свой код, чтобы я мог управлять только через Bluetooth, когда переключатель включен, однако он все еще не работает..., @Daniel Navarro

Возможно, вам лучше использовать `логическое состояние = true", а затем использовать "состояние = (bool)Serial1.read ()" и "если (состояние)..." Здесь не показано ничего, что гарантирует, что "Serial1.read ()" вернет значение 1, @Jim Mack

В этом вопросе отсутствует критическая информация. Какие данные вы отправляете по последовательному каналу? Текстовый или двоичный? Первая версия кода работает с символами 0" и 1". Вторая версия внезапно использует целочисленные значения " 0 и 1`. Что это дает? Вы должны определиться с тем, что вы хотите отправить. В настоящее время этот вопрос просто не имеет смысла., @AnT

"Я пытаюсь управлять реле как через Bluetooth, так и с помощью переключателя". Вам следует объяснить это подробнее. Как вы хотите, чтобы он действовал? Перекрывает ли одно другое другое?, @Delta_G


2 ответа


0

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

if (Serial1.available() > 0) {
    state = Serial1.read();
} else {
    state = -1; // недопустимо
}

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

if (state == '1')
,

1

Ну, есть пара проблем.

В исходном SW вы проверяете state = '0'и state = '1', но начальное значение состояния равно 0 (не '0'). По этой причине оба теста всегда возвращают значение false.

Кроме того, избегайте установки условий, когда в этом нет необходимости. else уже означает "все остальные параметры", поэтому, если у вас есть одна переменная, которая может быть только A или B, не пишите if A ... else if B ...; второе условие необходимо (и имеет смысл) только в том случае, если условие действительно вас волнует (поэтому вы хотите исключить условие C).

Я начал изменять ваш скетч с новой версии, и вот что я изменил:

  • Переменным был присвоен тип uint8_t; int неэффективен на 8-разрядных платформах, поэтому используйте 8-разрядные переменные всякий раз, когда это возможно
  • Вместо использования нескольких триггеров я использовал одну переменную (ledState) для вычисления состояния в каждом цикле. Таким образом, гораздо проще отслеживать изменения
  • упрощено управление вводом: теперь он включает светодиод, когда вход высокий, и ничего не делает (выключает его), когда он низкий
  • упрощено управление Bluetooth. С помощью "1" он включает светодиод, а все остальные символы выключают его; если вам нужно только "0", чтобы выключить его, вы можете легко изменить круглые скобки, чтобы игнорировать другие символы

Это код, который я написал. ПРИМЕЧАНИЕ: Я не тестировал его, поэтому могут быть остаточные ошибки. Дайте мне знать, работает ли это так, как вы ожидаете, или хотите получить некоторые дополнительные разъяснения:

uint8_t ledPin = 2;
uint8_t interruptor = 3;
uint8_t bluetoothState = '0';

void setup() {
    pinMode(ledPin, OUTPUT);
    pinMode(interruptor, INPUT);
    digitalWrite(ledPin, LOW);
    Serial1.begin(9600);
}

void loop() {
    uint8_t ledState = LOW;
    
    if (digitalRead(interruptor)) {
        ledState = HIGH;
        Serial1.println("LED: on (switch)");
    }
    
    if(Serial1.available() > 0){
        bluetoothState = Serial1.read();
    }
    
    if (bluetoothState == '1') {
        ledState = HIGH;
        Serial1.println("LED: on (BT)");
    }
    
    digitalWrite(ledPin, ledState);
    if (ledState == LOW) {
        Serial1.println("LED: off");
    }
}

Что еще предстоит сделать (ИМХО):

  • создайте надежный обработчик кнопок (например, с помощью библиотеки debounce)
  • избавьтесь от последовательных отладочных выходов
  • создайте лучший последовательный протокол
,

Надеюсь, проблема была решена за прошедшие 2,5 года ;), @Dave Newton

O_O почему тогда это было на главной странице? Я предположил, что это было что-то около 10 минут назад, ЛОЛ.. извините за некропост, @frarugi87

:пожимание плечами: Это сайт с низким трафиком, поэтому вещи натыкаются для видимости ;) И в любом случае это нормально-это кому-нибудь поможет, если не оператору :), @Dave Newton

уже 3,5 года. :), @Nick Gammon

* Я предполагал, что это было что-то вроде 10-минутной давности * ... да, SE действительно делает странные вещи, например делает сообщения релевантными, когда они не являются., @Nick Gammon