Подкрутил все кабели, все разъемы, соединил все экраны, подобрал места установки терминаторов путем отслеживания ошибок. Кстати в центре я все соединил без коммутатора (это узлы 6,8) на одном из них терминатор. Без него были ошибки. (На каком то буржуйском сайте производителя умных домов прочитал что в центре звезды тоже надо ставить терминатор)
Уже и контроль регистров TEC и REC устроил. И прерывание на прием настроил. А все сыпались ошибки. Причем как уже написал выше малейшая ошибка превращалась за счет дублей в шторм и поэтапную блокировку контроллеров (bus-off) при TEC>255
Пока основная задача добиться стабильной работы сети, ее контроля и авто восстановления узлов при сбоях.
По CАN, ничего не подскажу, могу только сказать, что, по описанным вами причина, у нас от нее отказались в пользу RS-422. Лет 20-ть назад, это уже в другой конторе, мне также довелось разрабатывать протоколы местной сети устройств и тогда выбор тоже был сделан в пользу RS-422. До сих пор прекрасно работает на сотнях объектов.
>На базе нашей совместной с MaxVV работы я пишу библиотеку https://github.com/graynet-dev/aHomeBus2 >Пока основная задача добиться стабильной работы сети, ее контроля и авто восстановления узлов при сбоях.
>Если заинтересует выложу здесь последнюю версию. (так и не разобрался как на гитхаб синхронизироваться)
Это библиотека может работать только как мастер-слейв ?
как мастер-мастер сможет работать ? если в сети все мастера )
Например если выключатель, который при нажатии должен отправить сигнал на включение света, и получить статус что бы поменять цвет индикации. ( тут слейв-мастер может жить) Дальше усложнение. Если с телефона я отправил команду включить свет, свет включился, но выключатель должен все равно сменить цвет индикации (поменять состояния на "включен")
riv назвал "мастер" "слейв" не в контексте канального уровня сети (это как в модбас и других сетях на RS485 нормальная коммуникация и порядок в сети обычно обеспечивается мастером, который общается со слейвами), а в контексте функционала узлов. (Имхо, действительно, чтобы не вносить путаницу, лучше бы назвал "шлюз"). При этом инициировать передачу сообщений может любой узел в любой момент времени. Т.е. у riv, я так понял, мастер является шлюзом между CAN сетью и другими коммуникациями, а слейв - просто запасной - следит за работой мастера, и если тот погиб, берёт его обязанности на себя.
Так что для осуществления вашей задачи никаких проблем нет.
проблема только остается в запихнуть это все в arduino nano на 8 битном)
Спасибо за толкование
MaxVV прав, насчёт логического уровня, 4 в в модели OSI. В сети есть 3 типа узлов master, slave, node. Master и Slave это шлюзы в Ethernet на Majordomo и контроллеры сети.
На Nano к сожалению либа не заточена, расчет на DUE master/slave и 2560 node. Хотя можно сделать либу и для Nano упростив код.
Просто исходя из названия темы мы делали модульную прошивку. Т. е. в node заливается одна и та же прошивка на всей сети. Функционал определяется настройками. Так же любой node работает шлюзом в modbus, uart и пр. сети.
tosiс, есть вариант использовать 19 ver. нашей прошивки, которая была то того, как riv начал делать библиотеку. Она конечно не простая в понимании, но могу снять видео как всё настраивать.
я пока изучаю вашу реализацию, так как моя толком не заработала ( времени пока мало, но скоро я продолжу), вы выбрали CAN по определенным принципам, и у вас работает прототип. Я пытался на rsXXX ( но от can пока не отказался, так как есть ТЗ)
Моя задача заключается в том, что бы это вся сборка уместилась в одном выключателе в 6см круглой коробочке. Куда подходит только витая пара ( топология звезда) А распайка дополнительно я can схемы состоящей их 2 немалых микросхем - усложняет реализацию. Также в выключателе помимо основной задачи включать и выключать (2-6 каналов) имеется дополнительные датчики температуры, света, IK приемник.
Данные с выключателя по температуре отправляются по интервалу. С ик датчика по активности. Датчик света тоже по активности, ну и включение света по действию. Если учесть что таких выключателей планируется 20 шт по дому, то сеть должна выдержать такой флуд.
Учитывая размеры устройства, я думаю опять вернуться к rs485 \ 422 и продолжить тестировать доставки пакетов широковещательно.
tosic, самый простой для Вас вариант выдрать из нашего кода формирователь и парсер сообщений CAN, или использовать пример из библиотеки mcp2515. Там есть даже CAN to Ethernet. А контроль сети организовать либо более мощным контроллером либо Линукс машиной. Универсальности не добьётесь но работать на nano будет. Ещё вариант использовать esp32, в нем встроенный can нужен только преобразователь уровней сигнала.
можно использовать двойной подрозетник, сняв выключатель, как бы задвигать плату в стену во второй подрозетник, так места для электроники будет больше. ну или по феншую, конечно, рисовать свою плату и в китай её на производство. Будет компактно. Тогда можно все уместить и в подрозетник.
В общем я думаю эксперименты по устойчивости физ уровня с контролем на уровне нашего протокола можно сказать завершены.
Работа на 250 кбит.
Следующая итерация контроль доставки на уровне нашего протокола. Пока думаю простую реализацию с передачей сообщения, ожиданием подтверждения ее получения в заданный период от получателя, в случае не получения подтверждения переповтор и так 3 раза, потом выставляем этот узел как аварийный в своей таблице, кидаем мастеру/слейву сообщение о аварийном соседе, приступаем к диагностике (периодически кидаем запрос на ответы от узла) если по результатам диагностики узел появился в сети опять включаем его в таблицы доступных и разрешаем на него маршрутизацию.
Ни контрольных сумм ни транзакционных механизмов делать пока не хочу. Can как бы делает все за нас на своем урони и поднимать в наш протокол не хочу.
Да основной ответ на вопрос зачем. Т.к мы на ардуине то работаем в жестком последовательном цикле. Увеличение кол-ва функционала приведет иногда к тому что мы просто сбросим принятый CAN конроллером пакет по переполнению обоих буферов не успев их изъять МК для обработки. Вот и вылез переповтор. Можно конечно лезть во FreeRTOS или писать свое разделение времени, и ли по пробовать attachInterrupt (у меня кстати не получилось его использовать внутри класса) но думаю этого должно хватить.
В общем с выходных поставлю тест на передачу например 5 сообщений в секунду с каждого узла , а потом реализацию протокола гарантированной доставки.
P.S. Кстати я помню ты вроде разобрался с масками и фильтрами библиотеки mcp_can
А мне вот в стародавние времена пришлось в CAN frame payload засунуть свой CRC-byte. Почему-то иногда приходило не то, что ожидал. Времени на раскачку не было, поэтому рассказать почему так - не могу. Но могу предупредить об этом ))
А мне вот в стародавние времена пришлось в CAN frame payload засунуть свой CRC-byte. Почему-то иногда приходило не то, что ожидал. Времени на раскачку не было, поэтому рассказать почему так - не могу. Но могу предупредить об этом ))
Честно говоря, CANHacker мне не показал битых пакетов по крайней мере в заголовке. А там все же 4 байта без сбоев.
Жалко 1 байт из 8 отдавать под CRC. Но буду иметь ввиду.
Видимо SDO придется реализовывать. Я честно говоря не хотел. Думал лучше больше команд.
Да кстати я скоро дойду до логики следующего уровня. Не хочешь продолжить?
У меня сделано 3 класса которые различаются для мастера, слейва, узла. В них должны храниться базовые функции 4 уровня. З уровень с маршрутизацией я буду добивать. А в 4 уровне ты традиционно силен. Я про твою логику по установке пинов, контролю исполнения команд и пр.
Я добьюсь гарантии доставки сообщения/команды а ты гарантии исполнения команды. Я имею ввиду перенос логики из твоей 19 версии. Кстати еще работу с EEPROM нужно добить. Конфиг писать и читать. У меня пока только адрес.
Соавтором я не выступлю, у меня нет такой системы для тестов. Но поумничать могу. Например - насчет attachInterrupt. Если у вас и так цикл крутится с проверкой, то видимого смысла в прерывании нет. В обработчике нормально со SPI не поработать, а выставление в нем флага "message arrived" и проверка его в лупе эквивалентна простой проверке ноги, куда INT заведен.
Кстати, Макс, как в автомобилях разруливается ситуация убийства фреймов при коллизиях? Например - фрейм от двигателя убил фрейм для управления фарой... Перепосылка идёт периодическая или используется механизм "посылка - подверждение получения"
attachInterrupt нужен чтобы прервать цикл, т.к если на МК крутится много логик, то как не крутись в момент прихода сообщения МК может быть занят, причем если сообщений много то буфер будет переполнен и CAN контроллер перестанет принимать сообщения. Поэтому нужно по приему сообщения выйти из loop и функций которые внутри него крутятся и обработать Receive.
А у нас во первых библиотека, а во во вторых класс. А чудная функция attachInterrupt(interrupt, function, mode) не может ни принимать не возвращать параметров.
Флеймить не буду, однако не очень себе представляю этот "выход из loop по прерыванию".
Если loop большой и в нем большое кол-во операций то пока мы их не выполним мы не начнем считывать буфер CAN в МК. Прерывание позволяет прервать текущее исполнение и выполнить код считывания и обработки буфера а потом вернуться в то же место продолжать считывать датчики вычислять что нибудь и пр.
Ну, теперь более-менее ясно. Вы пробовали в обработчике прерывания оперировать интерфейсами (в частности - SPI), которые требуют прерываний для работы?
Кстати, Макс, как в автомобилях разруливается ситуация убийства фреймов при коллизиях? Например - фрейм от двигателя убил фрейм для управления фарой... Перепосылка идёт периодическая или используется механизм "посылка - подверждение получения"
у всех по разному, так глубоко я не копал. Но важные данные по-любому с меньшим ID будут , т.к. они выиграют арбитраж. Поэтому в 11 ID битных сетях диагностика вся идёт с ID 0x7_ _ , потому как это не особо важные данные .
Просто данные (ну например датчиков каких-то, особенно которые очень часто обновляются - 10...50мс) естественно без всяких подтверждений в шину сыплются. А вот команды обычно с подтверждением. При коллизиях команды , скорее всего перепосылаются, если нет ответа.
Трудно такие моменты отслеживать, редко они. Да и не было нужды.
Просто данные (ну например датчиков каких-то, особенно которые очень часто обновляются - 10...50мс) естественно без всяких подтверждений в шину сыплются. А вот команды обычно с подтверждением. При коллизиях команды , скорее всего перепосылаются, если нет ответа.
Вот у меня тоже метрики уходят с ноды на гейтвей без подтверждения. Пока нод немного, вроде всё ок. Но, думаю, что это не очень мило, ибо есть вероятность, что нода с самым мелким ID теоретически может оккупировать канал. Да и надо бы срез из ~20 метрик передавать с гарантией получения гейтвеем в течении TTL...
какая частота обновления метрик? сделай с гейтвея бродкаст текущее время. Ответом от нодов будут метрики. Каждая нода отвечает метриками с задержкой (которая зависит от ID ноды) относительно получения бродкаста от гейтвея, так ответы от всех нодов будут разнесены по времени и шанс коллизий минимизируется
да ты чё, нифига там не будет, если раз в 5 сек. Для кана это вообще ниочем. ведь там аппаратные буферы, если арбитраж проиграла метрика, она отправится опять, как только шина освободится. Это надо умудриться отправку полностью убить, для этого надо шину загрузить по самое не хочу
Heartbreath я в шину выдаю для автоподбора скорости шины. Но на транзакции пока не хочу переходить - сильно уж геморно и сразу всё сваливается к логике 485-й шины, убивая всю прелесть CAN.
не согласен. В кане пусть порядок все же будет (синхра), но если экстренно что то нужно можно и без спросу данные послать (понятно что лучше с меньшим ID). В 485 так низя.
Я сделал отправку данных (параметров с датчиков и т.д.) по синхре времени, а всё остальное по желанию ноды - когда хочет тогда шлёт. В основном это команды. И команды у меня с подтверждением выполнения.
Ну, вишь, у меня односторонний поток - метрики к гейтвею. Основная цель - сохранить срез, чтобы напряжение фазы не пришло на мониторинг с током от предыдущего измерения. Так что идея с синхрой по hearthbreath вроде нормальная. Пока не пришлось досрочно срезы с максимумами, к примеру, отсылать на гейтвей...
Measure number я уже внедрил, токо payload тесен стал - не влезаю в 8 байт )) Хотел от CRC избавиться, но вспомнил, что хрень получал как-то вместо пакетов. Хотя, казалось бы, CAN их должен был на входе отстрелить.
Повтор случайно вылез.
дак конечно шилд делать по размеру самой ноды
Добился более менее устойчивой работы сети.
В то же время все равно много ошибок на контроллерах RX/TX, до bus-off не доходит но серьезно смущает.
Еще по какой то причине лезут дубли (а то и 3-5) отправленных сообщений. Т.е отправляю одно сообщение а по сети их принимают по 2-5 раз.
https://www.youtube.com/watch?v=aAMnVAc9-I8
а каким образом? все-таки репитеры шлюзы? можешь схему сети нарисовать ? топологию
Добился более менее устойчивой работы сети.
Подкрутил все кабели, все разъемы, соединил все экраны, подобрал места установки терминаторов путем отслеживания ошибок. Кстати в центре я все соединил без коммутатора (это узлы 6,8) на одном из них терминатор. Без него были ошибки. (На каком то буржуйском сайте производителя умных домов прочитал что в центре звезды тоже надо ставить терминатор)
Вот топология, но от коммутатора отказался.
Добился более менее устойчивой работы сети.
На базе нашей совместной с MaxVV работы я пишу библиотеку https://github.com/graynet-dev/aHomeBus2
Пока основная задача добиться стабильной работы сети, ее контроля и авто восстановления узлов при сбоях.
Если заинтересует выложу здесь последнюю версию. (так и не разобрался как на гитхаб синхронизироваться)
В центре 2 DUE они держат CAN сеть и являются шлюзами к Ethernet (socket, ModbusTCP, MQTT)
Абоненты Mega2560 pro у них GPIO + ModbusRTU для связи с контроллерами управления шторами, управление вентиляцией и отоплением.
По поводу повторителя. Так с ним и не разобрался. Думаю просто не совместимость MCP2551 и TJA1050 с модуля MCP2515.
Проблема выражалась в дублировании сообщений ( а то и 2-5 повторов) коммутатором, причем и ошибок тоже. В итоге ошибки быстро нарастали и гасили контроллер. Эту статью уже наизусть почти выучил http://microsin.net/adminstuff/hardware/mcp2515-stand-alone-can-controller-with-spi-interface.html
Уже и контроль регистров TEC и REC устроил. И прерывание на прием настроил. А все сыпались ошибки. Причем как уже написал выше малейшая ошибка превращалась за счет дублей в шторм и поэтапную блокировку контроллеров (bus-off) при TEC>255
Кстати прикупил тут по случаю для мультирума Комуутатор Kramer vs848 и Регулятор уровня Kramer VA-8xl у них 232, 485 есть.
Соответственно подключу через CAN в MQTT к Majordomo. Нашел 8 канальный усилитель на али (У меня 7 помещений, в одном стерео, остальные моно)
Спасибо за подробный ответ.
По CАN, ничего не подскажу, могу только сказать, что, по описанным вами причина, у нас от нее отказались в пользу RS-422. Лет 20-ть назад, это уже в другой конторе, мне также довелось разрабатывать протоколы местной сети устройств и тогда выбор тоже был сделан в пользу RS-422. До сих пор прекрасно работает на сотнях объектов.
От 485 я отказался из-за мономастерности.
Да и проблему удалось решить. Нужно просто соблюдать правила построения CAN и правила CKC для ВЧ сигналов. Как с 485 не прокатит.
Получил более или менее четкую картинку в сети.
скорость 125 кбит/с? думаю можно даже 100 поставить. Этого хватит
Сутки простоял на 100 кбит - без ошибок.
Сейчас поставил 250 кбит - пока ошибок нет.
1
>На базе нашей совместной с MaxVV работы я пишу библиотеку https://github.com/graynet-dev/aHomeBus2
>Пока основная задача добиться стабильной работы сети, ее контроля и авто восстановления узлов при сбоях.
>Если заинтересует выложу здесь последнюю версию. (так и не разобрался как на гитхаб синхронизироваться)
Это библиотека может работать только как мастер-слейв ?
как мастер-мастер сможет работать ? если в сети все мастера )
Например если выключатель, который при нажатии должен отправить сигнал на включение света, и получить статус что бы поменять цвет индикации. ( тут слейв-мастер может жить) Дальше усложнение. Если с телефона я отправил команду включить свет, свет включился, но выключатель должен все равно сменить цвет индикации (поменять состояния на "включен")
riv назвал "мастер" "слейв" не в контексте канального уровня сети (это как в модбас и других сетях на RS485 нормальная коммуникация и порядок в сети обычно обеспечивается мастером, который общается со слейвами), а в контексте функционала узлов. (Имхо, действительно, чтобы не вносить путаницу, лучше бы назвал "шлюз"). При этом инициировать передачу сообщений может любой узел в любой момент времени. Т.е. у riv, я так понял, мастер является шлюзом между CAN сетью и другими коммуникациями, а слейв - просто запасной - следит за работой мастера, и если тот погиб, берёт его обязанности на себя.
Так что для осуществления вашей задачи никаких проблем нет.
проблема только остается в запихнуть это все в arduino nano на 8 битном)
Спасибо за толкование
проблема только остается в запихнуть это все в arduino nano на 8 битном)
Спасибо за толкование
MaxVV прав, насчёт логического уровня, 4 в в модели OSI. В сети есть 3 типа узлов master, slave, node. Master и Slave это шлюзы в Ethernet на Majordomo и контроллеры сети.
На Nano к сожалению либа не заточена, расчет на DUE master/slave и 2560 node. Хотя можно сделать либу и для Nano упростив код.
Просто исходя из названия темы мы делали модульную прошивку. Т. е. в node заливается одна и та же прошивка на всей сети. Функционал определяется настройками. Так же любой node работает шлюзом в modbus, uart и пр. сети.
tosiс, есть вариант использовать 19 ver. нашей прошивки, которая была то того, как riv начал делать библиотеку. Она конечно не простая в понимании, но могу снять видео как всё настраивать.
спасибо MaksVV
я пока изучаю вашу реализацию, так как моя толком не заработала ( времени пока мало, но скоро я продолжу), вы выбрали CAN по определенным принципам, и у вас работает прототип. Я пытался на rsXXX ( но от can пока не отказался, так как есть ТЗ)
Моя задача заключается в том, что бы это вся сборка уместилась в одном выключателе в 6см круглой коробочке. Куда подходит только витая пара ( топология звезда) А распайка дополнительно я can схемы состоящей их 2 немалых микросхем - усложняет реализацию. Также в выключателе помимо основной задачи включать и выключать (2-6 каналов) имеется дополнительные датчики температуры, света, IK приемник.
Данные с выключателя по температуре отправляются по интервалу. С ик датчика по активности. Датчик света тоже по активности, ну и включение света по действию. Если учесть что таких выключателей планируется 20 шт по дому, то сеть должна выдержать такой флуд.
Учитывая размеры устройства, я думаю опять вернуться к rs485 \ 422 и продолжить тестировать доставки пакетов широковещательно.
tosic, самый простой для Вас вариант выдрать из нашего кода формирователь и парсер сообщений CAN, или использовать пример из библиотеки mcp2515. Там есть даже CAN to Ethernet. А контроль сети организовать либо более мощным контроллером либо Линукс машиной. Универсальности не добьётесь но работать на nano будет. Ещё вариант использовать esp32, в нем встроенный can нужен только преобразователь уровней сигнала.
можно использовать двойной подрозетник, сняв выключатель, как бы задвигать плату в стену во второй подрозетник, так места для электроники будет больше. ну или по феншую, конечно, рисовать свою плату и в китай её на производство. Будет компактно. Тогда можно все уместить и в подрозетник.
MaksVV, приветствую.
В общем я думаю эксперименты по устойчивости физ уровня с контролем на уровне нашего протокола можно сказать завершены.
Работа на 250 кбит.
Следующая итерация контроль доставки на уровне нашего протокола. Пока думаю простую реализацию с передачей сообщения, ожиданием подтверждения ее получения в заданный период от получателя, в случае не получения подтверждения переповтор и так 3 раза, потом выставляем этот узел как аварийный в своей таблице, кидаем мастеру/слейву сообщение о аварийном соседе, приступаем к диагностике (периодически кидаем запрос на ответы от узла) если по результатам диагностики узел появился в сети опять включаем его в таблицы доступных и разрешаем на него маршрутизацию.
Ни контрольных сумм ни транзакционных механизмов делать пока не хочу. Can как бы делает все за нас на своем урони и поднимать в наш протокол не хочу.
Да основной ответ на вопрос зачем. Т.к мы на ардуине то работаем в жестком последовательном цикле. Увеличение кол-ва функционала приведет иногда к тому что мы просто сбросим принятый CAN конроллером пакет по переполнению обоих буферов не успев их изъять МК для обработки. Вот и вылез переповтор. Можно конечно лезть во FreeRTOS или писать свое разделение времени, и ли по пробовать attachInterrupt (у меня кстати не получилось его использовать внутри класса) но думаю этого должно хватить.
В общем с выходных поставлю тест на передачу например 5 сообщений в секунду с каждого узла , а потом реализацию протокола гарантированной доставки.
P.S. Кстати я помню ты вроде разобрался с масками и фильтрами библиотеки mcp_can
1
_interface.init_Mask(0,1,0x000FF000);
//Маскируем 1 байт // Init first mask...
1
_interface.init_Filt(0,1,0x00000000);
//Ib бродкаст // Init first filter...
2
_interface.init_Filt(1,1,0x00013000);
//адрес узла // Init second filter...
3
4
_interface.init_Mask(1,1,0x00000000);
// Init second mask...
5
6
_interface.init_Filt(2,1,0x00000000);
// Init 3 filter...
7
_interface.init_Filt(3,1,0x00000000);
// Init 4 filter...
8
_interface.init_Filt(4,1,0x00000000);
// Init 5 filter...
9
_interface.init_Filt(5,1,0x00000000);
// Init 6 filter...
Хочу принимать пакеты только для себя destination address = NodeID или широковещательно destination address = 0
Подскажи как сформировать маску и фильтры.
А мне вот в стародавние времена пришлось в CAN frame payload засунуть свой CRC-byte. Почему-то иногда приходило не то, что ожидал. Времени на раскачку не было, поэтому рассказать почему так - не могу. Но могу предупредить об этом ))
А мне вот в стародавние времена пришлось в CAN frame payload засунуть свой CRC-byte. Почему-то иногда приходило не то, что ожидал. Времени на раскачку не было, поэтому рассказать почему так - не могу. Но могу предупредить об этом ))
Честно говоря, CANHacker мне не показал битых пакетов по крайней мере в заголовке. А там все же 4 байта без сбоев.
Жалко 1 байт из 8 отдавать под CRC. Но буду иметь ввиду.
Видимо SDO придется реализовывать. Я честно говоря не хотел. Думал лучше больше команд.
Да кстати я скоро дойду до логики следующего уровня. Не хочешь продолжить?
У меня сделано 3 класса которые различаются для мастера, слейва, узла. В них должны храниться базовые функции 4 уровня. З уровень с маршрутизацией я буду добивать. А в 4 уровне ты традиционно силен. Я про твою логику по установке пинов, контролю исполнения команд и пр.
Я добьюсь гарантии доставки сообщения/команды а ты гарантии исполнения команды. Я имею ввиду перенос логики из твоей 19 версии. Кстати еще работу с EEPROM нужно добить. Конфиг писать и читать. У меня пока только адрес.
Это , наверное, Максу предложение? У меня никакой 19 версии нет.
Вот же незадача. Сюда редко кто кроме MaxVV пишет. С телефона не обратил внимания на автора.
Да это Максу предложение.
Хотя я думаю он не будет против соавторов.
Соавтором я не выступлю, у меня нет такой системы для тестов. Но поумничать могу. Например - насчет attachInterrupt. Если у вас и так цикл крутится с проверкой, то видимого смысла в прерывании нет. В обработчике нормально со SPI не поработать, а выставление в нем флага "message arrived" и проверка его в лупе эквивалентна простой проверке ноги, куда INT заведен.
Кстати, Макс, как в автомобилях разруливается ситуация убийства фреймов при коллизиях? Например - фрейм от двигателя убил фрейм для управления фарой... Перепосылка идёт периодическая или используется механизм "посылка - подверждение получения"
attachInterrupt нужен чтобы прервать цикл, т.к если на МК крутится много логик, то как не крутись в момент прихода сообщения МК может быть занят, причем если сообщений много то буфер будет переполнен и CAN контроллер перестанет принимать сообщения. Поэтому нужно по приему сообщения выйти из loop и функций которые внутри него крутятся и обработать Receive.
А у нас во первых библиотека, а во во вторых класс. А чудная функция attachInterrupt(interrupt, function, mode) не может ни принимать не возвращать параметров.
.
Флеймить не буду, однако не очень себе представляю этот "выход из loop по прерыванию".
Флеймить не буду, однако не очень себе представляю этот "выход из loop по прерыванию".
Если loop большой и в нем большое кол-во операций то пока мы их не выполним мы не начнем считывать буфер CAN в МК. Прерывание позволяет прервать текущее исполнение и выполнить код считывания и обработки буфера а потом вернуться в то же место продолжать считывать датчики вычислять что нибудь и пр.
Ну, теперь более-менее ясно. Вы пробовали в обработчике прерывания оперировать интерфейсами (в частности - SPI), которые требуют прерываний для работы?
MaksVV, приветствую.
P.S. Кстати я помню ты вроде разобрался с масками и фильтрами библиотеки mcp_can
Хочу принимать пакеты только для себя destination address = NodeID или широковещательно destination address = 0
Подскажи как сформировать маску и фильтры.
01
byte
node_address = 0x13;
// my address
02
_interface.begin(MCP_STDEXT, CAN_250KBPS, MCP_8MHZ);
03
_interface.init_Mask(0,1,0x000FF000);
// first маска на разряд ID "target_ADDR"
04
_interface.init_Filt(0,1,(node_address & 0xFFFFFFFF)<<12);
// пропускаем мессаги только которые нам
05
_interface.init_Filt(1,1,0x00000000);
// пропускаем мессаги броадкасты
06
_interface.init_Mask(1,1,0x000FF000);
// second маска на разряд ID "target_ADDR"
07
_interface.init_Filt(2,1,0x00000000);
// пропускаем мессаги броадкасты
08
_interface.init_Filt(3,1,0x00000000);
// пропускаем мессаги броадкасты
09
_interface.init_Filt(4,1,0x00000000);
// пропускаем мессаги броадкасты
10
_interface.init_Filt(5,1,0x00000000);
// пропускаем мессаги броадкасты
11
_interface.setMode(MCP_NORMAL);
// Change to normal mode
у всех по разному, так глубоко я не копал. Но важные данные по-любому с меньшим ID будут , т.к. они выиграют арбитраж. Поэтому в 11 ID битных сетях диагностика вся идёт с ID 0x7_ _ , потому как это не особо важные данные .
Просто данные (ну например датчиков каких-то, особенно которые очень часто обновляются - 10...50мс) естественно без всяких подтверждений в шину сыплются. А вот команды обычно с подтверждением. При коллизиях команды , скорее всего перепосылаются, если нет ответа.
Трудно такие моменты отслеживать, редко они. Да и не было нужды.
Просто данные (ну например датчиков каких-то, особенно которые очень часто обновляются - 10...50мс) естественно без всяких подтверждений в шину сыплются. А вот команды обычно с подтверждением. При коллизиях команды , скорее всего перепосылаются, если нет ответа.
Вот у меня тоже метрики уходят с ноды на гейтвей без подтверждения. Пока нод немного, вроде всё ок. Но, думаю, что это не очень мило, ибо есть вероятность, что нода с самым мелким ID теоретически может оккупировать канал. Да и надо бы срез из ~20 метрик передавать с гарантией получения гейтвеем в течении TTL...
какая частота обновления метрик? сделай с гейтвея бродкаст текущее время. Ответом от нодов будут метрики. Каждая нода отвечает метриками с задержкой (которая зависит от ID ноды) относительно получения бродкаста от гейтвея, так ответы от всех нодов будут разнесены по времени и шанс коллизий минимизируется
Где-то секунд 5 ставил +/- рандомайз. Гейтвей всё равно выстреливает вверх раз в пять минут где-то - чаще смысла нет.
Но коллизии всё равно могут быть и в "выстрел" гейтвея могут попадать метрики из разных срезов.
Поэтому интересно, как это в Real-time системах устроено.
да ты чё, нифига там не будет, если раз в 5 сек. Для кана это вообще ниочем. ведь там аппаратные буферы, если арбитраж проиграла метрика, она отправится опять, как только шина освободится. Это надо умудриться отправку полностью убить, для этого надо шину загрузить по самое не хочу
Heartbreath я в шину выдаю для автоподбора скорости шины. Но на транзакции пока не хочу переходить - сильно уж геморно и сразу всё сваливается к логике 485-й шины, убивая всю прелесть CAN.
не согласен. В кане пусть порядок все же будет (синхра), но если экстренно что то нужно можно и без спросу данные послать (понятно что лучше с меньшим ID). В 485 так низя.
Я сделал отправку данных (параметров с датчиков и т.д.) по синхре времени, а всё остальное по желанию ноды - когда хочет тогда шлёт. В основном это команды. И команды у меня с подтверждением выполнения.
Ну, вишь, у меня односторонний поток - метрики к гейтвею. Основная цель - сохранить срез, чтобы напряжение фазы не пришло на мониторинг с током от предыдущего измерения. Так что идея с синхрой по hearthbreath вроде нормальная. Пока не пришлось досрочно срезы с максимумами, к примеру, отсылать на гейтвей...
сделай тогда уникальный номер измерения, и пусть вверх отправляются только с одинаковыми номерами
Measure number я уже внедрил, токо payload тесен стал - не влезаю в 8 байт )) Хотел от CRC избавиться, но вспомнил, что хрень получал как-то вместо пакетов. Хотя, казалось бы, CAN их должен был на входе отстрелить.
странно, да, по идее если сообщение прошло, оно уже проCRCлось. 29 ID можно использовать если сидишь на 11 битных. Туда часть инфы запихать.
riv , ты опять сменил назначение разрядов ID ?
riv , ты опять сменил назначение разрядов ID ?
Если ты обратил внимание библиотека это форк https://github.com/adlerweb/asysbus
Поэтому временно я не стал менять его разряды пока не разберусь как работает ряд фич.
После этого перейду на нашу разрядность.
P.S.
У Florian Knodt есть 2 интересных фичи - это хуки пинов и хуки пользовательских функций.
Я сейчас сетевой уровень добиваю. Контроль и маршрутизацию в сети. Поменять абстракцию можно в лет.
Вот смотри так реализована в классе CAN передача
01
bool
AHB_CAN::ahbSend_V(uint8_t type, uint8_t cmd, uint8_t target, uint8_t port, uint8_t source, uint8_t len,
byte
data[8]) {
02
uint32_t addr = ahbCanAddrAssemble(type, cmd, target, port, source);
03
if
(addr == 0){
04
//Serial.println(F("TX Message send addr=0"));
05
return
false
;
06
}
07
08
lastErr = _interface.sendMsgBuf(addr, 1, len, data);
09
if
(lastErr != CAN_OK) {
10
Serial
.println(
"CAN ahbSend lastErr = CAN_FAIL"
);
11
return
false
;
12
}
13
else
{
14
Serial
.println(
"CAN ahbSend lastErr = CAN_OK"
);
15
16
}
17
Serial
.println();
18
19
}
20
return
true
;
21
}
01
uint32_t AHB_CAN::ahbCanAddrAssemble(uint8_t f_type, uint8_t f_cmd, uint8_t f_target, uint8_t f_port, uint8_t f_source) {
02
uint32_t addr = 0x80000000;
03
04
if
(f_type == AHB_PKGTYPE_UNICAST) {
05
if
(f_target > 255) {
06
//Serial.println("f_target > 255");
07
return
0;}
08
if
(f_port < 0 || f_port > 15) {
09
//Serial.println("f_port < 0 || f_port > 15");
10
return
0;
11
}
12
}
13
else
{
14
if
(f_target > 255) {
15
//Serial.println("f_target > 255");
16
return
0;
17
}
18
}
19
20
if
(f_source > 255) {
21
//Serial.println("f_source > 255");
22
return
0;
23
}
24
25
addr = (f_type & 0xFFFFFFFF)<<28 | (f_cmd & 0xFFFFFFFF)<<20 | (f_target & 0xFFFFFFFF)<<12 | (f_port & 0xFFFFFFFF)<<8 | f_source ;
26
27
return
addr;
28
}
ага, всё как у нас почти, только разряды другие.
ага, всё как у нас почти, только разряды другие.
В оригинале было так. Он не использовал ниблы, а пошел более оптимальным путем с т.з. использования адресного пространства.
01
unsigned
long
ASB_CAN::asbCanAddrAssemble(
byte
type, unsigned
int
target, unsigned
int
source,
char
port) {
02
unsigned
long
addr = 0x80000000;
03
04
if
(type > 0x03)
return
0;
05
addr |= ((unsigned
long
)type << 28);
06
07
if
(type == ASB_PKGTYPE_UNICAST) {
08
if
(target > 0x7FF)
return
0;
09
if
(port < 0 ||port > 0x1F)
return
0;
10
11
addr |= ((unsigned
long
)port << 23);
12
}
else
{
13
if
(target > 0xFFFF)
return
0;
14
}
15
16
addr |= ((unsigned
long
)target << 11);
17
18
if
(source > 0x7FF)
return
0;
19
addr |= source;
20
21
return
addr;
22
}
23
24
bool
ASB_CAN::asbSend(
byte
type, unsigned
int
target, unsigned
int
source,
char
port,
byte
len,
const
byte
*data) {
25
unsigned
long
addr = asbCanAddrAssemble(type, target, source, port);
26
if
(addr == 0)
return
false
;
27
28
lastErr = _interface.sendMsgBuf(addr, 1, len, data);
29
if
(lastErr != CAN_OK)
return
false
;
30
return
true
;
31
}