Не хотят загораться лампочки (не работает функция if)

Добрый день! Смысл вложил такой: на сервопривод установлена дверь, когда она открыта gates.write (0) должен загореться зелёный светодиод, когда закрыта, то красный. Серво работает, но светодиоды не загораются (проблемы с условием). Пожалуйста, помогите сообразить с этим if-ом)

#include <Servo.h>
Servo gates;
#define GREEN 13
#define RED 12

void setup () {
  gates.attach (9);
  pinMode(GREEN, OUTPUT);
  pinMode (RED, OUTPUT);
    }

void loop () {
  gates.write (0); // ставим угол поворота 0
  delay (500);
  gates.write (180); // закрываем ворота
  delay (500);
  
  if (gates.write (0)) {digitalWrite (GREEN, HIGH);}
  else {digitalWrite (GREEN, LOW);}
  
  if (gates.write (180)) {digitalWrite (RED, HIGH);}
  else {digitalWrite (RED, LOW);}

}


Вам же написано - ГДЕ само условие ???

(gates.read() == 0)

Посмотрите в документации:

  1. Что возвращает ‘gates.write’.
  2. Что ожидается в скобках у оператора ‘if’.

Ну и сам по себе код бессмысленный, т.е. вы на каждой итерации:

  1. Сначала открываете ворота (0).
  2. Потом закрываете (180).
  3. А потом пытаетесь зажечь один из светодиодов.

Т.е. у вас, даже если пропишете условия корректно, никогда не загорится лампочка открытых ворот.

P.S.: и светодиоды надо через резисторы подключать, wokwi на это внимания не обращает и просто светит ими (если питание подать), в реальности же светодиод просто сгорит.

1 лайк

или того хуже, порт у ардуины

ЗЫ я фигею, дорогая редакция - и это все пишет “инженер”, собирающийся зарабатывать программированием :))))))))))))))))))

3 лайка

В общем, я пока сам только начал изучать тему. У меня вот так получилось.

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

#include <Servo.h>

#define RED_LED_PIN 6
#define GREEN_LED_PIN 5
#define SERVO_PIN 12

#define OPEN_GATE_VAL 180
#define CLOSED_GATE_VAL 0
#define GATE_SWITCH_DELAY 2000

Servo gate;

unsigned long lastGateSwitch = 0;

void setup() {
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  
  gate.attach(SERVO_PIN);
}

void loop() {
  if ((unsigned long)(millis() - lastGateSwitch) > GATE_SWITCH_DELAY)
    switchGate();
}

void switchGate() {
    gate.write(gate.read() == CLOSED_GATE_VAL ? OPEN_GATE_VAL : CLOSED_GATE_VAL);

    updateLeds();

    lastGateSwitch = millis();
}

void updateLeds() {
    bool isGateClosed = gate.read() == CLOSED_GATE_VAL;

    digitalWrite(RED_LED_PIN, isGateClosed ? HIGH: LOW);
    digitalWrite(GREEN_LED_PIN, isGateClosed ? LOW : HIGH);
}

image

Можете пояснить, что это за переменная?

Для хранения времени последнего открытия/закрытия “ворот”. Это вместо ‘delay’. Т.е. запоминаем последнее время переключения ворот и далее не выполняем следующее переключение (проверка в ‘loop’) пока не пройдёт какое-то время (в данном случае 2000ms).

1 лайк

Я же для ТС, в той ветке написал, какой язык ему стоит начать изучать! :wink:

очень смешно)

Что уж тут смешного ? Как вы до такого кода додумались ???

я с понедельника программирую

Опыт прямо пропорционален количеству выведенному из строя оборудования.

1 лайк

Ужас какой!
Куда смотрит правительство?

Пятница. Сокращенный рабочий день. Все согласно КЗОТу. Все бы правительство ругать

Да ну!
В принципе можно написать программу еще сложнее, но возникает вопрос - а кто даёт команду на открытие ворот? Дед Семен или Вы? Если Вы, то кто Вам мешает вместе с подачей команды на открытие ворот включить или выключить светодиод? Не надо плодить сучностей, их и так выше крыши.

Так это ведь не совсем корректное поведение будет. Я привёл упрощённый пример под конкретную задачу. В реальной же ситуации с воротами надо будет:

  1. Подать команду на открытие ворот. Светодиод оставить красным, т.к. ворота ещё не открыты.
  2. Проконтролировать (через какие-то датчики) процесс открытия. Они могут секунд 15-20 открываться. Они могут и не открыться, т.к. кто-то/что-то механически помешает этому, т.к. мотор заклинит или ещё что-нибудь.
  3. И только после того, как ворота реально откроются и проезд будет возможен, отключить красный светодиод и включить зелёный.

Ну т.е. индикация должна ориентироваться на реальное состояние, а не на предполагаемое.

Концевик поставьте и по нему ориентируйтесь, открылись ворота или нет.

1 лайк

Дык и проконтролируйте (через какие-то датчики). Это пишите, а не разную херню.

Это упрощённый пример согласно изначальной задаче.

Ну и в целом суть не изменится. Просто сейчас там только два состояния, которые переключаются по таймеру. А в реальном управлении воротами переключение будет не по таймеру, а по сигналам с каких-то датчиков, ну и состояний побольше будет.

Хотя, если более чисто реализовывать, то да, надо вовсе убрать вызов ‘updateLeds’ из ‘switchGate’ и перенести его ‘loop’, т.е. чтобы включение/отключение светодиодов вообще никак не зависело от подачи команды на открытие/закрытие и ориентировалось именно на реальное состояние ворот.

Да хоть 100500 состояний. Каждое из них описываете … и всё.
И не надо жаловаться на “сложность программирования” или “непонимание Вашей душевной организации”". Не прокатит. Надо написать алгоритм и перевести его на выбранный язык программирования.
И, Вы не поверите, и всё…заработает.