код - можно ли проще?

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

"ИС Дракон" - ну я его не понял :(

Так я правильно понимаю, что каждое действие это ветка; датчик, включение, пауза, выключение!?

начал вроде понимать :)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

И снова: "Датчик света" - выбор "темно" - поменяйте местами "Да" и "Нет" и нижняя ветка - маркер "Датчик света" .. "Царская дорога" - есть прямая. :)

Далее, ветка "Датчик1" - выбор "есть Движение?" тоже надо сделать рокировку условий и на "нет" - маркер "Датчик2", а на "да" - 1 икона Действие (а лучше 3): "Начинаем включение" с действиями: установить "начальную лампу", "установить шаг", "запретить паузу" и маркер "Включение ламп". Или как у вас "Включение1", если ветки разносите по отдельности.

Далее, ветка "Включение1" или "включение ламп": сначала проверяем "Лампа включена?" вот тут вниз идет ветка "нет" и икона-вставка (ибо вызов функции включения) "включаем текущую лампу" и маркер "Датчик2", а в ветке "да" ставим сначала действие "переход на след. лампу" и потом выбор "Все лампы?", с выбором "нет" вниз иконы на маркер "Датчик2" а вправо "да" и в этой ветке икона-действие (а лучше 3): "включить паузу", "установить лампу выключения", "установить шаг выключения" и маркер "датчик2".

Далее повтор тех же веток для датчика2: "датчик2" и "включение2" с маркерами вместо "датчик2" -> "Пауза".

А вот ветка пауза - тут последняя и она сторится точно также: всегда вниз рисуем тот выбор, что предпочтительнее (проще, чаще) по алгоритму - его локальная "царская дорога", а вправо то, что происходит реже, зависит от предыдущих веток и их выборов и установок.

Ну и я бы рисовал сразу все эти ветки внутри цикла датчиков, а сами ветки как части конечного автомата или в блоке "исполнять паралелльно", а не силуэта. Силуэт - только как тренировка. Но, давайте дорисуем, поскольку подходы тут - это и есть построение "абстракного алгоритма" и крайне полезны при решении любых задач и не только в программировани.

Для программиста это - по сути "билет в профессию" (почему надо рисовать алгоритм так, а не иначе).. Дерзайте. :)

 

 

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

 

Для программиста это - по сути "билет в профессию" (почему надо рисовать алгоритм так, а не иначе).. Дерзайте. :)

 

 

Да мне как бы он и без надобности :) простой интерес, не более! Но, очень интересно! ;) Потому и сижу, дерзаю!:)

А иногда думается, надо было просто заплатить людям денег, и пусть напишут и все! Так как врядли мне еще это пригодится! :)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Это кажется. Алгоритмирование своей деятельности по жизни встречается куда как чаще, чем ожидается. И как обычно "вход - рупь, выход - два". :) Сегодня сами сделали себе освещение .. завтра понадобится сваять расчетик в Экселе .. послезавтра, а почему бы автовыключалку света в ванее/туалете не забабахать .. и т.д.

Вот ДРАКОН как "чистый алгоритмизатор" как раз в помощь. Там ещё книжки есть и не менее полезные. По сути, все положения языка направлены на создание изначально оптимальных алгоритмов .. только и всего. Тут мы с вами пробуем и показываем остальным КАК можно этот подохд применять к разработке программ .. сразу правильных а не "как улучшить мой полет мысли". :)

На ДРАКОН очень неплохо упорядочивать выдачу заданий подчиненным (та самая извечная мячта всех разработчиков получить вменяемое ТЗ взамен "хотелок") .. и мн. др. применений "кроме программирования". И его недаром уже столько лет пользуют в космических разработках .. процитирую: "мне инженер-электронщик, не программист ни разу, приносит блок-схему своего устройства на ДРАКОН, я эту схему тупо перевожу в программу .. и оно работает сразу". Это та, "серая лошадка", которая всё время космических гонок позволяла СССР выходит вперед, имея на порядок и то и 2 меньшие затраты на разработку.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Ну тут я с Вами согласен, есть еще пару задумок! ;)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Ветка Датчик света!

Правельнее адрес этой ветки указывать на выход или же зациклить?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну .. раз у нас Силуэт, то наверно на "выход"..

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

"Выход" это же по сути окончание loop и возврат в начало(так как loop это безконечный цикл). Верно?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Тут, да. Такое можно допустить именно по причине того что loop() вызывается постоянно без вашего участия.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

