14.07.2015, 00:46 | #1 |
Старший Пользователь
Регистрация: 03.07.2015
Регион: 77, 97, 99, 177
Сообщений: 372
|
CITROEN-ARDUINO
Народ, а кто нить дружил Citroen с Arduino+CAN Shield?
Толи я чего-то не понимаю, толи я что-то не правильно делаю. #include <SPI.h> #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<len; 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? Поделитесь кто что знает! Я в этом совсем новенький. Последний раз редактировалось admin; 29.03.2016 в 12:34. |
14.07.2015, 13:23 | #2 |
Бывалый писикарщик
Регистрация: 23.04.2009
Возраст: 53
Город: Ставрополь
Регион: 26
Машина: Opel Zafira 2007
Сообщений: 5,275
|
В общем ты путаешь два понятия:
первое - это протокол по которому общаются устройства в твой машине, и он в каждой машине свой ( иногда даже разный в машинах одной и той же марки ), именно его ты и привёл в качестве примера. второе - это 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 об/мин. Если конечно прокол снимался на холостых оборотах.
__________________
Opel Zafira B --- ГАЗ 21 ВОЛГА в 21 веке --- Скин OpelZafira для RideRunner --- Скин CFStyle для RideRunner Плагин RRCheckEngine --- CFStyle для iCar DS --- iCarVOBD --- iCarDuino --- iCarCoreTemp --- iCarNotes --- iCarVoiceCommander |
14.07.2015, 21:34 | #3 |
Старший Пользователь
Регистрация: 03.07.2015
Регион: 77, 97, 99, 177
Сообщений: 372
|
Bersenev спасибо тебе огромное.
В моём протоколе это лишь кусок. У меня есть два лога- один без запуска двигателя, а второй с запуском и работой на ХХ. Ту часть которую привёл это с запуском. Но похоже это не тот ID поскольку на незапущенном двигателе он тоже меняется. Если поможешь, то могу выслать два лога. Какой программой можно анализировать траффик с ком порта? А то эта угадайка на долго. И если не сложно объясните мне как при помощи ардуины OBD II запросы слать и принимать ответы. лог без запуска (выборка по ID с убиранием повторяющихся сообщений) также попробовал написать if (canId = 8) { C = (buf[3]*256+buf[2])/16; Serial.println(C); } И получил пляшущие цифры ни малейшим образом не намекающие на обороты! Последний раз редактировалось T_r_D; 16.07.2015 в 21:13. |
15.07.2015, 22:09 | #4 |
Старший Пользователь
Регистрация: 03.07.2015
Регион: 77, 97, 99, 177
Сообщений: 372
|
Короче понятно.
Нужно идти стандартным путём- ELM327+Arduino |
15.07.2015, 23:28 | #5 | |
Бывалый писикарщик
Регистрация: 23.04.2009
Возраст: 53
Город: Ставрополь
Регион: 26
Машина: Opel Zafira 2007
Сообщений: 5,275
|
Цитата:
Код:
#include <mcp_can.h> #include <SPI.h> INT32U canId = 0x000; unsigned char len = 0; unsigned char buf[8]; char str[20]; boolean IsSend = false; unsigned long IsSend_millis = 0; unsigned char vspeed[8] = {2, 1, 13, 0, 0, 0, 0, 0}; unsigned char count = 0; MCP_CAN CAN0(10); void setup() { Serial.begin(9600); START_INIT: if(CAN0.begin(CAN_500KBPS) == CAN_OK) { Serial.println("CAN BUS Shield init ok!"); } else { Serial.println("CAN BUS Shield init fail"); Serial.println("Init CAN BUS Shield again"); delay(100); goto START_INIT; } pinMode(18, INPUT); } void loop() { if(!IsSend) { CAN0.sendMsgBuf(0x7DF, 0, 8, vspeed); IsSend = true; IsSend_millis = millis(); } if(!digitalRead(18)) { CAN0.readMsgBuf(&len, buf); canId = CAN0.getCanId(); if( (canId == 0x7E8) && (buf[0] == 3) && (buf[1] == 0x41) && (buf[2] == 0xD)) { Serial.println(buf[3]); IsSend_millis = millis()-2500; Serial.print("Speed: "); Serial.println(buf[3]); } } if( IsSend ) { if( IsSend_millis + 3000 < millis() ) { Serial.print("----"); IsSend = false; IsSend_millis = millis(); } } } Только номера пинов надо задать свои.
__________________
Opel Zafira B --- ГАЗ 21 ВОЛГА в 21 веке --- Скин OpelZafira для RideRunner --- Скин CFStyle для RideRunner Плагин RRCheckEngine --- CFStyle для iCar DS --- iCarVOBD --- iCarDuino --- iCarCoreTemp --- iCarNotes --- iCarVoiceCommander |
|
15.07.2015, 23:39 | #6 | |
Бывалый писикарщик
Регистрация: 23.04.2009
Возраст: 53
Город: Ставрополь
Регион: 26
Машина: Opel Zafira 2007
Сообщений: 5,275
|
Цитата:
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, а уже потом выполняем все действия, вот тогда получим правильное значение
__________________
Opel Zafira B --- ГАЗ 21 ВОЛГА в 21 веке --- Скин OpelZafira для RideRunner --- Скин CFStyle для RideRunner Плагин RRCheckEngine --- CFStyle для iCar DS --- iCarVOBD --- iCarDuino --- iCarCoreTemp --- iCarNotes --- iCarVoiceCommander |
|
15.07.2015, 23:54 | #7 | |
Бывалый писикарщик
Регистрация: 23.04.2009
Возраст: 53
Город: Ставрополь
Регион: 26
Машина: Opel Zafira 2007
Сообщений: 5,275
|
Цитата:
Я сделал себе программу для анализа протокола, протокол формирует этот скетч. Код:
#include <mcp_can.h> #include <SPI.h> INT32U canId = 0x000; unsigned char len = 0; unsigned char buf[8]; char str[20]; int count = 0; MCP_CAN CAN0(10); void setup() { Serial.begin(38400); while(!Serial){} START_INIT: if(CAN0.begin(CAN_500KBPS) == CAN_OK) { Serial.println("CAN BUS Shield init ok!"); } else { Serial.println("CAN BUS Shield init fail"); Serial.println("Init CAN BUS Shield again"); delay(100); goto START_INIT; } pinMode(18, INPUT); } void loop() { if(!digitalRead(18)) { CAN0.readMsgBuf(&len, buf); canId = CAN0.getCanId(); Serial.print("<");Serial.print(canId);Serial.print(","); for(int i = 0; i<len; i++) { Serial.print(buf[i]);Serial.print(","); } Serial.print(">"); Serial.println(); } } Только для того что бы найти обороты надо сделать следующее: Подключить шилд к машине, запустить монитор ком порта, включить зажигание секунд на пять, потом завести машину, потом медленно давить на газ что бы обороты плавно подымались, а потом также плавно опускать обороты до холостых. После этого глушим машину и сохраняем протокол. Вот тогда что бы найти обороты понадобится минут десять. Для скорости почти тоже самое, только надо равномерно разогнать машину километров до 40 - 50-ти, а потом также спокойно остановиться. Для уровня топлива нужны протоколы до и после заправок.
__________________
Opel Zafira B --- ГАЗ 21 ВОЛГА в 21 веке --- Скин OpelZafira для RideRunner --- Скин CFStyle для RideRunner Плагин RRCheckEngine --- CFStyle для iCar DS --- iCarVOBD --- iCarDuino --- iCarCoreTemp --- iCarNotes --- iCarVoiceCommander |
|
16.07.2015, 00:59 | #8 |
Старший Пользователь
Регистрация: 03.07.2015
Регион: 77, 97, 99, 177
Сообщений: 372
|
С имеет тип unsigned int. Задаётся в начале поэтому и небыло в куске.
С байт ты прав, но там числа получались до 65000. Можно попробовать ещё раз. Твой скетч тоже что и мой, только вывод строк в другом формате. у меня в хексе и без всяких скобок и разделителей кроме ":" между ID и сообщением, а у тя с доп символами. Ща перепишу свой чтоб выводилось в твоём формате. С посылкой по OBD II ща попробую сам разобраться Реально мне с ардуиной пока очень сложно так как опыта программирования МК у меня нет. PS А что делает строчка? INT32U canId = 0x000; и отличается ли она от моей unsigned char canId = CAN.getCanId(); |
16.07.2015, 08:00 | #9 | |
Бывалый писикарщик
Регистрация: 23.04.2009
Возраст: 53
Город: Ставрополь
Регион: 26
Машина: Opel Zafira 2007
Сообщений: 5,275
|
Цитата:
C = buf[2]; C = (C*256+buf[1])/16;
__________________
Opel Zafira B --- ГАЗ 21 ВОЛГА в 21 веке --- Скин OpelZafira для RideRunner --- Скин CFStyle для RideRunner Плагин RRCheckEngine --- CFStyle для iCar DS --- iCarVOBD --- iCarDuino --- iCarCoreTemp --- iCarNotes --- iCarVoiceCommander |
|
16.07.2015, 08:10 | #10 | |
Бывалый писикарщик
Регистрация: 23.04.2009
Возраст: 53
Город: Ставрополь
Регион: 26
Машина: Opel Zafira 2007
Сообщений: 5,275
|
Цитата:
Но самое главное у тебя здесь ошибка, так как идентификаторы могут быть 11-ти или 29-битные (в зависимости от системы адресации в конкретной can шине), а ты выделяешь под него один байт, то есть всего восемь бит. Правильно должно быть так unsigned long canId = CAN.getCanId(); или так INT32U canId = CAN.getCanId();
__________________
Opel Zafira B --- ГАЗ 21 ВОЛГА в 21 веке --- Скин OpelZafira для RideRunner --- Скин CFStyle для RideRunner Плагин RRCheckEngine --- CFStyle для iCar DS --- iCarVOBD --- iCarDuino --- iCarCoreTemp --- iCarNotes --- iCarVoiceCommander |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1) | |
|
|