Вы каждый раз проверяете сигнал. Т.е. смотрите, двигатель включён. Доехали до концевика, увидели на нём сигнал, поехали обратно. Вот тут бы Вам ехать две секунды не обращая внимания на сигнал, и остановитья, но Вы продолжаете его (сигнал) проверять. В итоге, как только вы чуть-чуть отехали обратно, сигнал оказывается потерян и Вы опять дрыгаетесь вперёд.
Я просто не пойму, что не так в коде, что в 100 посте... Ведь вроде бы все просто сигнал есть - включи вперед на 2 сек и сбрось управление, нет - на 2 сек назад и опять сбрось управление. Этот концевик независим от двигателя. Пробовал добавлять флаги - не помогает....
Я просто не пойму, что не так в коде, что в 100 посте... Ведь вроде бы все просто сигнал есть - включи вперед на 2 сек и сбрось управление, нет - на 2 сек назад и опять сбрось управление. Этот концевик независим от двигателя. Пробовал добавлять флаги - не помогает....
Нет, ну Вы смотрите на код-то.
Давайте по шагам. Вот Вы в первый раз включили двигатель (строки 39-40). При этом Вы не стали запоминать время включения, а сразу стали сравнивать текущий милли с previousMillis, который у Вас 0. Влетели в блок 41-45 и выключили двигатель.
Может разумнее в момент включения двигателя запоминать время включения, чтоб от него, а не от нуля отсчитывать 2 сек?
Кроме того, в течение этих 2 секунд двигатель отъедет от концевика и стало быть условие в строке 38 перестанет выполняться. Значит, сравнивать время (в процессе ожидания 2 сек) надо где-то снаружи, а не внутри блока 38-46.
Да, нет, ничего Вы не вынесли. Строки 14-19 и 25-30 как были внутри других условия, так и остались.
Ну, если Вам трудно сходу (а поначлу всегда трудно), распишите на бумаге конечный автомат. Я не знаю точно Вашей задачи, поэтому могу только вчерне набросать как он выглядит, а Вы уж напишите как надо.
Для начала выписываем все состояния в котором бывает Ваш автомат. например:
1. Стоит
2. Едет влево (до упора)
3. Едет вправо (до упора)
4. Откатывается назад влево (2 сек)
5. Откатывается назад вправо (2 сек)
Выпишите все состояния, какие бывают, наверняка у Вас там ещё есть.
Дальше выпишите логику работы автомата в терминах состояний и переходов между ними. например.
ЕСЛИ состояние == 1
Сгенерировать случайное число R от 0 до 1
ЕСЛИ R < 0,25 { поехать вправо; перейти в состояние 3; }
ИНАЧЕ ЕСЛИ R < 0,5 { поехать влево; перейти в состояние 2; }
ИНАЧЕ ЕСЛИ состояние == 2
ЕСЛИ достигнут концевик { поехать вправо; запомнить время_0; перейти в состояние 5; }
ИНАЧЕ ЕСЛИ состояние == 3
ЕСЛИ достигнут концевик { поехать влево; запомнить время_0; перейти в состояние 4; }
ИНАЧЕ ЕСЛИ состояние == 4
ЕСЛИ тек.время - время_0 >= 2 сек { остановиться; перейти в состояние 1; }
ИНАЧЕ ЕСЛИ состояние == 5
ЕСЛИ тек.время - время_0 >= 2 сек { остановиться; перейти в состояние 1; }
Всё это хозяйство выполняется в бесконечном цикле (в loop()). Как видите, у меня получился автомат, который иногда стоит на месте, потом вдруг начинает ехать вправо или влево, доезжает до концевика, откатывается назад в течение 2 сек и снова, постояв немного, куда-нибудь едет.
Когда Вы это распишете, проверьте всё внимательно и если логика правильная, то пишите программу.
Заведите одну переменную для номера состояния и просто замените в этом словесном тексте все пассажи типа "поехать вправо", "остановиться", "достигнут концевик" и т.п. на соответсвующие команды и проверки. Например, слова "перейти в состояние N" выльются в простое присваивание числа N Вашей переменной состояния.
Извиняюсь, что не в тему, может кому понадобится - это управление автоматическими порогами на авто.
Один геркон на две двери (на каждую сторону). Открыли дверь - выдвинулся порог, закрыли - задвинулся. Так как защиты двигателей у меня нет, решил подавать питание на 1,5 - 2 сек. и сбрасывать его.
По ссылке файл для Proteus со схемой и программой.
В общем ситуация такая, есть 2 реле, которые должны включатся отдельно друг от друга на разные периоды времени, которые задаются через переменные, а не объявляются сразу (задаются кнопками). В то время пока первое реле включено второе должно быть выключено и наоборот. Еще наверное нужно предусмотреть задержку (компенсацию) для включения и выключения реле чтобы они не сработали одновременно.
Время вводил в секундах, не могу понять, как перевести все в миллс, т.е. вроде бы время * 1000 но как же добавить пресловутый UL?
Уже с дисплеем разобрался и с кнопками, а вот с реле никак не получается (((
Пока горит первый светодиод, второй собака 5 раз успевает мигнуть. Я понимаю, что не разобрался с уловиями, но чего-то уже голова пухнет.. Может поможет кто найти ошибку, чтобы работало как с Delay
Ну, Вы остудите голову (можно лёд приложить) и спокойно разберитесь чего Вы хотите. В первом скетче Вы их включаете по очереди, а во втором запустили мигать параллельно. Вот они параллельно и мигают. Нормально так все.
И, кстати, что делают while в строка 15 и 23? Оно у Вас всё равно исполняется только по одному разу, т.к. Вы previousMillis внутри цикла меняете. Тогда почему не использовать более простую конструкцию if?
Да, и ещё, если Вам реально нужно, чтобы светодиоды светились сменяя друг друга (один светится - второй - нет), это не так делается. Зачем для этого два пина? Вполне достаточно одного. Схема нужна?
const int Zar = 10; //время заряда
const unsigned long tZar = Zar * 1000UL;
const int Raz = 1; //время разряда
const unsigned long tRaz = Raz * 1000UL;
bool mode_zar = 1; // 1 заряд / 0 разряд
bool v3,v5;
void setup() {
pinMode (3, OUTPUT);
digitalWrite(3, v3 = 1);
pinMode (5, OUTPUT);
digitalWrite(5, v5 = 0);
}
void loop() {
static unsigned long past = 0;
if (mode_zar && millis() - past >= tZar) {
past = millis();
mode_zar = 0;
digitalWrite(3, v3 = !v3);
digitalWrite(5, v5 = !v5);
}
if (!mode_zar && millis() - past >= tRaz) {
past = millis();
mode_zar = 1;
digitalWrite(3, v3 = !v3);
digitalWrite(5, v5 = !v5);
}
}
evgta пишет:
Вы так говорите что в delay есть что-то плохое?
если ненадо кнопки опрашивать или выполнять парралельные работы то в делей нет ничего плохого.
В delay() все плохо. Кажущая простота выключает мозг у новичков. Это как вы заявили: В ворах ничего плохого нет- они чистят подобно уборщикам ваши карманы.
Вы правильно меня поняли, нужно чтобы светодиоды светились сменяя друг друга (один светится - второй - нет). Время свечения задается переменными. А 2 пина используются потому, что вместо светодиодов будет другая нагрузка - реле или транзистор. Буду благодарен, если объясните или покажете как проще это реализовать.
Против Delay ничего не имею, но кнопки действительно нужно опрашивать, и еще выводить информацию. Просто очень удобная функция, жаль что накладывает ограничения.
Скетч видел, попробовал, спасибо огромное, все работает. Буду теперь разбираться, Как он работает ))
вместо делей можно использовать цикл такого вида, где tmot время задержки, но парралельности работы небудет
Паралельность, диагоналность. Понапридумывали всякой туфты. millis это банальные часы. а функция millis() -"узнать время" и все. Delay же это временная пробка. Процессор нихрена не делает , потому что он занят важной работой "нихрена не делать 1 секунду".
Да, видимо думаю я не как программист, мог бы и догадаться управлять обоими светодиодами из одного оператора как у qwone, а я уперся и пытался обрабатывать их разными.. Чего только не делал, и операторы менял, и разносил по разным функциям, придумывал новые условия.. А все проще оказалось ))
StasOn. Я тоже не программист. А то что я влегкую написал так. Так это результат долгого прохождения по швабрам, граблям гвоздям и прочей хр**ни. И в результате я могу сказать точно: я до сих пор не могу писать вменяемые программы.Но это секрет. :)
А 2 пина используются потому, что вместо светодиодов будет другая нагрузка - реле или транзистор. Буду благодарен, если объясните или покажете как проще это реализовать.
Реле прямо на пине быть не может, значит транзистор, включающий реле. Тогда Вам стопудово достаточно одного пина. И управлять им проще будет.
Вот смотрите со светодиодом для начала:
Если Ваши светодиоды разных цветов, то, возможно, Вы захотите поставить им разные резисторы. Тогда можно так:
Ну, а с транзистором тоже самое. Я тут им нарисовал в качестве нагрузки лампочки накаливания - замените на реле или на что Вам там нужно.
Один из транзисторов всегда открыт, а второй всегда закрыт. В принципе, есть некий наносекундный переходный процесс, когда один ещё не до конца закрылся, а второй уже начал открываться. Если надо это минимизировать возьмите более быстрые транзисторы. Если же надо это исключить полностью и железно, то надо будет немного усложнить схему или плюнуть и перейти на два пина.
Процессор нихрена не делает , потому что он занят важной работой "нихрена не делать 1 секунду".
Ну, так уж и ни хрена! Это ж Вам не POWER_DOWN режим! Он честно крутится в цикле и добросовестно осваивает бюджет перерабатывает электроэнергию в тепло :)
За схемы спасибо! С одним пином на 2 светодиода хитро, но не подходит. Сначала я сделаю управление до конца, потом возьмусь за питание ,а потом за высоковольтную часть (нагрузка будет 15в и от 0,1 до 5 А, еще не решил что лучше, реле - громкие, медленные, зато есть и подключать не сложно, или транзисторы - тихие, быстрые, но надо вникать, схемотехника посложнее). А зачем пины экономить? Я конечно понимаю, что можно сэкономить на памяти и на ресурсах, но пока всего хватает.
Еще хотел спросить qwone можно ли в его скетче предусмотреть задержку между включениями диодов? Т.к. от танцев с миллис пока далек ))
Зачем экономить пины (кроме случая, когда их не хватает - там-то понятно) зависит от задачи. Например, если важно одно включить, а другое выключить строго одновременно - только одним пином (или двумя, но строго на одном порте и в этом случае надо забыть о digitalWrite, а делать всё одной операцией с портом). Если включаете и выключаете двумя операциями digitalWrite, то между этими операциями неминуема задержка. А когда на одном пине (или одной операцией с портом) - всё реально одновременно.
Спасибо большое! Нет на свете ничего идеального (( Раньше, давно, забавлялся программками на VBA, писал макросы для Exel, так вот, делал программу, распечатывал ее на принтере и оптимизировал код. Бывало, что размер сокращался в 10 раз )).
А вопрос по теме - вставил я ваш код в свою программу, запустил, смотрю вроде не работает, попробовал залить отдельным скетчем, все ок. Снова залил свою программу задержки выставил на 1 сек., подождал, работает. Правда светодиоды моргают с задержкой примерно в 5 секунд. Может ли это быть следствием большого объема программы или где-то ошибка? (кривые руки)
Вообще дебаггер нужно поискать для ардуинки, а то что-то грустно методом тыка все.
Забудьте про большой объем программы. Это объяснение для нубов. Есть процессор. Он может выполнить определеное количество инструкций в секунду. Если вы криво напишете программу, дикие повторы, лишние петли, ненужные циклы, то ваш процессор просто не будет успевать это делать за определеное время, а значит тормозить. Возьмите общественный транспорт и такси. Расстояние одинаково но такси приходит быстрее не потому что маленькая, а потому что не делает кучу остановок на которых и еще и долго стоит. Ну да многие могут сказать, что в такси может сесть 5 человек, а в автобус 100. Значит автобус едет в 5 раз медленее. И еще тупее высказывание: если в такси и в автобусе по 5 человек, то они будут ехать одинаково.
Не знаю, буду смотреть. Я всю программу разбил по функциям, в loop они только вызываютсяпо одной кнопке. По идее если функция не вызвана, значит она не обрабатывается и не нагружает контроллер.
StasOn.Надо смотреть вашу программу. Но я не могу. Точнее после меня вы не сможете понять, как программа функционирует, а значить модернизировать в дальнейшем. Что сразу отправит программу на мусор.
Один из транзисторов всегда открыт, а второй всегда закрыт. В принципе, есть некий наносекундный переходный процесс, когда один ещё не до конца закрылся, а второй уже начал открываться. Если надо это минимизировать возьмите более быстрые транзисторы. Если же надо это исключить полностью и железно, то надо будет немного усложнить схему или плюнуть и перейти на два пина.
Евгений, при всём уважении, лучше эту схему убрать, а то начинающий какой вздумает собрать...
Один из транзисторов всегда открыт, а второй всегда закрыт. В принципе, есть некий наносекундный переходный процесс, когда один ещё не до конца закрылся, а второй уже начал открываться. Если надо это минимизировать возьмите более быстрые транзисторы. Если же надо это исключить полностью и железно, то надо будет немного усложнить схему или плюнуть и перейти на два пина.
Евгений, при всём уважении, лучше эту схему убрать, а то начинающий какой вздумает собрать...
Да. Для непонявших суть проблемы - рассмотрите ток из базы верхнего тр-ра в базу нижнего.
Спасибо, сделано уже в посте №139. Теперь бы ещё нашелся добрый админ и неправильные картинки удалил, чтобы никому мозги не пудрили. А, кстати, картинку я и сам кажется могу удалить. Щас попробую :)
В этой замечательной схеме, как говорилось, есть один момент. Когда пин находится в высокоимпедансном состоянии (Hi-Z), то светятся обе лампочки (или включены реле).
Если такое недопустимо, то нужно включить резисторы 220 Ом (навскидку номинал) между Б и Э каждого транз. В таком случае напряжение Б-Э при Hi-Z будет около 0.5 В и транз. будут закрыты.
В таком случае лампочки или не светятся или светится только одна из двух. Всего три состояния.
Чтобы получить 4 состояния, нужно схему подключить к пину, поддерживающий ШИМ, а параллельно лампочкам поставить конденсаторы по нескольку мкФ
1. обе светятся analogWrite(pin, 128);
2. обе не светятся pinMode(pin, INPUT);
3. светится одна analogWrite(pin, 0);
4. светится вторая analogWrite(pin, 255);
Всем доброго дня! В общем проблема такая - в скетче есть класс обработки кнопок который использует millis(), есть функция которая использует millis()(мигание светодиодов), если в функции loop() я просто включаю функцию мигания светодиода, то все ОК, если же я добавляю обработчик кнопки, то время горения светодиодов увеличивается в 5 раз.
Для мигания использовал скетч из сообщения #118 (пробовал другие)
Сейчас попробую вынести обработчик в отдельную функцию, посмотрю что получится, а всех, кто поможет дельным советом, как правильно выйти из этой ситуации, я заранее благодарю :)
const int Zar = 10; //время заряда
const unsigned long tZar = Zar * 1000UL;
const int Raz = 5; //время разряда
const unsigned long tRaz = Raz * 1000UL;
const int Paz = 1; //время паузы 1
const unsigned long tPaz = Paz * 1000UL;
byte mode = 0; // 0 заряд / 1 пауза1 / 2 разряд / 3 пауза2
void setup() {
pinMode (3, OUTPUT);
digitalWrite(3, 0);
pinMode (5, OUTPUT);
digitalWrite(5, 0);
}
void loop() {
static unsigned long past = 0;
if ((mode == 0) && millis() - past >= tPaz) { // Кончилась первая пауза начался разряд
past = millis();
mode = 1;
digitalWrite(3, LOW);
digitalWrite(5, HIGH);
}
if ((mode == 1) && millis() - past >= tRaz) { // Кончился разряд началась вторая пауза
past = millis();
mode = 2;
digitalWrite(3, LOW);
digitalWrite(5, LOW);
}
if ((mode == 2) && millis() - past >= tPaz) { // Кончилась вторая пауза начался заряд
past = millis();
mode = 3;
digitalWrite(3, HIGH);
digitalWrite(5, LOW);
}
if ((mode == 3) && millis() - past >= tZar) { // Кончился заряд началась первая пауза
past = millis();
mode = 0;
digitalWrite(3, LOW);
digitalWrite(5, LOW);
}
}
Всем Спасибо за помошь. Из обсуждения вынес много интересных и полезных вещей.)) Буду думать теперь над основной программой и оптимизацией. За любые советы и критику буду благодарен ))
static unsigned long previousMillis = 0; // храним время последнего переключения светодиода
if(millis() - previousMillis > INTERVAL) {
previousMillis = millis();
}
получается у нас диод маргнет только один раз ? точнее потом начнет переключаться с частотой процессора т.к. после первого србатывания if мы присваиваем previousMillis = millis(); но как только начинаем новый круг loop натыкаемся настрочку previousMillis = 0; получается после первой 1000 миллис у нас всегда if будет срабатывать т.к. previousMillis = 0 а millis() к этому времени будет много больше 1000. или я упускаю из виду чтото?
Упускаете, слово static делает переменную "глобальной", и при новом заходе в loop она не будет переинициализирована нулём, в ней будет значение от предыдущего loop-а.
после первого србатывания if мы присваиваем previousMillis = millis(); но как только начинаем новый круг loop натыкаемся настрочку previousMillis = 0; получается после первой 1000 миллис у нас всегда if будет срабатывать т.к. previousMillis = 0 а millis() к этому времени будет много больше 1000. или я упускаю из виду чтото?
Упускаете то, что previousMillis описан как static.
Вы каждый раз проверяете сигнал. Т.е. смотрите, двигатель включён. Доехали до концевика, увидели на нём сигнал, поехали обратно. Вот тут бы Вам ехать две секунды не обращая внимания на сигнал, и остановитья, но Вы продолжаете его (сигнал) проверять. В итоге, как только вы чуть-чуть отехали обратно, сигнал оказывается потерян и Вы опять дрыгаетесь вперёд.
Поятно? Не слишком запутанно?
По Вашему описанию все понятно, но что-то не получается у меня реализовать программно.....
Ну, думайте. Если никак, то показывайте.
Я просто не пойму, что не так в коде, что в 100 посте... Ведь вроде бы все просто сигнал есть - включи вперед на 2 сек и сбрось управление, нет - на 2 сек назад и опять сбрось управление. Этот концевик независим от двигателя. Пробовал добавлять флаги - не помогает....
Тяжело в деревне без нагана.Motor_lib.ino
Cl_Motor.h
Cl_Motor.cpp
Я просто не пойму, что не так в коде, что в 100 посте... Ведь вроде бы все просто сигнал есть - включи вперед на 2 сек и сбрось управление, нет - на 2 сек назад и опять сбрось управление. Этот концевик независим от двигателя. Пробовал добавлять флаги - не помогает....
Нет, ну Вы смотрите на код-то.
Давайте по шагам. Вот Вы в первый раз включили двигатель (строки 39-40). При этом Вы не стали запоминать время включения, а сразу стали сравнивать текущий милли с previousMillis, который у Вас 0. Влетели в блок 41-45 и выключили двигатель.
Может разумнее в момент включения двигателя запоминать время включения, чтоб от него, а не от нуля отсчитывать 2 сек?
Кроме того, в течение этих 2 секунд двигатель отъедет от концевика и стало быть условие в строке 38 перестанет выполняться. Значит, сравнивать время (в процессе ожидания 2 сек) надо где-то снаружи, а не внутри блока 38-46.
Тяжело в деревне без нагана.
Хорошо попразновали вчера? Даже завидно. Скорость у Вас задана раз и навсегда? Таким наганом только застрелиться!
Евгений, вот вынес я сравнение времени наружу и еще добавил флаги, а толка нет (проверяю в Протеусе), теперь пропала остановка по времени.
Уже перепробовал разные варианты, пересмотрел подобные примеры на форуме...
Да, нет, ничего Вы не вынесли. Строки 14-19 и 25-30 как были внутри других условия, так и остались.
Ну, если Вам трудно сходу (а поначлу всегда трудно), распишите на бумаге конечный автомат. Я не знаю точно Вашей задачи, поэтому могу только вчерне набросать как он выглядит, а Вы уж напишите как надо.
Для начала выписываем все состояния в котором бывает Ваш автомат. например:
1. Стоит
2. Едет влево (до упора)
3. Едет вправо (до упора)
4. Откатывается назад влево (2 сек)
5. Откатывается назад вправо (2 сек)
Выпишите все состояния, какие бывают, наверняка у Вас там ещё есть.
Дальше выпишите логику работы автомата в терминах состояний и переходов между ними. например.
Всё это хозяйство выполняется в бесконечном цикле (в loop()). Как видите, у меня получился автомат, который иногда стоит на месте, потом вдруг начинает ехать вправо или влево, доезжает до концевика, откатывается назад в течение 2 сек и снова, постояв немного, куда-нибудь едет.
Когда Вы это распишете, проверьте всё внимательно и если логика правильная, то пишите программу.
Заведите одну переменную для номера состояния и просто замените в этом словесном тексте все пассажи типа "поехать вправо", "остановиться", "достигнут концевик" и т.п. на соответсвующие команды и проверки. Например, слова "перейти в состояние N" выльются в простое присваивание числа N Вашей переменной состояния.
Евгений, спасибо Вам, - все получилось!!!
Извиняюсь, что не в тему, может кому понадобится - это управление автоматическими порогами на авто.
Один геркон на две двери (на каждую сторону). Открыли дверь - выдвинулся порог, закрыли - задвинулся. Так как защиты двигателей у меня нет, решил подавать питание на 1,5 - 2 сек. и сбрасывать его.
По ссылке файл для Proteus со схемой и программой.
http://my-files.ru/hnygkf
Не за что, с Победой!
Ребята, помогите разобраться с этим millis..
В общем ситуация такая, есть 2 реле, которые должны включатся отдельно друг от друга на разные периоды времени, которые задаются через переменные, а не объявляются сразу (задаются кнопками). В то время пока первое реле включено второе должно быть выключено и наоборот. Еще наверное нужно предусмотреть задержку (компенсацию) для включения и выключения реле чтобы они не сработали одновременно.
Время вводил в секундах, не могу понять, как перевести все в миллс, т.е. вроде бы время * 1000 но как же добавить пресловутый UL?
Уже с дисплеем разобрался и с кнопками, а вот с реле никак не получается (((
вроде бы время * 1000 но как же добавить пресловутый UL?
Большинство ларчиков открываются предельно просто: время * 1000ul
Блин, какая же приятная штука Delay, так все просто делается..
А вот с миллис разобраться не получается
Пока горит первый светодиод, второй собака 5 раз успевает мигнуть. Я понимаю, что не разобрался с уловиями, но чего-то уже голова пухнет.. Может поможет кто найти ошибку, чтобы работало как с Delay
Ну, Вы остудите голову (можно лёд приложить) и спокойно разберитесь чего Вы хотите. В первом скетче Вы их включаете по очереди, а во втором запустили мигать параллельно. Вот они параллельно и мигают. Нормально так все.
И, кстати, что делают while в строка 15 и 23? Оно у Вас всё равно исполняется только по одному разу, т.к. Вы previousMillis внутри цикла меняете. Тогда почему не использовать более простую конструкцию if?
Да, и ещё, если Вам реально нужно, чтобы светодиоды светились сменяя друг друга (один светится - второй - нет), это не так делается. Зачем для этого два пина? Вполне достаточно одного. Схема нужна?
Вы так говорите что в delay есть что-то плохое?
если ненадо кнопки опрашивать или выполнять парралельные работы то в делей нет ничего плохого.
Вы так говорите что в delay есть что-то плохое?
если ненадо кнопки опрашивать или выполнять парралельные работы то в делей нет ничего плохого.
В delay() все плохо. Кажущая простота выключает мозг у новичков. Это как вы заявили: В ворах ничего плохого нет- они чистят подобно уборщикам ваши карманы.
Вы правильно меня поняли, нужно чтобы светодиоды светились сменяя друг друга (один светится - второй - нет). Время свечения задается переменными. А 2 пина используются потому, что вместо светодиодов будет другая нагрузка - реле или транзистор. Буду благодарен, если объясните или покажете как проще это реализовать.
Если вы в упор не увидели мой скетч, то я тут бессилен.
Против Delay ничего не имею, но кнопки действительно нужно опрашивать, и еще выводить информацию. Просто очень удобная функция, жаль что накладывает ограничения.
Скетч видел, попробовал, спасибо огромное, все работает. Буду теперь разбираться, Как он работает ))
вместо делей можно использовать цикл такого вида, где tmot время задержки, но парралельности работы небудет
в цикл можно встроить опрос кнопок
вместо делей можно использовать цикл такого вида, где tmot время задержки, но парралельности работы небудет
Паралельность, диагоналность. Понапридумывали всякой туфты. millis это банальные часы. а функция millis() -"узнать время" и все. Delay же это временная пробка. Процессор нихрена не делает , потому что он занят важной работой "нихрена не делать 1 секунду".
Да, видимо думаю я не как программист, мог бы и догадаться управлять обоими светодиодами из одного оператора как у qwone, а я уперся и пытался обрабатывать их разными.. Чего только не делал, и операторы менял, и разносил по разным функциям, придумывал новые условия.. А все проще оказалось ))
StasOn. Я тоже не программист. А то что я влегкую написал так. Так это результат долгого прохождения по швабрам, граблям гвоздям и прочей хр**ни. И в результате я могу сказать точно: я до сих пор не могу писать вменяемые программы.Но это секрет. :)
А 2 пина используются потому, что вместо светодиодов будет другая нагрузка - реле или транзистор. Буду благодарен, если объясните или покажете как проще это реализовать.
Реле прямо на пине быть не может, значит транзистор, включающий реле. Тогда Вам стопудово достаточно одного пина. И управлять им проще будет.
Вот смотрите со светодиодом для начала:
Если Ваши светодиоды разных цветов, то, возможно, Вы захотите поставить им разные резисторы. Тогда можно так:
Ну, а с транзистором тоже самое. Я тут им нарисовал в качестве нагрузки лампочки накаливания - замените на реле или на что Вам там нужно.
Один из транзисторов всегда открыт, а второй всегда закрыт. В принципе, есть некий наносекундный переходный процесс, когда один ещё не до конца закрылся, а второй уже начал открываться. Если надо это минимизировать возьмите более быстрые транзисторы. Если же надо это исключить полностью и железно, то надо будет немного усложнить схему или плюнуть и перейти на два пина.
Процессор нихрена не делает , потому что он занят важной работой "нихрена не делать 1 секунду".
Ну, так уж и ни хрена! Это ж Вам не POWER_DOWN режим! Он честно крутится в цикле и добросовестно
осваивает бюджетперерабатывает электроэнергию в тепло :)За схемы спасибо! С одним пином на 2 светодиода хитро, но не подходит. Сначала я сделаю управление до конца, потом возьмусь за питание ,а потом за высоковольтную часть (нагрузка будет 15в и от 0,1 до 5 А, еще не решил что лучше, реле - громкие, медленные, зато есть и подключать не сложно, или транзисторы - тихие, быстрые, но надо вникать, схемотехника посложнее). А зачем пины экономить? Я конечно понимаю, что можно сэкономить на памяти и на ресурсах, но пока всего хватает.
Еще хотел спросить qwone можно ли в его скетче предусмотреть задержку между включениями диодов? Т.к. от танцев с миллис пока далек ))
Нельзя реле прямо на пин - транзисторы по-любому.
Зачем экономить пины (кроме случая, когда их не хватает - там-то понятно) зависит от задачи. Например, если важно одно включить, а другое выключить строго одновременно - только одним пином (или двумя, но строго на одном порте и в этом случае надо забыть о digitalWrite, а делать всё одной операцией с портом). Если включаете и выключаете двумя операциями digitalWrite, то между этими операциями неминуема задержка. А когда на одном пине (или одной операцией с портом) - всё реально одновременно.
Еще хотел спросить qwone можно ли в его скетче предусмотреть задержку между включениями диодов? Т.к. от танцев с миллис пока далек ))
ПС: Идеальным этот скетч не считаю. Это что бы быстрее разобрались
Спасибо большое! Нет на свете ничего идеального (( Раньше, давно, забавлялся программками на VBA, писал макросы для Exel, так вот, делал программу, распечатывал ее на принтере и оптимизировал код. Бывало, что размер сокращался в 10 раз )).
А вопрос по теме - вставил я ваш код в свою программу, запустил, смотрю вроде не работает, попробовал залить отдельным скетчем, все ок. Снова залил свою программу задержки выставил на 1 сек., подождал, работает. Правда светодиоды моргают с задержкой примерно в 5 секунд. Может ли это быть следствием большого объема программы или где-то ошибка? (кривые руки)
Вообще дебаггер нужно поискать для ардуинки, а то что-то грустно методом тыка все.
Забудьте про большой объем программы. Это объяснение для нубов. Есть процессор. Он может выполнить определеное количество инструкций в секунду. Если вы криво напишете программу, дикие повторы, лишние петли, ненужные циклы, то ваш процессор просто не будет успевать это делать за определеное время, а значит тормозить. Возьмите общественный транспорт и такси. Расстояние одинаково но такси приходит быстрее не потому что маленькая, а потому что не делает кучу остановок на которых и еще и долго стоит. Ну да многие могут сказать, что в такси может сесть 5 человек, а в автобус 100. Значит автобус едет в 5 раз медленее. И еще тупее высказывание: если в такси и в автобусе по 5 человек, то они будут ехать одинаково.
Не знаю, буду смотреть. Я всю программу разбил по функциям, в loop они только вызываютсяпо одной кнопке. По идее если функция не вызвана, значит она не обрабатывается и не нагружает контроллер.
StasOn.Надо смотреть вашу программу. Но я не могу. Точнее после меня вы не сможете понять, как программа функционирует, а значить модернизировать в дальнейшем. Что сразу отправит программу на мусор.
Наверное если промежутки должны быть точные то так?
Скажите, а может тормозить из-за того, что в программе присутствует класс для кнопок, который тоже использует millis?
надо смотреть. Если это мои классы, то они не тормозят.Если конечно к ним не подключены тормознутые обработчики .:)
[
Один из транзисторов всегда открыт, а второй всегда закрыт. В принципе, есть некий наносекундный переходный процесс, когда один ещё не до конца закрылся, а второй уже начал открываться. Если надо это минимизировать возьмите более быстрые транзисторы. Если же надо это исключить полностью и железно, то надо будет немного усложнить схему или плюнуть и перейти на два пина.
Евгений, при всём уважении, лучше эту схему убрать, а то начинающий какой вздумает собрать...
Евгений, при всём уважении, лучше эту схему убрать, а то начинающий какой вздумает собрать...
Да, спасибо, что заметили, но я теперь не могу удалить, т.к. Вы ответили на пост :(
Вообще, лучше не удалять, а исправить, но этого я теперь тоже не могу.
Исправлюсь здесь.
Вот работающая схема того же самого
[
Один из транзисторов всегда открыт, а второй всегда закрыт. В принципе, есть некий наносекундный переходный процесс, когда один ещё не до конца закрылся, а второй уже начал открываться. Если надо это минимизировать возьмите более быстрые транзисторы. Если же надо это исключить полностью и железно, то надо будет немного усложнить схему или плюнуть и перейти на два пина.
Евгений, при всём уважении, лучше эту схему убрать, а то начинающий какой вздумает собрать...
Да. Для непонявших суть проблемы - рассмотрите ток из базы верхнего тр-ра в базу нижнего.
[
ну да, базы разорвать, с баз в общую точку два резитора и на управление, сэкономить один резистор не удастся
Спасибо, сделано уже в посте №139. Теперь бы ещё нашелся добрый админ и неправильные картинки удалил, чтобы никому мозги не пудрили. А, кстати, картинку я и сам кажется могу удалить. Щас попробую :)
я тоже об этом подумал )))
В этой замечательной схеме, как говорилось, есть один момент. Когда пин находится в высокоимпедансном состоянии (Hi-Z), то светятся обе лампочки (или включены реле).
Если такое недопустимо, то нужно включить резисторы 220 Ом (навскидку номинал) между Б и Э каждого транз. В таком случае напряжение Б-Э при Hi-Z будет около 0.5 В и транз. будут закрыты.
В таком случае лампочки или не светятся или светится только одна из двух. Всего три состояния.
Чтобы получить 4 состояния, нужно схему подключить к пину, поддерживающий ШИМ, а параллельно лампочкам поставить конденсаторы по нескольку мкФ
1. обе светятся analogWrite(pin, 128);
2. обе не светятся pinMode(pin, INPUT);
3. светится одна analogWrite(pin, 0);
4. светится вторая analogWrite(pin, 255);
Всем доброго дня! В общем проблема такая - в скетче есть класс обработки кнопок который использует millis(), есть функция которая использует millis()(мигание светодиодов), если в функции loop() я просто включаю функцию мигания светодиода, то все ОК, если же я добавляю обработчик кнопки, то время горения светодиодов увеличивается в 5 раз.
Для мигания использовал скетч из сообщения #118 (пробовал другие)
Класс использовал http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-dlya-taktovoi-knopki (пробовал другие)
что не делал, пробема не уходит
Сейчас попробую вынести обработчик в отдельную функцию, посмотрю что получится, а всех, кто поможет дельным советом, как правильно выйти из этой ситуации, я заранее благодарю :)
Если есть желпние, то покопайся в этом #1074
Вот еще пакет https://yadi.sk/d/RW5tQtw-3J5ENA
Головной файл из этого пакета
Победил я наконец эту мигалку с миллис:
Всем Спасибо за помошь. Из обсуждения вынес много интересных и полезных вещей.)) Буду думать теперь над основной программой и оптимизацией. За любые советы и критику буду благодарен ))
получается у нас диод маргнет только один раз ? точнее потом начнет переключаться с частотой процессора т.к. после первого србатывания if мы присваиваем previousMillis = millis(); но как только начинаем новый круг loop натыкаемся настрочку previousMillis = 0; получается после первой 1000 миллис у нас всегда if будет срабатывать т.к. previousMillis = 0 а millis() к этому времени будет много больше 1000. или я упускаю из виду чтото?
Упускаете, слово static делает переменную "глобальной", и при новом заходе в loop она не будет переинициализирована нулём, в ней будет значение от предыдущего loop-а.
после первого србатывания if мы присваиваем previousMillis = millis(); но как только начинаем новый круг loop натыкаемся настрочку previousMillis = 0; получается после первой 1000 миллис у нас всегда if будет срабатывать т.к. previousMillis = 0 а millis() к этому времени будет много больше 1000. или я упускаю из виду чтото?
Упускаете то, что previousMillis описан как static.