я сделал отладку на прогмем, теперь отладка весит очень мало. убрал функцию DeCode_can_id_msg
количество узлов в сети полюбому нужно знать. Посмотри, где у меня оно используется. Например, чтобы задавать размер массива статусов равный количеству устройств в сети.
Проверить могу только вечером, у меня железо дома.
MaksVV пишет:
я сделал отладку на прогмем, теперь отладка весит очень мало. убрал функцию DeCode_can_id_msg
Посмотрю, что за зверь. Не сталкивался еще.
MaksVV пишет:
количество узлов в сети полюбому нужно знать. Посмотри, где у меня оно используется. Например, чтобы задавать размер массива статусов равный количеству устройств в сети.
2. У тебя n контроллеров имеет разные наборы датчиков, исп. устройств и либо подпрограмм конечных автоматов (чтобы тебя от работы с датчиками по сети абстрагировать и ты шлеш померить температуру в комнате, МК снимает показания с 3х датчиков, их усредняет и выдает тебе 1 цифру) корорые ты предлагаешь загнать в шаблоны.Т.е 20 контроллеров, 20 шаблонов с адресами устройств?
3. Ты предлагаешь в поле данных передавать из 8 байт
1. Байт адреса
2. Байт данных
3. Байт данных
4. Байт данных
5. Байт данных
6. Байт данных
7. Резерв
8. № сообщения
Так?
2. у меня так сейчас сделано, но это не очень удобно для дальнейшего развития
3. Нет не так.
если булевые и однобайтовые (4 переменных во фрейме)
Я не пойму зачем все время слать запрос статуса , это лишнее сообщение в шине. Пусть узлы сами его периодически шлют.
1. Центральный МК ничем кроме контроля и управления не занят, датчиков и ИУ не имеет и мощнее, это его задача.
2. как минимум у него должна быть процедура запросчик статуса инициативная по команде от сервера УД.
3. Никто не заставляет запрашивать постоянно, смотри алгоритм. Сверху именно процедура диагностики а это только запросчик.
2. Это легко сделать, не вопрос.
3. Считаю, что нужно постоянно. Всякое бывает, лучше бы побыстрее система узнала, что кто-то неисправен. Я думаю раз в секунду подчинённые должны слать статус живучести. Мастер может слать широковещательное статусное сообщение, где в поле данных будет время например.
1. В скетче узел периодически шлёт свой статус мастеру, выбранному по умолчанию. По команде эту переменную можно поменять, и узел начнет периодически слать статус другому МК (слейву например).
2. Так же узел по запросу шлёт статус тому кто прислал запрос.
3. По получении запроса мультифрейма (тип сообщения 7), узел отсылает на МК, кто послал запрос, мультифрейм со всеми переменными узла. (ну понятно для примера только несколько переменных показал. В примере мультифрейм состоит всего из 2 кадров).
мозгов не хватило универсальную конструкцию для мультифреймов придумать. Поэтому пока мультифрейм может быть один единственный - т.е. серия сообщений со всеми переменными узла.
тип сообщения MULTIFRAME_SEND я сделал, что это запрос на предоставление мультифрейма. Потому что не могу представить себе запрос чего-то в виде мультифрейма, т.е. чтобы мультифрейм являлся запросом, слишком жирно для запроса, да и не за чем.
Предлагаю такой алгоритм. Штатно работает рассылка подчиненным МК сообщений к мастеру. Если мастер увидел что МК не отвечает то он делает опрос сам и если и на него МК не ответил то делает ему ребут. После чего через 30 сек если тот не прислал сам еще раз проверяет и устанавливает ему Аварийный статус.
Я у себя сделал питание всех подчиненных МК из центра по 2й паре, через LiFePo 12В ИБП, так что дернуть, с помощью реле, питание не проблема.
Предлагаю такой алгоритм. Штатно работает рассылка подчиненным МК сообщений к мастеру. Если мастер увидел что МК не отвечает то он делает опрос сам и если и на него МК не ответил то делает ему ребут. После чего через 30 сек если тот не прислал сам еще раз проверяет и устанавливает ему Аварийный статус.
да, можно так сделать. по поводу поля данных и передачи в нем данных. Всё таки наверное считаю лишним делать уникальный номер сообщения. Не очень понятно зачем то нужно. Тем более всего 256 значений, потом обнуляется. И данных так меньше влазит, учитывая что ещё эта адресация переменных нужна.
По поводу поля данных. По разному типу данных (булевые , int ы и т.д.) можно сделать так . По FF ам выясняем какой тип данных тут в кадре. и соотвествующим образом парсим.
Нужно будет создать карту переменных (придётся всего 256 штук, не более, т.к. разряд адреса 1 байт). Лучше через директиву условной компиляции. На каждом МК можно будет выбирать какие переменные объявятся, соотвественно они будут, естественно, глобальные.
При парсинге, на приёмной стороне, делаем свитч кейс на 256 case . Проверятся в свитче будет байт адреса из поля данных. И если он равен какому нибудь case (а там соответсвующая переменнная с таким адресом). То эта переменная приравнивается к байту данных (или нескольним байтам) из поля данных, которая прикреплена к адресу, только проверенному в свитче.
Таким образом мы будет присваивать байты данных нужным нам переменным.
Я упорно выношу отлаженый код в отдельные файлы и процедуры. Твой код встроил, заменил DeCode_can_id_msg на DeCode_can_id_msg2, убрал структуры, заменил на твои переменные, они памяти меньше едят. https://yadi.sk/d/zkejlJ3K3Td48S
Насчет счетчика уникальных сообщений, как понять на какое сообщение ответил контроллер? Считаю что нужно отсавить.
Насчет емкости поля данных.
Ты же сам говорил ранее скорости сумашедшие, а сложная структура это лишний гемор в обработке. 1 фрейм 1 датчик или устройство.
Зачем делать в одном фрейме 10 датчиков?
Например в одном МК все датчики влезут во фрейм а в другом 2/3 и как быть?
Ааа, вот ты как хочешь, только твой NODE.ino разобрал. Идея супер, но я мультифрейм то думал для сырых длинномерных данных. А ты датчики туда запихнул. Тогда тем более смысл убирать 2 последних байтас №№ сообщений.
да, хорошо сделано. Я этот видос ещё года три назад смотрел. У них серьезные устройства подключаются к ethernet, с меньшим трафиком - CAN, а датчики, выключатели и мелкие ИУ - 1-wire.
в системе есть шлюзы CAN<->Ethernet и шлюзы CAN<->1-wire
т.е. у них локальной, минимально функционирующей единицей служит шлюз CAN<->1-wire. Настройки и управление из вне осущ. по CAN. Но если (уже после настройки) CAN отключить, То этот шлюз будет рулить по последнему настроенному сценарию, устройствами 1-wire. Хорошая задумка.
Кстати скорость CAN у них всего 64 кбит/с. Для надёжности видимо малую скорость выбрали.
И самый главный момент. Каждый элемент у них имеет собственный уникальный ID.
Вот нам нужно тоже сделать уникальный ID каждого элемента. Это будет отображаться в поле данных статусных сообщений.
При такой архитектуре как у них, видишь, сто пудово устройства тоже сами статусы периодически шлют, иначе как бы их система увидела при подключении.
Сначала при подключении устройство шлёт периодически статус с адресом 00 например. Я, так понимаю, при назначении какого-то сценария, где участвует данный ID оборудования, ему уже назначается адрес (который у нас в ID заголовке). Или сразу можно назначать, как в сети появился.
Ну хорошо, давай последний байт ID отдадим адресу у-ва а первый данных определим под тип -у ва.
Мне что то подсказывает что у них там не просто переходник а лежит либо плис либо мелкий мк со встроенным CAN.
Либо у них жесткая схема включения порт 1 только датчики, порт 2 только кнопки и д.д.
Они ведь показывали p&p для верхнего уровня.
Тут просто если данные от датчика пошли то считаем что он жив, отдали по CAN команду мастеру что на цифровом порту 10 появился датчик иначал гнать данные. Мастер по MQTT отправил по Ethernet выше Там УД понл что есть у-во и прописал.
Но есть нюанс, как понять по подключению что появился датчик особенно если он ничего не передает или если он не выдает на вход 1 или какойто сигнал если он ШИМ или аналоговый
Но есть нюанс, как понять по подключению что появился датчик особенно если он ничего не передает или если он не выдает на вход 1 или какойто сигнал если он ШИМ или аналоговый
ты не понял. Там все датчики цифровые. (шина 1-wire). Это как типа DS18B20. Т.е. шим, лог 1 или лог 0 уже подключаются к этому устройству 1-wire (которое и является датчиком). Оцифровываются и данные лог 0, лог 1 или ШИМ или аналоговый сигнал уже передаются в формате 1-wire.
Контроллеры-шлюзы CAN<->1-Wire кроме того, что транслируют данные между шинами, создают локальную автоматику, которая будет функционировать по последним настройкам даже при отключении внешней сети. CM9 он их там называет. Писюльки такие маленькие, на ARM наверное сделаны
я всё таки не понимаю зачем нам нужен уникальный номер сообщения и тип устройства. Вот послал запрос один МК, начинает ждать. Другой МК ему ответил. Ты говоришь - как мы узнаем на какое сообщение он ответил. Я этого не понимаю, как на какое? В запросе в заголовке ID же четко будет указан тип сообщения "запрос", и адрес "кому". Соответсвенно, если от этого "кому" придёт ответ уже с другим типом сообщения "ответ" - получается он и ответил на наш этот запрос.
А тип устройства? Где это использовать? (ну если мы конечно не будем каждую переменную в отдельном фрейме передавать, тогда понятно, этот тип устройства - это будет адрес параметра, как я называю. )
Ну и в общем то мы к такой схеме и идем как ты нарисовал. Я даже немного сложнее ее вижу с мастер слейвом на DUE и шлюзом в Ethernet на Orange Pi. (Хотя в примере либы есть конвертер CAN - Ethernet)
Хорошо, я согласен передавать по одной переменной в каждом фрейме. Действительно с парсингом меньше проблем. Тогда тип устройства, конечно, в заголовке нужен, он там у нас и есть. Ну и тогда два последних байта в поле данных свободные, можно там уникальный ID устройства передавать и уникальный номер сообщения
А в схеме нарисованы 1-wire. Лично мне не нравится эта шина. Модули 1wire стоят чуть ли не дороже кан модулей а скорость и надежность ниже гораздо. Я бы сделал вместо 1wire тоже CAN - локальный для помещения, скорость у него допустим 500 кбит, а шлюзы кан<->кан подключаются на 125 кбит к шлюзу эзернет<->кан.
А в схеме нарисованы 1-wire. Лично мне не нравится эта шина. Модули 1wire стоят чуть ли не дороже кан модулей а скорость и надежность ниже гораздо. Я бы сделал вместо 1wire тоже CAN - локальный для помещения, скорость у него допустим 500 кбит, а шлюзы кан<->кан подключаются на 125 кбит к шлюзу эзернет<->кан.
Ну у меня так и будет между доп контроллерами, в названиях видишь по 2-3 на помещение. Но датчики я уже затянул по проводам, дискретные, бинарные и аналоговые. Так что p&p игрушка хорошая но для комерсантов. Мы то настоящие индейцы ;-)
1-wire я может на температуру повешу, да и то под вопросом. А так да завышена цена.
Глянь код, я реализовал автомат, если МК ответил на переодический запрос то пропускаем остальные 2 запроса, если не оветил то крутим по 3 и отсылаем аварию наверх. Если не ответил то долбим до упора. Хотя от этого тоже избавлюсь.
Мало того за счет наследования меняй только node1.ino на node2.ino и собирай. А если ввести define по типу то весь код и мастера и слейва и МК ложиться в один проект. В nodeXX.ino должны лежать только настройки
1. Тип узла (мастер, слейв, МК)
2. Имя узла
3. Имя мастера и слейва
4. Настройки датчиков и ИУ
5. Базовая логика но и ее типизирую (во всех помещениях нужен климат и освещение) см. мою схему
Заработало. В автомате мастер каждые 60 сек (можно задать) опрашивает все узлы из ENUM, получив ответ перестает опрашивать, не получив ответ пробует еще 2 раза (можно задать) каждые 1 сек (можно задать) и если не получил ответ шлет на PC сообщение об аварии, после чего ждет еще 60 сек и повтор. https://yadi.sk/d/zkejlJ3K3Td48S
ну ты намудрииил! один массив long array_reqvest_status[NODS_NUMBER][6]; только чего стоит. Только один этот массив на Нане ест четверть операвтивки. Это кащунство для одного бита (флаги у тебя в основном там) использовать 4 байта О_О .
и вот эти ппц глаз режут: reqvest ansver программисты тебя не поймут.
И ты всё время кучу функций создаёшь, перемещая параметры. Дак вот, когда ты это делаешь (передаёшь параметры функции по значению), создаётся копия переменной в оперативке и делается это медленно, когда много данных. Хотя бы передавал по ссылке или указателю. Почитай про это.
и вот это равные выражения только второе короче и красивее a = a+1; тоже самое а++;
и где нужно небольшие переменные создать (до 256) не пиши int, лучше byte или uint8_t, байтик сэкономишь, а то ведь память когда нибудь закончится и глюки будут такими, что ты фиг определишь в чем причина.
Система должна быть с обратной связью. Тут как раз кнопку нажал -> опросил. А если просто ждать то что? Подождал, подождал если ничего не пришло то что? Ставим что не работает?
Я этот код вынесу в отдельный ino для мастера. Причешу. Кстати очепятки поправил теперь везде ansWer и reqUest ;-)
Система должна быть с обратной связью. Тут как раз кнопку нажал -> опросил. А если просто ждать то что? Подождал, подождал если ничего не пришло то что? Ставим что не работает?
Я этот код вынесу в отдельный ino для мастера. Причешу. Кстати очепятки поправил теперь везде ansWer и reqUest ;-)
1. В скетче узел периодически шлёт свой статус мастеру, выбранному по умолчанию. По команде эту переменную можно поменять, и узел начнет периодически слать статус другому МК (слейву например).
2. Так же узел по запросу шлёт статус тому кто прислал запрос.
а вообще-то да. Подождал, если нет ответа - то ставим что не работает. Где тут нарушение логики и здравого смысла? Если в алгоритме у подыинённых заложено периодически слать статус и он его не шлёт, значит уже чтото пошло не так. И че толку запрашивать, всё равно, скорее всего, не ответит, иначе и так ответил бы - сам, периодически.
т.е. ты можешь даже с другого подчинённого спросить, если надо, а живой ли данный первый подчинённый? И тому другому и придёт ответ статуса от данного первого.
ansver_status_reqvest(dev_addr, data_b7); //здесь dev_addr это полученый удаленный адрес!!
тебе библиотека уже дала байты в готовом виде в массива rxBuf_can[8]. А ты создаешь ещё 8 переменных, копируешь эти байты и ещё &0xFF . Это ты по аналогии с заголовком чтоли? Дак ведь там то, таким извратом занимались, т.к. библиотека ID заголовок даёт в виде целого большого числа 0x02154896, а нам нужны были отдельные разряды. Убери эту фигню, просто пользуй rxBuf_can[8]
т.е. ты можешь даже с другого подчинённого спросить, если надо, а живой ли данный первый подчинённый? И тому другому и придёт ответ статуса от данного первого.
Можно использовать оба механизма, или один на выбор. Важно чтобы они были. Я и от твоего не отказываюсь, но и свой оставляю.
Примерно так: если узел долго не шлет чтожив я его опрашиваю.
+ Как ты правильно заметил я могу с любого узла опросить любой. А если рассылка то придется писать в конфиге что присылать статус всем из списка.
И заметь это функция и механизм базовые. На ней можно опрос датчиков и управление ИУ делать. Т.е я сделал работу с инициативными запросами. Отправил -> Получил данные или квитанцию или еще что. Ведь кроме статуса можно ей датчики опрашивать и команды подавать. Функция то базовая почти.
Так что если тебе удасться ее причесать то быдет оч. круто.
ansver_status_reqvest(dev_addr, data_b7); //здесь dev_addr это полученый удаленный адрес!!
тебе библиотека уже дала байты в готовом виде в массива rxBuf_can[8]. А ты создаешь ещё 8 переменных, копируешь эти байты и ещё &0xFF . Это ты по аналогии с заголовком чтоли? Дак ведь там то, таким извратом занимались, т.к. библиотека ID заголовок даёт в виде целого большого числа 0x02154896, а нам нужны были отдельные разряды. Убери эту фигню, просто пользуй rxBuf_can[8]
Мммда умыл.
т.е надо вместо answer_status_request(dev_addr, data_b7);
сделать answer_status_request(dev_addr, rxBuf_can[7]); ?
И еще вопрос ты с фильтрами и масками из библиотеки не работал? Я пока фильтрую прямо в RX, но это ест проц, вроде в либе фильтр есть и маска чтобы отфильтровывать и не обрабатывать все что приходит не для меня.
И еще вопрос ты с фильтрами и масками из библиотеки не работал? Я пока фильтрую прямо в RX, но это ест проц, вроде в либе фильтр есть и маска чтобы отфильтровывать и не обрабатывать все что приходит не для меня.
вот проверь пожалста , Это типа мастер, который всё время ждет статусы.
я сделал отладку на прогмем, теперь отладка весит очень мало. убрал функцию DeCode_can_id_msg
количество узлов в сети полюбому нужно знать. Посмотри, где у меня оно используется. Например, чтобы задавать размер массива статусов равный количеству устройств в сети.
в скетче #401 были ошибки, исправил, проверил - работает!!!
вот проверь пожалста , Это типа мастер, который всё время ждет статусы.
Проверить могу только вечером, у меня железо дома.
я сделал отладку на прогмем, теперь отладка весит очень мало. убрал функцию DeCode_can_id_msg
Посмотрю, что за зверь. Не сталкивался еще.
количество узлов в сети полюбому нужно знать. Посмотри, где у меня оно используется. Например, чтобы задавать размер массива статусов равный количеству устройств в сети.
Ок.
вот ещё причесал
если 2-байтовые (2 переменных во фрейме)
1. Центральный МК ничем кроме контроля и управления не занят, датчиков и ИУ не имеет и мощнее, это его задача.
2. как минимум у него должна быть процедура запросчик статуса инициативная по команде от сервера УД.
3. Никто не заставляет запрашивать постоянно, смотри алгоритм. Сверху именно процедура диагностики а это только запросчик.
2. Это легко сделать, не вопрос.
3. Считаю, что нужно постоянно. Всякое бывает, лучше бы побыстрее система узнала, что кто-то неисправен. Я думаю раз в секунду подчинённые должны слать статус живучести. Мастер может слать широковещательное статусное сообщение, где в поле данных будет время например.
вот ещё вариант - изменён дебаг статусов подчинённых :
01
NODES CAN COMMUNICATION:
02
NULL_A FAIL!!!
03
Net_center_PC FAIL!!!
04
Net_center_oraPi1 FAIL!!!
05
Net_center_oraPi2 FAIL!!!
06
Net_center_Due1 FAIL!!!
07
Net_center_Due2 FAIL!!!
08
Hallway_net_center FAIL!!!
09
Hallway_main FAIL!!!
10
Hallway_light FAIL!!!
11
Kitchen_net_center FAIL!!!
12
Kitchen_main FAIL!!!
13
Kitchen_light FAIL!!!
14
WC_main FAIL!!!
15
WC_waterleak FAIL!!!
16
Bathroom_main FAIL!!!
17
Boxroom_main FAIL!!!
18
Balcony_meteo FAIL!!!
19
Loggia_main FAIL!!!
20
Loggia_recuoerator FAIL!!!
21
Livingroom_main FAIL!!!
22
Bedroom_main FAIL!!!
23
Cabinet_main FAIL!!!
при отправке на этот мастер фрейма с ID 0x06**0100 соответствующие статусы изменяться на OK на 5 сек.
где 6 - сообщение ответ статуса,
** - адрес отправителя, какой поставить тут, тот статус и будет меняться в массиве на мастере
01 - адрес МК на который будут высылаться периодически статусы (Net_center_PC в данном случае)
остальные разряды ID не участвуют, без разницы какие значение
вот набросал скетч одного из узлов , например Kitchen_main
1. В скетче узел периодически шлёт свой статус мастеру, выбранному по умолчанию. По команде эту переменную можно поменять, и узел начнет периодически слать статус другому МК (слейву например).
2. Так же узел по запросу шлёт статус тому кто прислал запрос.
3. По получении запроса мультифрейма (тип сообщения 7), узел отсылает на МК, кто послал запрос, мультифрейм со всеми переменными узла. (ну понятно для примера только несколько переменных показал. В примере мультифрейм состоит всего из 2 кадров).
мозгов не хватило универсальную конструкцию для мультифреймов придумать. Поэтому пока мультифрейм может быть один единственный - т.е. серия сообщений со всеми переменными узла.
тип сообщения MULTIFRAME_SEND я сделал, что это запрос на предоставление мультифрейма. Потому что не могу представить себе запрос чего-то в виде мультифрейма, т.е. чтобы мультифрейм являлся запросом, слишком жирно для запроса, да и не за чем.
Все твои скетчи проверил. Все работает.
Предлагаю такой алгоритм. Штатно работает рассылка подчиненным МК сообщений к мастеру. Если мастер увидел что МК не отвечает то он делает опрос сам и если и на него МК не ответил то делает ему ребут. После чего через 30 сек если тот не прислал сам еще раз проверяет и устанавливает ему Аварийный статус.
Я у себя сделал питание всех подчиненных МК из центра по 2й паре, через LiFePo 12В ИБП, так что дернуть, с помощью реле, питание не проблема.
да, можно так сделать. по поводу поля данных и передачи в нем данных. Всё таки наверное считаю лишним делать уникальный номер сообщения. Не очень понятно зачем то нужно. Тем более всего 256 значений, потом обнуляется. И данных так меньше влазит, учитывая что ещё эта адресация переменных нужна.
По поводу поля данных. По разному типу данных (булевые , int ы и т.д.) можно сделать так . По FF ам выясняем какой тип данных тут в кадре. и соотвествующим образом парсим.
Нужно будет создать карту переменных (придётся всего 256 штук, не более, т.к. разряд адреса 1 байт). Лучше через директиву условной компиляции. На каждом МК можно будет выбирать какие переменные объявятся, соотвественно они будут, естественно, глобальные.
При парсинге, на приёмной стороне, делаем свитч кейс на 256 case . Проверятся в свитче будет байт адреса из поля данных. И если он равен какому нибудь case (а там соответсвующая переменнная с таким адресом). То эта переменная приравнивается к байту данных (или нескольним байтам) из поля данных, которая прикреплена к адресу, только проверенному в свитче.
Таким образом мы будет присваивать байты данных нужным нам переменным.
Я упорно выношу отлаженый код в отдельные файлы и процедуры. Твой код встроил, заменил DeCode_can_id_msg на DeCode_can_id_msg2, убрал структуры, заменил на твои переменные, они памяти меньше едят. https://yadi.sk/d/zkejlJ3K3Td48S
Насчет счетчика уникальных сообщений, как понять на какое сообщение ответил контроллер? Считаю что нужно отсавить.
Насчет емкости поля данных.
Ты же сам говорил ранее скорости сумашедшие, а сложная структура это лишний гемор в обработке. 1 фрейм 1 датчик или устройство.
Зачем делать в одном фрейме 10 датчиков?
Например в одном МК все датчики влезут во фрейм а в другом 2/3 и как быть?
Ааа, вот ты как хочешь, только твой NODE.ino разобрал. Идея супер, но я мультифрейм то думал для сырых длинномерных данных. А ты датчики туда запихнул. Тогда тем более смысл убирать 2 последних байтас №№ сообщений.
Вот тут идеи интересные https://www.youtube.com/watch?v=23uQ8I8KSVE&feature=youtu.be
plug and play для датчиков, ИУ подключаемых к контроллерам
да, хорошо сделано. Я этот видос ещё года три назад смотрел. У них серьезные устройства подключаются к ethernet, с меньшим трафиком - CAN, а датчики, выключатели и мелкие ИУ - 1-wire.
в системе есть шлюзы CAN<->Ethernet и шлюзы CAN<->1-wire
т.е. у них локальной, минимально функционирующей единицей служит шлюз CAN<->1-wire. Настройки и управление из вне осущ. по CAN. Но если (уже после настройки) CAN отключить, То этот шлюз будет рулить по последнему настроенному сценарию, устройствами 1-wire. Хорошая задумка.
Кстати скорость CAN у них всего 64 кбит/с. Для надёжности видимо малую скорость выбрали.
И самый главный момент. Каждый элемент у них имеет собственный уникальный ID.
Вот нам нужно тоже сделать уникальный ID каждого элемента. Это будет отображаться в поле данных статусных сообщений.
При такой архитектуре как у них, видишь, сто пудово устройства тоже сами статусы периодически шлют, иначе как бы их система увидела при подключении.
Сначала при подключении устройство шлёт периодически статус с адресом 00 например. Я, так понимаю, при назначении какого-то сценария, где участвует данный ID оборудования, ему уже назначается адрес (который у нас в ID заголовке). Или сразу можно назначать, как в сети появился.
Ну хорошо, давай последний байт ID отдадим адресу у-ва а первый данных определим под тип -у ва.
Мне что то подсказывает что у них там не просто переходник а лежит либо плис либо мелкий мк со встроенным CAN.
Либо у них жесткая схема включения порт 1 только датчики, порт 2 только кнопки и д.д.
Они ведь показывали p&p для верхнего уровня.
Тут просто если данные от датчика пошли то считаем что он жив, отдали по CAN команду мастеру что на цифровом порту 10 появился датчик иначал гнать данные. Мастер по MQTT отправил по Ethernet выше Там УД понл что есть у-во и прописал.
Но есть нюанс, как понять по подключению что появился датчик особенно если он ничего не передает или если он не выдает на вход 1 или какойто сигнал если он ШИМ или аналоговый
ты не понял. Там все датчики цифровые. (шина 1-wire). Это как типа DS18B20. Т.е. шим, лог 1 или лог 0 уже подключаются к этому устройству 1-wire (которое и является датчиком). Оцифровываются и данные лог 0, лог 1 или ШИМ или аналоговый сигнал уже передаются в формате 1-wire.
Контроллеры-шлюзы CAN<->1-Wire кроме того, что транслируют данные между шинами, создают локальную автоматику, которая будет функционировать по последним настройкам даже при отключении внешней сети. CM9 он их там называет. Писюльки такие маленькие, на ARM наверное сделаны
я всё таки не понимаю зачем нам нужен уникальный номер сообщения и тип устройства. Вот послал запрос один МК, начинает ждать. Другой МК ему ответил. Ты говоришь - как мы узнаем на какое сообщение он ответил. Я этого не понимаю, как на какое? В запросе в заголовке ID же четко будет указан тип сообщения "запрос", и адрес "кому". Соответсвенно, если от этого "кому" придёт ответ уже с другим типом сообщения "ответ" - получается он и ответил на наш этот запрос.
А тип устройства? Где это использовать? (ну если мы конечно не будем каждую переменную в отдельном фрейме передавать, тогда понятно, этот тип устройства - это будет адрес параметра, как я называю. )
Вот все типы 1-wire
Насчет номера сообщения это мне НАСТОЯТЕЛЬНО рекомендовали мои колеги разработчики, у которых такая сеть живет в изделии. Завтра попытаю.
Ну и в общем то мы к такой схеме и идем как ты нарисовал. Я даже немного сложнее ее вижу с мастер слейвом на DUE и шлюзом в Ethernet на Orange Pi. (Хотя в примере либы есть конвертер CAN - Ethernet)
И посмотри я твою идею с дебагером немного допилил, получилось совсем красиво. https://yadi.sk/d/zkejlJ3K3Td48S
Твой дебагер я засунул в ф-ю декодер, и на RX TX и тепер ф отладке видно что передали, что отправили и что получилось на уровне выше.
Хорошо, я согласен передавать по одной переменной в каждом фрейме. Действительно с парсингом меньше проблем. Тогда тип устройства, конечно, в заголовке нужен, он там у нас и есть. Ну и тогда два последних байта в поле данных свободные, можно там уникальный ID устройства передавать и уникальный номер сообщения
А в схеме нарисованы 1-wire. Лично мне не нравится эта шина. Модули 1wire стоят чуть ли не дороже кан модулей а скорость и надежность ниже гораздо. Я бы сделал вместо 1wire тоже CAN - локальный для помещения, скорость у него допустим 500 кбит, а шлюзы кан<->кан подключаются на 125 кбит к шлюзу эзернет<->кан.
Думаю сделать уневерсальный скетч в котором будет #define master/slave/mk
+ Давай попробуем p&p на 1 wire.
Но увы у меня уже куча датчиков заложена не 1-wire
Я вот такие по 2 шт в каждый проем заложил https://ru.aliexpress.com/item/10PCS-LOT-E18-D80NK-Adjustable-Infrared-Sensor-Switch-3-80cm-for-Arduino-Infrared-Sensor-Switch/1999477248.html
А такие в каждую дверь и окно https://ru.aliexpress.com/item/40-pairs-17-10-5mm-Plastic-Wired-magnetic-Door-Window-Opening-Sensor-intruder-detector-NC/32690173183.html
Не 1 вире в топку
Ну у меня так и будет между доп контроллерами, в названиях видишь по 2-3 на помещение. Но датчики я уже затянул по проводам, дискретные, бинарные и аналоговые. Так что p&p игрушка хорошая но для комерсантов. Мы то настоящие индейцы ;-)
1-wire я может на температуру повешу, да и то под вопросом. А так да завышена цена.
Согласен!
Глянь код, я реализовал автомат, если МК ответил на переодический запрос то пропускаем остальные 2 запроса, если не оветил то крутим по 3 и отсылаем аварию наверх. Если не ответил то долбим до упора. Хотя от этого тоже избавлюсь.
Мало того за счет наследования меняй только node1.ino на node2.ino и собирай. А если ввести define по типу то весь код и мастера и слейва и МК ложиться в один проект. В nodeXX.ino должны лежать только настройки
1. Тип узла (мастер, слейв, МК)
2. Имя узла
3. Имя мастера и слейва
4. Настройки датчиков и ИУ
5. Базовая логика но и ее типизирую (во всех помещениях нужен климат и освещение) см. мою схему
Заработало. В автомате мастер каждые 60 сек (можно задать) опрашивает все узлы из ENUM, получив ответ перестает опрашивать, не получив ответ пробует еще 2 раза (можно задать) каждые 1 сек (можно задать) и если не получил ответ шлет на PC сообщение об аварии, после чего ждет еще 60 сек и повтор. https://yadi.sk/d/zkejlJ3K3Td48S
ну ты намудрииил! один массив long array_reqvest_status[NODS_NUMBER][6]; только чего стоит. Только один этот массив на Нане ест четверть операвтивки. Это кащунство для одного бита (флаги у тебя в основном там) использовать 4 байта О_О .
и вот эти ппц глаз режут: reqvest ansver программисты тебя не поймут.
И ты всё время кучу функций создаёшь, перемещая параметры. Дак вот, когда ты это делаешь (передаёшь параметры функции по значению), создаётся копия переменной в оперативке и делается это медленно, когда много данных. Хотя бы передавал по ссылке или указателю. Почитай про это.
и вот это равные выражения только второе короче и красивее a = a+1; тоже самое а++;
и где нужно небольшие переменные создать (до 256) не пиши int, лучше byte или uint8_t, байтик сэкономишь, а то ведь память когда нибудь закончится и глюки будут такими, что ты фиг определишь в чем причина.
а вот это что в RX() я вообще не понял
1
data_b0 = rxBuf_can[0]&0xFF;
2
data_b1 = rxBuf_can[1]&0xFF;
3
data_b2 = rxBuf_can[2]&0xFF;
4
data_b3 = rxBuf_can[3]&0xFF;
5
data_b4 = rxBuf_can[4]&0xFF;
6
data_b5 = rxBuf_can[5]&0xFF;
7
data_b6 = rxBuf_can[6]&0xFF;
8
data_b7 = rxBuf_can[7]&0xFF;
и RX и TX не такие , как я делал, там нет последних фишечек
Брал из твоих последних. Выкладывай последние, может пропустил. Ну и если можешь оптимизировать мое тэксказать творчество, то буду благодарен.
Есть идеи как мой изврат исправить?
1
data_b0 = rxBuf_can[0]&0xFF;
2
data_b1 = rxBuf_can[1]&0xFF;
3
data_b2 = rxBuf_can[2]&0xFF;
4
data_b3 = rxBuf_can[3]&0xFF;
5
data_b4 = rxBuf_can[4]&0xFF;
6
data_b5 = rxBuf_can[5]&0xFF;
7
data_b6 = rxBuf_can[6]&0xFF;
8
data_b7 = rxBuf_can[7]&0xFF;
А это я байты данных разбираю.
Потом использую
1
ansver_status_reqvest(dev_addr, data_b7);
//здесь dev_addr это полученый удаленный адрес!!
Я тогда и твои ошибки поправлю ;) countNoTAnsverNode[dev_addr] это твоя ф-я
И кстати это только для мастера этот массив для быстрого опроса подчиненных
нафига их опрашивать если они сами статус шлют?
Система должна быть с обратной связью. Тут как раз кнопку нажал -> опросил. А если просто ждать то что? Подождал, подождал если ничего не пришло то что? Ставим что не работает?
Я этот код вынесу в отдельный ino для мастера. Причешу. Кстати очепятки поправил теперь везде ansWer и reqUest ;-)
У меня основная задача протокол обмена вылизать. Примеров для датчиков и ИУ много а протокола нет.
Я твой код дебаггера из RX вынес в отдельную функцию
Система должна быть с обратной связью. Тут как раз кнопку нажал -> опросил. А если просто ждать то что? Подождал, подождал если ничего не пришло то что? Ставим что не работает?
Я этот код вынесу в отдельный ino для мастера. Причешу. Кстати очепятки поправил теперь везде ansWer и reqUest ;-)
дак я сделал вроде как обратную связь
1. В скетче узел периодически шлёт свой статус мастеру, выбранному по умолчанию. По команде эту переменную можно поменять, и узел начнет периодически слать статус другому МК (слейву например).
2. Так же узел по запросу шлёт статус тому кто прислал запрос.
а вообще-то да. Подождал, если нет ответа - то ставим что не работает. Где тут нарушение логики и здравого смысла? Если в алгоритме у подыинённых заложено периодически слать статус и он его не шлёт, значит уже чтото пошло не так. И че толку запрашивать, всё равно, скорее всего, не ответит, иначе и так ответил бы - сам, периодически.
т.е. ты можешь даже с другого подчинённого спросить, если надо, а живой ли данный первый подчинённый? И тому другому и придёт ответ статуса от данного первого.
этими запросами только шину за зря забивать будем.
1
data_b0 = rxBuf_can[0]&0xFF;
2
data_b1 = rxBuf_can[1]&0xFF;
3
data_b2 = rxBuf_can[2]&0xFF;
4
data_b3 = rxBuf_can[3]&0xFF;
5
data_b4 = rxBuf_can[4]&0xFF;
6
data_b5 = rxBuf_can[5]&0xFF;
7
data_b6 = rxBuf_can[6]&0xFF;
8
data_b7 = rxBuf_can[7]&0xFF;
А это я байты данных разбираю.
Потом использую
1
ansver_status_reqvest(dev_addr, data_b7);
//здесь dev_addr это полученый удаленный адрес!!
тебе библиотека уже дала байты в готовом виде в массива rxBuf_can[8]. А ты создаешь ещё 8 переменных, копируешь эти байты и ещё &0xFF . Это ты по аналогии с заголовком чтоли? Дак ведь там то, таким извратом занимались, т.к. библиотека ID заголовок даёт в виде целого большого числа 0x02154896, а нам нужны были отдельные разряды. Убери эту фигню, просто пользуй rxBuf_can[8]
т.е. ты можешь даже с другого подчинённого спросить, если надо, а живой ли данный первый подчинённый? И тому другому и придёт ответ статуса от данного первого.
Можно использовать оба механизма, или один на выбор. Важно чтобы они были. Я и от твоего не отказываюсь, но и свой оставляю.
Примерно так: если узел долго не шлет чтожив я его опрашиваю.
+ Как ты правильно заметил я могу с любого узла опросить любой. А если рассылка то придется писать в конфиге что присылать статус всем из списка.
И заметь это функция и механизм базовые. На ней можно опрос датчиков и управление ИУ делать. Т.е я сделал работу с инициативными запросами. Отправил -> Получил данные или квитанцию или еще что. Ведь кроме статуса можно ей датчики опрашивать и команды подавать. Функция то базовая почти.
Так что если тебе удасться ее причесать то быдет оч. круто.
1
data_b0 = rxBuf_can[0]&0xFF;
2
data_b1 = rxBuf_can[1]&0xFF;
3
data_b2 = rxBuf_can[2]&0xFF;
4
data_b3 = rxBuf_can[3]&0xFF;
5
data_b4 = rxBuf_can[4]&0xFF;
6
data_b5 = rxBuf_can[5]&0xFF;
7
data_b6 = rxBuf_can[6]&0xFF;
8
data_b7 = rxBuf_can[7]&0xFF;
А это я байты данных разбираю.
Потом использую
1
ansver_status_reqvest(dev_addr, data_b7);
//здесь dev_addr это полученый удаленный адрес!!
тебе библиотека уже дала байты в готовом виде в массива rxBuf_can[8]. А ты создаешь ещё 8 переменных, копируешь эти байты и ещё &0xFF . Это ты по аналогии с заголовком чтоли? Дак ведь там то, таким извратом занимались, т.к. библиотека ID заголовок даёт в виде целого большого числа 0x02154896, а нам нужны были отдельные разряды. Убери эту фигню, просто пользуй rxBuf_can[8]
Мммда умыл.
т.е надо вместо answer_status_request(dev_addr, data_b7);
сделать answer_status_request(dev_addr, rxBuf_can[7]); ?
Ммм да чет я замудрился.
Я твой код дебаггера из RX вынес в отдельную функцию
это ладно , я имел в виду отсутствие этого в RX
1
if
(can_frame_type && ((rxId_can & 0x20000000)>>29)) RTR_11BIT = 1;
//если 29-ый бит единичка, то это RTR 11 бит
2
else
RTR_11BIT = 0;
и этого в TX
1
if
(can_ID_type){
2
if
(can_frame_type) {txId_can = txId_can | 0xC0000000; DLC = 0;}
// формируем 29 битный ID REMOTE_FRAME
3
else
txId_can = txId_can | 0x80000000; }
// формируем 29 битный ID DATA_FRAME
4
else
if
(can_frame_type){ txId_can=txId_can|0x60000000; DLC = 0;}
// формируем 11 битный ID REMOTE_FRAME
И еще вопрос ты с фильтрами и масками из библиотеки не работал? Я пока фильтрую прямо в RX, но это ест проц, вроде в либе фильтр есть и маска чтобы отфильтровывать и не обрабатывать все что приходит не для меня.
т.е надо вместо answer_status_request(dev_addr, data_b7);
сделать answer_status_request(dev_addr, rxBuf_can[7]); ?
неа, так ты только последний элемент массива передаш
надо так
1
answer_status_request(dev_addr, rxBuf_can);
Глянь сам, по твоим ссылкам RIV1.rar последняя я все на диск скидываю. Небыло.
Вру было в RIV_NODE, проглядел. Думал там то же что и в RIV1
И еще вопрос ты с фильтрами и масками из библиотеки не работал? Я пока фильтрую прямо в RX, но это ест проц, вроде в либе фильтр есть и маска чтобы отфильтровывать и не обрабатывать все что приходит не для меня.
нет, тоже хотел в этом разобраться, пока не смог
Глянь сам, по твоим ссылкам RIV1.rar последняя я все на диск скидываю. Небыло.
Вру было в RIV_NODE, проглядел. Думал там то же что и в RIV1
проверил и в RIV1.rar есть. Может я чутка позже поправил, а ты ранее скачал