Очередной "Умный дом", на этот раз модульная система...

MaksVV
Offline
Зарегистрирован: 06.08.2015

т.е. выпавшие узлы получили непонятный тип сообщения, вернее тип 0. Может если такой тип получаем, заново инит MCP 2515 делать? 

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

т.е. выпавшие узлы получили непонятный тип сообщения, вернее тип 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 и Мастере

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

т.е. выпавшие узлы получили непонятный тип сообщения, вернее тип 0. Может если такой тип получаем, заново инит MCP 2515 делать? 

Чет я сразу не проникся, ты предлагаешь только init MCP2515 делать?

Т.е в RX() в обработке исключений если непонятный msg_id 

can.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK

или сделать отдельный CASE 0 ?

MaksVV
Offline
Зарегистрирован: 06.08.2015

case не 0 , а вообще default, т.е. если не наш тип сообщения то инит MCP 2515. Вот код 7 версии. Короче во вкладке system_variables выбираешь узлы, которые подключены к CAN шине. В зависимости от этого будет на них контролироваться посылать или нет аварию, и наличие по этим узлам отладки статуса. 

Также включен костыль ,  о котором говорим,  про несоответствующий тип сообщения. Будет инит MCP2515. Добавлены часы на милис для отладки. 

Для узлов включи флаг statusprint , для мастера выключи

MaksVV
Offline
Зарегистрирован: 06.08.2015

мне бы ещё логи выпавших узлов посмотреть

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

мне бы ещё логи выпавших узлов посмотреть

С них не собирал

riv
Offline
Зарегистрирован: 20.07.2017

Я кстати смотрю тебе наконец функции понравились. С ними действительно удобнее код наследовать.

MaksVV
Offline
Зарегистрирован: 06.08.2015

функции, в которые не передаётся куча параметров, это норм. 

riv
Offline
Зарегистрирован: 20.07.2017

Для MaksVV

И еще предлагаю к размышлению

1. Уже пора выводить в прошивке не только имя узла но и версию

2. Не плохо бы было весь однообразный код и переменные вынести в файлы .h и положить их в /arduino/libraries/CAN_LIB например

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

функции, в которые не передаётся куча параметров, это норм. 

Ну вот например can.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) это много параметров?

riv
Offline
Зарегистрирован: 20.07.2017

Поменяй плиз 

1PrintSystemTime();
2Serial.println(); Serial.print(F("              Принято  из  CAN:  "));

на

1PrintSystemTime();
2Serial.print(F("              Принято  из  CAN:  "));

а то сдвиг получается

00:05:30       
              Принято  из  CAN:  СТАТУС  От Кого:  node_7_Hallway_main          
 
00:05:30       
              Принято  из  CAN:  СТАТУС  От Кого:  node_8_Hallway_light         
 
00:05:30       
              Принято  из  CAN:  СТАТУС  От Кого:  node_9_Kitchen_net_center   
riv
Offline
Зарегистрирован: 20.07.2017

И где у тебя теперь периодичность вывода статуса меняется?

Чет ты намудрил.

Да и еще, у тебя отладка CAN FRAMES не отключается (только со всем дебагом), либо все либо то что мне.

Не плохо бы было чтобы была возможность выводить статус узлов без отладки  CAN FRAMES, забиваает весь экран, и может поэтому и вмснут контроллеры?

И к стати в дебаг факт реинита MCP2515 нужно как то выкинуть.

MaksVV
Offline
Зарегистрирован: 06.08.2015

я сделал часы на миллис. Просто дополнительные переменные не стал заводить и сделал  вывод в отладку на 30 - ой секунде. все can Frames уже не как не будут, т.к. фильтры аппаратные теперь

MaksVV
Offline
Зарегистрирован: 06.08.2015

совершенству нет предела и оттачивать эту отладку можно бесконечно, которую в конечном итого нужно будет просто выключить

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

Ну вот например can.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) это много параметров?

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

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

Не плохо бы было чтобы была возможность выводить статус узлов без отладки  CAN FRAMES, забиваает весь экран, и может поэтому и вмснут контроллеры?

для мастера 

01// настраиваем отладку
02 
03#define debug                     //отладка в сериал_монитор. Закоментировать строку после отладки
04 
05#ifdef debug
06#define debugStatus               //отладка в сериал_монитор - таблица статусов узлов CAN сети Закоментировать строку после отладки
07bool ID_Print = 0 ;               //флаг распечатки CAN FRAMES в монитор. 0 - будут, только адресованные на данный узел. 1 - все CANFRAMES 
08bool statusprint = 0 ;            //флаг распечатки статусов в монитор. 
09#include "debug.h"
10#endif