А ветки должны идти вниз, когда режим ожидания?

датчик света - темно,

датчик 1 - движения нет, паузы нет,

датчик 2 - движения нет, паузы нет,

выход на датчик света.

так должно быть основное!?

 Это же самый короткий путь!

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Решил пока делать одним датчиком, путаюсь пока! :(

Вроде так!?

хотя уже сам косяк нашел, иконы 33 и 34 надо поменять местами! и вопрос ДА/НЕТ

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Короче совсем запутался! :(

Причем здесь датчик 2 если включение 1 ? Или это проверка датчика 2?

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

объеденил ветки "включение ламп"

Правильны оба варианта в программе! А как правельнее то?

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Вроде рабочий вариант! Незнаю как целиком залить!:(

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Вау .. практически повторили то, что собирался вам выложить. Да, примерно так.

Пост #263: второй вариант - правильней, но после иконы 90 надо ещё добавить "включить паузу". Вы же должны зафиксировать время начала отсчета паузы или нет, где? :) Аналогично ветка выключения ламп будет правильна по второму варианту с иконой "остановить работу ламп" (step=0).

Пост №264: Ветка "пауза": после маркера икона с выбором "прошла пауза?" И префиксной иконой слева "ждать 3 минуты", а вот ветки выбор "выключение" по вашей логике ТЗ "быть не должно" как самостоятельной ветки. Она должна быть внутри ветки "Пауза", потому как: если сработал снова датчик, то запрещаем паузу" .. а не "выключение". Если ветка выключения стоит ВНЕ паузы, то процесс продолжится, хотя сама пауза будет запрещена.

В нем же: икона 22 какую роль играет в факте срабатывания датчика? Она приводит к игнорированию срабатывания датчика когда все лампы включены и идет отсчет паузы. А надо бы "продлить паузу" .. может быть "да" направить в разрыв 82 и 84 икон? И тогда, может быть, икона "запретить паузу" будет исполнять то же самое действие что и при "включении паузы" - просто фиксировать текущее время в переменной для "отсчета паузы заново", нет?

 

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Ну в моем понимании "запретить паузу" это не выполнять ее вообще! я вообще не пойму что она делает!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

А что такое "пауза" в вашем понимании? :)

Смотрите: в переменной запомнили некий момент времени из millis(), и далее сверяем при каждом заходе разницу между текущим и запомненным временем и заданным интервалом .. вот если эта разница "меньше" значит пауза "ещё не закончилась", а как только стала "больше" .. тут-то все и произошло. Так ведь?

А теперь .. если мы в процессе "ожидания паузы" будем периодически обновлять запомненное время заново, что произойдет? Упс .. пауза будет "ожидаться как-бы заново. То есть ожидание предыдущего интервала мы "запретили", задав новую точку отсчета и одновременно начали считать новую паузу. Вот, перенося выход из иконы 22 в разрыв между 82 и 84, вы тем самым, при срабатывании датчика в середине времени ожидания просто продляете паузу заново.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Ну это кажется понял! Перейду к датчикам, их 2 и делают они одно и тоже, значит их можно записать одной веткой! Верно?

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

А что такое "пауза" в вашем понимании? :)

 

Это какой то отрезок времени, который надо считать ( после неё что то там делать дальше), и ничего больше не делать!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Верно, но для наших целей рисовать это в ДРАКОН уже смысла не имеет. Можно просто охватить циклом по датчикам всю схему Силуэта.

Вот, наконец-то вытащил то, что хотел вам показать. "найдите 2 отличия" :)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

В каждой ветке, подветке .. своя царская дорога - есть прямая "на выход", свой в каждом случае .. это - важно. Одно из правил: развилка смещает вправо тот вариант, который "хуже": дороже по ресурсам, реже применяется, и т.д.

Ну, и глядя на последний код программы и этот вариант работы одного датчика, вы теперь легко разберетесь КАК были объединены ветки "включения" И "выключения". :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

ну незнаю, как то не логично, датчик 1, нет движения, ЗАЧЕМ идем на включение ламп?

Ага, понял, вопрос снят! :) Выход через икону №56, если все спокойно!

А вот икона №33 покоя мне не дает! Зачем начинать паузу(запоминать время), если мы еще не включили все лампы?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

См. выше. Чтобы отключить ожидание предыдущей паузы, по срабатыванию от которой второй датчик может активизировать выключение со своего конца .. и получим "драку за лампу". Как только мы запомнили время в 33, проверка "прошла пауза" даст фальш и блок выключения выпадет из работы.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Все, забыл что датчик то не один!

