Нет перезапрос нухно оставить, просто сделать с подтверждением. посвтор если не получил подтверждение в течении определенного времени.
всмысле перезапрос? говорю перезапрос то остаётся, убрать отправку отчёта 3 раза, сделать отправку отчета 1 раз. Перезапрос так и останется 5 раз, если не пришёл отчёт.
Или я тебя неправильно понял и ты называешь перезапросом переответ. Т.е. может ты имеешь в виду, что нужно делать так? :
Мк_1 отправил команду на МК_2.
МК_2 отправил отчет на МК_1.
МК_1 отправил отчёт о принятии отчёта на МК_2 // имхо это уже бред
Таймаут можно передавать в отчёте. Если у отчёта вид "команда была принята - идёт выполнение", то также в поле данных будет и значение тайм-аута.
или лучше так :
riv пишет:
Делаем константы с предельныим временем исполнения . И ждем это время если не получили ок то перезапрос выполненной команды.
MK_2 отправил подверждение о приеме командв и начале ее исполнения (сели не успел исполнить сразу) на МК1 указав время исполнения команды.
Если МК_1 не получил отчет о принятии команды от МК_2 то переотправка команды или диагностика МК_2 (надо думать)
МК_2 ждет исполнения и если исполнена то шлет на МК_1 отчет о исполнении
если МК_2 не исполник команду шлет отчет что команда не выполнена. Если успешно выполнена то отчет что выполнена.
МК_1 если не дождался отчета о успешном выполнении от МК_2 (о принятии команды отчет получен) то делает или диагностику МК_2 или переотправку команды. (Нужно продумать.)
Я поправил код. Пока только той стороны, которая отправляет команду (МК_1 в посте выше). Жирным курсивом мои коментарии к алгоритму.
riv пишет:
Мк_1 отправил команду на МК_2. (Происходит приращение глобального счетчика, потом команда ложится в ячейку очереди на отправку. статус ячейки здесь - "ждем отчета о получении команды". )
Если МК_1 не получил отчет о принятии команды от МК_2, то переотправка команды или диагностика МК_2 (надо думать) (тут только переотправка команды. Делается 5 попыток с одинаковым глобальным счетчиком, после чего команда убирается из очереди, отправка команды прекращается)
MK_2 отправил подверждение о приеме команды и начале ее исполнения (если не успел исполнить сразу) на МК1, указав время исполнения команды (нет, время в итоге лежит в заранее составленном массиве таймаутов ).
МК_2 ждет исполнения и если исполнена, то шлет на МК_1 отчет о исполнении
если МК_2 не исполнил команду, шлет отчет, что команда не выполнена. Если успешно выполнена, то отчет что выполнена.
МК_1 если получил отчёт о том, что команда НЕ выполнена , тут пока просто жалуемся в отладку, что произошла ошибка выполнения команды оппонетом.
МК_1 если не дождался отчета об успешном выполнении от МК_2 (о принятии команды отчет получен) то делает или диагностику МК_2 или переотправку команды. (Нужно продумать.) ( Тут, когда получен отчёт о приятии команды, ячейка команды переходит в статус "отчёт о приятии команды получен, ждем отчёта об успешном выполнении команды". Запускается таймер, в течение которого мы ждём этого отчета о выполнении команды. Если не дождались, пока просто жалуемся в отладку - можно например повторять отправку команды.
Если дождались - команда удаляется из очереди.
Единственное условие, в ENUM типа устройств нужно устройства, которые требуют время на выполнение команды, сделать в первой двадцатке, например, или десятке, если влезут. Это нужно, чтобы не создавать большой массив таймаутов на 94 байта, где куча байт не будет использоваться (типы устройств, где мгновенное выполнение команды или вообще датчики).
значение байт поля данных в команде (DLC = 5)
00 00 00 00 00
глоб. счётч на твое усм. тут тип отчета ст. разряд команды мл. разряд команды
по сути команда вся состоит в итоге вообще из 4 байт, их то мы и забиваем в функцию SendCommand():
SendCommand( младший разряд, старший разряд, адрес получателя, тип устройства):
я вот думаю как отправку отчетов COMMAND_ANSWER организовать. Нужен алгоритм, без него чёто башка не варит.
Получили мы команду. С быстрым выполнением команд всё понятно. Выполняем действие команды и сразу отправляем отчёт с типом COMPLETE
Если выполнение команды медленное (как мы это узнаем? это у нас уже заложено в типе устройств?), отправляем тип отчёта EXECUTING причем не просто отправляем, а также ставим в очередь (по аналогии с COMMAN_SEND). Потому как нам нужно убегать из обработчика поступающих к нам команд case COMMAND_SEND: Это означает что данные по команде (адрес отправителя, сама команда, тип устройства, глобальный счетчик) нужно где то сохранить. А храним мы их как раз в ячейке очереди.
Далее вот что делать? Тоже такой же таймаут запускать (как в COMMAND_SEND)? но чуть меньше (а то если тайкой же - то отправляющая команду сторона может не дождаьться отчёта, нужно раньше этого нам отчет отправить).
Ну допустим ладно, запустили таймер. Как-то распознали (тоже не знаю как), что реальное действие выполнения команды закончено. Теперь надо отчёт отослать - COMPLETE. Нужно как-то узнать номер недавно сохраненной ячейки, который вот соответсвует вот этим законченным реальным действиям команды. тогда мы сможем отправить отчёт. (ведь в отчете нужно отправлять и глоб. счетчик такой же как мы получили в команде от удалённого МК и тип устройства и адрес от кого команда пришла - это всё есть в ячейке).
Как-то распознали (тоже не знаю как), что реальное действие выполнения команды НЕ выполнено, и таймер закончился. Теперь надо отправить отчёт FAIL
я специально убрал, чё себя то смотреть)) понятно, раз в мониторе порта что то есть значит типа жив. Активность CAN Сам себя не сможешь мониторить, т.к. МК не видит в CAN сообщения, которые сам же отправил. Типа статус самому себе слать не получится.
я специально убрал, чё себя то смотреть)) понятно, раз в мониторе порта что то есть значит типа жив. Активность CAN Сам себя не сможешь мониторить, т.к. МК не видит в CAN сообщения, которые сам же отправил. Типа статус самому себе слать не получится.
Я понял что ты сделал, сам к этому пришел, почему свой узел FAIL начал разбираться, так его просто принудительно по номеру узла ОК давать ;-)
ещё вот такой вариант развития событий. Допустим отправли команду закрыть радиатор, он начал закрываться, идёт закрытие и в этот момент прилетает ещё одна команда (естественно с другим глобальным счетчиком, если счетчики одинаковые, мы считаем, что это одна и та же команда), пусть будет опять на закрытие. получается у нас в очередь на отчёты в разные ячейки лягут две одинаковые команды, с одним типом устройств, отличаться будут только глобальные счетчики. Ну и на какую команду нам отвечать по завершении закрытия радиатора?
я вот думаю как отправку отчетов COMMAND_ANSWER организовать. Нужен алгоритм, без него чёто башка не варит.
1. Если устройство выполняет команду долго, то нужно задавать таймаут предельного ожидания команды. Помнишь мы думали где хранить это таймаут на master или на mk.
Есть смысл хранить этитаймауты везде, т.к отправкой команд может заниматься не только мастер.
2. Можно извратиться со 2й очередью длинных команд если боишься что из этой вылетишь по переполнению.
Или для длинных команд отдельная процедура с длинной очередью.
Или отдельный массив с длинными командами, как я в своем опросчике сделал.
3. По поводу ожидания ответа как раз и говорю что лучше разделить ответчики долгих команд чтобы не менять таймауты.
4. Как распознать что выполнение команды закончено. Я у себя например на электрокранах защиты от протечек BUGATTI PRO 12В ¾ ставлю концевик который нажмется желтым рычагом. По нему я пойму что команда выполнена. Кран закрывается примерно (по паспорту) 20 сек. Если в теч 25 сек. концевик не сообщит что кран закрыт я верну что команда не выполнена. И разошлю аварию высшей категории.
ещё вот такой вариант развития событий. Допустим отправли команду закрыть радиатор, он начал закрываться, идёт закрытие и в этот момент прилетает ещё одна команда (естественно с другим глобальным счетчиком, если счетчики одинаковые, мы считаем, что это одна и та же команда), пусть будет опять на закрытие. получается у нас в очередь на отчёты в разные ячейки лягут две одинаковые команды, с одним типом устройств, отличаться будут только глобальные счетчики. Ну и на какую команду нам отвечать по завершении закрытия радиатора?
Вот очень хороший вопрос.
Вариантов два.
1 вариант команда прилетел от этого же контроллера - здесь лучше решать блокировками, просто не дать прилететь команде закрыться раньше чем придет отчет о ОК & FAIL на открыться.
2. вариант от другого - здесь тоже нужно думать на тему кто же все же главный и какого фига все кому не лень шлют команду.
Вообще нужно просто аппаратно продумать контроль исполнения команды, а для длинных команд делать не очереди а выставлять влаги через массив, типа статуса контроллеров.
Посмотрел в массив а у меня там последняя команда на радиатор №1 была открыться а на №2-15 закрыться.
произошло. Мы игнорируем повторную команду и не оказываем физические воздействия на элемент - пусть себе дальше перемещается по первой команде, а шаловливому МК, который всё же невпопад команду вдогонку отправил, сразу без очередей всяких отправляем ALREADY_RUNNING
1 вариант команда прилетел от этого же контроллера - здесь лучше решать блокировками, просто не дать прилететь команде закрыться раньше чем придет отчет о ОК & FAIL на открыться.
а если ты шторы с пульта хочешь открыть, а они закрываются в этот момент, у тебя просто на кнопку не будет реагировать, пока не закроются. Стрёмно
короче делаем так . МК_1 отправил на МК_2 команду на закрытие, на МК_1 команда легла в очередь, статус ячейки ("ждём отчета о приятии команды")
МК_2 получил команду, отправил EXECUTING . У МК_1 команда в очереди, поменяла статус ячейки на ("ждём отчета о выполнении команды"). У МК_2 отчёт для MK_1 ложится в очередь.
Элемент начинает закрываться. Прилетает опять на закрытие ( допустим от МК_3). У МК_3 команда легла в очередь, статус "ждём отчета о приятии команды"
МК_2 получил команду, ничё с элементом не делает, он продолжает закрываться. МК_2 отправил на МК_3 отчёт EXECUTING
На МК_3 команда в очереди, поменяла статус ячейки на ("ждём отчета о выполнении команды"). У МК_2 отчёт для MK_3 ложится в очередь.
Элемент всё ещё закрывается.
Далее ещё хлеще. МК_1 ещё раз решил отправить на закрытие, но у него в очереди уже лежит такая команда и ждёт отчета о выполнении команды. Мы проверяем очередь: если такая команда там уже есть, нефиг её опять отпралять. Просто игнорируем инициирование команды (ну например нажатие на кнопку на пульте "закрыть", чё на неё реагировать, если мы и так уже ждём закрытия элемента).
Элемент наконец закрылся. Проверяется очередь отчётов, (там их два лежит). МК_2 отправляет COMPLETE на МК_1 и на MK_3
1 вариант команда прилетел от этого же контроллера - здесь лучше решать блокировками, просто не дать прилететь команде закрыться раньше чем придет отчет о ОК & FAIL на открыться.
а если ты шторы с пульта хочешь открыть, а они закрываются в этот момент, у тебя просто на кнопку не будет реагировать, пока не закроются. Стрёмно
Сборка на Arduino Due имеет особенности. Т.к в плату встороены 2 CAN порта но без линейной части (надо искать и покупать SN65HVD230) используем MCP2515. Для работы MCP2515 c DUE нужно
1. В скетче CAN0 и/или CAN1 заменить на люьой другой (Я использовал CAN3), пин 53 заменить на 52
Мне бы с этим разобраться. Скетч получился жесть какой сложный в понимании что к чему. Может ты и разберёшься - следи по Serial.print-ам куда заводит логика программы, я всё выводил в монитор. Позже может видяху сниму.
В видео нужно будет рассмотреть несколько примеров развития событий - Что при этом делается :
1. Классический сценарий. МК_1 отправляет долгую команду на МК_2. Что при этом делается
2. Долгая команда уже была ранее отправлена от МК_1 на МК_2. МК_1 опять послал такую же команду с таким же глобальным счетчиком.
3. Долгая команда уже была ранее отправлена от МК_1 на МК_2. МК_1 опять послал такую же команду с другим глобальным счетчиком.
4. Долгая команда уже была ранее отправлена от МК_1 на МК_2. Теперь МК_3 послал такую же команду с любым глобальным счетчиком.
5. Классический сценарий. МК_1 отправляет быструю команду на МК_2.
6. МК_1 отправляет быструю команду на МК_2. (и, допустим МК_1, сразу не получает отчёт о выполнении от МК_2 и начинает сыпать этой же командой с тем же глобальным счётчиком 5 раз).
7. Отправка отчётов от МК_2, когда он получает неизвестную долгую или быструю команду
8. Когда на МК_2 заканчивается таймаут выполнения долгой команды что происходит. Как МК_2 узнаёт физически выполнилась ли команда или нет. В зависимости от этого, формирование типа отчёта на эту долгую команду.
Я сейчас занимаюсь разворачиванием всей сети. Пока на столе. Поставлю Due 2 шт. , Mega 2560 Pro 11 шт, и так по мелочи что насобираю, всего 15 узлов + CanHacker.
Залью скетчи и буду смотреть что получилось. (Вообще нужно наверное 2 CanHacker)
Сейчас две задачи как это все визуализировать для отладки (anHacker уже просто не справляется), как заливать скетч дистанционно, как сопрягать с серверами умного дома.
P.S. Насчет AMS, MySensors и esp-link написал скорее от понимания того ужаса творящегося на столе, и еще большего ужаса от понимания во что обойдется перезаливка скетча если не сделать загрузку по сети.
Я сейчас занимаюсь разворачиванием всей сети. Пока на столе. Поставлю Due 2 шт. , Mega 2560 Pro 11 шт, и так по мелочи что насобираю, всего 15 узлов + CanHacker.
Залью скетчи и буду смотреть что получилось. (Вообще нужно наверное 2 CanHacker)
Сейчас две задачи как это все визуализировать для отладки (anHacker уже просто не справляется), как заливать скетч дистанционно, как сопрягать с серверами умного дома.
P.S. Насчет AMS, MySensors и esp-link написал скорее от понимания того ужаса творящегося на столе, и еще большего ужаса от понимания во что обойдется перезаливка скетча если не сделать загрузку по сети.
Уже есть решения для заливки скетча
1. RS-485
2. nRF24 - nRF5
3. ESP8266
Скетч твой вечером залью
имхо, это всё ещё рановато. Толком в скетче ещё не реализованы все типы сообщений. Я кое как вроде заканчиваю. с
Так я и говорю про дистанционную перезаливку скетча, или по 485, или по nRF, или по WiFi ну или по CAN. Чтобы платы в стенах спрятать и отлаживать на местах.
всмысле перезапрос? говорю перезапрос то остаётся, убрать отправку отчёта 3 раза, сделать отправку отчета 1 раз. Перезапрос так и останется 5 раз, если не пришёл отчёт.
Или я тебя неправильно понял и ты называешь перезапросом переответ. Т.е. может ты имеешь в виду, что нужно делать так? :
Мк_1 отправил команду на МК_2.
МК_2 отправил отчет на МК_1.
МК_1 отправил отчёт о принятии отчёта на МК_2 // имхо это уже бред
Таймаут можно передавать в отчёте. Если у отчёта вид "команда была принята - идёт выполнение", то также в поле данных будет и значение тайм-аута.
или лучше так :
Мк_1 отправил команду на МК_2.
MK_2 отправил подверждение о приеме командв и начале ее исполнения (сели не успел исполнить сразу) на МК1 указав время исполнения команды.
Если МК_1 не получил отчет о принятии команды от МК_2 то переотправка команды или диагностика МК_2 (надо думать)
МК_2 ждет исполнения и если исполнена то шлет на МК_1 отчет о исполнении
если МК_2 не исполник команду шлет отчет что команда не выполнена. Если успешно выполнена то отчет что выполнена.
МК_1 если не дождался отчета о успешном выполнении от МК_2 (о принятии команды отчет получен) то делает или диагностику МК_2 или переотправку команды. (Нужно продумать.)
Как то так.
Я поправил код. Пока только той стороны, которая отправляет команду (МК_1 в посте выше). Жирным курсивом мои коментарии к алгоритму.
Мк_1 отправил команду на МК_2. (Происходит приращение глобального счетчика, потом команда ложится в ячейку очереди на отправку. статус ячейки здесь - "ждем отчета о получении команды". )
Если МК_1 не получил отчет о принятии команды от МК_2, то переотправка команды или диагностика МК_2 (надо думать) (тут только переотправка команды. Делается 5 попыток с одинаковым глобальным счетчиком, после чего команда убирается из очереди, отправка команды прекращается)
МК_2 ждет исполнения и если исполнена, то шлет на МК_1 отчет о исполнении
если МК_2 не исполнил команду, шлет отчет, что команда не выполнена. Если успешно выполнена, то отчет что выполнена.
МК_1 если получил отчёт о том, что команда НЕ выполнена , тут пока просто жалуемся в отладку, что произошла ошибка выполнения команды оппонетом.
МК_1 если не дождался отчета об успешном выполнении от МК_2 (о принятии команды отчет получен) то делает или диагностику МК_2 или переотправку команды. (Нужно продумать.) ( Тут, когда получен отчёт о приятии команды, ячейка команды переходит в статус "отчёт о приятии команды получен, ждем отчёта об успешном выполнении команды". Запускается таймер, в течение которого мы ждём этого отчета о выполнении команды. Если не дождались, пока просто жалуемся в отладку - можно например повторять отправку команды.
Если дождались - команда удаляется из очереди.
Единственное условие, в ENUM типа устройств нужно устройства, которые требуют время на выполнение команды, сделать в первой двадцатке, например, или десятке, если влезут. Это нужно, чтобы не создавать большой массив таймаутов на 94 байта, где куча байт не будет использоваться (типы устройств, где мгновенное выполнение команды или вообще датчики).
значение байт поля данных в команде (DLC = 5)
00 00 00 00 00
глоб. счётч на твое усм. тут тип отчета ст. разряд команды мл. разряд команды
по сути команда вся состоит в итоге вообще из 4 байт, их то мы и забиваем в функцию SendCommand():
SendCommand( младший разряд, старший разряд, адрес получателя, тип устройства):
тип отчета это:
скетч
PS. есть изменения в файле can_struct.h
Видео тестирования скетча
продолжение видео
В типах сообщения зачем поубирал аварию ACCIDENT_SEND?
я не убирал. Я просто из своего скетча переделывал. А меня этого и небыло
Я думал ты в моих смотришь. Добавь тип сообщения отправка сообщения о аварии.
пытаюсь теперь Command_Answer в таком же ключе запрограммировать.
Ты получается всю структуру поменял, У меня void SendCommand_queue() поехала
да поменял, теперь в массиве ячейки очереди 8 элементов хранится, а были отдельные переменные
Ты получается в разных ветках даешь одинаковые имена разным типам. И проект сыпется.
Выкладывай плиз тогда и SendCommand_queue()
в смысле? это где
Я уже за тобой не успеваю, больше пытаюсь тыой код понять чем свой писать :-)
ты полностью мой скетч с моими файлами попробуй скомпилить. Всё работало
у меня такой строки нет, как ты в в посте #512 указал. Ты чето неправильно соединил. Это уже старое Command_TX_body[i][3] = 0
я поменял название у этой переменной
В твоем последнем скетче нет SendCommand_queue
Ааа блин ты ее SendCommandAnswer_queNe назвал, а я переименовал в SendCommandAnswer_queUe
только что ещё раз по ссылке скачал #503 . Всё там есть и компилируется. Более того проверено в работе.
Я с твоей подачи грамматические ошибки в переменных везде исправляю
очередь - queUe, так что и не мог найти функцию.
SendCommandAnswer_quene() пока не переделывал. Он рабоает по первоначальной схеме - если я получил команду, отправляю отчёт три раза и всё.
Я с твоей подачи грамматические ошибки в переменных везде исправляю
очередь - queUe, так что и не мог найти функцию.
ты прав, косякнул и я. CTRL+F и там есть такая чудесная кнопочка "найти и заменить"
Лучше глянь https://yadi.sk/d/zkejlJ3K3Td48S
Я твои изменения внес и сделал код практически идентичный для 5 нодов, делим только Define type_node_master или type_node_slave или type_node_mk
В функцию StatusControl
в if (i!= node_address) вставь
1
else
2
{PrintADDR (i);
Serial
.println (F(
" OK!!!"
)) ;}
а то в списке самого себя нет
я вот думаю как отправку отчетов COMMAND_ANSWER организовать. Нужен алгоритм, без него чёто башка не варит.
Получили мы команду. С быстрым выполнением команд всё понятно. Выполняем действие команды и сразу отправляем отчёт с типом COMPLETE
Если выполнение команды медленное (как мы это узнаем? это у нас уже заложено в типе устройств?), отправляем тип отчёта EXECUTING причем не просто отправляем, а также ставим в очередь (по аналогии с COMMAN_SEND). Потому как нам нужно убегать из обработчика поступающих к нам команд case COMMAND_SEND: Это означает что данные по команде (адрес отправителя, сама команда, тип устройства, глобальный счетчик) нужно где то сохранить. А храним мы их как раз в ячейке очереди.
Далее вот что делать? Тоже такой же таймаут запускать (как в COMMAND_SEND)? но чуть меньше (а то если тайкой же - то отправляющая команду сторона может не дождаьться отчёта, нужно раньше этого нам отчет отправить).
Ну допустим ладно, запустили таймер. Как-то распознали (тоже не знаю как), что реальное действие выполнения команды закончено. Теперь надо отчёт отослать - COMPLETE. Нужно как-то узнать номер недавно сохраненной ячейки, который вот соответсвует вот этим законченным реальным действиям команды. тогда мы сможем отправить отчёт. (ведь в отчете нужно отправлять и глоб. счетчик такой же как мы получили в команде от удалённого МК и тип устройства и адрес от кого команда пришла - это всё есть в ячейке).
Как-то распознали (тоже не знаю как), что реальное действие выполнения команды НЕ выполнено, и таймер закончился. Теперь надо отправить отчёт FAIL
В функцию StatusControl
в if (i!= node_address) вставь
1
else
2
{PrintADDR (i);
Serial
.println (F(
" OK!!!"
)) ;}
а то в списке самого себя нет
я специально убрал, чё себя то смотреть)) понятно, раз в мониторе порта что то есть значит типа жив. Активность CAN Сам себя не сможешь мониторить, т.к. МК не видит в CAN сообщения, которые сам же отправил. Типа статус самому себе слать не получится.
В функцию StatusControl
в if (i!= node_address) вставь
1
else
2
{PrintADDR (i);
Serial
.println (F(
" OK!!!"
)) ;}
а то в списке самого себя нет
я специально убрал, чё себя то смотреть)) понятно, раз в мониторе порта что то есть значит типа жив. Активность CAN Сам себя не сможешь мониторить, т.к. МК не видит в CAN сообщения, которые сам же отправил. Типа статус самому себе слать не получится.
Я понял что ты сделал, сам к этому пришел, почему свой узел FAIL начал разбираться, так его просто принудительно по номеру узла ОК давать ;-)
ну если тебе так легче, то...)))
ещё вот такой вариант развития событий. Допустим отправли команду закрыть радиатор, он начал закрываться, идёт закрытие и в этот момент прилетает ещё одна команда (естественно с другим глобальным счетчиком, если счетчики одинаковые, мы считаем, что это одна и та же команда), пусть будет опять на закрытие. получается у нас в очередь на отчёты в разные ячейки лягут две одинаковые команды, с одним типом устройств, отличаться будут только глобальные счетчики. Ну и на какую команду нам отвечать по завершении закрытия радиатора?
я вот думаю как отправку отчетов COMMAND_ANSWER организовать. Нужен алгоритм, без него чёто башка не варит.
1. Если устройство выполняет команду долго, то нужно задавать таймаут предельного ожидания команды. Помнишь мы думали где хранить это таймаут на master или на mk.
Есть смысл хранить этитаймауты везде, т.к отправкой команд может заниматься не только мастер.
2. Можно извратиться со 2й очередью длинных команд если боишься что из этой вылетишь по переполнению.
Или для длинных команд отдельная процедура с длинной очередью.
Или отдельный массив с длинными командами, как я в своем опросчике сделал.
3. По поводу ожидания ответа как раз и говорю что лучше разделить ответчики долгих команд чтобы не менять таймауты.
4. Как распознать что выполнение команды закончено. Я у себя например на электрокранах защиты от протечек BUGATTI PRO 12В ¾ ставлю концевик который нажмется желтым рычагом. По нему я пойму что команда выполнена. Кран закрывается примерно (по паспорту) 20 сек. Если в теч 25 сек. концевик не сообщит что кран закрыт я верну что команда не выполнена. И разошлю аварию высшей категории.
ещё вот такой вариант развития событий. Допустим отправли команду закрыть радиатор, он начал закрываться, идёт закрытие и в этот момент прилетает ещё одна команда (естественно с другим глобальным счетчиком, если счетчики одинаковые, мы считаем, что это одна и та же команда), пусть будет опять на закрытие. получается у нас в очередь на отчёты в разные ячейки лягут две одинаковые команды, с одним типом устройств, отличаться будут только глобальные счетчики. Ну и на какую команду нам отвечать по завершении закрытия радиатора?
Вот очень хороший вопрос.
Вариантов два.
1 вариант команда прилетел от этого же контроллера - здесь лучше решать блокировками, просто не дать прилететь команде закрыться раньше чем придет отчет о ОК & FAIL на открыться.
2. вариант от другого - здесь тоже нужно думать на тему кто же все же главный и какого фига все кому не лень шлют команду.
Вообще нужно просто аппаратно продумать контроль исполнения команды, а для длинных команд делать не очереди а выставлять влаги через массив, типа статуса контроллеров.
Посмотрел в массив а у меня там последняя команда на радиатор №1 была открыться а на №2-15 закрыться.
Нужно просто из попробовать опросить.
может ещё тип отчёта добавить кроме
1
#define FAIL 0x03
2
#define EXECUTING 0x02
3
#define COMPLETE 0x01
ещё такую, типа такая команда уже выполняется
1
#define ALREADY_RUNNING 0x04
Т.е. если такое
Вариантов два.
1 вариант команда прилетел от этого же контроллера - здесь лучше решать блокировками, просто не дать прилететь команде закрыться раньше чем придет отчет о ОК & FAIL на открыться.
а если ты шторы с пульта хочешь открыть, а они закрываются в этот момент, у тебя просто на кнопку не будет реагировать, пока не закроются. Стрёмно
короче делаем так . МК_1 отправил на МК_2 команду на закрытие, на МК_1 команда легла в очередь, статус ячейки ("ждём отчета о приятии команды")
МК_2 получил команду, отправил EXECUTING . У МК_1 команда в очереди, поменяла статус ячейки на ("ждём отчета о выполнении команды"). У МК_2 отчёт для MK_1 ложится в очередь.
Элемент начинает закрываться. Прилетает опять на закрытие ( допустим от МК_3). У МК_3 команда легла в очередь, статус "ждём отчета о приятии команды"
МК_2 получил команду, ничё с элементом не делает, он продолжает закрываться. МК_2 отправил на МК_3 отчёт EXECUTING
На МК_3 команда в очереди, поменяла статус ячейки на ("ждём отчета о выполнении команды"). У МК_2 отчёт для MK_3 ложится в очередь.
Элемент всё ещё закрывается.
Далее ещё хлеще. МК_1 ещё раз решил отправить на закрытие, но у него в очереди уже лежит такая команда и ждёт отчета о выполнении команды. Мы проверяем очередь: если такая команда там уже есть, нефиг её опять отпралять. Просто игнорируем инициирование команды (ну например нажатие на кнопку на пульте "закрыть", чё на неё реагировать, если мы и так уже ждём закрытия элемента).
Элемент наконец закрылся. Проверяется очередь отчётов, (там их два лежит). МК_2 отправляет COMPLETE на МК_1 и на MK_3
Вариантов два.
1 вариант команда прилетел от этого же контроллера - здесь лучше решать блокировками, просто не дать прилететь команде закрыться раньше чем придет отчет о ОК & FAIL на открыться.
а если ты шторы с пульта хочешь открыть, а они закрываются в этот момент, у тебя просто на кнопку не будет реагировать, пока не закроются. Стрёмно
Тогда 2 типа команд прерываемые и не прерываемые.
Какие то можно прервать а какие то ждем до упора.
Сборка на Arduino Due имеет особенности. Т.к в плату встороены 2 CAN порта но без линейной части (надо искать и покупать SN65HVD230) используем MCP2515. Для работы MCP2515 c DUE нужно
1. В скетче CAN0 и/или CAN1 заменить на люьой другой (Я использовал CAN3), пин 53 заменить на 52
2. Подключение
MCP2515 DUE (Колодка SPI)
int 2 digital io
SCK 3 SPI
SI 4 SPI
SO 1 SPI
CS 52 digital io
GND 6 SPI
VCC 2 SPI
Помоему, использовать встроенный контроллер CAN не получится, если писать скетч в ардуино IDE. Поэтому проще MCP2515
На гит хабе вроде была библиотека для DUE,но тогда код будет уже не кроссплатный. Так что встроенные в топку. ;-)
Подключил к DUE еще и W5500 (Ethernet) и теперь все что по CAN приходит отправляю на сервер.
Можно на due инфу обрабатывать и на сервер слать уже готовые переменные.
Я пока рассматриваю оба варианта и передача на сервер сырых данных и передача уже обработанных.
почти запрограммировал алгоритм #534
почти запрограммировал алгоритм #534
Супер.
Вот глянь к размышлению 2 проекта
1. http://mysensors.ru/download/protokol-obmena-2-x/
Здесь радиосеть, протокол и прошивка по воздуху.
2. https://hi-lab.ru/arduino-mega-server/documentation/equipment/wireless/nrf24/ams-nrf24-controller-sensor
Здесь и радиосеть с протоколом и Web сервер.
Пока голова другим забита.
почти запрограммировал алгоритм #534
Мне бы с этим разобраться. Скетч получился жесть какой сложный в понимании что к чему. Может ты и разберёшься - следи по Serial.print-ам куда заводит логика программы, я всё выводил в монитор. Позже может видяху сниму.
В видео нужно будет рассмотреть несколько примеров развития событий - Что при этом делается :
1. Классический сценарий. МК_1 отправляет долгую команду на МК_2. Что при этом делается
2. Долгая команда уже была ранее отправлена от МК_1 на МК_2. МК_1 опять послал такую же команду с таким же глобальным счетчиком.
3. Долгая команда уже была ранее отправлена от МК_1 на МК_2. МК_1 опять послал такую же команду с другим глобальным счетчиком.
4. Долгая команда уже была ранее отправлена от МК_1 на МК_2. Теперь МК_3 послал такую же команду с любым глобальным счетчиком.
5. Классический сценарий. МК_1 отправляет быструю команду на МК_2.
6. МК_1 отправляет быструю команду на МК_2. (и, допустим МК_1, сразу не получает отчёт о выполнении от МК_2 и начинает сыпать этой же командой с тем же глобальным счётчиком 5 раз).
7. Отправка отчётов от МК_2, когда он получает неизвестную долгую или быструю команду
8. Когда на МК_2 заканчивается таймаут выполнения долгой команды что происходит. Как МК_2 узнаёт физически выполнилась ли команда или нет. В зависимости от этого, формирование типа отчёта на эту долгую команду.
9. Пиши исчо.
Я сейчас занимаюсь разворачиванием всей сети. Пока на столе. Поставлю Due 2 шт. , Mega 2560 Pro 11 шт, и так по мелочи что насобираю, всего 15 узлов + CanHacker.
Залью скетчи и буду смотреть что получилось. (Вообще нужно наверное 2 CanHacker)
Сейчас две задачи как это все визуализировать для отладки (anHacker уже просто не справляется), как заливать скетч дистанционно, как сопрягать с серверами умного дома.
P.S. Насчет AMS, MySensors и esp-link написал скорее от понимания того ужаса творящегося на столе, и еще большего ужаса от понимания во что обойдется перезаливка скетча если не сделать загрузку по сети.
Уже есть решения для заливки скетча
1. RS-485
2. nRF24 - nRF5
3. ESP8266
Скетч твой вечером залью
Я сейчас занимаюсь разворачиванием всей сети. Пока на столе. Поставлю Due 2 шт. , Mega 2560 Pro 11 шт, и так по мелочи что насобираю, всего 15 узлов + CanHacker.
Залью скетчи и буду смотреть что получилось. (Вообще нужно наверное 2 CanHacker)
Сейчас две задачи как это все визуализировать для отладки (anHacker уже просто не справляется), как заливать скетч дистанционно, как сопрягать с серверами умного дома.
P.S. Насчет AMS, MySensors и esp-link написал скорее от понимания того ужаса творящегося на столе, и еще большего ужаса от понимания во что обойдется перезаливка скетча если не сделать загрузку по сети.
Уже есть решения для заливки скетча
1. RS-485
2. nRF24 - nRF5
3. ESP8266
Скетч твой вечером залью
имхо, это всё ещё рановато. Толком в скетче ещё не реализованы все типы сообщений. Я кое как вроде заканчиваю. с
COMMAND_SEND, COMMAND_ANSWER, STATUS_REQUEST_SEND, STATUS_REQUEST_ANSWER
а ещё нужно с передачей переменных разобраться, т.е.
REQUEST_SEND, REQUEST_ANSWER
Так я и говорю про дистанционную перезаливку скетча, или по 485, или по nRF, или по WiFi ну или по CAN. Чтобы платы в стенах спрятать и отлаживать на местах.
ты же вроде вывел провода rs485 в одно место от каждого МК, и научился по 485 скетч лить. Тогда этот вариант видимо нужно качать.
ПС. #544 скетч поправил немного.
У меня блин только CanHacker и один модуль MCP2515 (ещё заказаны, никак дойти не могут). Вот и не получается нормально потестить пинг понг.