для узла 

01// настраиваем отладку
02 
03#define debug                     //отладка в сериал_монитор. Закоментировать строку после отладки
04 
05#ifdef debug
06#define debugStatus               //отладка в сериал_монитор - таблица статусов узлов CAN сети  Закоментировать строку после отладки
07bool ID_Print = 0 ;               //флаг распечатки CAN FRAMES в монитор. 0 - будут, только адресованные на данный узел. 1 - все CANFRAMES 
08bool statusprint = 1 ;            //флаг распечатки статусов в монитор. 
09#include "debug.h"
10#endif

 

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

я сделал часы на миллис. Просто дополнительные переменные не стал заводить и сделал  вывод в отладку на 30 - ой секунде. все can Frames уже не как не будут, т.к. фильтры аппаратные теперь

Я просто ввел bool ID_Print2 = 1 ;  и поставил его

1#ifdef debug   
2if (!ID_Print2){
3bool prin = 1;

в итоге дебаг включен, статус печатается а Отправлено в CAN нет, просто каждый раз добавляю ;-)

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

совершенству нет предела и оттачивать эту отладку можно бесконечно, которую в конечном итого нужно будет просто выключить

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

riv
Offline
Зарегистрирован: 20.07.2017

Сейчас NODES CAN COMMUNICATION: выводит раз в 60 сек, где изменить период.

MaksVV
Offline
Зарегистрирован: 06.08.2015

а сколько тебе нужно? сделай отдельный таймер 

01uint32_t prevStat = 0;
02byte intervalstat = 20 ;  //  интервал распечатки, сек
03// всё что выше - глобальные переменные
04 
05// всё что ниже в луп.
06 
07if (curMillis - prevStat > (uint32_t) intervalstat *1000 ) {
08 
09// тут печатаем статус или что там нужно
10 
11prevStat = curMillis;}

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

я сделал для мастера отладку статусов по всем узлам раз в минуту  - куда уж меньше отладки. 

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

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

а сколько тебе нужно? сделай отдельный таймер 

Да я сделать могу, думал просто зачем каждый раз твой код переписывать. И пытаюсь у тебя спросить.

Просто у тебя стоит 30000 мсек, а вывод раз в 60000 все ищу где еще.

01#ifdef type_node_master
02if (curMillis >= 30000 && !flag_alarmAccident) {flag_alarmAccident = 1;
03 
04for (int i = 0; i<NODS_NUMBER; i++) if (!StatusNode_OK[i] && i!= node_address && NodeCANpresence [i]!=0) SendAccident(i);}
05 
06 
07if (ss == 30 && !printstatus) {PrintSystemTime(); PrintStatus(); printstatus = 1;}
08if (ss != 30) printstatus = 0;
09 
10#endif

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

это другое. То что ты показываешь,

1if (curMillis >= 30000 && !flag_alarmAccident) {flag_alarmAccident = 1;

это стоит таймер на 30 сек после старта МК, через который начинается контроль аварии на узлы. Как бы фора даётся 30 секунд, чтобы на связь все успели выйти.

Вот вывод статуса раз в минуту на 30-й секунде  - в функции timers() 

1if (ss == 30 && !printstatus) {PrintSystemTime(); PrintStatus(); printstatus = 1;}
2if (ss != 30) printstatus = 0;

а ну в принципе да, ты же это и показал))

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

это другое. То что ты показываешь, это стоит таймер на 30 сек после старта МК, через который начинается контроль аварии на узлы. Как бы фора даётся 30 секунд, чтобы на связь все успели выйти.

Вот вывод статуса раз в минуту на 30-й секунде  - в функции timers() 

1if (ss == 30 && !printstatus) {PrintSystemTime(); PrintStatus(); printstatus = 1;}
2if (ss != 30) printstatus = 0;

а ну в принципе да, ты же это и показал))

Так все понял. Вывод накаждой 30 секунде минуты, но раз в минуту. Блин а зачем это?

Тогда уже к NTP  и точному времени пора приходить, для нормальных не цыклических таймеров.

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

Так все понял. Вывод накаждой 30 секунде минуты, но раз в минуту. Блин а зачем это?

Говорю же на скорую руку делал. Лень было переменные для таймера отдельного добавлять. Часы то уже были сделаны до этого. Да и код приблизился к 75% глобальных переменных. Всё низя больше ничё добавлять)) компилятор уже подругивается. Хотя это всё для uno справедливо. Меге то ещё пофиг