Я так понял в Вашей ветке датчика движения нет опроса "есть пауза?" который я предложил?

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Ну вообщем как бы вполне понял как это все строиться! Надо просто тренироваться!

Дальше сложнее!!! :( (чем дальше в лес, тем толще партизаны :D)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016
void loop()

{
// if( isDayNow() ){ /*выключить всё*/ return; }

for(uint8_t num=0; num<2; num++)
{
  FadeCycle * cur = &(fadeControl[num]);

  if( digitalRead(cur->pir_pin) )
  {
    cur->step = 1;
    cur->lamp = (num==0? 0 : MAX_LED-1);
    cur->max  = (num==0? MAX_LED : -1);
  }
  if(
      (cur->step > 0)                                  // если включаем лампы, то сразу
      || (
           (cur->step < 0)                             // а вот если вЫключаем, то
           && (millis() - startedPause >= WAIT_PAUSE)  // по истечению паузы
        )
  )
  {
    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);
        if( fadeControl[1-num].step < 0 ){ fadeControl[1-num].step = 0; }
        //startedPause = millis()+5000;

      }
    }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); // теперь сюда передаем номер группы!
      }
  }
}
}

Как теперь понять то что куда тут!? ;(

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

А теперь в каждом квадратике есть три мелких квадратика с дополнительными текстами. Тут слева-направо: "Текст А" -- комментарий Заказчика/Тестера/Приемщика (не забываем, писано для военных), "Текст Б" -- комментарий программиста, коррекция по замечаниям из"А", "П-код" -- собственно текст программы, который потом преобразуется в программу на заданном языке программирования. Чтобы кодогенератор заработал, тут надо на схему добавить схему "Гном" в которой указывается какой язык программирования, какие тексты надо вставить "до" и "после" и т.д.

На сайте есть видеоуроки, в т.ч. и по программированию микроконтроллеров (правда серии PIC, но это без разницы), посмотрите их до конца, многое станет понятней. Ну и ещё я тут поднимал темку http://arduino.ru/forum/obshchii/drakon-i-arduino-atmel-mega-est-gotovye-resheniya когда внезапно обнаружил, что всё чему меня когда-то учили оказывается называется ДРАКОН и имеет вполне конректное и давнее применение. :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

https://www.youtube.com/watch?v=Ua9dUUONjdk

Вот нашел, вполне понятно! Но для того чтоб все это зделать, надо знать что и где, в коде, или как его делать вообще, а этого я еще не догоняю! Так, мало-мало!:)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Икона 64: "шаг =0", а не номер лампы. Приравнивая шаг к 0, мы тем самым запрещаем И включение И выключение одновременно. :)

Собственно добиваться окончательной кодогенерации через ИС Дракон, я ни перед собой ни перед Вами такой цели не ставил. Но это можно освоить по тому примеру что Вы нашли. Я так и сделал в теме по ссылке, сдела схему Гном и 2 схемы "Примитив" для Blink.ino. Одну для setup() и вторую для loop(). С тем же успехом для loop() можно применить и Силуэт и даже со свойством "автомат". Но можно и не делать, а дальше, просто глядя на схему (или держа её в голове, даже вовсе не строя) писать оптимальный код. Поначалу, лучше конечно отрисовывать, чтобы "не потерять" куски из исходного ТЗ.

А тут далее "всё просто":

Вариант "пишем сразу, глядя на схему":

void loop()
{
  // 4. Датчик света
  if( isDayNow() ){
    return; // маркер "Завершение"
  }

  // 39. Датчик движения
  if( digitalRead(..) )
  {
    // 47. Проверка паузы:
    if( millis() > (startedPause + WAIT_PAUSE) ){
      // Код для икон 70,35,75
    }
    // 76. Начать новую паузу
    startedPause = millis();
  }
  // 17. Включение ламп
  .. и так далее
}

Вариант 2: тыкаемся в ИС Дракон в каждый правый квадратик и в редакторе снизу пишем набор операторов, соответствующий квадратику .. тут лучше изучить видео и попробовать на простом примере типа Blink.ino и ещё парочке типа "Блин без делай". Надо будет ещё втыкнуть схему Гном, указать в ней как называется ваш дракон файл и какой язык будет использован для кодогенерации ..

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Правильно понял?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну да, примерно так и есть. В ИС Дракон реализацию можно писать в отдельном слое - последний маленький квадратик каждой иконы .. и тогда, при наличии схемы Гном, он сам соберет вам "в кучку", пардон программу все такие куски. Но писать их все одно - ручками. Смелее. :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

Ну да, примерно так и есть. В ИС Дракон реализацию можно писать в отдельном слое - последний маленький квадратик каждой иконы .. и тогда, при наличии схемы Гном, он сам соберет вам "в кучку", пардон программу все такие куски. Но писать их все одно - ручками. Смелее. :)

это я понял, просто пока для меня так понятнее!

SOCHINEC
Offline
Зарегистрирован: 01.05.2016
 if( digitalRead(cur->pir_pin) )
    {
      if( millis() > (startedPause + WAIT_PAUSE) )
  {
    cur->step = 1;
    cur->lamp = (num==0? 0 : MAX_LED-1);
    cur->max  = (num==0? MAX_LED : -1);
  }
    startedPause = millis();
    }

в скетч правильно вписал проверку и включение паузы?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

К сожалению нет. Это я накосячил. Проверка длительности паузы работает только в одном "волшебном виде":

millis() - started > interval

, поскольку millis() беззнаковый, то и все остальное должно быть беззнаковым. Тут идет игра на игнорировании признака переноса при переполнениях. Когда started велико и близко к максимально возможному числу и интервал приходится на значение millis(), которое не влезает в разрядную сетку .. значение millis() в определенный момент переполняется и оно начинает отсчитываться снова с нуля .. и только эта форма, позволяет тем не менее правильно посчитать интервал и сранить его с заданным. На примере наверное будет понятней:

считаем до 10 .. то есть millis() пусть принимает значения 0,1,..9,0 или 1 десятичный разряд. Интервал (паузу) хотим в 3 единицы и начинаем отсчет паузы в момент когда started = 8:

1) 8-8=0, 0>=3? false

2) 9-8=1? 1>=3? false

3) .. упс, переполнение и millis() = 0! А теперь: 0 - 8 = сколько? А вот когда числа беззнаковые, то они не могут быть меньше 0! и стало быть получаем 0-8 = (1)0-8 = 2! Тут в скобках показан заем из старшего, отсутствующего разряда .. то есть установленный признак переноса. А далее проверяем как обычно 2>3? false

4) 1-8=(1)1-8=11-8=3, 3>=3? true..

Проверьте самостоятельно что получится при вашей записи .. совсем не то, что ожидалось.

Соответственно, нам надо проверить "идет ли пауза?" .. но пауза идет, если выражение меньше интервала. То есть единственно верный вариант этот:

if( millis()-started < interval ){ пауза идет: разность времен меньше длительности паузы }

 

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Получилось вроде работает, только теперь при срабатывании обоих датчиков сразу, включается только от одного! :(

Как вывести в порт отсчет паузы? (хочу посмотреть, что происходит с отсчетом паузы)

if( digitalRead(cur->pir_pin) )
    {
     if( millis()-startedPause <= WAIT_PAUSE )
  {
    cur->step = 1;
    cur->lamp = (num==0? 0 : MAX_LED-1);
    cur->max  = (num==0? MAX_LED : -1);
  }
    startedPause = millis();
    }

Правильно?

Видимо нет, не работает! :(

Мммм, да, я в школе столько не учил как тут! :)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Почему только от одного? По тексту схемы такого нет. Если оба датчика сработали одновременно (второй в процессе включения первого, ибо совсем одновременно практически не бывает), то оба датчика будут включать схему каждый со своего конца .. видимо что-то напутано в программе.

Проверка должна работать корректно. Она выдаст "да" в том случае, если у вас текущая пауза ещё не закончилась и "нет" если пауза уже сработала. Но, посмотрите на код: если пауза НЕ закончилась (да), то запускаем включение датчика, а если нет - то пропускаем .. это совсем не то, что нам хотелось .. мы с вами напутали в схеме. :)

А что "хотелось"? А хотелось, что если датчик сработал, то запускаем его включение безотносительно к остальным условиям (до проверки), а вот если пауза "идет" (не закончилась как в вашей проверке), то надо .. продлить паузу, то есть запомнить текущее время как начало паузы. Мы не те действия вложили в это условие .. бывает. :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

А как надо было? Вроде все логично, и в голове и на схеме!

ПАУЗА ЕСТЬ?   ДА :        (запоминаем, устанавливаем, влючаем лампы...) это все побоку, нам нужна только пауза....

                      НЕТ:          запоминаем, устанавливаем, влючаем лампы...

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

И как же это оно у вас ТАК получилось? :)

Смотрим код #285:

ПАУЗА ЕСТЬ? (разница меньше интервала) ДА: выполняем то что в скобках (устанавливаем шаг, лампу, предел)

                                                           НЕТ: пропускаем то, что в скобках (то есть НЕ устанавливаем..).

и только потом, независимо от вопроса, устанавливаем паузу строкой 9.

А надо по вашему ТЗ не так, а наоборот так как вы написали выше .. и тут видно, что никакой разницы нет "есть пауза (жизнь на Марсе)" или нет её.. раз датчик сработал, значит НАДО установить шаг, лампу и предел .. а уже потом разбираться есть пауза или нет и надо ли её устанавливать заново..

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Ну блин, моя твоя не понимать совсем! :)

 

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

И как же это оно у вас ТАК получилось? :)

 

Я смотрю по схеме! А вот в коде, точно все не так!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Да, вы правы. На схемах #276,#280 стоит одно условие, а в коде #285 обратное:

на схемах: "если идет пауза" (разница времен меньше интервала паузы), то пропускаем включение, поскольку оно и так все включено. Далее просто продляем паузу.

В коде: "если разница времен меньше или равна интервалу паузы" (то есть пауза "идет"), то запускаем включение, хотя в этом случае оно и так все включено .. надо изменить в #285 условие в строке 3, наоборот на ">=".

Но! В случае двух датчиков .. это не спасет. :) Смотрите: сработал первый датчик и пауза "уже прошла" .. он запустит свое включение и .. установит паузу. Далее, проходя по циклу датчиков обнаруживаем что сработал и второй, но пауза уже переустановлена и он не запустит свое включение.

Вот поэтому, на моей схеме #270 и нет такой проверки. Она хороша только для схемы с одним датчиком, а вот в случае двух и более датчиков такая "оптимизация" только головная боль. А реализовать "оптимизацию" для случая двух датчиков будет затратней чем просто пробежаться по коду "лишний раз" .. :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

изменил, вообще не работает ни чего, не включается! :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

 

Но! В случае двух датчиков .. это не спасет. :) Смотрите: сработал первый датчик и пауза "уже прошла" .. он запустит свое включение и .. установит паузу. Далее, проходя по циклу датчиков обнаруживаем что сработал и второй, но пауза уже переустановлена и он не запустит свое включение.

 

А что сделает 2 датчик?

Продлит опять паузу!? Так мне это и надо вроде!

Зачем нам его включение, уже все горит то!?

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

SOCHINEC пишет:

изменил, вообще не работает ни чего, не включается! :)

ага, заработало, только почему то как будто перед началом программы, "залезла" наша пауза :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Так, ну вроде все работает, но только от датчиков по отдельности.

А сразу два, не хотят! Пока идет включение от 1 датчика, 2 в игноре(жизнь на Марсе отсутствует :)),

а вот выключается когда, от 1 датчика, второй норма(включает свои лампы)!

Почему так может быть?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Верно. Этот код из #285, и схем №276,280 с вопросом про паузу будет "тормозить" сразу после запуска, ибо пока не натикает миллис дальше интервала паузы от нуля .. будет считаться что "пауза идет". Это первое.

