Тема - программирование конструирование.
Мне нужна помощь с -
Вопросы:
1) Конверсия числа из байтов в UINT32?
2) CAN id, почему используется операция И 0х1FFFFFF? И из за этого ли конечные устройства не понимают когда идет обращение к ним?
Источники внизу.
С характеристиками следующее:
2 платы Uno и 2 МСР2515, 2 Интернет шилда на базе W5100.
Соединены по схеме
Соединение MCP2515 с Uno следующее:
Контакты INT и CS могут быть переназначены в скетче.
Установка шилда на ардуино в описании не нуждается, собрать как лего.
На плате MCP2515 устанавливается перемычка J1 - терминирующий резистор.
Первая плата - та у которой порт 2000, вторая - порт 2001.
Эта связка включена в разрыв шины, передача двунаправленная, проверено - работает.
Конечные устройства теряют связь друг с другом из за проблем с пакетами.
1)
Проблема - конвертация числа UINT32 из 4х Uchar
если использовать метод
то в результате любое число будет FFFFxxxx где x это нормальная часть числа без потерь.
если использовать вариант:
unsigned long number3 = pow(256, 0) * bytes[0] + pow(256, 1) * bytes[1] + pow(256, 2) * bytes[2] + pow(256, 3) * bytes[3];
то число будет иметь вид хххххх00 где х это нормально восстановленная часть числа а 00 всегда в конце
Почему так происходит? В VS19 тестовый пример с обеими данными функциями не приводит к потере фрагментов числа.
2)
Теперь вторая часть, касаемо формата CAN rxID он имеет расширение UINT32 зачем в тестовом примере сделано вот так? (См выделенную желтым область)
Прилагаю разъяснение работы устройств.
Для работы с UDP используется библиотека <EthernetUdp.h>
Подготовка параметров выглядит так:
Указываем желаемый MAC и IP. IP dest это целевой адрес устройства с которым будем связывать первую ардуину, а REMOTE_PORT соответственно куда мы будем посылать данные.
SERV_PORT будет ожидать данные от второго устройства.
Передача данных начинается с того, что нужно прочитать посылку CAN - ее читать с помощью следующей функции:
с начала проверяем какой уровень сигнала на контакте CAN0_UNT и если он высокий значит есть посылка.
в функцию readMsgBuf должно быть передано три параметра - 1 идентификатор пакета, длина (DLC) и массив данных, в случае чтения эти параметры будут перезаписаны да же если в них есть данные.
далее создаем пакет на 13 элементов где 0-3 будет хранить 4 байта числа UINT32, 4 - количество данных (DLC), и оставшиеся 5-12 блок данных.
После окончания формирования массива передадим его в функцию отправки UDP для этого вызвав метод write() в него необходимо передать массив и размер в байтах, в данном случае с типом char размер будет 13 байт.
функция НЕ умеет работать с UINT32 и больше.
А что бы отправить данные конкретному устройству - в функции beginPacket() нужно передать IP адрес и порт того устройства которому это все адресовано.
Не забываем endPacket(), иначе данные не отправятся.
Работа с CAN:
Инициализировать объект класса следующими параметрами.
begin()
MCP_ANY - не знаю что такое.
KBPS - скорость CAN шины, в текущем устройстве будет 50.
MHZ - частота работы кварца модуля МСР2515 (есть версии на 16 МГц).
setMode()
режимы работы (информации об этом нет) мне известно что режим Normal обеспечивает прием/передачу в нормальном режиме.
На рисунке показаны все доступные режимы работы.
pinMode()
выбрать контакт назначенный на прерывания при получении посылки.
Теперь для работы с отправкой сообщений нужно создать буфер с подготовленными данными.
Поскольку они получены по UDP в том же виде как мы их передали то их необходимо собрать.
Первые 4 байта это будущее число UINT32 хранящее rxID.
Восстановим число с помощью метода pow(), но на конце будет всегда 00, поэтому по завершению преобразования прибавим еще раз 0 элемент полученного пакета.
В примере используется дополнительно объявленный буфер, на самом деле он не нужен и лишь лишний. Работать можно сразу с полученными данными.
Теперь после формирования rxID нужно сформировать блок данных пакета CAN, теперь уже нужно создать отдельный массив на 8 элементов и перенести в него 5-12 элементы принятого массива.
Теперь можно отправлять посылку вызовом метода sendMsgBuf() в нее нужно передать наше число UINT32 - rxIDб.
Второе число 1 - *ext, это переменная отвечающая за выбор типа посылки (Если 0 то STANDART а если 1 то EXTENDED) если будет выбор стандартного пакета то половина rxID будет потеряна и посылка отправится с коротким ID пакета.
И обязательно не забываем про включение режима однократной отправки enOneShotTX().
Если не использовать эту команду то модуль МСР2515 имеющий 3 буфера сообщений будет бесконечно, на максимальной скорости слать последние 3 сообщения.
Об этом нет информации нигде просто, я догадался сам анализируя голую библиотеку CAN рассматривая в блокноте.
что бы выключить этот режим вызовите функцию disOneShotTX().
Так же прилагаю полный список функций класса CAN
Большинству этих функций описание не известно, я бы сказал его вообще нет. Применение функций можно увидеть только в тестовых скетчах идущих с библиотекой.
Далее в функцию передаем 4 элемент - который хранит длину поля данных (DLC) и передаем блок данных.
Не стоит волноваться о том что при DLC = 4 блок будет на 8 элементов, функция отправки обрежет сообщение до 4х ячеек и отправит.
На этом отправка сообщения завершена и МСР2515 готов к получению данных.
Моя система работает в обе стороны одновременно.
В текущий момент есть проблемы - не корректно собирается rxID, конечные устройства теряют связь друг с другом поскольку что то не так с rxID.
Полезные источники:
1) Библиотека которая поддерживает сразу CAN EXTEND+STANDART frames, CAN2.0B https://github.com/coryjfowler/MCP_CAN_lib
2) Datasheet для МСР2515 https://ww1.microchip.com/downloads...d-Alone-CAN-Controller-with-SPI-20001801J.pdf
3) Описание команд для UDP с примерами http://mypractic.ru/urok-64-tcp-server-i-klient-na-arduino-biblioteka-uipethernet.html
4) Если нет второй ардуины то можно достучаться к ней с ПК http://mypractic.ru/urok-69-protoko...hyu-biblioteki-uipethernet.html#comment-72076
Примечание: если вы используете какую то другую библиотеку MCP и CAN не с этого репозитория (см источник 1) то эта информация описанная выше не актуальна.
Каждый (не) уважаемый программист создал свой клон библиотеки для работы с CAN и MCP2515 при этом не указав первоисточник.
Всякие can_hack lib сделаны на коленке и не умеют работать с extended фреймами. Так же can hack tool скетч ни разу не рабочий, он не видит да же обычные фреймы.
В примерах из этой библиотеки все работает, главное настроить скорость и не забыть про частоту.
Мне нужна помощь с -
Вопросы:
1) Конверсия числа из байтов в UINT32?
2) CAN id, почему используется операция И 0х1FFFFFF? И из за этого ли конечные устройства не понимают когда идет обращение к ним?
Источники внизу.
С характеристиками следующее:
2 платы Uno и 2 МСР2515, 2 Интернет шилда на базе W5100.
Соединены по схеме
Соединение MCP2515 с Uno следующее:
MCP2515 | Uno |
INT | 2 |
SCK | 13 |
SI | 11 |
SO | 12 |
CS | 10 |
GND | GND |
VCC | +5V |
Установка шилда на ардуино в описании не нуждается, собрать как лего.
На плате MCP2515 устанавливается перемычка J1 - терминирующий резистор.
Первая плата - та у которой порт 2000, вторая - порт 2001.
Эта связка включена в разрыв шины, передача двунаправленная, проверено - работает.
Конечные устройства теряют связь друг с другом из за проблем с пакетами.
1)
Проблема - конвертация числа UINT32 из 4х Uchar
если использовать метод
то в результате любое число будет FFFFxxxx где x это нормальная часть числа без потерь.
если использовать вариант:
unsigned long number3 = pow(256, 0) * bytes[0] + pow(256, 1) * bytes[1] + pow(256, 2) * bytes[2] + pow(256, 3) * bytes[3];
то число будет иметь вид хххххх00 где х это нормально восстановленная часть числа а 00 всегда в конце
Почему так происходит? В VS19 тестовый пример с обеими данными функциями не приводит к потере фрагментов числа.
2)
Теперь вторая часть, касаемо формата CAN rxID он имеет расширение UINT32 зачем в тестовом примере сделано вот так? (См выделенную желтым область)
Прилагаю разъяснение работы устройств.
Для работы с UDP используется библиотека <EthernetUdp.h>
Подготовка параметров выглядит так:
Указываем желаемый MAC и IP. IP dest это целевой адрес устройства с которым будем связывать первую ардуину, а REMOTE_PORT соответственно куда мы будем посылать данные.
SERV_PORT будет ожидать данные от второго устройства.
Передача данных начинается с того, что нужно прочитать посылку CAN - ее читать с помощью следующей функции:
с начала проверяем какой уровень сигнала на контакте CAN0_UNT и если он высокий значит есть посылка.
в функцию readMsgBuf должно быть передано три параметра - 1 идентификатор пакета, длина (DLC) и массив данных, в случае чтения эти параметры будут перезаписаны да же если в них есть данные.
далее создаем пакет на 13 элементов где 0-3 будет хранить 4 байта числа UINT32, 4 - количество данных (DLC), и оставшиеся 5-12 блок данных.
После окончания формирования массива передадим его в функцию отправки UDP для этого вызвав метод write() в него необходимо передать массив и размер в байтах, в данном случае с типом char размер будет 13 байт.
функция НЕ умеет работать с UINT32 и больше.
А что бы отправить данные конкретному устройству - в функции beginPacket() нужно передать IP адрес и порт того устройства которому это все адресовано.
Не забываем endPacket(), иначе данные не отправятся.
Работа с CAN:
Инициализировать объект класса следующими параметрами.
begin()
MCP_ANY - не знаю что такое.
KBPS - скорость CAN шины, в текущем устройстве будет 50.
MHZ - частота работы кварца модуля МСР2515 (есть версии на 16 МГц).
setMode()
режимы работы (информации об этом нет) мне известно что режим Normal обеспечивает прием/передачу в нормальном режиме.
На рисунке показаны все доступные режимы работы.
pinMode()
выбрать контакт назначенный на прерывания при получении посылки.
Теперь для работы с отправкой сообщений нужно создать буфер с подготовленными данными.
Поскольку они получены по UDP в том же виде как мы их передали то их необходимо собрать.
Первые 4 байта это будущее число UINT32 хранящее rxID.
Восстановим число с помощью метода pow(), но на конце будет всегда 00, поэтому по завершению преобразования прибавим еще раз 0 элемент полученного пакета.
В примере используется дополнительно объявленный буфер, на самом деле он не нужен и лишь лишний. Работать можно сразу с полученными данными.
Теперь после формирования rxID нужно сформировать блок данных пакета CAN, теперь уже нужно создать отдельный массив на 8 элементов и перенести в него 5-12 элементы принятого массива.
Теперь можно отправлять посылку вызовом метода sendMsgBuf() в нее нужно передать наше число UINT32 - rxIDб.
Второе число 1 - *ext, это переменная отвечающая за выбор типа посылки (Если 0 то STANDART а если 1 то EXTENDED) если будет выбор стандартного пакета то половина rxID будет потеряна и посылка отправится с коротким ID пакета.
И обязательно не забываем про включение режима однократной отправки enOneShotTX().
Если не использовать эту команду то модуль МСР2515 имеющий 3 буфера сообщений будет бесконечно, на максимальной скорости слать последние 3 сообщения.
Об этом нет информации нигде просто, я догадался сам анализируя голую библиотеку CAN рассматривая в блокноте.
что бы выключить этот режим вызовите функцию disOneShotTX().
Так же прилагаю полный список функций класса CAN
Большинству этих функций описание не известно, я бы сказал его вообще нет. Применение функций можно увидеть только в тестовых скетчах идущих с библиотекой.
Далее в функцию передаем 4 элемент - который хранит длину поля данных (DLC) и передаем блок данных.
Не стоит волноваться о том что при DLC = 4 блок будет на 8 элементов, функция отправки обрежет сообщение до 4х ячеек и отправит.
На этом отправка сообщения завершена и МСР2515 готов к получению данных.
Моя система работает в обе стороны одновременно.
В текущий момент есть проблемы - не корректно собирается rxID, конечные устройства теряют связь друг с другом поскольку что то не так с rxID.
Полезные источники:
1) Библиотека которая поддерживает сразу CAN EXTEND+STANDART frames, CAN2.0B https://github.com/coryjfowler/MCP_CAN_lib
2) Datasheet для МСР2515 https://ww1.microchip.com/downloads...d-Alone-CAN-Controller-with-SPI-20001801J.pdf
3) Описание команд для UDP с примерами http://mypractic.ru/urok-64-tcp-server-i-klient-na-arduino-biblioteka-uipethernet.html
4) Если нет второй ардуины то можно достучаться к ней с ПК http://mypractic.ru/urok-69-protoko...hyu-biblioteki-uipethernet.html#comment-72076
Примечание: если вы используете какую то другую библиотеку MCP и CAN не с этого репозитория (см источник 1) то эта информация описанная выше не актуальна.
Каждый (не) уважаемый программист создал свой клон библиотеки для работы с CAN и MCP2515 при этом не указав первоисточник.
Всякие can_hack lib сделаны на коленке и не умеют работать с extended фреймами. Так же can hack tool скетч ни разу не рабочий, он не видит да же обычные фреймы.
В примерах из этой библиотеки все работает, главное настроить скорость и не забыть про частоту.
Вложения
-
8.2 KB Просмотры: 3
-
8.1 KB Просмотры: 4
Изменено: