Arduino + MCP2515
- Войдите на сайт для отправки комментариев
Здравствуйте, друзья! Помогите разобраться в фильтрации кан сообщений. Использую несколько модулей состоящих из ардуино про мини и mcp2515+mcp2551. Эти модули использую в своем автомобиле. В теории все работает, но на практике жуткие тормоза. Использую библиотеку "mcp_can". Кроме моих модулей в сети кан общаются еще штатные модули(н\р приборная панель). Там тормозов не замечено.
Вот в таком варианте работает безупречно. Тормозов нет. Но тут можно принять сообщение только с одним ID.
#include <mcp_can.h> #include <SPI.h> uint8_t temp_buf[8] = {0,0,0,0,0,0,0,0}; MCP_CAN CAN(10); void setup() { CAN.begin(CAN_250KBPS); CAN.init_Mask(0, 0, 0x3ff); CAN.init_Mask(1, 0, 0x3ff); CAN.init_Filt(0, 0, 0x64); } void loop() { if (CAN_MSGAVAIL == CAN.checkReceive()) { CAN.readMsgBuf(&len, temp_buf);
if (temp_buf[0] == 1) { digitalWrite(4, HIGH); } else { digitalWrite(4, LOW); }
if (temp_buf[1] == 1) { digitalWrite(5, HIGH); } else { digitalWrite(5, LOW); }
if (temp_buf[2] == 1) { digitalWrite(6, HIGH); } else { digitalWrite(6, LOW); }
} }
Если принимать сообщения с разными ID, то начинаются проскакивание сообщений. Сообщения пропускаются, а на практике это выливается в задержки ответной реакции в принимающей стороне (переключение выходов).
#include <mcp_can.h> #include <SPI.h> uint8_t temp_buf[8] = {0,0,0,0,0,0,0,0}; uint8_t buf_1[8] = {0,0,0,0,0,0,0,0}; uint8_t buf_2[8] = {0,0,0,0,0,0,0,0}; MCP_CAN CAN(10); void setup() { CAN.begin(CAN_250KBPS); CAN.init_Mask(0, 0, 0x3ff); CAN.init_Mask(1, 0, 0x3ff); CAN.init_Filt(0, 0, 0x64); CAN.init_Filt(1, 0, 0x75); } void loop() { if (CAN_MSGAVAIL == CAN.checkReceive()) { CAN.readMsgBuf(&len, temp_buf); if(CAN.getCanId() == 0x64) { for(int i = 0; i<len; i++) { buf_1[i] = temp_buf[i]; } } if(CAN.getCanId() == 0x75) { for(int i = 0; i<len; i++) { buf_2[i] = temp_buf[i]; } } } if (buf_1[0] == 1) { digitalWrite(4, HIGH); } else { digitalWrite(4, LOW); } if (buf_1[1] == 1) { digitalWrite(5, HIGH); } else { digitalWrite(5, LOW); } if (buf_1[2] == 1) { digitalWrite(6, HIGH); } else { digitalWrite(6, LOW); } if (buf_2[0] == 1) { digitalWrite(7, HIGH); } else { digitalWrite(7, LOW); } if (buf_2[1] == 1) { digitalWrite(8, HIGH); } else { digitalWrite(8, LOW); } if (buf_2[2] == 1) { digitalWrite(9, HIGH); } else { digitalWrite(9, LOW); } }
Понятно, что используется больше тактов для цикла присваивания, но задержка получения данных всегда с разной длительностью. Может сразу принять сообщение, а может и через некоторое время.
Спасибо, за ответ, но все не так просто. Согласен, пример не очень полно отражает картину. Немного поправлю:
Пример абстрактный! Отражающий логику работы. Периоды у посылок разные 100мс и 50мс. Более медленная посылка может приниматься очень долго, а может сразу проскочить.
очень корявый подход у вас. Что вы вообще хотите сделать? и что конкретно сейчас не получается?
Пример абстрактный! Отражающий логику работы.
"отражающий логику "- это хорошо сказано. Точнее полное отсутсвие логики.
Макс правильно говорит - вставьте работу с пришедшими данными внутрь проверики условия на конкретный ID - внутрь IF строк 26 и 31. Вы же так делали в своем первом коде, который работал "безупречно" - зачем же вы тут нагородили какую-то околесицу? Кстати, тогда и отдельный буфер для каждого ID станет не нужен.
Суд по коду - проблема тут не в том, что "КАН тормозит", а в плохом проектировании программы.
Я хочу принимать сообщения из сети кан и работать с данными в этих сообщениях. Сейчас у меня происходит задержка в получении сообщений - то сообщение, которое чаще отправляется приходит, например 10 раз подряд, а второе, которое реже - один, а может и дольше не попадать в приемное устройство. могут и сразу оба придти.
У меня сообщения от двух устройств одновременно. И с этими данными я работаю постоянно. Где тогда полученные данных хранить?
Я согласен, что в #2 логики не особо много, но не знаю как показать, что сообщения нельзя в одну кучу смешивать.
У меня сообщения от двух устройств одновременно. И с этими данными я работаю постоянно. Где тогда полученные данных хранить?
зачем их хранить? - насколько я вижу, по результатам приема вы включаете и выключаете выходы - так делайте это сразу
Что еще есть в прогграмме? Может дело в том, что у вас цикл ЛУП выполняется больше 50мс? - задержек или каких-то медленных действий в программе нет?
У меня сообщения от двух устройств одновременно. И с этими данными я работаю постоянно. Где тогда полученные данных хранить?
зачем их хранить? - насколько я вижу, по результатам приема вы включаете и выключаете выходы - так делайте это сразу
Что еще есть в прогграмме? Может дело в том, что у вас цикл ЛУП выполняется больше 50мс? - задержек или каких-то медленных действий в программе нет?
Программа для примера. Там не только входы - выходы. Данные из сообщения обрабатываются, с ними производятся определенные действия.
В первом коде все работает, потому что фильтр отсекает все кроме нужного ID еще на уровне MCP. Когда фильтров больше одного начинается каша. Приход сообщений отлично видно через последовательный порт.
Вопрос был о фильтрах.
Вопрос был о фильтрах.
с фильтрами у вас все нормально.
Поэтому я и спрашиваю про программу. Вы зря не верите - но если у вас программа делает в цикле что-то еще и принимает ссобщение по КАН шине порядка раз в 50мс или реже - вы всегда будете принимать только более частое сообщение и лишь изредко то, что приходит реже.
А вот если оставить только один адрес - будет ощущение, что потерь нет, какие бы задержки не стояли.
Вы пробовали измерить, сколько миллисекунд у вас занимает испольнение цикла loop() ? - попробуйте, рузльтат может быть интерсеным
так и делайте. Например так, возможно ваша проблема исчезнет при таком подходе. Только тестируйте именно этот код!
где это в вашем коде?! Так не пойдёт. Зачем выкладывать сюда другой код? Выкладывайте тот код, на котором вы выявили проблему.