CITROEN-ARDUINO
Народ, а кто нить дружил Citroen с Arduino+CAN Shield?
Толи я чего-то не понимаю, толи я что-то не правильно делаю. #include #include "mcp_can.h" MCP_CAN CAN(10); unsigned char len = 0; unsigned char buf[8]; INT32U canId = 0x000; void setup() { Serial.begin(115200); START_INIT: if(CAN_OK == CAN.begin(CAN_500KBPS,MCP_8MHz)) { Serial.println("Init OK!"); } else { Serial.println("Init fail"); delay(100); goto START_INIT; } } void loop() { if(CAN_MSGAVAIL == CAN.checkReceive()) // check if data coming { CAN.readMsgBuf(&len, buf); canId = CAN.getCanId(); // unsigned long canId = CAN.getCanId(); Serial.print("<");Serial.print(canId);Serial.print(","); for(int i = 0; i Serial.print(buf[i]);Serial.print(","); } Serial.print(">"); Serial.println(); } } Пытаюсь отловить обороты. Но получаю на выходе при чтение что-то типо 8 : 1C F0 32 0 4C 30 0 32 68 : 0 0 FF D : 0 0 0 0 0 0 0 B 8 : 1C F0 31 0 4C 30 0 32 48 : 0 30 2 42 C8 3 1 0 5 : 7F FF 0 5 58 0 5 : 7F FF 1 85 D9 0 8 : 1C F0 31 0 4C 30 0 32 32 : 81 5B 48 FE 0 0 68 : 0 0 FF D : 0 0 0 0 0 0 0 C 92 : 0 0 0 8 : 1C F2 31 0 4C 30 0 32 48 : 0 30 2 42 C8 3 1 0 5 : 7F FF 0 5 6B 0 12 : 73 20 1 3D 0 4D : 0 0 0 0 0 0 0 0 И не одного упоминания о 0C Обороты двигателя (Engine RPM)! И почему такие короткие ID у сообщений? Я чего-то не дописал или у ситроенов обороты под другим ID? Поделитесь кто что знает! Я в этом совсем новенький. |
В общем ты путаешь два понятия:
первое - это протокол по которому общаются устройства в твой машине, и он в каждой машине свой ( иногда даже разный в машинах одной и той же марки ), именно его ты и привёл в качестве примера. второе - это OBD II протокол, то есть диагностический протокол, который должен быть реализован в каждой машине, но из практики могу сказать, что есть он почти во всех новых машинах, но не во всех реализован в полном объёме. Данный протокол работает по запросу, то есть ты сначала запрашиваешь у диагностического устройства с ид 7DF, то что тебе нужно, а потом получаешь ответ от устройства с ид. 7E8 ( возможны варианты от 7E8 до 7EF). Вот именно в этом протоколе 0C это обороты двигателя. Более подробно читаем здесь https://en.wikipedia.org/wiki/OBD-II_PIDs#Mode_1_PID_1C Теперь по поводу твоего протокола, как я и говорил у каждой машины он свой, допустим в грузовиках ISUZU мы получаем такое сообщение <217056256,240,125,126,188,18,0,255,255,> вот именно в сообщениях с идентификатором 217056256 в 4-м и 5-м байтах находятся обороты двигателя, при чём для получения нужного числа надо (18*256+188)/8 = 599,5 об/мин твой протокол слишком короткий, что бы точно сказать, что именно именно передаёт обороты двигателя, но скорее всего обороты здесь 8 : 1C F2 31 0 4C 30 0 32 Причем вычисляется так 31 это 49 десятичное, F2 - 242. (49*256+242)/16 = 799,125 об/мин. Если конечно прокол снимался на холостых оборотах. |
Bersenev спасибо тебе огромное.
В моём протоколе это лишь кусок. У меня есть два лога- один без запуска двигателя, а второй с запуском и работой на ХХ. Ту часть которую привёл это с запуском. Но похоже это не тот ID поскольку на незапущенном двигателе он тоже меняется. Если поможешь, то могу выслать два лога. Какой программой можно анализировать траффик с ком порта? А то эта угадайка на долго. И если не сложно объясните мне как при помощи ардуины OBD II запросы слать и принимать ответы. лог без запуска (выборка по ID с убиранием повторяющихся сообщений) также попробовал написать if (canId = 8) { C = (buf[3]*256+buf[2])/16; Serial.println(C); } И получил пляшущие цифры ни малейшим образом не намекающие на обороты! |
Короче понятно.
Нужно идти стандартным путём- ELM327+Arduino |
Цитата:
Код:
#include Только номера пинов надо задать свои. |
Цитата:
C = (buf[3]*256+buf[2])/16; Я не знаю тип переменной C , но в принципе это и не важно. buf[3]*256 - байт умножается на 256 и сохраняется в байт, то есть всегда равно 0. Теперь к нулю прибавляем байт buf[2] и делим на 16 в результате значения от 0 до 15. а надо так, если C имеет тип unsigned int, то C = buf[3]; C = (C*256+buf[2])/16; То есть сначала байт преобразуем в unsigned int, а уже потом выполняем все действия, вот тогда получим правильное значение |
Цитата:
Я сделал себе программу для анализа протокола, протокол формирует этот скетч. Код:
#include Только для того что бы найти обороты надо сделать следующее: Подключить шилд к машине, запустить монитор ком порта, включить зажигание секунд на пять, потом завести машину, потом медленно давить на газ что бы обороты плавно подымались, а потом также плавно опускать обороты до холостых. После этого глушим машину и сохраняем протокол. Вот тогда что бы найти обороты понадобится минут десять. Для скорости почти тоже самое, только надо равномерно разогнать машину километров до 40 - 50-ти, а потом также спокойно остановиться. Для уровня топлива нужны протоколы до и после заправок. |
С имеет тип unsigned int. Задаётся в начале поэтому и небыло в куске.
С байт ты прав, но там числа получались до 65000. Можно попробовать ещё раз. Твой скетч тоже что и мой, только вывод строк в другом формате. у меня в хексе и без всяких скобок и разделителей кроме ":" между ID и сообщением, а у тя с доп символами. Ща перепишу свой чтоб выводилось в твоём формате. С посылкой по OBD II ща попробую сам разобраться :) Реально мне с ардуиной пока очень сложно так как опыта программирования МК у меня нет. PS А что делает строчка? INT32U canId = 0x000; и отличается ли она от моей unsigned char canId = CAN.getCanId(); |
Цитата:
C = buf[2]; C = (C*256+buf[1])/16; |
Цитата:
Но самое главное у тебя здесь ошибка, так как идентификаторы могут быть 11-ти или 29-битные (в зависимости от системы адресации в конкретной can шине), а ты выделяешь под него один байт, то есть всего восемь бит. Правильно должно быть так unsigned long canId = CAN.getCanId(); или так INT32U canId = CAN.getCanId(); |
Часовой пояс GMT +4, время: 03:30. |
Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot