т.е. выпавшие узлы получили непонятный тип сообщения, вернее тип 0. Может если такой тип получаем, заново инит MCP 2515 делать?
Возможный но думаю самый крайний вариант.
Вот смотри у меня в памяти контроллера сидит количество людей в помещении. Я его ресечу и теряю данные. (Можно конечно извратится и хранить данные на сервере и при перезагрузке их засасывать по MQTT но как то это уже на надежность повлияет, ИМХО)
Надо всеже понять причину
1. Вариант отражения и решаем терминаторами
2. Вариант контроллер MCP2515 не справляется с потоком
3. Вариант шина SPI между MCP2515 и Mega 2560 не справляется с потоком
4. Mega 2560 не справляется с потоком
Сегодня проконсультировался с колегами разработчиками (которые на CAN изделия делают) , мне пояснили где и как ставить терминаторы в моей иерархии, больше похожей на 3 куста отходящие от центра.
Как оказалось нужно ставить терминаторы не только на самых дальних ветках, но и например если есть точка в которую приходит длинный линк из нее уходит длинный конечный линк и к ней подключены короткими отрезками по 10 см 2 и более контроллеров, нужно ставить терминатор не только на длинный конечный линк но и на один из коротких линков.
Попоробую сегодня
1. Наставить побольше терминаторов
2. Снизить скорость
3. Отключить Debug на все кроме распечатки ID c 05 и 06 msg id на MK и Мастере
case не 0 , а вообще default, т.е. если не наш тип сообщения то инит MCP 2515. Вот код 7 версии. Короче во вкладке system_variables выбираешь узлы, которые подключены к CAN шине. В зависимости от этого будет на них контролироваться посылать или нет аварию, и наличие по этим узлам отладки статуса.
Также включен костыль , о котором говорим, про несоответствующий тип сообщения. Будет инит MCP2515. Добавлены часы на милис для отладки.
Для узлов включи флаг statusprint , для мастера выключи
я сделал часы на миллис. Просто дополнительные переменные не стал заводить и сделал вывод в отладку на 30 - ой секунде. все can Frames уже не как не будут, т.к. фильтры аппаратные теперь
Ну вот например can.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) это много параметров?
но зачастую обратная сторона бывает. Начинаешь код отслеживать, а тебя всё дальше и дальше в дебри уводят по функциям - только и крутишь поиск без конца. Нельзя впадать в крайности. Считаю, что функции нужны чтобы не дублировать одни и теже строки кода.
я сделал часы на миллис. Просто дополнительные переменные не стал заводить и сделал вывод в отладку на 30 - ой секунде. все can Frames уже не как не будут, т.к. фильтры аппаратные теперь
это стоит таймер на 30 сек после старта МК, через который начинается контроль аварии на узлы. Как бы фора даётся 30 секунд, чтобы на связь все успели выйти.
Вот вывод статуса раз в минуту на 30-й секунде - в функции timers()
это другое. То что ты показываешь, это стоит таймер на 30 сек после старта МК, через который начинается контроль аварии на узлы. Как бы фора даётся 30 секунд, чтобы на связь все успели выйти.
Вот вывод статуса раз в минуту на 30-й секунде - в функции timers()
Так все понял. Вывод накаждой 30 секунде минуты, но раз в минуту. Блин а зачем это?
Говорю же на скорую руку делал. Лень было переменные для таймера отдельного добавлять. Часы то уже были сделаны до этого. Да и код приблизился к 75% глобальных переменных. Всё низя больше ничё добавлять)) компилятор уже подругивается. Хотя это всё для uno справедливо. Меге то ещё пофиг
Я у себя ds3231 поставил и в поле данных статуса мастера раз в секунду передаётся время для всех узлов.
Так все понял. Вывод накаждой 30 секунде минуты, но раз в минуту. Блин а зачем это?
Говорю же на скорую руку делал. Лень было переменные для таймера отдельного добавлять. Часы то уже были сделаны до этого. Да и код приблизился к 75% глобальных переменных. Всё низя больше ничё добавлять)) компилятор уже подругивается. Хотя это всё для uno справедливо. Меге то ещё пофиг
Я у себя ds3231 поставил и в поле данных статуса мастера раз в секунду передаётся время для всех узлов.
Ты просто передаешь время на МК или на МК еще как то его в переменную или еще куда кидаешь?
Это неверно. Например, C-bus - синхронный, но не использует ни бит-стаффинг, ни байт-стаффинг
Путаешь теплое и мягкое :). C-bus живет в асинхронном канале передачи данных. CSMA/CD как бы говорит сам за себя.
triac пишет:
Каким образом из того, что некоторые синхронные протоколы используют бит-стаффинг, следует, что мне не надо использовать байт-стаффинг там, где мне это удобно? Где логика?
Ты же не считаешь разработчиков C-bus дураками, отчего же они не пользуются бит/байт стаффингом. Наверно потому, что есть другие способы обозначить начало пакетов.
На парней наезжаешь, что они применив CAN протокол, нерационально используют пропускную способность канала, а сам предлагаешь ничуть не лучше. С таким же успехом можно передавать данные в текстовом виде, а для старт/стоп использовать бинарные значения.
На деле riv, MaksVV, triac, вы допустили одну серьезную ошибку: никто в здравом уме не использует игрушки для разработки систем жизнеобеспечения.
ну раз время там передаю - то логично каждую секунду. Чтобы все секунды уловить. В нашем вот коде с тобой - раз в две секунды))
Время на узлах использую сейчас для также логов, например. На втором этаже у меня МК свет. Там по времени автоматически включается и выключается функция автосвет. У меня врядли будет сложная система с верхними уровнями типа мажордомо. Поэтому узлы сами кое что делают. Может это и не правильная концепция, но так было ещё довольно давно сделано, когда не было такого как сейчас кода. Я ещё даже на нашу библиотеку для MCP2515 не перешёл - всё на старой пока работает.
ну раз время там передаю - то логично каждую секунду. Чтобы все секунды уловить. В нашем вот коде с тобой - раз в две секунды))
Время на узлах использую сейчас для также логов, например. На втором этаже у меня МК свет. Там по времени автоматически включается и выключается функция автосвет. У меня врядли будет сложная система с верхними уровнями типа мажордомо. Поэтому узлы сами кое что делают. Может это и не правильная концепция, но так было ещё довольно давно сделано, когда не было такого как сейчас кода. Я ещё даже на нашу библиотеку для MCP2515 не перешёл - всё на старой пока работает.
Ну насколько я помню мы так и думали, достаточно сложная логика на каждом МК с обменом данными в сети и принятием решений на уровне МК и шлюзование наверх для загрузки скорее сценариев работы.
На деле riv, MaksVV, triac, вы допустили одну серьезную ошибку: никто в здравом уме не использует игрушки для разработки систем жизнеобеспечения.
под словом игрушки надо понимать китайскую ардуину и наш говнокод? Проведу аналогию с автомобилем - мы не собираемся подушками безопасности управлять или ABS. Максимум магнитолой, климатом, оповещением об опасности.
ну, например , для какой-либо синхронизации. Вот смотри. Чтобы разнести по времени (для разгрузки шины) отправку статусов от узлов, мы включаем таймер относительно получения статуса мастера, тут всё гуд.
А вот периодическая отправка параметров у нас сделана раз в 30 сек. Я только в начале (в setup() ) сместил по узлам этот таймер во времени , но т.к. millis не точен и разных узлов тикает по разному, то когда нибудь всё таки отправка данных от разных МК может наложится во времени друг на друга, что не гуд. Поэтому лучше синхронизироваться постоянно относительно чего-то общего. Вот здесь то мы и сделаем отправку параметров узлов относительно какого-либо нужного нам ВРЕМЕНИ МАСТЕРА.
Это неверно. Например, C-bus - синхронный, но не использует ни бит-стаффинг, ни байт-стаффинг
Путаешь теплое и мягкое :). C-bus живет в асинхронном канале передачи данных. CSMA/CD как бы говорит сам за себя.
triac пишет:
Каким образом из того, что некоторые синхронные протоколы используют бит-стаффинг, следует, что мне не надо использовать байт-стаффинг там, где мне это удобно? Где логика?
Ты же не считаешь разработчиков C-bus дураками, отчего же они не пользуются бит/байт стаффингом. Наверно потому, что есть другие способы обозначить начало пакетов.
В CAN протоколе бит-стаффингом вообще называется бит, который устанавливается после 5 подряд одинаковых бит (бит-стаффинг противоположен значению этим 5 бит). Я плохо в этом шарю. Но сделано это типа для того, чтобы получатель отличал такие байты с одинаковыми подряд битами от пауз.
Приёмники соответсвенно, получив 5 одинаковых бит подряд, не обращают внимание на шестой (так как это бит-стаффинг), ну всмысле как бы пропускают его при построении байта.
вот 8 версия. Часы на миллис обновляются только у мастера. Он передаёт их в статусе. Если у какого либо узла встали часы, значит нет связи по шине. Послее время, которое будет показывать, и будет время поломки )).
проверил, даже если CAN модуль в адеквате, шлю ему с канхакера неправильный тип сообщения и наш переинит приводит, наоборот, к зависанию и неработе MCP, но дуня пашет. Переделал, теперь переинит работает, но хз - поможет ли это, когда MCP уже в глюке находится.
Путаешь теплое и мягкое :). C-bus живет в асинхронном канале передачи данных. CSMA/CD как бы говорит сам за себя.
Полная чушь. C-bus - это синхронный канал и CSMA/CA. В каждом сегменте сети всегда есть узел, который дает импульс синхронизации каждые 2 мс. Коллизии избегаются на битовом уровне. RTFM.
Andy пишет:
triac пишет:
Каким образом из того, что некоторые синхронные протоколы используют бит-стаффинг, следует, что мне не надо использовать байт-стаффинг там, где мне это удобно? Где логика?
Ты же не считаешь разработчиков C-bus дураками, отчего же они не пользуются бит/байт стаффингом. Наверно потому, что есть другие способы обозначить начало пакетов.
То есть, логика: "в огороде-бузина, в Киеве - дядька".
Есть несколько способов что-то сделать. Какой бы способ я ни выбрал, вылезет Andy и скажет, что этот способ не годится, потому что "есть другие способы сделать то же самое".
Andy пишет:
На парней наезжаешь, что они применив CAN протокол, нерационально используют пропускную способность канала
Вот только прям так по-детски врать-тo не надо.
Я ни разу не высказывал претензий к тому, как они используют пропускную способность канала. Говорил что CAN сложно и неудобно использовать.
Andy пишет:
С таким же успехом можно передавать данные в текстовом виде, а для старт/стоп использовать бинарные значения.
Я уже упоминал про вариант передачи данных в формате XML или JSON. Для этой задачи он вполне реален и имеет много достоинств. Правда, разборка JSON требует довольно много ресурсов, поэтому я пока его отложил. А пропускной способности хватает.
Проверил, наши фильтры пропускают все короткие ID. Настроил фильтр, чтобы короткие ID почти не просачивались (проходит только 0x000 да и то, когда в поле данных первые два байта равны 0 - абсолютно все запретить аппаратно у меня не получилось).
В функции RX добавил переинициалицию MCP когда получаем короткий нулевой ID 0x000 или расширенный 0x00000000.
На всякий случай добавил в функцию test() ручную переинициализацию MCP - нужно с териманла отправить цифру 9. В случае глюка узла - попробуй вручную таким образом оживить, вот и узнаем помогает ли такая переинициализация.
Заодно исправил функцию печати отладки (в debug.h), а то у тебя, похоже, были глюки при отправке в печать в отладку с DUE, судя по логам.
В отладке теперь везде показывает ID и поле данных.
Блин, сейчас то должен заработать этот костыль. В случае глюков снимай логи как с мастера, так и с узла - посмотрим что они получают в момент глюка.
т.е. выпавшие узлы получили непонятный тип сообщения, вернее тип 0. Может если такой тип получаем, заново инит MCP 2515 делать?
т.е. выпавшие узлы получили непонятный тип сообщения, вернее тип 0. Может если такой тип получаем, заново инит MCP 2515 делать?
Возможный но думаю самый крайний вариант.
Вот смотри у меня в памяти контроллера сидит количество людей в помещении. Я его ресечу и теряю данные. (Можно конечно извратится и хранить данные на сервере и при перезагрузке их засасывать по MQTT но как то это уже на надежность повлияет, ИМХО)
Надо всеже понять причину
1. Вариант отражения и решаем терминаторами
2. Вариант контроллер MCP2515 не справляется с потоком
3. Вариант шина SPI между MCP2515 и Mega 2560 не справляется с потоком
4. Mega 2560 не справляется с потоком
Сегодня проконсультировался с колегами разработчиками (которые на CAN изделия делают) , мне пояснили где и как ставить терминаторы в моей иерархии, больше похожей на 3 куста отходящие от центра.
Как оказалось нужно ставить терминаторы не только на самых дальних ветках, но и например если есть точка в которую приходит длинный линк из нее уходит длинный конечный линк и к ней подключены короткими отрезками по 10 см 2 и более контроллеров, нужно ставить терминатор не только на длинный конечный линк но и на один из коротких линков.
Попоробую сегодня
1. Наставить побольше терминаторов
2. Снизить скорость
3. Отключить Debug на все кроме распечатки ID c 05 и 06 msg id на MK и Мастере
т.е. выпавшие узлы получили непонятный тип сообщения, вернее тип 0. Может если такой тип получаем, заново инит MCP 2515 делать?
Чет я сразу не проникся, ты предлагаешь только init MCP2515 делать?
Т.е в RX() в обработке исключений если непонятный msg_id
can.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK
или сделать отдельный CASE 0 ?
case не 0 , а вообще default, т.е. если не наш тип сообщения то инит MCP 2515. Вот код 7 версии. Короче во вкладке system_variables выбираешь узлы, которые подключены к CAN шине. В зависимости от этого будет на них контролироваться посылать или нет аварию, и наличие по этим узлам отладки статуса.
Также включен костыль , о котором говорим, про несоответствующий тип сообщения. Будет инит MCP2515. Добавлены часы на милис для отладки.
Для узлов включи флаг statusprint , для мастера выключи
мне бы ещё логи выпавших узлов посмотреть
мне бы ещё логи выпавших узлов посмотреть
С них не собирал
Я кстати смотрю тебе наконец функции понравились. С ними действительно удобнее код наследовать.
функции, в которые не передаётся куча параметров, это норм.
Для MaksVV
И еще предлагаю к размышлению
1. Уже пора выводить в прошивке не только имя узла но и версию
2. Не плохо бы было весь однообразный код и переменные вынести в файлы .h и положить их в /arduino/libraries/CAN_LIB например
функции, в которые не передаётся куча параметров, это норм.
Ну вот например can.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) это много параметров?
Поменяй плиз
1
PrintSystemTime();
2
Serial
.println();
Serial
.print(F(
" Принято из CAN: "
));
на
1
PrintSystemTime();
2
Serial
.print(F(
" Принято из CAN: "
));
а то сдвиг получается
И где у тебя теперь периодичность вывода статуса меняется?
Чет ты намудрил.
Да и еще, у тебя отладка CAN FRAMES не отключается (только со всем дебагом), либо все либо то что мне.
Не плохо бы было чтобы была возможность выводить статус узлов без отладки CAN FRAMES, забиваает весь экран, и может поэтому и вмснут контроллеры?
И к стати в дебаг факт реинита MCP2515 нужно как то выкинуть.
я сделал часы на миллис. Просто дополнительные переменные не стал заводить и сделал вывод в отладку на 30 - ой секунде. все can Frames уже не как не будут, т.к. фильтры аппаратные теперь
совершенству нет предела и оттачивать эту отладку можно бесконечно, которую в конечном итого нужно будет просто выключить
Ну вот например can.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) это много параметров?
но зачастую обратная сторона бывает. Начинаешь код отслеживать, а тебя всё дальше и дальше в дебри уводят по функциям - только и крутишь поиск без конца. Нельзя впадать в крайности. Считаю, что функции нужны чтобы не дублировать одни и теже строки кода.
Не плохо бы было чтобы была возможность выводить статус узлов без отладки CAN FRAMES, забиваает весь экран, и может поэтому и вмснут контроллеры?
для мастера
01
// настраиваем отладку
02
03
#define debug //отладка в сериал_монитор. Закоментировать строку после отладки
04
05
#ifdef debug
06
#define debugStatus //отладка в сериал_монитор - таблица статусов узлов CAN сети Закоментировать строку после отладки
07
bool
ID_Print = 0 ;
//флаг распечатки CAN FRAMES в монитор. 0 - будут, только адресованные на данный узел. 1 - все CANFRAMES
08
bool
statusprint = 0 ;
//флаг распечатки статусов в монитор.
09
#include "debug.h"
10
#endif
для узла
01
// настраиваем отладку
02
03
#define debug //отладка в сериал_монитор. Закоментировать строку после отладки
04
05
#ifdef debug
06
#define debugStatus //отладка в сериал_монитор - таблица статусов узлов CAN сети Закоментировать строку после отладки
07
bool
ID_Print = 0 ;
//флаг распечатки CAN FRAMES в монитор. 0 - будут, только адресованные на данный узел. 1 - все CANFRAMES
08
bool
statusprint = 1 ;
//флаг распечатки статусов в монитор.
09
#include "debug.h"
10
#endif
я сделал часы на миллис. Просто дополнительные переменные не стал заводить и сделал вывод в отладку на 30 - ой секунде. все can Frames уже не как не будут, т.к. фильтры аппаратные теперь
Я просто ввел bool ID_Print2 = 1 ; и поставил его
1
#ifdef debug
2
if
(!ID_Print2){
3
bool
prin = 1;
в итоге дебаг включен, статус печатается а Отправлено в CAN нет, просто каждый раз добавляю ;-)
совершенству нет предела и оттачивать эту отладку можно бесконечно, которую в конечном итого нужно будет просто выключить
я не просто так выключаю максимум отладки, может из-за этого глючит. Оставляю только необходимый минимум.
Сейчас NODES CAN COMMUNICATION: выводит раз в 60 сек, где изменить период.
а сколько тебе нужно? сделай отдельный таймер
01
uint32_t prevStat = 0;
02
byte
intervalstat = 20 ;
// интервал распечатки, сек
03
// всё что выше - глобальные переменные
04
05
// всё что ниже в луп.
06
07
if
(curMillis - prevStat > (uint32_t) intervalstat *1000 ) {
08
09
// тут печатаем статус или что там нужно
10
11
prevStat = curMillis;}
я сделал для мастера отладку статусов по всем узлам раз в минуту - куда уж меньше отладки.
На узлах каждый статус мастера выводится, иначе как узнать в какой момент косяк произошёл.
а сколько тебе нужно? сделай отдельный таймер
Да я сделать могу, думал просто зачем каждый раз твой код переписывать. И пытаюсь у тебя спросить.
Просто у тебя стоит 30000 мсек, а вывод раз в 60000 все ищу где еще.
01
#ifdef type_node_master
02
if
(curMillis >= 30000 && !flag_alarmAccident) {flag_alarmAccident = 1;
03
04
for
(
int
i = 0; i<NODS_NUMBER; i++)
if
(!StatusNode_OK[i] && i!= node_address && NodeCANpresence [i]!=0) SendAccident(i);}
05
06
07
if
(ss == 30 && !printstatus) {PrintSystemTime(); PrintStatus(); printstatus = 1;}
08
if
(ss != 30) printstatus = 0;
09
10
#endif
это другое. То что ты показываешь,
1
if
(curMillis >= 30000 && !flag_alarmAccident) {flag_alarmAccident = 1;
это стоит таймер на 30 сек после старта МК, через который начинается контроль аварии на узлы. Как бы фора даётся 30 секунд, чтобы на связь все успели выйти.
Вот вывод статуса раз в минуту на 30-й секунде - в функции timers()
1
if
(ss == 30 && !printstatus) {PrintSystemTime(); PrintStatus(); printstatus = 1;}
2
if
(ss != 30) printstatus = 0;
а ну в принципе да, ты же это и показал))
это другое. То что ты показываешь, это стоит таймер на 30 сек после старта МК, через который начинается контроль аварии на узлы. Как бы фора даётся 30 секунд, чтобы на связь все успели выйти.
Вот вывод статуса раз в минуту на 30-й секунде - в функции timers()
1
if
(ss == 30 && !printstatus) {PrintSystemTime(); PrintStatus(); printstatus = 1;}
2
if
(ss != 30) printstatus = 0;
а ну в принципе да, ты же это и показал))
Так все понял. Вывод накаждой 30 секунде минуты, но раз в минуту. Блин а зачем это?
Тогда уже к NTP и точному времени пора приходить, для нормальных не цыклических таймеров.
Так все понял. Вывод накаждой 30 секунде минуты, но раз в минуту. Блин а зачем это?
Говорю же на скорую руку делал. Лень было переменные для таймера отдельного добавлять. Часы то уже были сделаны до этого. Да и код приблизился к 75% глобальных переменных. Всё низя больше ничё добавлять)) компилятор уже подругивается. Хотя это всё для uno справедливо. Меге то ещё пофиг
Я у себя ds3231 поставил и в поле данных статуса мастера раз в секунду передаётся время для всех узлов.
для отладки и на миллис сойдет, нужно косяк быстрее выявить
Так все понял. Вывод накаждой 30 секунде минуты, но раз в минуту. Блин а зачем это?
Говорю же на скорую руку делал. Лень было переменные для таймера отдельного добавлять. Часы то уже были сделаны до этого. Да и код приблизился к 75% глобальных переменных. Всё низя больше ничё добавлять)) компилятор уже подругивается. Хотя это всё для uno справедливо. Меге то ещё пофиг
Я у себя ds3231 поставил и в поле данных статуса мастера раз в секунду передаётся время для всех узлов.
Ты просто передаешь время на МК или на МК еще как то его в переменную или еще куда кидаешь?
Если кинешь пример буду благодарен.
для отладки и на миллис сойдет, нужно косяк быстрее выявить
Ну уже 1.30 стоит, пока норм.
в каждом узле есть переменные: секунды, минуты, часы, дни, месяцы и т.д.
На мастере, где есть ds3231, эти переменные обновляются при помощи библиотеки ds3231.
Раз в секунду мастер шлёт широковещательно свой статус, в поле данных которого :
data [8] = {сек, мин, часы, дни недели, дни месяца, месяц, последние две цифры года, не исп.}
узлы считывают статус мастера и из поле данных вытягивают эти переменные, тем самым обновляя свои.
Ну и, как ты знаешь, получив статус от мастера, сами шлют ему свой статус, только с разной задержкой, величина которой зависит от адреса узла.
в каждом узле есть переменные: секунды, минуты, часы, дни, месяцы и т.д.
На мастере, где есть ds3231, эти переменные обновляются при помощи библиотеки ds3231.
Раз в секунду мастер шлёт широковещательно свой статус, в поле данных которого :
data [8] = {сек, мин, часы, дни недели, дни месяца, месяц, последние две цифры года, не исп.}
узлы считывают статус мастера и из поле данных вытягивают эти переменные, тем самым обновляя свои.
Ну и, как ты знаешь, получив статус от мастера, сами шлют ему свой статус, только с разной задержкой, величина которой зависит от адреса узла.
А используешь как? В смысле для чего. Именно идеи интересуют.
И кстати 1 раз в секунду статус не часто?
На парней наезжаешь, что они применив CAN протокол, нерационально используют пропускную способность канала, а сам предлагаешь ничуть не лучше. С таким же успехом можно передавать данные в текстовом виде, а для старт/стоп использовать бинарные значения.
На деле riv, MaksVV, triac, вы допустили одну серьезную ошибку: никто в здравом уме не использует игрушки для разработки систем жизнеобеспечения.
ну раз время там передаю - то логично каждую секунду. Чтобы все секунды уловить. В нашем вот коде с тобой - раз в две секунды))
Время на узлах использую сейчас для также логов, например. На втором этаже у меня МК свет. Там по времени автоматически включается и выключается функция автосвет. У меня врядли будет сложная система с верхними уровнями типа мажордомо. Поэтому узлы сами кое что делают. Может это и не правильная концепция, но так было ещё довольно давно сделано, когда не было такого как сейчас кода. Я ещё даже на нашу библиотеку для MCP2515 не перешёл - всё на старой пока работает.
ну раз время там передаю - то логично каждую секунду. Чтобы все секунды уловить. В нашем вот коде с тобой - раз в две секунды))
Время на узлах использую сейчас для также логов, например. На втором этаже у меня МК свет. Там по времени автоматически включается и выключается функция автосвет. У меня врядли будет сложная система с верхними уровнями типа мажордомо. Поэтому узлы сами кое что делают. Может это и не правильная концепция, но так было ещё довольно давно сделано, когда не было такого как сейчас кода. Я ещё даже на нашу библиотеку для MCP2515 не перешёл - всё на старой пока работает.
Ну насколько я помню мы так и думали, достаточно сложная логика на каждом МК с обменом данными в сети и принятием решений на уровне МК и шлюзование наверх для загрузки скорее сценариев работы.
Насчет Majordomo я тебе помогу без проблем.
На деле riv, MaksVV, triac, вы допустили одну серьезную ошибку: никто в здравом уме не использует игрушки для разработки систем жизнеобеспечения.
под словом игрушки надо понимать китайскую ардуину и наш говнокод? Проведу аналогию с автомобилем - мы не собираемся подушками безопасности управлять или ABS. Максимум магнитолой, климатом, оповещением об опасности.
имхо, в любом случае пусть время всем раздаётся в статусе мастера, пригодится по-любому. Тем более чем то же надо тело фрейма статуса забить))
имхо, в любом случае пусть время всем раздаётся в статусе мастера, пригодится по-любому. Тем более чем то же надо тело фрейма статуса забить))
Да я без наездов, просто пытался придумать куда его приспособить и как.
Пока вижу как замену NTP и Часов на МК. Ну и соответственно получается 2 часов
1. Это millis();
2. Полученные сверху по CAN время с точнотью +- 50мс
а у мастера можно добавить еще и NTP по Ethernet
P.S.
Тест пока стоит без сбоев.
01
02:26:30
02
NODES CAN COMMUNICATION:
03
node_5_Net_center_Due2 OK!!!
04
node_6_Hallway_net_center OK!!!
05
node_7_Hallway_main OK!!!
06
node_8_Hallway_light OK!!!
07
node_9_Kitchen_net_center OK!!!
08
node_10_Kitchen_main OK!!!
09
node_11_Kitchen_light OK!!!
10
node_12_WC_main OK!!!
11
node_13_WC_waterleak OK!!!
12
node_14_Bathroom_main OK!!!
13
node_15_Boxroom_main OK!!!
14
node_17_Loggia_main OK!!!
15
node_18_Loggia_recuperator OK!!!
16
node_19_Livingroom_main OK!!!
17
node_20_Bedroom_main OK!!!
18
node_21_Cabinet_main OK!!!
ну, например , для какой-либо синхронизации. Вот смотри. Чтобы разнести по времени (для разгрузки шины) отправку статусов от узлов, мы включаем таймер относительно получения статуса мастера, тут всё гуд.
А вот периодическая отправка параметров у нас сделана раз в 30 сек. Я только в начале (в setup() ) сместил по узлам этот таймер во времени , но т.к. millis не точен и разных узлов тикает по разному, то когда нибудь всё таки отправка данных от разных МК может наложится во времени друг на друга, что не гуд. Поэтому лучше синхронизироваться постоянно относительно чего-то общего. Вот здесь то мы и сделаем отправку параметров узлов относительно какого-либо нужного нам ВРЕМЕНИ МАСТЕРА.
Набрел на глюк node_10_Kitchen_main постоянно перезагружается.
В CAN протоколе бит-стаффингом вообще называется бит, который устанавливается после 5 подряд одинаковых бит (бит-стаффинг противоположен значению этим 5 бит). Я плохо в этом шарю. Но сделано это типа для того, чтобы получатель отличал такие байты с одинаковыми подряд битами от пауз.
Приёмники соответсвенно, получив 5 одинаковых бит подряд, не обращают внимание на шестой (так как это бит-стаффинг), ну всмысле как бы пропускают его при построении байта.
Набрел на глюк node_10_Kitchen_main постоянно перезагружается.
это стало происходить через какое то время во время теста? может он как раз инит MCP2515 всё время пытается сделать?
вот 8 версия. Часы на миллис обновляются только у мастера. Он передаёт их в статусе. Если у какого либо узла встали часы, значит нет связи по шине. Послее время, которое будет показывать, и будет время поломки )).
Набрел на глюк node_10_Kitchen_main постоянно перезагружается.
это стало происходить через какое то время во время теста? может он как раз инит MCP2515 всё время пытается сделать?
Сразу в ресет.
Короче сдох мастер
вот и он получил неправильный тип сообщения и ушел в постоянный инит. Видать костыль с переинитом MCP2515 не помогает.
проверил, даже если CAN модуль в адеквате, шлю ему с канхакера неправильный тип сообщения и наш переинит приводит, наоборот, к зависанию и неработе MCP, но дуня пашет. Переделал, теперь переинит работает, но хз - поможет ли это, когда MCP уже в глюке находится.
видос
Путаешь теплое и мягкое :). C-bus живет в асинхронном канале передачи данных. CSMA/CD как бы говорит сам за себя.
Полная чушь. C-bus - это синхронный канал и CSMA/CA. В каждом сегменте сети всегда есть узел, который дает импульс синхронизации каждые 2 мс. Коллизии избегаются на битовом уровне. RTFM.
То есть, логика: "в огороде-бузина, в Киеве - дядька".
Есть несколько способов что-то сделать. Какой бы способ я ни выбрал, вылезет Andy и скажет, что этот способ не годится, потому что "есть другие способы сделать то же самое".
На парней наезжаешь, что они применив CAN протокол, нерационально используют пропускную способность канала
Вот только прям так по-детски врать-тo не надо.
Я ни разу не высказывал претензий к тому, как они используют пропускную способность канала. Говорил что CAN сложно и неудобно использовать.
С таким же успехом можно передавать данные в текстовом виде, а для старт/стоп использовать бинарные значения.
Я уже упоминал про вариант передачи данных в формате XML или JSON. Для этой задачи он вполне реален и имеет много достоинств. Правда, разборка JSON требует довольно много ресурсов, поэтому я пока его отложил. А пропускной способности хватает.
Проверил, наши фильтры пропускают все короткие ID. Настроил фильтр, чтобы короткие ID почти не просачивались (проходит только 0x000 да и то, когда в поле данных первые два байта равны 0 - абсолютно все запретить аппаратно у меня не получилось).
В функции RX добавил переинициалицию MCP когда получаем короткий нулевой ID 0x000 или расширенный 0x00000000.
На всякий случай добавил в функцию test() ручную переинициализацию MCP - нужно с териманла отправить цифру 9. В случае глюка узла - попробуй вручную таким образом оживить, вот и узнаем помогает ли такая переинициализация.
Заодно исправил функцию печати отладки (в debug.h), а то у тебя, похоже, были глюки при отправке в печать в отладку с DUE, судя по логам.
В отладке теперь везде показывает ID и поле данных.
Блин, сейчас то должен заработать этот костыль. В случае глюков снимай логи как с мастера, так и с узла - посмотрим что они получают в момент глюка.
Скетч v10.
Собрал, залил, проверил. Ждем утра.
Не все сразу сбой и бесконечный инит. Так не полетит.
Есть 3 варианта
1. В библиотеке есть
1
void
mcp2515_reset(
void
);
// Soft Reset MCP2515
1
can.mcp2515_reset();
Но она в файле mcp_can.h стоит private: ее нужно перекинуть в public:
В итоге должно получиться
1
can.mcp2515_reset();
2
delay(1000);
3
MCP2515_Init ();
2. Просто дать больше времени на инит или закрутить его в цикле пока не переинциализируется. Не давая принимать. Но это криво.
3. Тупо дать ресет всей системе, но это самый край.
Ну и совсем по правильному смотрим на структуру самой функции mcp2515_reset из библиотеки:
1
#define MCP_RESET 0xC0
1
#define MCP2515_SELECT() digitalWrite(MCPCS, LOW)
2
#define MCP2515_UNSELECT() digitalWrite(MCPCS, HIGH)
1
void
MCP_CAN::mcp2515_reset(
void
)
2
{
3
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
4
MCP2515_SELECT();
5
spi_readwrite(MCP_RESET);
6
MCP2515_UNSELECT();
7
SPI.endTransaction();
8
delayMicroseconds(10);
9
}
Ну и ручками ресетим.