Arduino UNO и MCP2515 CAN

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

Можно включать таймер после запроса, при получении ответов таймер сбрасывается. Если ответа нет, таймер дотикает до конца, это и есть ошибка. Таймер можно на millis().

bezzeb
Offline
Зарегистрирован: 02.11.2013

sadman41 пишет:
Есть методы. Три раза пульнуть посылку и получить "Все буфера заняты".

а можно поподробнее?

отправка идет постоянно.

а вот как получить "все буфера заняты"?

sadman41
Offline
Зарегистрирован: 19.10.2016

bezzeb пишет:

sadman41 пишет:
Есть методы. Три раза пульнуть посылку и получить "Все буфера заняты".

а можно поподробнее?

отправка идет постоянно.

а вот как получить "все буфера заняты"?

В библиотеке, которую я использую (https://github.com/autowp/arduino-mcp2515), функция sendMessage() возвращает значение ERROR_FAILTX, если все TX буфера (а их 3 шт) заняты отправкой.

Таким образом, максимум через 3 посылки, система может понять, что MCP-шка не может выкинуть пакеты в CAN-bus, стало быть есть какие-то причины, препятствующие этому.

Так же имеется функция getStatus(), читающая его прямиком с MCP. По даташиту можно разобраться, в каком состоянии он находится.

bezzeb
Offline
Зарегистрирован: 02.11.2013

sadman41 

спасибо

stebne
Offline
Зарегистрирован: 09.02.2021

Добрый день , помогите переделать скеч.

нужно чтобы  при нажатии кнопки отправлялась первая команда ( mcp2515.sendMessage(&canMsg1);) один раз, после отпускания вторая (mcp2515.sendMessage(&canMsg2);) один раз.

Спасибо..

#include <SPI.h>
#include <mcp2515.h>
const int butPin = 5;
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);

void setup() {
  canMsg1.can_id  = 0x821;
  canMsg1.can_dlc = 8;
  canMsg1.data[0] = 0x00;
  canMsg1.data[1] = 0x02;
  canMsg1.data[2] = 0x09;
  canMsg1.data[3] = 0x00;
  canMsg1.data[4] = 0x58;
  canMsg1.data[5] = 0x00;
  canMsg1.data[6] = 0x40;
  canMsg1.data[7] = 0x00;

  canMsg2.can_id  = 0x231;
  canMsg2.can_dlc = 8;
  canMsg2.data[0] = 0x00;
  canMsg2.data[1] = 0x00;
  canMsg2.data[2] = 0x01;
  canMsg2.data[3] = 0x00;
  canMsg2.data[4] = 0x58;
  canMsg2.data[5] = 0x00;
  canMsg2.data[6] = 0x40;
  canMsg2.data[7] = 0x00;
  
  pinMode(butPin,INPUT_PULLUP);
 
  while (!Serial);
  Serial.begin(115200);
  SPI.begin();
 
  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS, MCP_16MHZ);
  mcp2515.setNormalMode();
 
 }
void loop() {
  if (digitalRead(butPin) == LOW) {
     mcp2515.sendMessage(&canMsg1);
     delay(500);
     mcp2515.sendMessage(&canMsg2);
     }
     delay(200);
  }

     

vadiks
Offline
Зарегистрирован: 25.04.2020

stebne пишет:

Добрый день , помогите переделать скеч.

нужно чтобы  при нажатии кнопки отправлялась первая команда ( mcp2515.sendMessage(&canMsg1);) один раз, после отпускания вторая (mcp2515.sendMessage(&canMsg2);) один раз.

Спасибо..

Курсовую делаете? ;)

stebne
Offline
Зарегистрирован: 09.02.2021

Нет,нужно для автомобиля , управление БК ,краткое нажатие и длинное.

vadiks
Offline
Зарегистрирован: 25.04.2020

stebne пишет:

Добрый день , помогите переделать скеч.

нужно чтобы  при нажатии кнопки отправлялась первая команда ( mcp2515.sendMessage(&canMsg1);) один раз, после отпускания вторая (mcp2515.sendMessage(&canMsg2);) один раз.

Спасибо..

stebne пишет:
...нужно для автомобиля , управление БК ,краткое нажатие и длинное.

Может я вас не правильно понимаю, но если сделать так как вы хотите, у вас при любом нажатии (короткое и длинное) будут уходить обе команды.

sadman41
Offline
Зарегистрирован: 19.10.2016

К CAN кнопка отношения не имеет, поэтому просто подскажу: ловить нужно не состояние кнопки, а его изменение.

stebne
Offline
Зарегистрирован: 09.02.2021

Нажал,пошла 1 команда держишь после отпустил кнопку пошла 2 команда.
Если удержание до 2000 млс короткая,если больше 2000 млс длинная.
Длинная вкл выкл
Короткая переключение режимов.

vadiks
Offline
Зарегистрирован: 25.04.2020

Подключайте таймер для таких целей.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Для интервалов порядка единиц секунд таймер не нужен.

Valer1
Offline
Зарегистрирован: 05.03.2021

Железо: nano + mcp2515

Задача: после подачи питания посылать в CAN шину 500 кбс набор из нескольких посылок (например 2 или 4 сообщения) с периодом 10-40ms до выключения подачи питания. Период у сообщений может быть разным.

Прочитал всю ветку - все 15 страниц, но не увидел ответ на два вопроса заданных в самом первом посте и в посте #305

chiptuningnt пишет:

....Подключаю модуль к CANHacker, прием есть, но:
вначале получаю пакет canMsg1 899 раз с периудом 251 микросекунды, далее начинается цикличный прием canMsg2 до бесконечности с периудом 1 микросекунда.
Судя по скетчу он должен поочередно отправлять пакеты с периудом 100 милисекунд, почему не так не могу понять. Пробовал задержку ставить больше но все ровно так же.
.....
кварц ардуино 16Мгц, кан модуля 8Мгц

son32 пишет:

.... Второй вопрос мне нужно что бы один пакет сообщения отправлялся с периодом в 100мс, а второй с периодом в 50мс? сразу скажу в програмировании не силен, но что то по примерам получается делать.

У меня первое соообщение шлется постоянно а второе отанавливается. Изменения Delay (1000) особо ничего не меняют - первое сообщение период 1 ms - увеличиь до 10 не удается.

В сети много топиков на тему - не испольуйте delay а используйте interruptions, аппаратный таймер1, multitask но не понял как нужно изменить скетч (скетч как у ребят выше).

https://roboticsbackend.com/arduino-interrupts/б

https://playground.arduino.cc/Code/Timer1/

https://eeenthusiast.com/arduino-delay-function-tutorial-on-software-interrupts-timer-library-alternatives-to-delay/

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Valer1 пишет:

son32 пишет:

.... Второй вопрос мне нужно что бы один пакет сообщения отправлялся с периодом в 100мс, а второй с периодом в 50мс? сразу скажу в програмировании не силен, но что то по примерам получается делать.

В сети много топиков на тему - не испольуйте delay а используйте interruptions, аппаратный таймер1, multitask но не понял как нужно изменить скетч (скетч как у ребят выше).

http://arduino.ru/tutorials/BlinkWithoutDelay

Valer1
Offline
Зарегистрирован: 05.03.2021

это я самое первое что прочитал,  но не пойму как изменить известный скетч с двумя CAN посылками? Можете помочь?

sadman41
Offline
Зарегистрирован: 19.10.2016

Valer1 пишет:

это я самое первое что прочитал,  но не пойму как изменить известный скетч с двумя CAN посылками? Можете помочь?

Так-то тут не стол исполнения желаний. 

Показывайте что делали, подскажем где ошибка.

Valer1
Offline
Зарегистрирован: 05.03.2021

sadman41 пишет:

Показывайте что делали, подскажем где ошибка.

Наверняка есть те кто разобралcя как это сделать на nano / uno

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Valer1 пишет:

Наверняка есть те кто разобралcя как это сделать на nano / uno

Наверняка есть...

dimas6000
Offline
Зарегистрирован: 11.04.2014

Ребят, подскажите пожалуйста, в чем может быть проблема? Сам сообразить не могу что-то, и найти в сети тоже.


#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg;
MCP2515 mcp2515(53);

void setup() {
  Serial.begin(115200);
  SPI.begin();
  
  mcp2515.reset();
  mcp2515.setBitrate (CAN_100KBPS,  MCP_8MHZ);
  mcp2515.setListenOnlyMode();
  
  Serial.println("------- CAN Read ----------");
  Serial.println("ID  DLC   DATA");
}

void loop() {
  
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
      
    Serial.print(canMsg.can_id, HEX); // print ID
    Serial.print(" "); 
    Serial.print(canMsg.can_dlc, HEX); // print DLC
    Serial.print(" ");
    
    for (int i = 0; i<canMsg.can_dlc; i++)  {  // print the data
        
      Serial.print(canMsg.data[i],HEX);
      Serial.print(" ");

    }

    Serial.println();      
  }

}

 

Если я ставлю mcp2515.setNormalMode(); и отправляю через can-hacker один пакет, то всё отлично. Ловится один пакет. Если же поставить mcp2515.setListenOnlyMode(); то бесконечно падает в монитор порта последний отправленный пакет. Код залит в arduino mega2560. Выглядит это так:
 

16:43:03.328 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.328 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.394 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.394 -> 470 8 0 FF FF 44 0 0 0 0 
16:43:03.394 -> 470 8 0 FF FF 44 0 0 0 0 

В библиотеке задано CANCTRL_REQOP_LISTENONLY = 0x60 и CANCTRL_REQOP_NORMAL = 0x00.

Можете подсказать, в чем может быть причина и как это пофиксить?

sadman41
Offline
Зарегистрирован: 19.10.2016

Полагаю, что собака зарыта тут:

"Listen-Only mode is a silent mode, meaning no messages will be transmitted while in this mode (including error flags or Acknowledge signals)."

Плюс это:

"In the Acknowledge field of a message, the transmitter checks if the Acknowledge Slot bit (which has been sent out as a recessive bit) contains a dominant bit. If not, no other node has received the frame correctly. An Acknowledge error has occurred, an error frame is generated and the message will have to be repeated."

Одна сторона не отправляет Acknowledge , вторая считает, что произошла ошибка в сети и повторяет фрейм.

dimas6000
Offline
Зарегистрирован: 11.04.2014

Очень интересно, спасибо. А не подскажете откуда этот текст? Datasheet?

Вообще мне кажется такого быть не должно, т.к. пакет отсылаю в канхакере через one-shot mode или как-то так. По идее он не должен повторять пакет. Но спасибо, попробую разъеденить шину и посмотреть на результат.

Еще меня очень смущает, что в монитор порта падает в одно и то же время множество раз пакет: 

16:43:03.361 -> 470 8 0 FF FF 44 0 0 0 0
 

Т.е. будто пакет принимается и потом множество раз в цикле читается.

Вообще я немного не понимаю как работает строчка
 if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) 

Т.е. он читает сообщение, если он корректное, то заходим в условие.

И из-за того, что в одно и то же время множество раз отправляются данные в монитор порта, кажется, будто в режиме NormalMode он один раз читает данные из mcp2515 и далее они как-то отмечаются прочитанными, а в listenOnlyMode будто он одно и то же принятое сообщение читает множество раз и не отмечает прочитанным.

sadman41
Offline
Зарегистрирован: 19.10.2016

Просто подключите к шине один модуль в normal mode, а второй в listen only. Затем запускайте свой пакет из канхакера. Тот, что в normal, ответит передающему, что получил и он перестанет репитить. Тогда сразу будет ясно - это в listen only узле застрял мессейдж или же все по даташиту. Из которого и выдержки на англ.

dimas6000
Offline
Зарегистрирован: 11.04.2014

sadman41 пишет:
Просто подключите к шине один модуль в normal mode, а второй в listen only. Затем запускайте свой пакет из канхакера. Тот, что в normal, ответит передающему, что получил и он перестанет репитить. Тогда сразу будет ясно - это в listen only узле застрял мессейдж или же все по даташиту. Из которого и выдержки на англ.

Спасибо, к сожалению такой возможности нет, нет еще одного модуля.
Попробую подключить к машине и посмотреть будет ли там так же глючить.

dimas6000
Offline
Зарегистрирован: 11.04.2014

sadman41, спасибо, действительно, дело было в том что модуль в режиме listen only не отвечал никак на сообщение и передатчик повторно отправлял его. 
Я почему-то думал, что кнопка Single Shot в can hacker подразумевает отправку сообщения в One-Shot Mode, а это видимо не так. Не сообразил что-то.

andrey14
Offline
Зарегистрирован: 19.04.2015

Решил поснифить на Audi какие запросы отправляет VCDS. Поставил запрос температуры приборной панели. Пакеты ловлю, но не могу понять где запрос, а где ответ. Может у кого получалось разобраться и знает, что надо отправить через CanHacker, что бы пришел ответ?

Time   ID     DLC Data

22,032 300      8 23 05 05 71 05 05 8D 05
22,043 300      3 14 05 6E                
22,047 751      1 B5                      
22,166 751      1 A3                      
22,172 300      6 A1 0F 8A FF 4A FF       
22,180 751      5 1B 00 02 21 04          
22,193 300      8 25 00 0E 61 04 06 40 B4
22,202 300      8 26 05 05 71 05 05 8D 05
22,212 300      3 17 05 6E                
22,217 751      1 B8                      
22,339 751      5 1C 00 02 21 04          
22,343 300      1 BD                      
22,352 300      8 28 00 0E 61 04 06 40 B4
22,363 300      8 29 05 05 71 05 05 8D 05
22,372 300      3 1A 05 6E                
22,377 751      1 BB                      
22,486 751      5 1D 00 02 21 04          
22,493 300      1 BE                      
22,502 300      8 2B 00 0E 61 04 06 40 B4
22,512 300      8 2C 05 05 71 05 05 8D 05
22,522 300      3 1D 05 6E                
22,528 751      1 BE                      
22,643 751      5 1E 00 02 21 04          
22,651 300      1 BF                      
22,662 300      8 2E 00 0E 61 04 06 40 B7
22,672 300      8 2F 05 05 71 05 05 8D 05
22,682 300      3 10 05 6E                
22,687 751      1 B1                    

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

поставить в разрыв VCDS и автомобиля ардуину с двумя MCP2515. (отличается только пин CS остальные параллельно подключить).  Скетч сделать тупо гейт между vcds и автомобилем, ну и в терминал выводя фреймы, вы уже будете знать кто что отправляет.

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg_VCDS;
struct can_frame canMsg_AUDI;

MCP2515 VCDS (9);       // этот кан модуль подключить к диагностике 
MCP2515 AUDI (10);      // этот кан модуль подключить к машине

void setup() {
  Serial.begin(115200);
  SPI.begin();
  
  VCDS.reset();
  VCDS.setBitrate(CAN_500KBPS);
  VCDS.setNormalMode();

  AUDI.reset();
  AUDI.setBitrate(CAN_500KBPS);
  AUDI.setNormalMode();
  
  
}

void loop() {
  
  if (VCDS.readMessage(&canMsg_VCDS) == MCP2515::ERROR_OK) {
    AUDI.sendMessage(&canMsg_VCDS);      // транслируем в другую шину
    Serial.print("              VCDS send:   ");   
    Serial.print(canMsg_VCDS.can_id, HEX); // print ID
    Serial.print(" "); 
    Serial.print(canMsg_VCDS.can_dlc, HEX); // print DLC
    Serial.print(" ");
    
    for (int i = 0; i<canMsg_VCDS.can_dlc; i++)  {  // print the data
        
      Serial.print(canMsg_VCDS.data[i],HEX);
      Serial.print(" ");

    }

    Serial.println();      
  }


   if (AUDI.readMessage(&canMsg_AUDI) == MCP2515::ERROR_OK) {
    VCDS.sendMessage(&canMsg_AUDI);  // транслируем в другую шину
    Serial.print("AUDI send:   "); 
    Serial.print(canMsg_AUDI.can_id, HEX); // print ID
    Serial.print(" "); 
    Serial.print(canMsg_AUDI.can_dlc, HEX); // print DLC
    Serial.print(" ");
    
    for (int i = 0; i<canMsg_AUDI.can_dlc; i++)  {  // print the data
        
      Serial.print(canMsg_AUDI.data[i],HEX);
      Serial.print(" ");

    }

    Serial.println();  
    
    
  }

}

 

Fayton
Offline
Зарегистрирован: 10.12.2018

прошивка версия 15 https://drive.google.com/file/d/1y6oMNv7GWRqrmNjT5Pf2jH4b9TjtweqB/view?usp=sharing

CanSan V15 CANHACKER WiFi LIN

1 встроенный бомбер ID и BYTE

2 один динамический сендер

3 один статический сендер

4 IF to SEND - чекер для авто-удаления ошибок 5 полноценный канхакер (CANHACKER) в режиме работы по USB или Bluetooth

6 Встроенный рекордер для записи и воспроизведения CAN Сохранение файла плеера редактирование и загрузка. Теперь можно делится файлами не только!

7 Смена SSID и PASSWORD

8 Установка таймера работы для проката

9 Удобная мобильная версия встроенного сайта

10 Питание 5/12V 11 отключения Wifi для сокращения потребления и скрытого режима

12 режимы 11 бит или 29 бит

13 Скорости CAN: 5Kbps 10Kbps 20Kbps 33,3Kbps 40Kbps 50Kbps 83.3Kbps 100Kbps 125Kbps 200Kbps 250Kbps 500Kbps 1000Kbps

14 Автоматическое определение скорости и битности сети CAN

15 Установка скорости через программу

16 Поддержка протокола LIN тест

17 Адаптивный протокол

////////////////////////////////////////////////////////////////////////////

Скорость CAN можно устанавливать в веб интерфейсе или через интерфейс программы. (запоминает последний) 11/29 бит устанавливается в веб интерфейсе.

Скорость работы по USB с программами 115200

Перемычка WiFi отключает Wifi Перемычку J1 на модуле mcp2515 ставим кода подключаем к периферийным устройствам и снимаем когда подключаем к машине или ЭБУ!

Драйвер менять обязательно на SH65VP230 или SH65VP232!

Питание платы от USB или если установлен внешний DC-DC 12V (Боится переполюсовки)!

Землю подключаем обязательно и в первую очередь!

Для обучения работы с другими программами работающими по протоколу CanHacker (lawicel) достаточно установить ID123 DLS8 byte 11 22 33 44 55 66 77 88 и подключится к программе 1 раз

Arman-Nursultan
Offline
Зарегистрирован: 14.10.2021

Я перепробовал разные библиотеки, остановился на двух - mcp2515.h и mcp_can.h и обе они изначально рассчитаны на 16 мГц кварц в mcp2515. Вы либо командой принудительно дайте 8мГц или поправьте в библиотеках. Также обнаружил одну вещь, собрав стенд из двух esp8266 и mcp2515. Начал гонять данные между ними. Все отлично, вот только на скорости 5 кбит не хотят работать. Вот сижу копаю. Мне для работы нужно раскопать общение по CAN шине оборудование сименс. Подозреваю, что там как раз самая низкая скорость используется. До этого подключался и пытался слушать, но ничего не было. Наверное из-за этого. Сижу библиотеку вкуриваю.

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

это скорее всего изза трансивера tja1040 . Нужен другой для такой скорости . Возможно будет работать mcp2551

Arman-Nursultan
Offline
Зарегистрирован: 14.10.2021

Тоже так думаю, надо попробовать. Вроде они даже по выводам совпадают и можно просто перепаять. 

У меня другой вопрос. Вот есть elm327 can сканер для авто. Как им слушать шину? Обычно приводится только список команд для управления. И почему-то только для авто. Но ведь это сканер. Не могу найти нормальный манул как им можно именно в качестве сканера пользоваться.

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

слушать шину можно бесплатной программой для фордов ELMconfig . там есть режим сниффера. Правда скорости CAN  только 125 и 500.   Вы говорите слово "сканер" , это означает совсем не сниффер. Я так понял вам нужен именно  сниффер шины. 

А вот Диагностика в качестве сканера  - это нужно соответствующее ПО для елм, типа Torque для андроид или для конкретной марки авто, например форскан для фордов.  

Arman-Nursultan
Offline
Зарегистрирован: 14.10.2021

с помощью mcp2515 я спокойно снифю кан шину, от 10 кбит до 1 мбит, вот только самый нижний режим 5 кбит почему-то не  хочет работать. Отправлять отправляет, но вот не читает. А под рукой оказался elm327, вот и подумал, почему бы его не использовать в качествен сниффера

 

Maksim_b27
Offline
Зарегистрирован: 15.10.2021

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

#include <mcp_can.h>
#include <SPI.h>
MCP_CAN CAN0(10);     // Set CS to pin 10
void setup()
{
  Serial.begin(115200);
  if(CAN0.begin(MCP_ANY, CAN_250KBPS, MCP_8MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
  else Serial.println("Error Initializing MCP2515...");
  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
}
byte data[8] = {0xB3, 0x29, 0xEC, 0x29, 0x53, 0x2A, 0x00, 0x80};
byte data2[8] = {0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
byte data3[8] = {0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
void loop()
{
  byte sndStat = CAN0.sendMsgBuf(0x18FFC183, 1, 8, data);
  if(sndStat == CAN_OK){
    Serial.println("Message Sent Successfully!");
  } else {
    Serial.println("Error Sending Message...");
  }
   delay(50);
  byte sndStat2 = CAN0.sendMsgBuf(0x0CF02400, 1, 8, data2);
  if(sndStat2 == CAN_OK){
    Serial.println("Message Sent Successfully!");
  } else {
    Serial.println("Error Sending Message...");}
       delay(1);
       byte sndStat3 = CAN0.sendMsgBuf(0x18FFC184, 1, 8, data);
  if(sndStat == CAN_OK){
    Serial.println("Message Sent Successfully!");
  } else {
    Serial.println("Error Sending Message...");
  }
   delay(50);
}
MaksVV
Offline
Зарегистрирован: 06.08.2015

Научитесь код вставлять правильно и потом ищите лучше, даже в этой теме было уже

rudachok
Offline
Зарегистрирован: 16.10.2021

Добрый день, нужна помощь в оптимизации кода. Нужно добавить ещё около 20 пакетов с разными периодами, может можно как-то на один таймер привязать несколько пакетов с одинаковым периодом?

// CAN Send Example
//

#include <mcp_can.h>
#include <SPI.h>

MCP_CAN CAN0(10);     // Set CS to pin 10
uint32_t timer1 = millis();
uint32_t timer2 = millis();
uint32_t timer3 = millis();
uint32_t timer4 = millis();
uint32_t timer5 = millis();
uint32_t timer6 = millis();

void setup()
{
  Serial.begin(115200);
  CAN0.begin(MCP_ANY, CAN_250KBPS, MCP_8MHZ);
  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted

}

byte data1[8] = {0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF};
byte data2[8] = {0xF0, 0x7D, 0x7D, 0xFC, 0x10, 0xFF, 0x00, 0x7D};
byte data3[8] = {0x20, 0x13, 0x00, 0x03, 0xFF, 0xE1, 0xFE, 0x00};
byte data4[8] = {0x01, 0x41, 0x00, 0x40, 0x06, 0x75, 0xC0, 0x5D};
byte data5[8] = {0x02, 0x4B, 0x5C, 0x13, 0x19, 0xA0, 0x2E, 0x19};
byte data6[8] = {0x03, 0xA0, 0x2E, 0x80, 0x0C, 0x19, 0xFF, 0xFF};

void loop()
{
  if (millis() - timer1 >= 1000)
  {
    byte sndStat = CAN0.sendMsgBuf(0x18FECA10, 1, 8, data1);
    timer1 = millis();
  }
  if (millis() - timer2 >= 100) {
    byte sndStat = CAN0.sendMsgBuf(0x18F00010, 1, 8, data2);
    timer2 = millis();
  }
  if (millis() - timer3 >= 5000) {
    byte sndStat = CAN0.sendMsgBuf(0x18ECFF10, 1, 8, data3);
    timer3 = millis();
  }
  if (millis() - timer4 >= 5000) {
    byte sndStat = CAN0.sendMsgBuf(0x18EBFF10, 1, 8, data4);
    timer4 = millis();
  }
  if (millis() - timer5 >= 5000) {
    byte sndStat = CAN0.sendMsgBuf(0x18EBFF10, 1, 8, data5);
    timer5 = millis();
  }
  if (millis() - timer6 >= 5000) {
    byte sndStat = CAN0.sendMsgBuf(0x18EBFF10, 1, 8, data6);
    timer6 = millis();
  }
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

"На один таймер" можно даже все привязать, если найти наибольший общий делитель всех интервалов.

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

просто подряд не есть хорошо все сообщения отправлять. Допустим если с интервалом 5000мс будет куча сообщений, они "за раз" все и будут отправляться, их нужно разносить по времени хотя бы на 20мс.  Примерно так может : 

#include <mcp_can.h>
#include <SPI.h>

MCP_CAN CAN0(10);     // Set CS to pin 10

struct message 
{
  uint32_t ID;
  byte data[8];
  int incr;
  int interval;
} ;

// ниже создаем массив структур CAN сообщений, последний столбец это периодичность отправки
// предпоследний столбец забиваем разные значения, чтобы разнести отправку по времени 
// значение в предпоследнем столбце должны отличаться минимум на 20мс, 
// и не должны превышать число последнего столбца

message can_mes[] = {
0x18FECA10, {0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}, 20,  1000,
0x18FECA20, {0xF0, 0x7D, 0x7D, 0xFC, 0x10, 0xFF, 0x00, 0x7D}, 567, 1000,

0x18FECA30, {0x20, 0x13, 0x00, 0x03, 0xFF, 0xE1, 0xFE, 0x00}, 167, 5000,
0x18FECA40, {0x01, 0x41, 0x00, 0x40, 0x06, 0x75, 0xC0, 0x5D}, 289, 5000,
0x18FECA50, {0x02, 0x4B, 0x5C, 0x13, 0x19, 0xA0, 0x2E, 0x19}, 1345, 5000,
0x18FECA60, {0x03, 0xA0, 0x2E, 0x80, 0x0C, 0x19, 0xFF, 0xFF}, 2456, 5000

};

void setup()
{
  Serial.begin(115200);
  CAN0.begin(MCP_ANY, CAN_250KBPS, MCP_8MHZ);
  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
}

void loop()
{
  static uint32_t prev = 0; 
  if (micros() - prev >= 1000)
  {
    for(int i = 0 ; i<sizeof(can_mes)/16; i++) 
        {
         can_mes[i].incr++; 
         if (can_mes[i].incr>=can_mes[i].interval)
          {
           can_mes[i].incr=0; 
           CAN0.sendMsgBuf(can_mes[i].ID, 1, 8, can_mes[i].data); // отправляем сообщения
          }
        }// end for
   prev = micros();
  }

// остальной код
 
}

 

son32
Offline
Зарегистрирован: 04.12.2017

Доброго времени суток всем!!! Нужна помощь, а точнее подсказать. Суть такова: есть пакет кан допустим 375 [8] 00 00 00 00 00 00 00 00. Так скажем интересует первый байт пакета: первый бит имеет значение либо 0 либо C, второй бит имеет постоянно изменяемые значения, но строго по порядку от 0 до F. так вот мне нужно что бы в моем проекте arduino+mcp2515+модуль реле, при чтении кан шины при появлении значения C в первом бите отрабатывало реле, при этом не важно какие значения во втором бите. я конечно могу каждое значение прописать C0, C1, C2.... CF, но получится огромный массив в условиях.  

#include <SPI.h>
#include <mcp2515.h>
//struct can_frame canMsg;
struct can_frame canMsg1;
MCP2515 Can0(10);
int KL1 = 3;

void setup() {

  canMsg1.can_id  = 0x375;
  canMsg1.can_dlc = 8;

  pinMode(KL1, OUTPUT);
  digitalWrite(KL1, LOW);
  Can0.reset();
  Can0.setBitrate(CAN_500KBPS);
  Can0.setNormalMode();
}

void loop() {
  if (Can0.readMessage(&canMsg1) == MCP2515::ERROR_OK) {
    if (canMsg1.data[0] == 0xC0) { // C0 прописано для примера
      digitalWrite(KL1, HIGH);
    }
    else {
      digitalWrite(KL1, LOW);
    }
  }
}

 

Komandir
Offline
Зарегистрирован: 18.08.2018

Обнулить младший полубайт через & 0xF0 и сравнивать только с 0xC0

son32
Offline
Зарегистрирован: 04.12.2017

спасибо!!! но можно как то в примере?

да и еще, возможно как то сделать что бы вообще не учитывалось значение второго бита? только чтение первого бита.

sadman41
Offline
Зарегистрирован: 19.10.2016

Пример в любом гугле по фразе "Битовые операции".
https://all-arduino.ru/programmirovanie-arduino/bitwiseand/

Komandir
Offline
Зарегистрирован: 18.08.2018

son32 Вам в детский сад - здесь нет битов ! Здесь ПОЛУБАЙТЫ !

if ((canMsg1.data[0] & 0xF0) == 0xC0)

son32
Offline
Зарегистрирован: 04.12.2017

sadman41 пишет:
Пример в любом гугле по фразе "Битовые операции". https://all-arduino.ru/programmirovanie-arduino/bitwiseand/

Согласен гугл рулит. Спасибо!!! но мне это ни о чем не говорит((( 

son32
Offline
Зарегистрирован: 04.12.2017

Komandir пишет:

son32 Вам в детский сад - здесь нет битов !

ну уж извините пожалуйста!!! что не все рождены умными!!!

son32
Offline
Зарегистрирован: 04.12.2017

Komandir пишет:

son32 Вам в детский сад - здесь нет битов ! Здесь ПОЛУБАЙТЫ !

if ((canMsg1.data[0] & 0xF0) == 0xC0)

Спасибо попробую!!!

Извиняюсь что не знаю как правильно называются эти вещи!!!

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

son32 пишет:
ну уж извините пожалуйста!!! что не все рождены умными!!!

Тогда какогохрена ты в CAN-шину лезешь?  Она для умных.

son32
Offline
Зарегистрирован: 04.12.2017

DetSimen пишет:

son32 пишет:
ну уж извините пожалуйста!!! что не все рождены умными!!!

Тогда какогохрена ты в CAN-шину лезешь?  Она для умных.

А вот это мое дело лезть мне в кан или нет!!!

Не нужно указвать что человеку делать, заниматься чем то или нет, и куда ему идти!!!

ко мне тоже часто люди обращаются за помощью, очень часто, очень грамотные люди, и со смешными до нельзя

проблемами!!! ни одному из них не указал что им делать, а просто помогаю.

b707
Offline
Зарегистрирован: 26.05.2017

son32 пишет:

А вот это мое дело лезть мне в кан или нет!!!

ну кабы вы сами решали свои проблемы - это было бы ваше дело, а так и наше тоже.

 

Цитата:
ко мне тоже часто люди обращаются за помощью, очень часто, очень грамотные люди, и со смешными до нельзя проблемами!!! ни одному из них не указал что им делать, а просто помогаю.

наверно не бесплатно?