Проблема с оператором For !!!
- Войдите на сайт для отправки комментариев
Пт, 12/04/2013 - 10:02
Добрый день!!!Использую оператор for в своем коде для запуска генератора.Вот эта часть:
for (int i = 0; i<=3; i++) { digitalWrite(10,LOW); digitalWrite(8,LOW); //то гасим индикатор работы от сети digitalWrite(11,HIGH); //зажигание digitalWrite(12,HIGH); //подсос delay(5000); //задержка подсоса на 5 секунд digitalWrite(13,HIGH); //пробуем завести генератор delay(5000); //задержка на 5 секунд }
Написал это для того чтобы блок операторов в фигурных скобках выполнился трижды, пока i не примет значение 3 , а потом вышел из цикла и пошел дальше выполнять остальной код. Но вот проблема, когда программа доходит до этого места, цикл этот выполняется бесконечно. Что я делаю не так?)
А где стоит кусок этого кода? В setup() или в loop()?
Этот кусок кода стоит в Void loop()
> фигурных скобках выполнился трижды, пока i не примет значение 3
Будет выполнять при i=0,1,2,3 - То есть четыре раза выполнится. Вам нужно либо i начинать с единицы, либо использоват оператор "меньше", а не "меньше или равно".
>цикл этот выполняется бесконечно
Как говорил Швейк: "осмелюсь доложить - что-то я сомневаюсь".
Как вы это узнали? Намного вероятней что, из-за того что он в loop(), сам for целиком запускается раз-за разом.
Сделайте перед ним Serial.println("start"); и после него Serial.println("done");
Откройте сериал монитор. Если там будет одно слово "start" и больше ничего - значит случилось чудо и действительно цикл бесконечно крутится.
А если будете видить "start done start done start done" - значит вы его запускаете раз за разом, и бага в коде который вы не показали.
На данный момент код выглядит так. Далее будет предусмотрен индикатор аварии(если генератор не запустился с трех попыток) и кнопка сброса того самого индикатора. Но пока заступорился на зацикленности в for. Понимаю что не правильно пишу,но сделать как надо пока не хватает опыта.
Сделал как Вы сказали и получил на последовательном порту "start done start done start done"
Объявите переменную
char done;
Поставьте в setup()
done=0;
В loop() оберните свой цикл конструкцией:
Расскажите о результате
Если правильно Вас понял сделал вот так :
В результате цикл в Вашей конструкции выполнился один раз!!!)
Я попробовал сразу прописать в конструкции done=3; , думая что цикл выполнится 3 раза, но не получилось))))))))он выполнился тоже один раз)))
Почитайте что такое setup() и что такое loop()
setup() - это то что выполняется один раз при старте скетча.
loop() - то что запускается раз за разом. когда loop() выполняется до конца - его выполнение опять начинается с начала.
Поэтому "начальное положение у всех портов "0" логично было-бы видеть в setup(), а не в loop(), по крайней мере если вам не нужно выставлять все в Low() раз за разом.
Учитывая свойство loop(), ваш for будет запускаться раз-за разом, до тех пор пока выполняется условие digitalRead(2)==HIGH &&digitalRead(3)==HIGH
Внимание!!! не в момент "когда оно первый раз настанет", а "все время, пока выполняется". До тех пор пока 2 или 3тий пин не упадут в low
И еще. Вот этот if - в строке 26 очень не красиво выглядит. Желательно все-таки обернуть for в {} (как вы делали с if-ом в 22 строке). А то ни скобками, ни отсутупами (кстати их тоже желательно сделать), не видно что for отсносится к этому if-фу.
Кстати на 80% уверен, что когда вы добавляли print-ты - вы забыли про это. И это добавление - полностью сменило вам логику (вместо того что-бы просто "показать что происходит). А если бы for был обернут в скобки, то println ничего не менял-бы в поведении, только давал возможность "подглядеть".
Я попробовал сразу прописать в конструкции done=3; , думая что цикл выполнится 3 раза, но не получилось))))))))он выполнился тоже один раз)))
Тогда обьявлять ее надо как int, и проверять if(done<3) инкременируя ее каждый раз
В прошлом посте нумерация строк относилась с скетчу #4
>В результате цикл в Вашей конструкции выполнился один раз!!!)
Как там может выполнится цикл один раз, если там вообще нет цикла? Там только набор digitalWrite-тов, вы не внимаетльно читали что вам писал step962.
А писал он оберните свой цикл конструкцией, а не "оберните тело своего цикла". Вы же выбросили for, зачем? Вот весь for целиком с потрохами и нужно було пихать в конструкцию step962
P.S. А я бы done объявилу как bool, тогда было-бы понятенй что это флаг делал done=true;
Если как флаг то согласен, вопрос только зачем ему вообще здесь нужен цикл? вполне можно было обойтись и без него. Тем самым сэкономить память.
Если как флаг то согласен, вопрос только зачем ему вообще здесь нужен цикл? вполне можно было обойтись и без него. Тем самым сэкономить память.
Если какое-то действие нужно выполнить четко три раза - то именно цикл экономит память.
Зачем топикстартеру нужно это делать именно три раза - понятия не имею. Если речь про автомобиль - то скорее всего что-бы угробить стартер.
Цикл мне нужен для того чтобы если генератор не запустится с трех попыток , то загорится индикатор аварии . А если запустится с первой или второй попытки ,то нужно выйти из цикла заранее(правда это еще дописать нужно)
Речь идет про запуск бензинового генератора на даче при изчезновении сетевого питания.
А у вас в цикле, нет "трех попыток".
При первом проходе цикла - выставтся digitalWrite-ты. И так и останутся до тех пор пока цикл не закончится. То есть каждый проход цикла - добавляет вам "ожидание 2sec" и больше ничего.
При этом, если генератор завелся сразу, то все-равно еще 5-ть секунд будет крутится стратер. Не знаю конструкцию вашего генератора, но в автомобиле это означает "трындец стартеру". Если повезет - после нескольких таких стартов, если нет - сразу.
А у вас в цикле, нет "трех попыток".
При первом проходе цикла - выставтся digitalWrite-ты. И так и останутся до тех пор пока цикл не закончится. То есть каждый проход цикла - добавляет вам "ожидание 2sec" и больше ничего.
Блин вот это тупанул.Не прописал выключения digitalWrit-ов!!!!!!!!!!!
Если так?
Ну - больше похоже на правду.
Но...
1. Я уже писал выше, что цикл у вас выполняется не три, а четыре раза.
2. Непонятно зачем строки с 05 по 10 внесены в цикл. IMHO их можно просто один раз выполнить до цикла, а внутри - игратся только с 13-тым пином.
3. Нет проверки что генератор таки завелся. Но.. даже если вы ее вставите, то во время delay(5000) - стартер будет маслать в люобм случае. Нормально для вашего стартера работать 5 секунд при включенном движке - я не знаю. IMHO delay() нужно вообще убирать.
4. Зачем выключать подсос при кручении стартера - не понятно (но может это специфика вашего генератора).
С учетом последних замечаний прописал вот так:
Но вот как туда засунуть проверку и чтоб при запуске генератора выйти из цикла не зависимо от того на какой (с 1 по 3) попытке мы находимся?
> i<=2
Можно и так. Но более традиционным является for(int i=0;i<3;i++)
Так "какая цифра" "столько раз и выполнятся будет". Это скорее "традиция" которой придерживаются 99%. Поэтому любой читающий бегло ваш код - быстрее поймет, меньше шансов что ошибется.
> выйти из цикла не зависимо от того на какой
Можно почитать документацию Программирование Ардуино | Аппаратная платформа Arduino и в разделе "Управляющие операторы" узнать о существовании волшебного оператора break (кстати там и пример - близок к вашей задаче). А вообще нужно ОБЯЗАТЕЛЬНО проштудировать и знать все эти операторы (кроме goto - про него лучше забыть навсегда).
Если бы я делал - то я бы вообще просто вынес все эту логику старта в отдельную функцию. Скажем runStarter() и просто делал return() как только генератор завелся.
Вариант. Работать - будет. Но в любой комманде сделают как минимум щелобан в нос за такое :) Есть специальный оператор для этого - даже ссылку выше дал. И вообще менять i в таких циклах внутри тела цикла - ОЧЕНЬ плохой тон. Очень затрудняет, потом, сопровождение кода, поиск ошибкой и т.п.
Да банально. завтра решите что попыток нужно 5-ть. В форе поменяете, а внизу - забудете. И привет бесконечный попытки завестись.
Моветон согласен, но тут вопрос не о красоте.
Моветон согласен, но тут вопрос не о красоте.
Тут вопрос не о красоте, а о заботливо подложенных граблях. На которые рано или поздно - кто нибудь наступит почти наверняка. А если войдет в привычку... то лучше сразу завязывать с програмированием.
Представте себе что к вам пришел мастер что-то чинить. И забивает гвозди плоскогубцами. При этом молоток лежит рядом. А гвоздь пытается держать пальцами ног. Ваше мнение о таком мастере? Что вы будете ждать от него кроме "ну когда же уже врежет по пальцам?" и "только бы не сломал то_что_чинит". Даже если гвоздь он все-таки забъет.
Ну грабли, на то и нужны что бы на них наступать:) Тем более если рядом такой человек как вы подсказывает где они лежат.
А вопрос тут помоему стоит стандартный, "Вам шашечки или ехать?" Для данной задачи, такое решение подходит, тем более как я писал выше, я бы вообще избавился от цикла.
>А вопрос тут помоему стоит стандартный, "Вам шашечки или ехать?"
Ехать, но желательно в салоне, а не пупсиком на капоте, пытаясь ягодицами создать разрежение, что-бы не свалится.
> я бы вообще избавился от цикла.
можно и так, но...
PuskCount - нигде не обнуляется (а вдуг заглохо не один раз?)
ну тут много чего нет, защиты от кратковременного пропадания напряжения, остановку генератора, и т.д.
ну тут много чего нет, защиты от кратковременного пропадания напряжения, остановку генератора, и т.д.
Это не "много чего нет". Вы оттолкнулись - "можно без for". Значит и вариант должен быть "эквивалентным". Как минимум иметь те же функции.
А так вы показали "альтернативный вариант", которые не делает того что делал изначальный. При повторном пропадании - опять делать три попытки. Вот когда будет "аналогичное поведение", тогда и можно будет смотреть "как проще". А то выйдет что "без for-а, зато 5-ть if-ов добавилось).
пожалуйста