Короткий простой код управления кареткой

Добрый день.

ТЗ: есть каретка перемещения вверх-вниз. На конце маршрута каретки стоят датчики (герконы). Когда каретка доехала, геркон замыкается. Каретка приводится в движение винтовой парой (вращение двигателя по часовой и против часовой стрелке двигает каретку вверх-вниз.

Для определенности на концевые герконы применил пины 10 (верх) и 9(низ), а для выхода управления применил выходы 20 и 22. Появление высокого уровня на 20 двигает каретку вниз, появление высокого уровня на пине 22 двигает вверх.
Подача лог 1 на 20 и 22 одновременно не допустима (защита есть, но желательно ограничить и программно - исключить)

Логика такая. Когда каретка стоит посередине, концевики разомкнуты и нужно начать двигать каретку вниз до замыкания датчика. Если датчики 10 и 9 = 0 (разомкнуты) и нет сигнала на управление двигателем - 20 и 22 = 0 (каретка стоит, мотор не работает, например после отключения электричества. Тогда должен появлятся лог 1 на 20 и начатся движение вниз.

после того как приехали вниз, пауза 1 сек и появление лг 1 на 22, для движения вверх. В положении верх замыкается датчик 10, пауза 10 сек и начинаем движение вниз. Бесконечный цикл вверх-вниз с паузами внизу и вверху. Написал такой скетч

void setup() {
pinMode(10, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(20, INPUT_PULLUP);
pinMode(22, INPUT_PULLUP);

}

void loop() {
if (digitalRead(10) == 0 & (digitalRead(9) == 0 & (digitalRead(20) == 0 | digitalRead(22) == 0))) {
delay(1000);
pinMode(20, OUTPUT);
digitalWrite(20, 1);
} else {
if (digitalRead(10) == 1 & digitalRead(9) == 0) {
pinMode(22, OUTPUT);
digitalWrite(22, 0);
delay(101000);
pinMode(20, OUTPUT);
digitalWrite(20, 1);
} else {
if (digitalRead(10) == 1 & digitalRead(9) == 0) {
pinMode(20, OUTPUT);
digitalWrite(20, 0);
delay(1
1000);
pinMode(22, OUTPUT);
digitalWrite(22, 1);
}
}
}

}

он запускается и сразу встает в digitalWrite 20 = 1 до бесконечности, на датчики не реагирует. Помогите, пожалуйста, разобраться. что я делаю не так.

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

Прежде чем писать - научитесь читать !

@Топтунов

& и | - это битовые операции.

а в условиях применяются логические операции “и” и “или” - && и ||

2 лайка

да, извините.

void setup() {
  pinMode(10, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(20, INPUT_PULLUP);
  pinMode(22, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(10) == 0 & (digitalRead(9) == 0 & (digitalRead(20) == 0 | digitalRead(22) == 0))) {
    delay(1000);
    pinMode(20, OUTPUT);
    digitalWrite(20, 1);
  } else {
    if (digitalRead(10) == 1 & digitalRead(9) == 0) {
      pinMode(22, OUTPUT);
      digitalWrite(22, 0);
      delay(10 * 1000);
      pinMode(20, OUTPUT);
      digitalWrite(20, 1);
    } else {
      if (digitalRead(10) == 1 & digitalRead(9) == 0) {
        pinMode(20, OUTPUT);
        digitalWrite(20, 0);
        delay(1 * 1000);
        pinMode(22, OUTPUT);
        digitalWrite(22, 1);
      }
    }
  }
}

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

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

Странный Вы человек. С одной стороны утверждаете:

и при этом Вы сами же и пишете

Какой, по Вашему, уровень будет после этих операций на пинах 20 и 22?

И, кстати, зачем их объявлять INPUT, если Вы ими управляете, почему не OUTPUT? Не Знаю, что там за схема у Вас, но может не работать уже только поэтому.

Далее у Вас идёт весьма забавная конструкция (со строки №14):

    if (digitalRead(10) == 1 & digitalRead(9) == 0) {
      pinMode(22, OUTPUT);
      digitalWrite(22, 0);
      delay(10 * 1000);
      pinMode(20, OUTPUT);
      digitalWrite(20, 1);
    } else {
      if (digitalRead(10) == 1 & digitalRead(9) == 0) {

Я это понимаю так

ЕСЛИ (digitalRead(10) == 1 & digitalRead(9)) == 0 ТО
   *делать нечто*
ИНАЧЕ ПОДУМАТЬ ХОРОШЕНЬКО И 
ЕСЛИ ТАКИ ПЕРЕДУМАЕШЬ И ((digitalRead(10) == 1 & digitalRead(9) == 0)) ТО
  *делать что-то*
КОНЕЦ ЕСЛИ.

У Вас такая логика была? Или какая-то другая?

1 лайк

я понимаю ваше коллективное негодование, наверное этот говнокод этому способствует. Но другого еще писать не научился. Этот первый в моей жизни, я другой пока не умею. Первые строки, буквально.
С вашей помощью, надеюсь, научится лучшему.

Схему нарисую в течение дня. Постараюсь. Возможно я не достаточно подготовился для вопроса.

При чём тут негодование? Я показал Вам ошибки и подсказал как их исправить. Жду переработанного кода, и описания, что на этот раз не так, а не оправданий на тему почему этот получился таким.

1 лайк

если каретка вверху, она замыкает геркон. на входе 10 появляется лог 1 (геркон подтянут к земле) и в разомкнутом состоянии на входе 10 лог 0
Если каретка внизу, она тоже замыкает геркон, на входе 9

По поводу вводной части кода, думаю, надо отвязаться от програмной подтяжки в питанию и назначить входы и выходы

void setup() {
pinMode(10, INPUT);
pinMode(9, INPUT);
pinMode(20, OUTPUT);
pinMode(22, OUTPUT);

}

До работы доеду, попробую в работе.

Вторую часть моего сообщения Вы не заметили? Ну, ладно, пробуйте.

заметил. думаю как это внятно обьяснить.

void setup() {
  pinMode(10, INPUT);
  pinMode(9, INPUT);
  pinMode(20, OUTPUT);
  pinMode(22, OUTPUT);
}

void loop() {
  if (digitalRead(10) == 0 & (digitalRead(9) == 0 & (digitalRead(20) == 0 | digitalRead(22) == 0))) { // если каретка ни вверху и не внизу и никакие пины не подают сигналы (лог 0), то двигать вниз после паузы
    delay(1000); // пауза перед движением вниз
    pinMode(20, OUTPUT); // сигнал на спуск на выходе 20
    digitalWrite(20, 1); // едем вниз
  } else { // если услвоие в строке 9 не выполняется, тоесть каретка или едет или находится вверху или внизу, проверяем на езду и положение.
    if (digitalRead(10) == 1 & digitalRead(9) == 0) { // если есть лог 1 на выходе 10,  и лог 0 на выходе 9, то каретка вверху, надо её остановить. сделать паузу и начать двигать вниз
      pinMode(22, OUTPUT); // сигнал на водьем на выходе 20
      digitalWrite(22, 0); // останавливаем движение каретки вверх
      delay(10 * 1000); // пауза перед спуском
      pinMode(20, OUTPUT); //сигнал на спуск на выходе 20
      digitalWrite(20, 1); // начинаем движение каретки вниз
    } else {
      if (digitalRead(10) == 0 & digitalRead(9) == 1) { // если ло 1 на выходе 9 и лог на выходе 10, то каретка внизу, надо её остановить, сделать паузу, двигать вверх
        pinMode(20, OUTPUT); // сигнал на спуск на входе 20
        digitalWrite(20, 0); // останавливаем движение вниз
        delay(1 * 1000); // пауза в нижнем положении
        pinMode(22, OUTPUT); // сигнал на подьем на выходе 22
        digitalWrite(22, 1); // начинаем движение вверх (go to 15)
      }
    }
  }
}

Подскажите, нужно ли в этой конструкции в строках, например 11, 22 писать pinMode (20, OUTPUT) или достаточно того, что это определено в void setup?

Строка 9:

Думаете, два концевика могут быть нажаты одновременно|?

Сообщение #4 - не заметили? а зря

Они НЕ нажаты одновременно.

Я учел в программе, код выложил еще старый.

А вот это уже похоже на издевательство над присутствующими.

Т.е. @MMM потратил время на изучение Вашего кода и написания комментария, а Вы ему: “Да, ты там старьё какое-то изучал, у меня уже всё по-другому”.

Вы уверены, что такое отношение способствует тому, чтобы он и впредь тратил на Вас своё время?

void setup() {
  pinMode(10, INPUT);
  pinMode(9, INPUT);
  pinMode(20, OUTPUT);
  pinMode(22, OUTPUT);
}

void loop() {
  if (digitalRead(10) == 0 && (digitalRead(9) == 0 && (digitalRead(20) == 0 || digitalRead(22) == 0))) { // если каретка ни вверху и не внизу и никакие пины не подают сигналы (лог 0), то двигать вниз после паузы
    delay(1000); // пауза перед движением вниз
    pinMode(20, OUTPUT); // сигнал на спуск на выходе 20
    digitalWrite(20, 1); // едем вниз
  } else { // если услвоие в строке 9 не выполняется, тоесть каретка или едет или находится вверху или внизу, проверяем на езду и положение.
    if (digitalRead(10) == 1 && digitalRead(9) == 0) { // если есть лог 1 на выходе 10,  и лог 0 на выходе 9, то каретка вверху, надо её остановить. сделать паузу и начать двигать вниз
      pinMode(22, OUTPUT); // сигнал на водьем на выходе 20
      digitalWrite(22, 0); // останавливаем движение каретки вверх
      delay(10 * 1000); // пауза перед спуском
      pinMode(20, OUTPUT); //сигнал на спуск на выходе 20
      digitalWrite(20, 1); // начинаем движение каретки вниз
    } else {
      if (digitalRead(10) == 0 && digitalRead(9) == 1) { // если ло 1 на выходе 9 и лог 0 на выходе 10, то каретка внизу, надо её остановить, сделать паузу, двигать вверх
        pinMode(20, OUTPUT); // сигнал на спуск на входе 20
        digitalWrite(20, 0); // останавливаем движение вниз
        delay(1 * 1000); // пауза в нижнем положении
        pinMode(22, OUTPUT); // сигнал на подьем на выходе 22
        digitalWrite(22, 1); // начинаем движение вверх (go to 15)
      }
    }
  }
}

@Топтунов , это делается на конечных автоматах. Если попросите Евгения, он вам даст ссылку, где он подробно разъяснял.

Строки №№ 11, 15, 18, 22, 25. Зачем?

@Топтунов
пробовали этот код?
По-моему должно работать.

Обьявление выхода(пина).
Повторно спрошу, достаточно ли их обьявления в сетапе, можно в теле программы не писать?