"Лифт" (подъемник) на 2 этажа
- Войдите на сайт для отправки комментариев
Пт, 06/07/2018 - 12:00
Здравствуйте. Исходные материалы: ардуино, двойной релейный модуль, 2 концевика и кнопка( вообще 3 кнопки вызова - внизу, наверху и в лифте - каждая из которых может отправить лифт в любом направлении взависимости от положения лифта).
Набросал пример для управления светодиодами вместо реле. Но так как это мой первый код, он оказался не рабочим (хотя по моей логике должно все работать), возможно подключение не правильное.
int flagStart; //команда Старт - была нажата кнопка вызова int flagDirection; //Направление движения - читаем какой концевик нажат int flagMotion; //Включаем реле void setup(){ Serial.begin(9600); pinMode(1,INPUT); //кнопка вызова pinMode(2,INPUT); //концевик внизу pinMode(3,INPUT); //концевик вверху pinMode(4,OUTPUT); //мотор вверх pinMode(5,OUTPUT); //мотор вниз } void loop(){ if (digitalRead(1)==HIGH) { flagStart=true; //кнопка вызова была нажата Direction(); //проверяем положение лифта по концевикам для старта flagMotion=true; //запуск лифта } if (flagMotion==true) { digitalWrite(flagDirection,HIGH); //посылаем сигнал на реле в зависимости от состояние концевика(вверх/вниз) flagStart==false; //отпускаем команду вызова } Direction();//проверяем положение лифта во время движения, для остановки по концевику } void Direction(){ //проверяем какой концевик нажат //проверка для старта (т.е. нажат концевик внизу и нажата кнопка вызова, включаем реле вверх) if ((digitalRead(2)==HIGH) && (flagStart==true)) flagDirection=4; if ((digitalRead(3)==HIGH) && (flagStart==true)) flagDirection=5; //проверка состояние концевиков во время движение и остановка движения если сработал концевик if ((digitalRead(2)==HIGH) && (flagMotion==true)) flagMotion=false; if ((digitalRead(3)==HIGH) && (flagMotion==true)) flagMotion=false; }
Для начала, это как бы не весь код. А где собственно включение и выключение моторов (светодиодов) в зависимости от всех этих кнопок и флагов?
Так за этим и на форум пришел... чтобы моторы начали включаться.
Включение - если digitalRead(1) ==HIGH (кликнули кнопку вызова)- то проверяем какой концевик нажат (допустим digitalRead(2) == HIGH -лифт внизу) и определяем переменную flagDirection = 4 или 5 (верх или вниз, в данном случае 4(вверх)) для digitalWrite(flagDirection,HIGH) - мотор начал движение
Выключение - если переменная flagMotion включена(лифт движется), а она включается после клика по кнопке вызова - то проверяем положение лифта по концевикам в функции Direction - если flagMotion =True и нажат концевик Вверх(лифт доехал до верха), то объявляем переменную flagMotion =false и тогда в void loop условие if flagMotion не выполняется - соответсвенно digitalWrite(flagDirection,HIGH) не выполняется.
я пишу и читаю это так)
Сорри, да, запуск-то есть. А остановка мотора где?
поправьте пожалуйста если я ошибаюсь - я думал, что если условие не выполняется (т.е. flagMotion не равен True), то и сигнал на digitalWrite(flagDirection,HIGH) отправлятся не будет
От этого HIGH на выводе не пропадёт. Надо LOW записать. Возможно в Direction(), где концевики проверяете и сбрасываете флаг flagMotion=false.
пробовал в void loop дописывать
if
(flagMotion==
false
)
digitalWrite(flagDirection,LOW);Вы в логике запутались. Вынесите проверки в функции с говорящими именами. Сразу станет намного легче разбираться.
запутаться запутался, прошу помогите распутаться. первый раз пишу
запутаться запутался, прошу помогите распутаться. первый раз пишу
Ну я имел ввиду так:
Если едем и сработал концевик, то остановить соответствующий двигатель и сбросить флаг. Но не факт, что этого достаточно. (4 и 5 сами проверьте кто там верх, кто низ)
Ещё возможно стоит добавить:
пока едем - нечего кнопки давить.
попробовал, не работает. я все думаю, что проблемы с подключением
Блин, фига се глюк! написал обстоятельный ответ, а он пропал :( Только маленький кусочек остался
запутаться запутался, прошу помогите распутаться. первый раз пишу
Я думал, что я Вам уже помог фразой
Вынесите проверки в функции с говорящими именами. Сразу станет намного легче разбираться.
Но, Вы, похоже, её не поняли.
Хорошо, давайте подробнее. Вот смотрите, что у Вас написано, например
начнём с того, что комментарий неправильный - последняя строка - она про верхний концевик, а в комментарии о нём ничего не сказано.
Сделайте несколько простых вещей (привыкните их делать всегда) и Вам сразу станет намного легче писать программы и искать в них ошибки.
1. Никогда не используйте числовые номера пинов - только названия
2. Все проверки и действия выделите в отдельные функции с говорящими названиями. Например
Теперь, Вы никогда не пишете "if (digitalRead ...", но всегда пишете "if (isUpperLimitSwitchActive() ..."
Точно также, Вы никогда не пишете "digitalWrite(...", а пишете "goUp()"
Уже одно только это повысит читабельность программы в разы, и Вы будете меньше путаться.
2. Вы завели ТРИ флага и запутались в них. Это немудрено. Три флага дают 8 состояний и в них чёрт ногу сломит. Уйдите от использования флагов и работайте через состояния системы. Их меньше и они понятнее. Обязательно дайте им имена (ни в коем случае не числа!!!). Например,
И везде используйте состояния, тогда флаги не нужны вовсе. А с так названными состояниями, им и комментарии не нужны - они сами себя комментируют.
Вот теперь попробуйте переписать программу с учётом всего, что я написал, и почувствуйте разницу.
Два замечания напоследок:
1) уйдите от пина 1. Используйте другой. Привыкайте использовать пины 0 и 1 только по прямому назначению. Потом поймёте почему и когда можно, а когда нельзя, пока же - только для UART и ни для каких кнопок
2) у Вас что, одна кнопка вызова?
---------------------------
А если хотите научится писать такие программы грамотно, то у Вас просто изначально неверный подход. Это классическая автоматная задача и делать её надо автоматом. Вот посмотрите пример со светофором на стр. 8+ вот в этой книге. С лифтом всё точно также. Оцените как элегантно и просто получается с таблицей состояний и переходов - проще некуда. Вот так это и надо делать.
Большое Вам спасибо за потраченное время на ответ. Сижу изучаю, уже понимаю насколько примитивно и запутано я все написал. Постараюсь изучить больше, так как сейчас не все понятно. сейчас буду читать про
inline
void ,
почемуто ругается на строкахinline
void
goUp(
void
)
К
нопок вызова 3. на 1 этаже, на втором и в кабине (в кабине хочу подключить беспроводную кнопку). Думаю они все должны быть паралельны. Чтобы нажав на любую из кнопокк можно было вызвать или отправить "лифт"Еще раз большое спасибо!
Если не понимаете на что ругаетмся - показывайте. И код и копипасту ругани.
Да посидел 20 минут подумал и не разобрался. как я понял дальше следует в void loop() записать условия
if (isCallButtonActive==true && isLowerLimitSwitchActive==true) goUp();
if (isCallButtonActive==true && isUpperLimitSwitchActive==true) goDown();
но как указать, что пора остановиться?
а ругается In function 'void goUp()': 42:13: error: redefinition of 'void goUp()' 34:13: error: 'void goUp()' previously defined here
Там две функции с одинаковым именем - goUp(), это ошибка. Переименуй вторую функцию, например goDown()
К
нопок вызова 3. на 1 этаже, на втором и в кабине (в кабине хочу подключить беспроводную кнопку). Думаю они все должны быть паралельны.Если все кнопки будут "параллельны" - как лифт узнает, вызываете лм вы его с первого этажа или со второго? Думаю, все три кнопки должны быть независимы.
переименовывал. и поправлял регистр. думаю это глюк какой то был на сайте эмулятора. с 4ой попытки получилось
понимать должен по состоянию концевиков. он либо вверху, либо внизу.
надо время разобраться. я почему то думал, что быстрее разбирусь с управлением через контроллер, но пока быстрее получилось подключить через реверсивный пускатель и два нормально открытых реле.