Я у себя ds3231 поставил и в поле данных статуса мастера раз в секунду передаётся время для всех узлов. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

для отладки и на миллис сойдет, нужно косяк быстрее выявить

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

riv пишет:

Так все понял. Вывод накаждой 30 секунде минуты, но раз в минуту. Блин а зачем это?

Говорю же на скорую руку делал. Лень было переменные для таймера отдельного добавлять. Часы то уже были сделаны до этого. Да и код приблизился к 75% глобальных переменных. Всё низя больше ничё добавлять)) компилятор уже подругивается. Хотя это всё для uno справедливо. Меге то ещё пофиг

Я у себя ds3231 поставил и в поле данных статуса мастера раз в секунду передаётся время для всех узлов. 

Ты просто передаешь время на МК или на МК еще как то его в переменную или еще куда кидаешь? 

Если кинешь пример буду благодарен.

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

для отладки и на миллис сойдет, нужно косяк быстрее выявить

Ну уже 1.30 стоит, пока норм.

MaksVV
Offline
Зарегистрирован: 06.08.2015

в каждом узле есть переменные:  секунды, минуты, часы, дни, месяцы и т.д. 

На мастере, где есть ds3231, эти переменные обновляются при помощи библиотеки ds3231. 

Раз в секунду мастер шлёт широковещательно свой статус, в поле данных которого :

data [8] = {сек, мин, часы, дни недели, дни месяца, месяц, последние две цифры года, не исп.}

узлы считывают статус мастера и из поле данных вытягивают эти переменные, тем самым обновляя свои. 

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

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

в каждом узле есть переменные:  секунды, минуты, часы, дни, месяцы и т.д. 

На мастере, где есть ds3231, эти переменные обновляются при помощи библиотеки ds3231. 

Раз в секунду мастер шлёт широковещательно свой статус, в поле данных которого :

data [8] = {сек, мин, часы, дни недели, дни месяца, месяц, последние две цифры года, не исп.}

узлы считывают статус мастера и из поле данных вытягивают эти переменные, тем самым обновляя свои. 

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

А используешь как? В смысле для чего. Именно идеи интересуют.

И кстати 1 раз в секунду статус не часто?

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

triac пишет:
Это неверно. Например, C-bus - синхронный, но не использует ни бит-стаффинг, ни байт-стаффинг
Путаешь теплое и мягкое :). C-bus живет в асинхронном канале передачи данных. CSMA/CD как бы говорит сам за себя.

triac пишет:
Каким образом из того, что некоторые синхронные протоколы используют бит-стаффинг, следует, что мне не надо использовать байт-стаффинг там, где мне это удобно? Где логика?
Ты же не считаешь разработчиков C-bus дураками, отчего же они не пользуются бит/байт стаффингом. Наверно потому, что есть другие способы обозначить начало пакетов.

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

На деле riv, MaksVV, triac, вы допустили одну серьезную ошибку: никто в здравом уме не использует игрушки для разработки систем жизнеобеспечения.

MaksVV
Offline
Зарегистрирован: 06.08.2015

ну раз время там передаю  - то логично каждую секунду. Чтобы все секунды уловить. В нашем вот коде с тобой - раз в две секунды))

Время на узлах использую сейчас для также логов, например. На втором этаже у меня МК свет. Там по времени автоматически включается и выключается функция автосвет. У меня врядли будет сложная система с верхними уровнями типа мажордомо. Поэтому узлы сами кое что делают. Может это и не правильная концепция, но так было ещё довольно давно сделано, когда не было такого как сейчас кода. Я ещё даже на нашу библиотеку для MCP2515 не перешёл - всё на старой пока работает. 

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

ну раз время там передаю  - то логично каждую секунду. Чтобы все секунды уловить. В нашем вот коде с тобой - раз в две секунды))

Время на узлах использую сейчас для также логов, например. На втором этаже у меня МК свет. Там по времени автоматически включается и выключается функция автосвет. У меня врядли будет сложная система с верхними уровнями типа мажордомо. Поэтому узлы сами кое что делают. Может это и не правильная концепция, но так было ещё довольно давно сделано, когда не было такого как сейчас кода. Я ещё даже на нашу библиотеку для MCP2515 не перешёл - всё на старой пока работает. 

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

Насчет Majordomo я  тебе помогу без проблем.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Andy пишет:

На деле riv, MaksVV, triac, вы допустили одну серьезную ошибку: никто в здравом уме не использует игрушки для разработки систем жизнеобеспечения.

