Ок, хотя мне кажется, что запутываете Вы себя сами, собственной неуверенностью и только.
"Почему тогда во время паузы от 1 датчика, при срабатывании 2, пауза вроде как ставится с начала, НО и все равно выключение от двух датчиков!(как будто 1+2)"
Попробуйте с ручкой и бумажкой последовательно расписать что происходит в таком случае в программе. От момента срабатывания первого датчика и до начала выключения:
Нет, не верно. Смотрите по коду №219 внимательнее, давайте начну:
1. Сработал первый датчик: переменная цикла num=0, указатель cur смотрит на структуру fadesControl[0], условие 116 "да". Соответственно поля этой структуры настроили на "включение", установив ->step == 1 и остальные. А вот поля второй структуры fadesControl[1] .. как были так и остались .. не заданы никак. Тут они будут равны 0, ибо по включению память заполнена нулями (я бы на вашем месте проверил это утверждение или установил значение шагов в ноль, в setup() вместе с номерами пинов, что является "хорошим стилем").
Соответственно, двигаясь далее и при последующих входах в loop() тоже, для структуры [0] сработает условие "step>0" и исполнитель попаде на следующую проверку "лампа включена?" (129), которая при первом попадании даст "нет" и далее 140 "лампа выключается и выключена?", которая снова даст "нет" и попадаем на 148 - включение 1-й лампы на 1 шаг.
Второй проход по циклу (num=1) ничего не изменит, поскольку его "датчик" ещё НЕ сработал, и ни одна из проверок 123-126 не даст ответа "ДА" .. и так будет повторяться до тех пор пока яркость первой лампы не станет 255. Верно?
А как только яркость станет равна 255, сработает условие 129, и для структуры с num==0, номер лампы увеличится на 1 .. переход к следующей лампе (строка 131), и тут же далее попадаем на 132: проверка "это все лампы?" .. нет, была только первая. .. и переход к п.2 произойдет ТОЛЬКО после стольких повторов, пока в структуре fadesControl[0] номер lamp не станет равен max.
2. Включение завершено, состояние автоматов: .. и? Для автомата num=0, как только сработала проверка в строке 132, но до выполнения блока 133-138 имеем: step=1, lamp == max. А сразу после блока имеем: step= -1, lamp = 0, max = MAX_LED .. а в каком состоянии второй автомат? А как был step=0, так и остался, ибо его датчик ещё НЕ сработал. Плюсом время паузы пошло отсчитываться от этого момента (строка 134).
3. .. продолжайте вот так же детально, по строчкам.
3. Сработал второй датчик: переменная цикла num=1, указатель cur смотрит на структуру fadesControl[1], условие 116 "да". Соответственно поля этой структуры настроили на "включение", установив ->step = 1 и остальные. А вот поля второй структуры fadesControl[0] .. как были так и остались step= -1, lamp = 0, max = MAX_LED. (так как мы их не выключали)
Соответственно, двигаясь далее , для структуры [1] сработает условие "step>0" и исполнитель попадет на следующую проверку "лампа включена и яркость 255?" (129) - ДА, здесь мы попадаем на (132) и сразу получим ответ ДА, Так как лампы уже горят(от num=0 ) и сразу получим fadesControl[1] = max
Включение завершено, состояние автоматов: Для автомата num=0 останется как было (step= -1, lamp = 0, max = MAX_LED)
Для автомата num=1, как только сработала проверка в строке 132, но до выполнения блока 133-138 имеем: step=1, lamp == max. А сразу после блока имеем: step= -1, lamp = MAX_LED-1, max = -1
и общую паузу startedPause = millis();
Соответственно после паузы, здесь (cur->step < 0) && (millis() - startedPause >= WAIT_PAUSE) мы получим ответ ДА, и начнем выключение.
Последнее утверждение неверно, точнее неполно. В первой части, описанной мною, первый автомат (num==0) к моменту завершения паузы имеет step==-1, а стало быть будет выключать лампы со своего конца. Правильное последнее предложение выглядит так:
Соответственно, после паузы, мы получим ответ "да" для ОБОИХ автоматов и при num==0 И при num==1. Нет? :)
Ну, так и какой будет ответ на ваш вопрос: "Почему тогда во время паузы от 1 датчика, при срабатывании 2, пауза вроде как ставится с начала, НО и все равно выключение от двух датчиков!(как будто 1+2)" :)
А, заодно и на этот:
Цитата:
Arhat109-2 пишет: теперь переход в состояние включения НЕ производится при повторном срабатывании датчика во время паузы
.. Или это относится только к тому датчику, который включил эту паузу? :)
Ну, и соответственно (надеюсь разобрались почему такое происходит), Вы теперь можете предложить решение, "что делать?", нет? Предлагайте.
Второе предложение верно для ситуации "во время паузы сработал второй датчик" .. конечно. Раз его автомат ещё не включался, то его шаг =0 и первая часть условия даст "ДА", как Вы и отметили. Вторая часть - не проверяется, поскольку "ИЛИ" - вполне достаточно первого "ДА".
Подсказка: "сработал датчик" .. в этом блоке уже есть проверка на состояние "своего автомата" .. то ли он неактивен, то ли уже включается, то ли ждет паузу .. так ведь?
Что мешает на дополнить этот блок ещё и проверкой состояний "второго" автомата? Но .. тогда возникает вопрос: а какие состояния второго автомата в этот момент нам "интересны"?
.. "идет пауза от первого датчика .. сработал .. ВТОРОЙ .. что делать с .. первым?" (отрисовали таблицу состояний или так и забросили?) :)
Ну, наконец-то! :) А теперь надо ВНИМАТЕЛЬНО посмотреть что получится, если при "чужом" step<0 мы только продлим паузу .. смотрите: датчик1 - "включил всё и его [0].step<0, теперь сработал датчик2, он НЕ активен (==0) .. надо его прогонять, чтобы он потом выключал тоже 1+2 или раз второй датчик сработал уже в паузе, то он и будет выключать после паузы или будет выключать только первый датчик?
Ситуации:
1. все выключено, прошел чел "слева-направо" (Датчик1) .. лампы включились по ЕГО ХОДУ и после паузы также и выключились .. второй датчик как-бы и не участвовал;
2. Все выключено, пошли с обоих концов одноверменно .. тот, что сработает позже (не бывает "синхронно", помним, так ведь!), тоже запустит включение со своего конца (ибо ни один датчик не стоит <0) .. прошла пауза, выключаем 1+2 с двух сторон и одновременно.
3. Все выключено, прошел первый, загорелись лампы, пошла пауза .. прошел чел в обратном направлении .. и? Кто "потом" должен выключать лампы: первый или второй? :) Если первый, то можно тупо игнорировать срабатывание второго датчика во время паузы (у чужого step <0 И идет пауза), а если второй, то в этой ситуации надо "отключить" чужой автомат, сделав ему step==0. Но, тогда:
4. Прошел первый, в паузе прошли обратно .. первый автомат отключен, в этой паузе ещё раз прошли прямо .. вот уже и "второй автомат отключен" .. кто выключать будет? :)
1. Да, так и надо! (второй датчик как-бы и не участвовал;- мы его пересечем уже в паузе)
2.И тут ДА!(Нет паузы, значит так и надо 1+2 ! Нет? :) )
3. Кто включил и начал паузу первым, тот и главный, ему и выключать!
Аналогично должно быть если датчик2 был первым!
Если идет один чел, он в любом случае (если он конечно не человек метеор :)) пересечет 2 датчик, когда уже началась пауза. Тоесть мы должны включить ВСЕ лампы, до пересечения 2 датчика!(ну это уже опытным путем)
У меня вопрос к п.2:
Прошли 1+2, включили все, пауза пошла! Что будет потом, во время паузы когда пересечем любой датчик?
(По логике вроде ни чего, так как мы сохранили ОБА датчика, значит мы только продлим паузу или же не продлим)
:) Если "кто первый - тот и выключает", то это просто: Если при срабатывании датчика, другой датчик УЖЕ всё включил (ждет выключения, step<0 и идет пауза! п."в" #312), то тоже пропускаем запуск и тупо продляем паузу. А если другой датчик УЖЕ начал выключение (пауза кончилась, п."г" #312)? Как понимаю, его надо "перезапустить" на выключение заново ..
И, в этом случае, получаем эффект: первый прошел слева-направо, включил паузу .. во время паузы прошло 100500 человек справа-налево, но .. выключаться лампы будут от первого - слева-направо. Так, надо? :)
А ежели вот "кто последний тот и выключает", в этом разе лампы будут выключаться справа-налево .. как-бы оно понятно, кто последний прошел - за ним, в его порядке и выключаем.
Но тогда, при срабатывании датчика, если другой датчик всё включил (шаг другого автомата <0) и идет пауза, а равно, если он уже начал выключать (пауза кончилась), Мы можем его смело ставить в режим "неактивен", но при этом запускать себя на включение.И проверять идет или пауза в этом варианте как-бы и "без разницы". И последнее действие (запуск), уже есть в коде и оно важно как раз для предотвращения ситуации п.4. предыдущего моего поста. Остается только проверить "интерференцию" состояний:
1. Та проверка, что уже поставлена в код: запускает на включение свой автомат в случае, если он НЕ активен, или УЖЕ активен или Выключает лампы.
2. Нам надо её дополнить вариантом: "если чужой датчик все включил, то безактивировать его", а себя запустить на включение.
Получается, что если после п.1 мы воткнем проверку и действие:
и только потом будет код запускающий включение .. то наша задача - решена: сработала проверка "своего состояния" .. надо включаться. Проверяем чужое состояние, и ежели что - отменяем его выключение и далее запускаем себя на включение и далее переставляем паузу. Вроде "как надо"... нет?
А ежели вот "кто последний тот и выключает", в этом разе лампы будут выключаться справа-налево .. как-бы оно понятно, кто последний прошел - за ним, в его порядке и выключаем.
Ну вот смотрите;
Пошли, прошли 1, зажгли слево - направо, пауза началась до того как мы прошли 2
Прошли 2 и мы ж поменяем направление ламп, а зачем, если мы лампами должны проиди путь человека!?(куда идем туда включаем, затем выключаем ЗА ним)
И, в этом случае, получаем эффект: первый прошел слева-направо, включил паузу .. во время паузы прошло 100500 человек справа-налево, но .. выключаться лампы будут от первого - слева-направо. Так, надо? :)
-"Пап, а как убрать из условия ультразвуковой датчик? Я его снять хочу!"
-"Ну убери вместе с условием"
-"Так это, что? Мне придется полпрограммы изменять?!?"
-"Зачем? Вместо проверки результата по расстоянию поставь 2>1, оно же всегда больше, правда?"
-"А! Э.. у .. ничего ты хитрый какой!"
:)
---
Приведите весь скетч с этой вставкой заново, и не забудьте в setup() установить оба шага в 0, для верности.. а то, так уже нить алгоритма как-то потерялась.
Нет. "всё как надо" быть не может .. что такое 2-num, если num [0,1]? 2-0 = 2, 2-1=1 .. но управляющего автомата (fadesControl) с номером 2 - у нас "не в природе"! И .. эт-та .. куда подевался "свой" автомат, который через cur->?
Было вроде так:
if( digitalRead(cur->pir_pin) )
{
if( cur->step >= 0 || millis() - startedPause > WAIT_PAUSE )
{
// сюда попадаем если: а) неактивен (==0); б) включает (>0);
// ИЛИ: <0 (ничего из предыдущего!) И прошла пауза .. т.е. г) выключает
cur->step = 1;
cur->lamp = (num==0? 0 : MAX_LED-1);
cur->max = (num==0? MAX_LED : -1);
}
startedPause = millis();
}
ДОБАВИЛИ проверку "чужого автомата" .. а стало совсем не так .. как это? Вы же собирались ДОБАВИТЬ это:
ну так и добавьте. Зачем выкидывать то, что было? Кстати, выражение из ДРАКОН схемы Вы инвертировали неверно:
"(Шаг чужого датчика < 0) И (идет пауза)", это экв.: "(Шаг чужого датчика < 0) И (разница времен <= интервал)", инверируем:
"!((Шаг чужого датчика < 0) И (разница времен <= интервал))", раскрываем скобки: "!(Шаг чужого датчика < 0) !И !(разница времен <= интервал)", что экв.:
"(Шаг чужого датчика >= 0) ИЛИ (разница времен > интервал)" Вот с таким условием на ДРАКОН схеме можно поменять местами "ДА" и "НЕТ", не меняя икон. И соответственно такое условие можно добавить после проверки "своего" автомата .. ещё проверить и это..
И вот уже хорошо видно, что проверка "идет ли пауза" нам в loop() требуется уже трижды .. может её 1 раз заранее посчитать, учитывая что loop() пробегает ну очень быстро? Тогда "итого" получится:
#define fadePin1 3 // пин управления MOSFET транзистором
#define fadePin2 5 // пин управления MOSFET транзистором
#define fadePin3 6 // пин управления MOSFET транзистором
#define fadePin4 9 // пин управления MOSFET транзистором
#define fadePin5 10 // пин управления MOSFET транзистором
#define fadePin6 11 // пин управления MOSFET транзистором
#define pirPin1 2 // пин подключения управляющего сигнала PIR датчика1
#define pirPin2 4 // пин подключения управляющего сигнала PIR датчика2
int calibrationTime = 30; // Время калибровки датчика (10-60 сек. по даташиту)
// структура - описание понятия "Лампа" - это пин и текущая яркость:
typedef struct{
uint8_t pin;
uint8_t bright;
} Led;
typedef struct{
uint8_t pir_pin; // номер пина для датчика движения
char step; // бывшая переменная isGo, теперь это "шаг" изменения яркости.
char lamp; // номер текущей лампы, которой изменяем яркость
char max; // номер последней лампы (недосчитывая) ДО которой будем перебирать лампы
unsigned long startedAt; // начало текущей паузы шага изменения лампы
} FadeCycle;
FadeCycle fadeControl[2];
void setup()
{
fadeControl[0].pir_pin = pirPin1;
fadeControl[1].pir_pin = pirPin2;
fadeControl[0].step = 0;
fadeControl[1].step = 0;
pinMode(pirPin1, INPUT); // настариваем 2 пин как вход для сигналов с датчика
pinMode(pirPin2, INPUT); // настариваем 4 пин как вход для сигналов с датчика
pinMode(fadePin1, OUTPUT); // пины на выход, для управления транзисотором
pinMode(fadePin2, OUTPUT);
pinMode(fadePin3, OUTPUT);
pinMode(fadePin4, OUTPUT);
pinMode(fadePin5, OUTPUT);
pinMode(fadePin6, OUTPUT);
Serial.begin(9600);
Serial.print("Calibrating"); //дадим датчику время на калибровку
for(int i = 0; i < calibrationTime; i++)
{
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
}
// теперь создадим список ламп, заодно и введем константу "всего ламп"
#define MAX_LED 6
Led fades[MAX_LED] = {{fadePin1, 0}, {fadePin2, 0}, {fadePin3, 0},
{fadePin4, 0}, {fadePin5, 0}, {fadePin6, 0}};
#define WAIT_1 5 // 10мсек - пауза между изменениями яркости
uint32_t startedAt = 0; // тут будем хранить время последнего запуска fadeLed
#define WAIT_PAUSE 30000 // пауза когда MAX_LED=255
uint32_t startedPause = 0; // тут будем вести отсчет паузы до выключения
uint8_t isDayNow(void){ return 0; }
void fadeLED(uint8_t num)
{
Led * ptr = &(fades[fadeControl[num].lamp]); // врем. лок. указатель на структуру "лампа"
if(
millis() - fadeControl[num].startedAt >= WAIT_1 // пора изменять яркость?
&& (
(fadeControl[num].step==1 && ptr->bright < 255) // включаем И есть куда?
||
(fadeControl[num].step==-1 && ptr->bright > 0) // или вЫключаем И есть куда?
)
){
fadeControl[num].startedAt = millis(); // новое время для отсчета следующей паузы
ptr->bright += fadeControl[num].step; // изменяем яркость
analogWrite( ptr->pin, ptr->bright); // устанавливаем на выходе
Serial.print(" b="); Serial.println(ptr->bright); // передаем данные в порт для отладки
//if((( fadesControl[1-num].step<0 )&&( fadesControl[2-num].step<0 )) && (millis() - startedPause <= WAIT_PAUSE))
}
}
void loop()
{
// "ДА" -- пауза уже прошла, "НЕТ" - пауза ещё идет:
uint8_t isEndPause = (millis() - startedPause) > WAIT_PAUSE;
// if( isDayNow() ){ /*выключить всё*/ return; }
for(uint8_t num=0; num<2; num++)
{
FadeCycle * cur = &(fadeControl[num]);
if( digitalRead(cur->pir_pin) )
{
if(
(cur->step >= 0 && (fadesControl[1-num].step >= 0) // (неактивны или включают) .. оба (И!)
|| isEndPause // ИЛИ уже выключаем, без разницы каким способом!
){
cur->step = 1;
cur->lamp = (num==0? 0 : MAX_LED-1);
cur->max = (num==0? MAX_LED : -1);
}
}
startedPause = millis();
}
if(
(cur->step > 0) // если включаем лампы, то сразу
|| (
(cur->step < 0) // а вот если вЫключаем, то
&& isEndPause // по истечению паузы
)
){
if( cur->step > 0 && fades[cur->lamp].bright == 255 )
{
cur->lamp += (num==0? 1 : -1);
if( cur->lamp == cur->max )
{
startedPause = millis();
cur->step = -1;
cur->lamp = (num==0? 0 : MAX_LED-1);
cur->max = (num==0? MAX_LED : -1);
}
}else
if( cur->step < 0 && fades[cur->lamp].bright == 0 )
{
cur->lamp += (num==0? 1 : -1);
if( cur->lamp == cur->max )
{
cur->step = 0;
}
}else{
fadeLED(num); // теперь сюда передаем номер группы!
}
}
} // end for
} // end loop
Если "одно", то { Если "другое", то { тут что-то делаем }} эксвивалентно: Если ("одно" И "другое"), то { тут что-то делаем }
А если ставить "по отдельности", то:
Если "одно", то { тут что-то делаем }. Если "другое", то { тут что-то делаем }. То "тут что-то делаем" надо писать дважды, и оно будет делаться как при первом "ДА", так и при втором "ДА" независимо друг от друга. То есть эквивалетно: Если ("одно" ИЛИ "другое"), то { тут что-то делаем }.
Наверно поэтому .. не могу точнее сказать, поскольку остается так и непонятным КАК вы это пробовали "по отдельности"...
Не совсем. указатель cur в процессе обхода цикла по автоматам принимает адрес 0-го автомата и потом 1-го. Соответственно, трактовать cur->step надо как "текущий шаг", то есть если num=0 при первом проходе, то это "датчик1", а если num=1 при втором проходе, то это "датчик2". А вот 1-num дает "чужой" датчик при каждом проходе: num=0, 1-num=1 то есть, когда "свой" это "датчик1", то "чужой" это "датчик2" и наоборот при втором проходе.
Данное логическое выражение является упрощением вида: (A or B) and (C or B), раскрывая скобки получим: (A and C) or (A and B) or (C and B) or (B and B), где последнее выражение это просто B, а второе и третье не зависят ни от А ни от С и поэтому их просто выбрасываем
, итого: (A or B) and (C or B) = (A and C) or B, что там и сделано.
Ну и "только одна проверка" будет работать только с одним датчиком. Поэтому и не работало или так не работало или эдак.
Надеюсь, теперь всё работает "как надо"? :)
P.S. Вот ежели бы Вы ещё в районе поста 28 сделали детальный разбор состояний, с составлением той самой таблички состояний, вместо того чтобы сразу кодить .. это результат можно было бы получить значительно быстрей. Но, мне кажется что и так оно тоже пошло на пользу.
P.S. Вот ежели бы Вы ещё в районе поста 28 сделали детальный разбор состояний, с составлением той самой таблички состояний, вместо того чтобы сразу кодить .. это результат можно было бы получить значительно быстрей. Но, мне кажется что и так оно тоже пошло на пользу.
Ага, работает! :)
Так мне кажется даже нагляднее вышло, я понял какие состояния могут быть, до этого для меня было только;
Включили пауза выключили)
Сейчас еще разберусь с яркостью не по +1 и когда 1+2 выключать от центра надо, красявее будет! :)
Понял откуда задержка, если датчик постоянно активен, включение как бы откладывается! Но тут без Arhat109-2 я точно не разберусь! А он куда то пропал, покинул нас что ли, или в отпуске! :)
На самом деле, Вы вполне способны разобраться самостоятельно, просто почему-то боитесь. Смелее и всё у Вас получится я видел ваши "слезы о помощи", но не стал отвечать именно по этой причине, смелее: "не боги горшки обжигают". :)
Не боги, согласен! Но пока как то не получается, пытаюсь! Все собрал уже как должно быть"в железе", все работает. Видимо чуть мозгов не хватает, или думаю не в ту сторону!:)
И на эти вопросы Вы теперь вполне можете ответить самостоятельно. Смелее. :)
Я так думаю, что надо как то "разъеденить" датчики, что бы получить три автомата, датчик№1, датчик№2 и датчик №1+2
теперь переход в состояние включения НЕ производится при повторном срабатывании датчика во время паузы
Вот это разве не ЭТО?
Или это относится только к тому датчику, который включил эту паузу?
Хотя я думаю что это должно относиться ко всем датчикам!
И на эти вопросы Вы теперь вполне можете ответить самостоятельно. Смелее. :)
Сомневаюсь! :(
Я еще больше запутался, чем раньше!
Ок, хотя мне кажется, что запутываете Вы себя сами, собственной неуверенностью и только.
"Почему тогда во время паузы от 1 датчика, при срабатывании 2, пауза вроде как ставится с начала, НО и все равно выключение от двух датчиков!(как будто 1+2)"
Попробуйте с ручкой и бумажкой последовательно расписать что происходит в таком случае в программе. От момента срабатывания первого датчика и до начала выключения:
1. Сработал первый датчик: ...
2. Включение завершено, состояние автоматов: ..
3. Идет пауза, сработал второй датчик: ..
4. Новая пауза кончилась: ..
Выкладывайте что получается.
1. Сработал первый датчик: шаг=1, начальная лампа(1), яркость +
2. Включение завершено, состояние автоматов: шаг=1, последняя лампа(1), пауза
3. Идет пауза, сработал второй датчик: шаг=1, начальная лампа(2), яркость +;
шаг=1, последняя лампа(1), последняя лампа(2),
4. Новая пауза кончилась: шаг = - 1, начальная лампа(1), яркость -
начальная лампа(2), яркость -
Я вижу так...
Нет, не верно. Смотрите по коду №219 внимательнее, давайте начну:
1. Сработал первый датчик: переменная цикла num=0, указатель cur смотрит на структуру fadesControl[0], условие 116 "да". Соответственно поля этой структуры настроили на "включение", установив ->step == 1 и остальные. А вот поля второй структуры fadesControl[1] .. как были так и остались .. не заданы никак. Тут они будут равны 0, ибо по включению память заполнена нулями (я бы на вашем месте проверил это утверждение или установил значение шагов в ноль, в setup() вместе с номерами пинов, что является "хорошим стилем").
Соответственно, двигаясь далее и при последующих входах в loop() тоже, для структуры [0] сработает условие "step>0" и исполнитель попаде на следующую проверку "лампа включена?" (129), которая при первом попадании даст "нет" и далее 140 "лампа выключается и выключена?", которая снова даст "нет" и попадаем на 148 - включение 1-й лампы на 1 шаг.
Второй проход по циклу (num=1) ничего не изменит, поскольку его "датчик" ещё НЕ сработал, и ни одна из проверок 123-126 не даст ответа "ДА" .. и так будет повторяться до тех пор пока яркость первой лампы не станет 255. Верно?
А как только яркость станет равна 255, сработает условие 129, и для структуры с num==0, номер лампы увеличится на 1 .. переход к следующей лампе (строка 131), и тут же далее попадаем на 132: проверка "это все лампы?" .. нет, была только первая. .. и переход к п.2 произойдет ТОЛЬКО после стольких повторов, пока в структуре fadesControl[0] номер lamp не станет равен max.
2. Включение завершено, состояние автоматов: .. и? Для автомата num=0, как только сработала проверка в строке 132, но до выполнения блока 133-138 имеем: step=1, lamp == max. А сразу после блока имеем: step= -1, lamp = 0, max = MAX_LED .. а в каком состоянии второй автомат? А как был step=0, так и остался, ибо его датчик ещё НЕ сработал. Плюсом время паузы пошло отсчитываться от этого момента (строка 134).
3. .. продолжайте вот так же детально, по строчкам.
Разработку программы лучше выполнить после или одновременно с разработкой алгоритма, с использованием блок-схем формируемых в ИС Дракон.
С Дракон-схемами затратите меньше времени, чем на словесное описание взаимодействия.
Программа ИС Дракон используется продолжительное время и отработана с пользователями.
Если по программе ИС Дракон у Вас есть вопросы или сложности, то пишите здесь, я могу дать пояснения и рекомендации.
3. Идет пауза, сработал второй датчик:
3. .. продолжайте вот так же детально, по строчкам.
Так он же делает то же самое, только со своими значениями(и плюс значения от первого)! Или я не прав?
Не знаю .. вы же не расписали пока ещё. :)
3. Сработал второй датчик: переменная цикла num=1, указатель cur смотрит на структуру fadesControl[1], условие 116 "да". Соответственно поля этой структуры настроили на "включение", установив ->step = 1 и остальные. А вот поля второй структуры fadesControl[0] .. как были так и остались step= -1, lamp = 0, max = MAX_LED. (так как мы их не выключали)
Соответственно, двигаясь далее , для структуры [1] сработает условие "step>0" и исполнитель попадет на следующую проверку "лампа включена и яркость 255?" (129) - ДА, здесь мы попадаем на (132) и сразу получим ответ ДА, Так как лампы уже горят(от num=0 ) и сразу получим fadesControl[1] = max
Включение завершено, состояние автоматов: Для автомата num=0 останется как было (step= -1, lamp = 0, max = MAX_LED)
Для автомата num=1, как только сработала проверка в строке 132, но до выполнения блока 133-138 имеем: step=1, lamp == max. А сразу после блока имеем: step= -1, lamp = MAX_LED-1, max = -1
и общую паузу startedPause = millis();
Соответственно после паузы, здесь (cur->step < 0) && (millis() - startedPause >= WAIT_PAUSE) мы получим ответ ДА, и начнем выключение.
Последнее утверждение неверно, точнее неполно. В первой части, описанной мною, первый автомат (num==0) к моменту завершения паузы имеет step==-1, а стало быть будет выключать лампы со своего конца. Правильное последнее предложение выглядит так:
Соответственно, после паузы, мы получим ответ "да" для ОБОИХ автоматов и при num==0 И при num==1. Нет? :)
Ну, так и какой будет ответ на ваш вопрос: "Почему тогда во время паузы от 1 датчика, при срабатывании 2, пауза вроде как ставится с начала, НО и все равно выключение от двух датчиков!(как будто 1+2)" :)
А, заодно и на этот:
Ну, и соответственно (надеюсь разобрались почему такое происходит), Вы теперь можете предложить решение, "что делать?", нет? Предлагайте.
Ну то что я забыл что оба датчика объеденены, но так и остались num==0 И num==1
Получается что, для второго датчика, вроде как и ни чего не включалось, так как шаг у каждого свой!
Соответственно здесь ответ ДА, так как шаг=0 для num=1
Но.....:(
Я думаю надо спросить шаг конкретно или для num=0 или num=1
Ни чё не понял .. ещё раз и детальнее.
Второе предложение верно для ситуации "во время паузы сработал второй датчик" .. конечно. Раз его автомат ещё не включался, то его шаг =0 и первая часть условия даст "ДА", как Вы и отметили. Вторая часть - не проверяется, поскольку "ИЛИ" - вполне достаточно первого "ДА".
Я просто не учел, что num у нас 2 штуки, и что от первого сработавшего мы храним переменные!
Уже лучше. :)
И теперь, Ваши предложения КАК решить вопрос со вторым датчиком, сработавшим во время паузы? :)
Я думаю как то надо не передавать переменные от второго датчика, во время паузы! Но как еще незнаю!
Подсказка: "сработал датчик" .. в этом блоке уже есть проверка на состояние "своего автомата" .. то ли он неактивен, то ли уже включается, то ли ждет паузу .. так ведь?
Что мешает на дополнить этот блок ещё и проверкой состояний "второго" автомата? Но .. тогда возникает вопрос: а какие состояния второго автомата в этот момент нам "интересны"?
.. "идет пауза от первого датчика .. сработал .. ВТОРОЙ .. что делать с .. первым?" (отрисовали таблицу состояний или так и забросили?) :)
Мысли;
Если для num[0] step= -1, значит мы включили лампы от num[0] и идет пауза,
сработал num[1] step=0, значит он нам не нужен, но он должен продлить паузу
Я так думаю здесь важен не только step, но и от какого автомата он.
Ну, наконец-то! :) А теперь надо ВНИМАТЕЛЬНО посмотреть что получится, если при "чужом" step<0 мы только продлим паузу .. смотрите: датчик1 - "включил всё и его [0].step<0, теперь сработал датчик2, он НЕ активен (==0) .. надо его прогонять, чтобы он потом выключал тоже 1+2 или раз второй датчик сработал уже в паузе, то он и будет выключать после паузы или будет выключать только первый датчик?
Ситуации:
1. все выключено, прошел чел "слева-направо" (Датчик1) .. лампы включились по ЕГО ХОДУ и после паузы также и выключились .. второй датчик как-бы и не участвовал;
2. Все выключено, пошли с обоих концов одноверменно .. тот, что сработает позже (не бывает "синхронно", помним, так ведь!), тоже запустит включение со своего конца (ибо ни один датчик не стоит <0) .. прошла пауза, выключаем 1+2 с двух сторон и одновременно.
3. Все выключено, прошел первый, загорелись лампы, пошла пауза .. прошел чел в обратном направлении .. и? Кто "потом" должен выключать лампы: первый или второй? :) Если первый, то можно тупо игнорировать срабатывание второго датчика во время паузы (у чужого step <0 И идет пауза), а если второй, то в этой ситуации надо "отключить" чужой автомат, сделав ему step==0. Но, тогда:
4. Прошел первый, в паузе прошли обратно .. первый автомат отключен, в этой паузе ещё раз прошли прямо .. вот уже и "второй автомат отключен" .. кто выключать будет? :)
1. Да, так и надо! (второй датчик как-бы и не участвовал;- мы его пересечем уже в паузе)
2.И тут ДА!(Нет паузы, значит так и надо 1+2 ! Нет? :) )
3. Кто включил и начал паузу первым, тот и главный, ему и выключать!
Аналогично должно быть если датчик2 был первым!
Если идет один чел, он в любом случае (если он конечно не человек метеор :)) пересечет 2 датчик, когда уже началась пауза. Тоесть мы должны включить ВСЕ лампы, до пересечения 2 датчика!(ну это уже опытным путем)
У меня вопрос к п.2:
Прошли 1+2, включили все, пауза пошла! Что будет потом, во время паузы когда пересечем любой датчик?
(По логике вроде ни чего, так как мы сохранили ОБА датчика, значит мы только продлим паузу или же не продлим)
:) Если "кто первый - тот и выключает", то это просто: Если при срабатывании датчика, другой датчик УЖЕ всё включил (ждет выключения, step<0 и идет пауза! п."в" #312), то тоже пропускаем запуск и тупо продляем паузу. А если другой датчик УЖЕ начал выключение (пауза кончилась, п."г" #312)? Как понимаю, его надо "перезапустить" на выключение заново ..
И, в этом случае, получаем эффект: первый прошел слева-направо, включил паузу .. во время паузы прошло 100500 человек справа-налево, но .. выключаться лампы будут от первого - слева-направо. Так, надо? :)
А ежели вот "кто последний тот и выключает", в этом разе лампы будут выключаться справа-налево .. как-бы оно понятно, кто последний прошел - за ним, в его порядке и выключаем.
Но тогда, при срабатывании датчика, если другой датчик всё включил (шаг другого автомата <0) и идет пауза, а равно, если он уже начал выключать (пауза кончилась), Мы можем его смело ставить в режим "неактивен", но при этом запускать себя на включение.И проверять идет или пауза в этом варианте как-бы и "без разницы". И последнее действие (запуск), уже есть в коде и оно важно как раз для предотвращения ситуации п.4. предыдущего моего поста. Остается только проверить "интерференцию" состояний:
1. Та проверка, что уже поставлена в код: запускает на включение свой автомат в случае, если он НЕ активен, или УЖЕ активен или Выключает лампы.
2. Нам надо её дополнить вариантом: "если чужой датчик все включил, то безактивировать его", а себя запустить на включение.
Получается, что если после п.1 мы воткнем проверку и действие:
if( fadesControl[1-num].step<0 ){ fadesControl[1-num],step = 0; }
и только потом будет код запускающий включение .. то наша задача - решена: сработала проверка "своего состояния" .. надо включаться. Проверяем чужое состояние, и ежели что - отменяем его выключение и далее запускаем себя на включение и далее переставляем паузу. Вроде "как надо"... нет?
А если другой датчик УЖЕ начал выключение (пауза кончилась, п."г" #312)? Как понимаю, его надо "перезапустить" на выключение заново ..
Вот тут малость не понял!
Это же ПОСЛЕ паузы! Здесь как бы включаем заново!
А ежели вот "кто последний тот и выключает", в этом разе лампы будут выключаться справа-налево .. как-бы оно понятно, кто последний прошел - за ним, в его порядке и выключаем.
Ну вот смотрите;
Пошли, прошли 1, зажгли слево - направо, пауза началась до того как мы прошли 2
Прошли 2 и мы ж поменяем направление ламп, а зачем, если мы лампами должны проиди путь человека!?(куда идем туда включаем, затем выключаем ЗА ним)
И, в этом случае, получаем эффект: первый прошел слева-направо, включил паузу .. во время паузы прошло 100500 человек справа-налево, но .. выключаться лампы будут от первого - слева-направо. Так, надо? :)
да хоть 100501 человек :) Да, так и надо!
Вот так надо!
Делайте! (можно и так тоже) :)
Если так то это проверка только одного датчика! Так?
Кстати не кушает компилятор это :(
усе, скушал, буква лишняя одноко s :)
ну как написали.. почему нет-то?
ага, вот оно как :)
А как второй добавить незнаю!
Примерно с полчаса назад:
-"Пап, а как убрать из условия ультразвуковой датчик? Я его снять хочу!"
-"Ну убери вместе с условием"
-"Так это, что? Мне придется полпрограммы изменять?!?"
-"Зачем? Вместо проверки результата по расстоянию поставь 2>1, оно же всегда больше, правда?"
-"А! Э.. у .. ничего ты хитрый какой!"
:)
---
Приведите весь скетч с этой вставкой заново, и не забудьте в setup() установить оба шага в 0, для верности.. а то, так уже нить алгоритма как-то потерялась.
Если по одному датчики срабатывают, то все как надо!
а вот 1+2 теперь нет, и когда выключение, такой сырбор получился, жуть! :)
Нет. "всё как надо" быть не может .. что такое 2-num, если num [0,1]? 2-0 = 2, 2-1=1 .. но управляющего автомата (fadesControl) с номером 2 - у нас "не в природе"! И .. эт-та .. куда подевался "свой" автомат, который через cur->?
Было вроде так:
ДОБАВИЛИ проверку "чужого автомата" .. а стало совсем не так .. как это? Вы же собирались ДОБАВИТЬ это:
ну так и добавьте. Зачем выкидывать то, что было? Кстати, выражение из ДРАКОН схемы Вы инвертировали неверно:
"(Шаг чужого датчика < 0) И (идет пауза)", это экв.: "(Шаг чужого датчика < 0) И (разница времен <= интервал)", инверируем:
"!((Шаг чужого датчика < 0) И (разница времен <= интервал))", раскрываем скобки: "!(Шаг чужого датчика < 0) !И !(разница времен <= интервал)", что экв.:
"(Шаг чужого датчика >= 0) ИЛИ (разница времен > интервал)" Вот с таким условием на ДРАКОН схеме можно поменять местами "ДА" и "НЕТ", не меняя икон. И соответственно такое условие можно добавить после проверки "своего" автомата .. ещё проверить и это..
Получится:
И вот уже хорошо видно, что проверка "идет ли пауза" нам в loop() требуется уже трижды .. может её 1 раз заранее посчитать, учитывая что loop() пробегает ну очень быстро? Тогда "итого" получится:
Я думал что так мы проверим и 1 и 2 датчики!
и опять забыл что они не 1 и 2, а 0 и 1
Поясните почему эти условия работают только вместе как надо?
Я делал их отдельно, а так мозга не хватило!
Если "одно", то { Если "другое", то { тут что-то делаем }} эксвивалентно: Если ("одно" И "другое"), то { тут что-то делаем }
А если ставить "по отдельности", то:
Если "одно", то { тут что-то делаем }. Если "другое", то { тут что-то делаем }. То "тут что-то делаем" надо писать дважды, и оно будет делаться как при первом "ДА", так и при втором "ДА" независимо друг от друга. То есть эквивалетно: Если ("одно" ИЛИ "другое"), то { тут что-то делаем }.
Наверно поэтому .. не могу точнее сказать, поскольку остается так и непонятным КАК вы это пробовали "по отдельности"...
Я ставил или одну верхнюю или нижнюю! Только одну!
А тут не пойму как работает! (Проверяем шаг не важно от какого датчика >= 0 && (проверяем шаг датчика 1 >= 0 ) ИЛИ (разница времен > интервал)
или нет?
Не совсем. указатель cur в процессе обхода цикла по автоматам принимает адрес 0-го автомата и потом 1-го. Соответственно, трактовать cur->step надо как "текущий шаг", то есть если num=0 при первом проходе, то это "датчик1", а если num=1 при втором проходе, то это "датчик2". А вот 1-num дает "чужой" датчик при каждом проходе: num=0, 1-num=1 то есть, когда "свой" это "датчик1", то "чужой" это "датчик2" и наоборот при втором проходе.
Данное логическое выражение является упрощением вида: (A or B) and (C or B), раскрывая скобки получим: (A and C) or (A and B) or (C and B) or (B and B), где последнее выражение это просто B, а второе и третье не зависят ни от А ни от С и поэтому их просто выбрасываем
, итого: (A or B) and (C or B) = (A and C) or B, что там и сделано.
Ну и "только одна проверка" будет работать только с одним датчиком. Поэтому и не работало или так не работало или эдак.
Надеюсь, теперь всё работает "как надо"? :)
P.S. Вот ежели бы Вы ещё в районе поста 28 сделали детальный разбор состояний, с составлением той самой таблички состояний, вместо того чтобы сразу кодить .. это результат можно было бы получить значительно быстрей. Но, мне кажется что и так оно тоже пошло на пользу.
Надеюсь, теперь всё работает "как надо"? :)
P.S. Вот ежели бы Вы ещё в районе поста 28 сделали детальный разбор состояний, с составлением той самой таблички состояний, вместо того чтобы сразу кодить .. это результат можно было бы получить значительно быстрей. Но, мне кажется что и так оно тоже пошло на пользу.
Ага, работает! :)
Так мне кажется даже нагляднее вышло, я понял какие состояния могут быть, до этого для меня было только;
Включили пауза выключили)
Сейчас еще разберусь с яркостью не по +1 и когда 1+2 выключать от центра надо, красявее будет! :)
Ребят, все-таки без Вас мне пока не справиться! :(
После включения первой лампы, пауза какая то, секунды 2-3, потом все остальные лампы включаются как надо, без задержек!
Понял откуда задержка! И она почему то только на 2 пине! Пока датчик посылает сигнал, включение остальных 5 ламп не происходит!
что за беда?
Пока только просматриваю тему. Здесь используется Дракон - круто!
Понял откуда задержка, если датчик постоянно активен, включение как бы откладывается! Но тут без Arhat109-2 я точно не разберусь! А он куда то пропал, покинул нас что ли, или в отпуске! :)
А он куда то пропал, покинул нас что ли, или в отпуске! :)
Arhat109-2 проебался.
Ну в общем-то "покинул" ..
На самом деле, Вы вполне способны разобраться самостоятельно, просто почему-то боитесь. Смелее и всё у Вас получится я видел ваши "слезы о помощи", но не стал отвечать именно по этой причине, смелее: "не боги горшки обжигают". :)
Ну в общем-то "покинул" ..
"не боги горшки обжигают". :)
Что так то?
Не боги, согласен! Но пока как то не получается, пытаюсь! Все собрал уже как должно быть"в железе", все работает. Видимо чуть мозгов не хватает, или думаю не в ту сторону!:)