Цифровой ввод с помощью кнопки не работает должным образом при ее использовании для управления реле
Я пытаюсь управлять реле как через Bluetooth, так и с помощью переключателя. Проблема в том, что, когда светодиод выключен, я могу включить его с помощью переключателя, но тогда, если я выключу переключатель, реле останется включенным. Что-то не так с моим кодом? Заранее спасибо. Переключатель устанавливается следующим образом:
Вот мой код: Переключатель подключен к контакту 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");
}
}
}
@Daniel Navarro, 👍2
Обсуждение2 ответа
Вы должны аннулировать переменную состояния, когда
последовательный
номер недоступен, иначе вы будете вести себя странно.
if (Serial1.available() > 0) {
state = Serial1.read();
} else {
state = -1; // недопустимо
}
Кроме того, последовательные значения будут символами, а не целыми числами, поэтому сравните их со значениями символов, например,
if (state == '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
- Заменить механический переключатель электрическим переключателем или реле.
- Arduino Pro Micro, получить данные с контакта Tx?
- Управление двигателем Arduino Uno с помощью 2 реле, 2 концевых выключателей и Bluetooth. Вперед Назад Стоп
- 2-ходовой переключатель с Arduino?
- Как управлять коммутатором (proteus) с помощью Bluetooth-карты (HC-05) и arduino?
- Помощь проектом слишком быстрого переключения реле водяного насоса.
- Как включить/выключить питание, чтобы сократить БОЛЬШИЕ токи (200 А)?
- Новичок в ардуино, помогите подключить реле
Схема работает правильно при использовании команд 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