под словом игрушки надо понимать китайскую ардуину и наш говнокод? Проведу аналогию с автомобилем - мы не собираемся подушками безопасности управлять или ABS.  Максимум магнитолой, климатом, оповещением об опасности. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

имхо, в любом случае пусть время всем раздаётся в статусе мастера, пригодится по-любому. Тем более чем то же надо тело фрейма статуса забить))

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

имхо, в любом случае пусть время всем раздаётся в статусе мастера, пригодится по-любому. Тем более чем то же надо тело фрейма статуса забить))

Да я без наездов, просто пытался придумать куда его приспособить и как.

Пока вижу как замену NTP  и Часов на МК. Ну и соответственно получается 2 часов

1. Это millis();

2. Полученные сверху по CAN время с точнотью +- 50мс

а у мастера можно добавить еще и NTP  по Ethernet

P.S.

Тест пока стоит без сбоев.

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:
пытался придумать куда его приспособить и как.

ну, например , для какой-либо синхронизации. Вот смотри. Чтобы разнести по времени (для разгрузки шины) отправку статусов от узлов, мы включаем таймер относительно получения статуса мастера, тут всё гуд. 

А вот периодическая отправка параметров у нас сделана раз в 30 сек. Я только в начале (в setup() ) сместил по узлам этот таймер во времени , но т.к. millis не точен и разных узлов тикает по разному, то когда нибудь всё таки отправка данных от разных МК может наложится во времени друг на друга, что не гуд. Поэтому лучше синхронизироваться постоянно относительно чего-то общего. Вот здесь то мы и сделаем отправку параметров узлов относительно какого-либо нужного нам ВРЕМЕНИ МАСТЕРА. 

riv
Offline
Зарегистрирован: 20.07.2017

Набрел на глюк node_10_Kitchen_main постоянно перезагружается.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Andy пишет:

triac пишет:
Это неверно. Например, C-bus - синхронный, но не использует ни бит-стаффинг, ни байт-стаффинг
Путаешь теплое и мягкое :). C-bus живет в асинхронном канале передачи данных. CSMA/CD как бы говорит сам за себя.

triac пишет:
Каким образом из того, что некоторые синхронные протоколы используют бит-стаффинг, следует, что мне не надо использовать байт-стаффинг там, где мне это удобно? Где логика?
Ты же не считаешь разработчиков C-bus дураками, отчего же они не пользуются бит/байт стаффингом. Наверно потому, что есть другие способы обозначить начало пакетов.

В CAN протоколе бит-стаффингом вообще называется бит, который устанавливается после 5 подряд одинаковых бит (бит-стаффинг противоположен значению этим 5 бит). Я плохо в этом шарю. Но сделано это типа для того, чтобы получатель отличал такие байты с одинаковыми подряд битами от пауз.

Приёмники соответсвенно, получив 5 одинаковых бит подряд, не обращают внимание на шестой (так как это бит-стаффинг), ну всмысле как бы пропускают его при построении байта. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

Набрел на глюк node_10_Kitchen_main постоянно перезагружается.

это стало происходить через какое то время во время теста? может он как раз инит MCP2515 всё время пытается сделать? 

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот 8 версия. Часы на миллис обновляются только у мастера. Он передаёт их в статусе. Если у какого либо узла встали часы, значит нет связи по шине. Послее время, которое будет показывать, и будет время поломки )).

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

riv пишет:

Набрел на глюк node_10_Kitchen_main постоянно перезагружается.

это стало происходить через какое то время во время теста? может он как раз инит MCP2515 всё время пытается сделать? 

Сразу в ресет.

riv
Offline
Зарегистрирован: 20.07.2017

Короче сдох мастер

03:34:30       
  NODES CAN COMMUNICATION:
node_5_Net_center_Due2       OK!!!
node_6_Hallway_net_center    OK!!!
node_7_Hallway_main          OK!!!
node_8_Hallway_light         OK!!!
node_9_Kitchen_net_center    OK!!!
node_10_Kitchen_main         OK!!!
node_11_Kitchen_light        OK!!!
node_12_WC_main              OK!!!
node_13_WC_waterleak         OK!!!
node_14_Bathroom_main        OK!!!
node_15_Boxroom_main         OK!!!
node_17_Loggia_main          OK!!!
node_18_Loggia_recuperator   OK!!!
node_19_Livingroom_main      OK!!!
node_20_Bedroom_main         OK!!!
node_21_Cabinet_main         OK!!!
Error Initializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_Due1ɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_Due1tializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_Due1ɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_DueɁInitializing MCP2515...
 