И сразу оба датчика работать НЕ смогут. Почему - отписал выше: как только сработал первый из них, то для него "пауза уже прошла" и он запустит свое включение И переставит паузу заново. А вот прохождение кода для второго датчика становится НЕ ТАКИМ .. его проверка "идет ли пауза" (строка 3 из #285) .. СРАБОТАЕТ: "да, идет!" (тока что включили первым датчиком!) и он ПРОПУСТИТ свою пачку команд на включение со своего конца, а просто ещё дальше продлит паузу.

Вот если убрать такую проверку вовсе (строку 3), то оба датчика будут запускать свое включение безотносительно того идет ли пауза или нет и продлять её принудительно.. то есть "будут работать".

Недостаток такого решения только в том, что код будет "пытаться включать лампы каждый раз, когда сработал датчик" .. но они и так уже включены .. ну пробежится алгоритм повторно, убедится что всё включено "впустую". Это меньшее зло чем строить "оптимизирующие" проверки: а включено ли уже все, а прошла ли пауза, а первый это датчик сработал или второй .. проверить 6 ламп и условия для них в цикле на 16 мегагерцах .. пшик, по сравнению с кодом, который можно тут навороить для полноценного избегания такой "пробежки". Это к вопросу "лучшее - враг хорошего". :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

1. Верно. Этот код из #285, и схем №276,280 с вопросом про паузу будет "тормозить" сразу после запуска, ибо        пока не натикает миллис дальше интервала паузы от нуля .. будет считаться что "пауза идет". Это первое.

Вот если убрать такую проверку вовсе (строку 3), то оба датчика будут запускать свое включение безотносительно того идет ли пауза или нет и продлять её принудительно.. то есть "будут работать".

2. Недостаток такого решения только в том, что код будет "пытаться включать лампы каждый раз, когда сработал датчик" .. но они и так уже включены .. ну пробежится алгоритм повторно, убедится что всё включено "впустую". 

1. МИЛЛИС - тикае всегда чтоли, зачем, почему?  Но это только после подачи питания, потом все норма вроде!?

2. так он же переставит начальную и конечные лампы, так? а этого то не надо!

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

 СРАБОТАЕТ: "да, идет!" (тока что включили первым датчиком!) и он ПРОПУСТИТ свою пачку команд на включение со своего конца, а просто ещё дальше продлит паузу.

(тока что включили первым датчиком!) - а как так то? мы же еще не включили ВСЕ лампы, зачем нам пауза?

Значит надо паузу определить не датчиками, а лампами! Включили ВСЕ? ПАУЗА!

Или я опять чего то не догоняю!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Вы похоже запутались в собственном ТЗ, схеме и коде .. давайте "по частям":

1. ТЗ: "сработавший датчик должен включать все лампы со своего конца: 1-й с начала в прямом порядке, 2-й с последней к началу.
Схема (#270): за это действие отвечают иконы веток "Датчик1" и "Датчик2" а также ветки "включение".
Код (#219) строки 118-120 - запуск и строки 131,132,133,138,148 "включение".

2. ТЗ: "все лампы должны гореть заданное время.
Схема: внутри веток включение по завершению включения всех ламп, запускаем отсчет паузы. За это отвечает выбор "лампы кончились" и его ветка "да". Длительность паузы проверяется в ветке "Пауза".
Код: строки 134-137 - установка паузы, часть условия (строки 125,126) - проверяют длительность паузы в режиме выключения.

3. ТЗ "после паузы лампы должны выключаться в том же порядке"
Схема: Выключение ламп производится внутри ветки "Пауза" после завершения паузы.
Код: строки 140-146,148 выключают лампы в требуемом порядке.

3. ТЗ: "после выключения переходим в режим ожидания движения"
Схема: Икона "шаг=0" (зелененькая, последняя) запрещает как режим включения так и режим выключения, оставляя рабочими только ветки датчиков.
Код: строка 145 делает тоже самое.

Фсё-ё.. :) И это всё - есть в коде.

А вот дальше, у нас возникла "засада": что если датчик срабатывает во время паузы ожидания выключения, то возможна "драка за лампу" .. когда сработавший датчик запускает алгоритм включения, хотя лампы и так включены, а в это же самое время "кончается пауза" и второй датчик начинает методично выключать лампы .. там, где они встречаются проиходит "драка за лампу". Всё остальное делалось исключительно в целях устранения этого нехорошего эффекта.

И вот для его устранения вполне достаточно(!) только добавить в ветку запуска включения ещё одно действие, а именно "переустановить паузу заново" .. без каких-либо проверок и пробросов кода. Что я Вам и показал на схеме #270. Нет? Проверьте. :)

 

SOCHINEC
Offline
Зарегистрирован: 01.05.2016
void loop()

{


for(uint8_t num=0; num<2; num++)
{
  FadeCycle * cur = &(fadeControl[num]);

  if( digitalRead(cur->pir_pin) )
    {
     if( millis()-startedPause >= WAIT_PAUSE )
  {
    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)                             // а вот если вЫключаем, то
           && (millis() - startedPause >= WAIT_PAUSE)  // по истечению паузы
        )
  )

  {
    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); // теперь сюда передаем номер группы!
      }
  }
}
}

Ну вроде все так! Как и хотелось! только вот вечно какие то "засады"!

Вот как сейчас код, меня устраивает все, кроме одного - (игнор одного из датчиков при включении)

нет включения от краев в центр, соответственно нет и выключения! :(