Мой адрес в сети CAN:  node_4_Net_center_Due1tializing MCP2515...
 
MaksVV
Offline
Зарегистрирован: 06.08.2015

вот и он получил неправильный тип сообщения и ушел в постоянный инит. Видать костыль с переинитом MCP2515 не помогает. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

проверил, даже если CAN модуль в адеквате, шлю ему с канхакера неправильный тип сообщения и наш переинит приводит, наоборот, к зависанию и неработе MCP, но дуня пашет. Переделал, теперь переинит работает, но хз - поможет ли это, когда MCP уже в глюке находится. 

MaksVV
Offline
Зарегистрирован: 06.08.2015
triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

Andy пишет:

Путаешь теплое и мягкое :). C-bus живет в асинхронном канале передачи данных. CSMA/CD как бы говорит сам за себя.

Полная чушь. C-bus - это синхронный канал и CSMA/CA. В каждом сегменте сети всегда есть узел, который дает импульс синхронизации каждые 2 мс. Коллизии избегаются на битовом уровне. RTFM.

Andy пишет:
triac пишет:
Каким образом из того, что некоторые синхронные протоколы используют бит-стаффинг, следует, что мне не надо использовать байт-стаффинг там, где мне это удобно? Где логика?
Ты же не считаешь разработчиков C-bus дураками, отчего же они не пользуются бит/байт стаффингом. Наверно потому, что есть другие способы обозначить начало пакетов.

То есть, логика: "в огороде-бузина, в Киеве - дядька".

Есть несколько способов что-то сделать. Какой бы способ я ни выбрал, вылезет Andy и скажет, что этот способ не годится, потому что "есть другие способы сделать то же самое".

Andy пишет:

На парней наезжаешь, что они применив CAN протокол, нерационально используют пропускную способность канала

Вот только прям так по-детски врать-тo не надо.

Я ни разу не высказывал претензий к тому, как они используют пропускную способность канала.  Говорил что CAN сложно и неудобно использовать.

Andy пишет:

С таким же успехом можно передавать данные в текстовом виде, а для старт/стоп использовать бинарные значения.

Я уже упоминал про вариант передачи данных в формате  XML или  JSON. Для этой задачи он вполне реален и имеет много достоинств. Правда, разборка JSON требует довольно много ресурсов, поэтому я пока его отложил. А пропускной способности хватает.
 

MaksVV
Offline
Зарегистрирован: 06.08.2015

Проверил, наши фильтры пропускают все короткие ID. Настроил фильтр, чтобы короткие ID почти не просачивались (проходит только 0x000 да и то, когда в поле данных первые два байта равны 0 - абсолютно все запретить аппаратно у меня не получилось). 

В функции RX добавил переинициалицию MCP когда получаем короткий нулевой ID 0x000 или расширенный 0x00000000. 

На всякий случай добавил в функцию test() ручную переинициализацию MCP - нужно с териманла отправить цифру 9. В случае глюка узла - попробуй вручную таким образом оживить, вот и узнаем помогает ли такая переинициализация. 

Заодно исправил функцию печати отладки (в debug.h),  а то у тебя, похоже, были глюки при отправке в печать в отладку с DUE, судя по логам. 

В отладке теперь везде показывает ID и поле данных. 

Блин, сейчас то должен заработать этот костыль. В случае глюков снимай логи как с мастера, так и с узла - посмотрим что они получают в момент глюка. 

Скетч v10

 

riv
Offline
Зарегистрирован: 20.07.2017

Собрал, залил, проверил. Ждем утра.

Не все сразу сбой и бесконечный инит. Так не полетит.

riv
Offline
Зарегистрирован: 20.07.2017

Есть 3 варианта

1. В библиотеке есть

1void mcp2515_reset(void);                                           // Soft Reset MCP2515
вызывается
1can.mcp2515_reset();

Но она в файле mcp_can.h стоит  private:  ее нужно перекинуть в public:

В итоге должно получиться

1can.mcp2515_reset();
2delay(1000);
3MCP2515_Init ();

2. Просто дать больше времени на инит или закрутить его в цикле пока не переинциализируется. Не давая принимать. Но это криво.

3. Тупо дать ресет всей системе, но это самый край.

Ну и совсем по правильному смотрим на структуру самой функции mcp2515_reset из библиотеки:

1#define MCP_RESET           0xC0
1#define MCP2515_SELECT()   digitalWrite(MCPCS, LOW)
2#define MCP2515_UNSELECT() digitalWrite(MCPCS, HIGH)
1void 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}

Ну и ручками ресетим.