-
Вложений: 2
OBD-II диагностика на Arduino
Схему нарисовал, осталось изучить протокол общения с автомобилем и написать прошивку :)
Искрене надеюсь на вашу помощь.
Для связки компьютера по seral и автомобиля нужно использовать библиотеку SoftwareSerial
Пример работы arduino с софтверным Serial Port:
PHP код:
#include <SoftwareSerial.h>
#define rxPin 3
#define txPin 2
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
byte pinState = 0;
void setup()
{
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
mySerial.begin(9600);
}
void loop() {
char someChar = mySerial.read();
mySerial.print(someChar);
}
Пример кода OBD-II терминала для Arduino
PHP код:
#include <SoftwareSerial.h>
#define rxPin 3
#define txPin 2
#define K_IN 0
#define K_OUT 1
#define READ_ATTEMPTS 125
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
char command; //Terminal Commands
char pid_reslen[] = //PID Lengths
{
// pid 0x00 to 0x1F
4,4,2,2,1,1,1,1,1,1,1,1,2,1,1,1,
2,1,1,1,2,2,2,2,2,2,2,2,1,1,1,4,
// pid 0x20 to 0x3F
4,2,2,2,4,4,4,4,4,4,4,4,1,1,1,1,
1,2,2,1,4,4,4,4,4,4,4,4,2,2,2,2,
// pid 0x40 to 0x4E
4,8,2,2,2,1,1,1,1,1,1,1,1,2,2
};
long tempLong;
char str[40];
void setup() {
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
digitalWrite(txPin, HIGH);
delay(500);
pinMode(K_IN, INPUT);
pinMode(K_OUT, OUTPUT);
pinMode(13, OUTPUT);
mySerial.begin(9600);
mySerial.println("-=Arduino OBD2 Terminal=-");
}
void loop() {
command = mySerial.read();
switch (command) {
case '1':
obdConnect();
break;
case '2':
mySerial.println("MIL Selected");
get_pid(0x01, str, &tempLong);
break;
case '3':
mySerial.println("RPM Selected");
get_pid(0x03, str, &tempLong);
break;
case '4':
mySerial.println("MAF Selected");
get_pid(0x10, str, &tempLong);
break;
}
}
int obdConnect(){
mySerial.println("Attempting ECU initialization...");
if (iso_init() == 0){
mySerial.println("PASS");
return 0;
}
else{
mySerial.println("FAIL");
return 1;
}
}
byte iso_init()
{
byte b;
serial_tx_off(); //disable UART so we can "bit-Bang" the slow init.
serial_rx_off();
delay(3000); //k line should be free of traffic for at least two secconds.
digitalWrite(K_OUT, HIGH); // drive K line high for 300ms
delay(300);
// send 0x33 at 5 bauds
digitalWrite(K_OUT, LOW); // start bit
delay(200);
b=0x33;
for (byte mask = 0x01; mask != 0; mask <<= 1)
{
if (b & mask)
digitalWrite(K_OUT, HIGH);
else
digitalWrite(K_OUT, LOW);
delay(200);
}
digitalWrite(K_OUT, HIGH); // stop bit + 60 ms delay
delay(260);
Serial.begin(10400); // switch now to 10400 bauds
byte i=0; // wait for 0x55 from the ECU (up to 300ms)
while(i<3 && !iso_read_byte(&b)){
i++;
}
mySerial.println(b, BYTE);
if(b != 0x55){
return 1;
}
iso_read_byte(&b);
mySerial.println(b, BYTE); // wait for kw1 and kw2
iso_read_byte(&b);
mySerial.println(b, BYTE);
iso_write_byte(~b); // send ~kw2 (invert of last keyword)
iso_read_byte(&b);
mySerial.println(b, BYTE); // ECU answer by 0xCC (~0x33)
if(b!=0xCC)
return 1;
return 0;
}
void serial_rx_off() {
UCSR0B &= ~(_BV(RXEN0));
}
void serial_tx_off() {
UCSR0B &= ~(_BV(TXEN0));
delay(20); //allow time for buffers to flush
}
void serial_rx_on() {
Serial.begin(10400);
}
boolean iso_read_byte(byte * b)
{
int readData;
boolean success = true;
byte t=0;
while(t != READ_ATTEMPTS && (readData=Serial.read())==-1) {
delay(1);
t++;
}
if (t>=READ_ATTEMPTS) {
success = false;
}
if (success)
{
*b = (byte) readData;
}
return success;
}
void iso_write_byte(byte b)
{
serial_rx_off();
Serial.print(b);
delay(10);
serial_rx_on();
}
byte iso_checksum(byte *data, byte len)
{
byte i;
byte crc;
crc=0;
for(i=0; i<len; i++)
crc=crc+data[i];
return crc;
}
byte iso_write_data(byte *data, byte len)
{
byte i, n;
byte buf[20];
// ISO header
buf[0]=0x68;
buf[1]=0x6A; // 0x68 0x6A is an OBD-II request
buf[2]=0xF1; // our requesterХs address (off-board tool)
// append message
for(i=0; i<len; i++)
buf[i+3]=data[i];
// calculate checksum
i+=3;
buf[i]=iso_checksum(buf, i);
// send char one by one
n=i+1;
for(i=0; i<n; i++)
{
iso_write_byte(buf[i]);
}
return 0;
}
// read n byte(s) of data (+ header + cmd and crc)
// return the count of bytes of message (includes all data in message)
byte iso_read_data(byte *data, byte len)
{
byte i;
byte buf[20];
byte dataSize = 0;
for(i=0; i<len+6; i++)
{
if (iso_read_byte(buf+i))
{
dataSize++;
}
}
memcpy(data, buf+5, len);
delay(55); //guarantee 55 ms pause between requests
return dataSize;
}
boolean get_pid(byte pid, char *retbuf, long *ret)
{
byte cmd[2]; // to send the command
byte buf[10]; // to receive the result
byte reslen = pid_reslen[pid]; // receive length depends on pid
cmd[0]=0x01; // ISO cmd 1, get PID
cmd[1]=pid;
iso_write_data(cmd, 2); // send command, length 2
if (!iso_read_data(buf, reslen)) // read requested length, n bytes received in buf
{
mySerial.println("ISO Read Data Error.");
return false;
}
*ret=buf[0]*256U+buf[1]; // a lot of formulas are the same so calculate a default return value here
mySerial.print("Return Value ");
mySerial.print(pid, DEC);
mySerial.print(" : ");
mySerial.println(*ret);
return true;
}
Вложение 5979
-
Re: OBD-II диагностика на Carduino (Arduino)
я так понял, что порт один...
Т.е. через него будет и связь с машиной, и связь с компом?
-
Re: OBD-II диагностика на Carduino (Arduino)
Нет не один, используется библиотека софтового Serial Port <SoftwareSerial.h>
А хардверный порт так и остается , просто в примере он не используется
-
Re: OBD-II диагностика на Carduino (Arduino)
ясно, я думал, эта библиотека от хардового, хотя название ее говорит само за себя :)
-
Re: OBD-II диагностика на Carduino (Arduino)
mySerial используется для связи с компьютером? если да тогда почему судя по картинке она подключена к машине
Код:
#define rxPin 3
#define txPin 2
...
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
это + картинка показывают работу с машиной,
а вот здесь
Код:
void loop() {
command = mySerial.read();
switch (command) {
case '1':
obdConnect();
break;
case '2':
mySerial.println("MIL Selected");
get_pid(0x01, str, &tempLong);
break;
case '3':
mySerial.println("RPM Selected");
get_pid(0x03, str, &tempLong);
break;
case '4':
mySerial.println("MAF Selected");
get_pid(0x10, str, &tempLong);
break;
}
}
вроде как связь с ком портом компьютера, т.е. ожидание какой номер команды введут скажем в гипертерминале, или я что-то не так понял?
-
Re: OBD-II диагностика на Carduino (Arduino)
коллеги, а кто-нибудь эту тему дальше развивал?
есть мысль читать через CAN-шину сообщения от подрулевых переключателей.
вообще, пока нашёл только один(!) похожий проект:
http://code.google.com/p/opengauge/w/list
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
softic
коллеги, а кто-нибудь эту тему дальше развивал?
есть мысль читать через CAN-шину сообщения от подрулевых переключателей.
вообще, пока нашёл только один(!) похожий проект:
http://code.google.com/p/opengauge/w/list
http://code.google.com/p/multidisplay/
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
Chip
...
Пример кода OBD-II терминала для Arduino / Carduino...
Кто-нибудь попробовал?
-
Re: OBD-II диагностика на Carduino (Arduino)
На японца праворукова начну пробовать, как придет индикатор 16х2, через неделю. На Duino. Будет железячный вариант. Валентин 8080 помоги с пидами, плиз.
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
Noid
На японца праворукова начну пробовать, как придет индикатор 16х2, через неделю. На Duino. Будет железячный вариант. Валентин 8080 помоги с пидами, плиз.
Начали пробовать?
-
Re: OBD-II диагностика на Carduino (Arduino)
Уважаемые гуру, подскажите как правильно снять данные с OBD II разъема, снимать буду arduino duemilanove, данные выводить на подключенный к нему же ЖКИ, интересует схема подключения и алгоритм считывания данных, нужен только тахометр. К OBD II уже подключен маршрутный компьютер, если я подключусь в параллель не будут проблемы?
Вариант из первого поста работоспособный?
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
MariMax
mySerial используется для связи с компьютером? если да тогда почему судя по картинке она подключена к машине
Код:
#define rxPin 3
#define txPin 2
...
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
это + картинка показывают работу с машиной,
а вот здесь
Код:
void loop() {
command = mySerial.read();
switch (command) {
case '1':
obdConnect();
break;
case '2':
mySerial.println("MIL Selected");
get_pid(0x01, str, &tempLong);
break;
case '3':
mySerial.println("RPM Selected");
get_pid(0x03, str, &tempLong);
break;
case '4':
mySerial.println("MAF Selected");
get_pid(0x10, str, &tempLong);
break;
}
}
вроде как связь с ком портом компьютера, т.е. ожидание какой номер команды введут скажем в гипертерминале, или я что-то не так понял?
Так никто и не ответил
-
Re: OBD-II диагностика на Carduino (Arduino)
Я этот проект на работоспособность не проверял.
-
Re: OBD-II диагностика на Carduino (Arduino)
Уже заказал mc33290, придет буду паять. Помогите с портами разобраться, как-то не сходится скетч и схема, SoftwareSerial mySerial используется как для обмена данными по k-line так и для связи с терминалом ПК
Код:
mySerial.println("MIL Selected");
, возможно просто опечатка. Можно ли считать этот способ самым простым для получения данных тахометра? Извиняюсь за возможно глупые вопросы, новичек еще, но надеюсь исправиться. Заранее спасибо.
-
Re: OBD-II диагностика на Carduino (Arduino)
-
Re: OBD-II диагностика на Carduino (Arduino)
Спасибо огромное, и снова вопрос: в скетче указываем пины для софтварного serial
Код:
#define rxPin 3
#define txPin 2
но в схеме D2и D3 свободны, так и должно быть?
-
Re: OBD-II диагностика на Carduino (Arduino)
D2 D3 нужно подключить вместо D0, D1
Или подключить через переходник к com порту компьютера
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
izeldur
Уже заказал mc33290, придет буду паять. ...
Продвинулось у Вас?
-
Re: OBD-II диагностика на Carduino (Arduino)
Есть проект на эту тему, http://obduino.ca, исходники открыты. Варианты на МЕГИ 16К и 32К, под Duino. Пробовал код 16К(с редакцией), компилится, но не влазит в 16 дуину средствами родного софта - остается всего 700 байт. Где программа ложит HEX файл? Хочу прошить другой.:confused:
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
edw123
Продвинулось у Вас?
Развел плату, спаял, сейчас со скетчем разбираюсь, думаю через пару дней будет видно.
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
izeldur
...сейчас со скетчем разбираюсь...
А с чем конкретно?
-
Re: OBD-II диагностика на Carduino (Arduino)
Инициализация не работает
Код:
if(b != 0x55)
return 1;
Думаю в чем проблема, может микруха померла, я один раз перепутал ножки, к Rx и Tx подал +5V и соответственно к Vdd -> D0 и CEN -> D1. Может подскажет кто как проверить жива ли MC33290?
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
izeldur
Инициализация не работает
Код:
if(b != 0x55)
return 1;
Думаю в чем проблема, может микруха померла, я один раз перепутал ножки, к Rx и Tx подал +5V и соответственно к Vdd -> D0 и CEN -> D1. Может подскажет кто как проверить жива ли MC33290?
Осцилографом на выходе Ардуины - входе 33290? 33290 - вроде простой транслятор входа на выход, без всякой логики. Если есть на входе и нет на выходе - дело в 33290 или питании.
-
Re: OBD-II диагностика на Carduino (Arduino)
Доброе утро! Наткнулся на тему, которая мне сейчас очень актуальна. Ничего не понимаю в программировании и автомобилях, но понадобилось очень сделать штучку. Как сделать что бы ардуина считывала показания скорости автомобиля, и в случае привышения скорости свыше 150 км в час, подавала сигнал на один из пинов? И как подключить всё это правильно, желательно если можно с картинками как для детей)
-
Re: OBD-II диагностика на Carduino (Arduino)
Добрый день!
Пытаюсь собрать подобное устройство, но при компиляции ArduinoIDE ругается
tripcomp.cpp: In function 'void serial_rx_off()':
tripcomp:146: error: 'UCSR0B' was not declared in this scope
tripcomp:146: error: 'RXEN0' was not declared in this scope
tripcomp.cpp: In function 'void serial_tx_off()':
tripcomp:151: error: 'UCSR0B' was not declared in this scope
tripcomp:151: error: 'TXEN0' was not declared in this scope
В чем может быть проблема? Спасибо за ответ.
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
Slava111
Добрый день!
Пытаюсь собрать подобное устройство, но при компиляции ArduinoIDE ругается ...
Побороли?
-
Re: OBD-II диагностика на Carduino (Arduino)
В скетче есть строчка:
Serial.begin(10400);
Эта скорость вроде отсутствует в списке "стандартных"? Ничего специально для её получения не надо делать?
-
Re: OBD-II диагностика на Carduino (Arduino)
Здесь есть онлайн калькулятор
или можно вычислить значение регистра UBRR по формуле: UBRR=fck/16/BAUD-1, 95=16000000/16/10400-1
Что бы получить требуемую скорость 10400 (раельно получится 10416), нужно в регистр UBRR положить значение 95 UBBR=95
проверяем по формуле: BAUD = fck / (16(UBRR+1)), 10416=16000000/(16(95+1))
где:
BAUD - скорость обмена, бод;
fck - частота тактового генератора микроконтроллера, МГц;
UBRR - содержимое 8-битного доступного для записи регистра UBRR (0 - 255).
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
Chip
... Что бы получить требуемую скорость 10400 (раельно получится 10416), нужно в регистр UBRR положить значение 95 UBBR=95...
То есть это надо в скетч добавлять? Один раз в void setup() или каждый раз в void serial_rx_on()?
-
Re: OBD-II диагностика на Carduino (Arduino)
Ничего не нужно добавлять, это все есть в идущей в комплекте с IDE библиотеке
Нужно только указать скорость порта , а программа сама рассчитает что в регистр UBRR положить
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
Chip
Ничего не нужно добавлять, это все есть в идущей в комплекте с IDE библиотеке
Нужно только указать скорость порта , а программа сама рассчитает что в регистр UBRR положить
Ясно. Просто в списке скоростей передачи не указана 10400, а на РС, знаю, мучаются с установкой такой скорости. Значит с Ардуино легче.
-
Re: OBD-II диагностика на Carduino (Arduino)
А по протоколу ssm1 (старые субару) кто-нибудь подключал ардуину?
-
Re: OBD-II диагностика на Carduino (Arduino)
Есть информация по подключению к nissan. Известно что подключение производится в моем случае по протоколу ISO-14230 (fast init). Использую вот такой алгоритм:
1. на выход K-line подаю HIGH не менее 300 мс
2. на выход K-line подаю LOW 25 мс
3. на выход K-line подаю HIGH 25 мс
4. далее StartCommunication на скорости 10400
5. прием ответа
Код HTML:
#include <LiquidCrystal.h>
#define K_IN 0
#define K_OUT 1
//create object to control an LCD.
enum { LCD_WIDTH = 16, LCD_HEIGHT = 2 };
LiquidCrystal lcd(7, 6, 4, 5, 2, 3);
void setup() {
pinMode(K_IN, INPUT);
pinMode(K_OUT, OUTPUT);
}
void loop()
{
lcd.clear();
lcd.print("ECU init...");
obdConnect();
delay(1000);
}
void obdConnect()
{
int n,i;
byte buf[20];
buf[0]=0x81;
buf[1]=0x10;
buf[2]=0xFC;
buf[3]=0x81;
buf[4]=0x0E;
serial_tx_off();
serial_rx_off();
digitalWrite(K_OUT, HIGH);
delay(300);
digitalWrite(K_OUT, LOW);
delay(25);
digitalWrite(K_OUT, HIGH);
delay(25);
Serial.begin(10400); // switch now to 10400 bauds
for(i=0;i<5;i++)
{
Serial.write(buf[i]);
}
lcd.clear();
n=Serial.available();
if (i > 0)
{
for (i=0;i<n;i++)
{
buf[i]=Serial.read();;
}
lcd.clear();
lcd.print("OK");
}
else
{
lcd.clear();
lcd.print("Error");
}
}
void serial_rx_off() {
UCSR0B &= ~(_BV(RXEN0));
}
void serial_tx_off() {
UCSR0B &= ~(_BV(TXEN0));
delay(20);
}
Но ECU ответа не дает. Знающие, помогите в чем может быть проблема.
Есть сомнения в моменте переключения на скорость 10400. Может быть проблема в самом подходе к решению задачи?
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
murano
Но ECU ответа не дает.
Проблему решил. Нужно было добавить паузу после посылки запроса и еще объединить минус arduino c минусом авто (до этого запитывал arduino с нетбука)
-
Re: OBD-II диагностика на Carduino (Arduino)
Цитата:
Сообщение от
murano
Проблему решил. Нужно было добавить паузу после посылки запроса и еще объединить минус arduino c минусом авто (до этого запитывал arduino с нетбука)
В каком месте Вашего скетча забита пауза?
-
Re: OBD-II диагностика на Carduino (Arduino)
В представленном выше есть некоторые неточности. А паузу надо выдержать между записью запроса и приемом ответа.
-
Re: OBD-II диагностика на Carduino (Arduino)
С новой библиотекой Softwareserial на скорости 10400 не работает. Чтобы заработало надо отредактировать SoftwareSerial.cpp вставив строчку для частоты 16МГц { 10400, 106, 218, 218, 215, }. Проверено, работает.
-
Re: OBD-II диагностика на Carduino (Arduino)
А как часто и как быстро можно получать данные с OBD-II ?
Каждый ли раз при запросе данных нужно осуществлять вход? или войдя однажды можно запросы сколь угодно долго обрабатывать?
-
Re: OBD-II диагностика на Carduino (Arduino)
Данные получаются в соответствии со скоростью обмена. Как запросил - так и получил ответ. Другой вопрос - сколько времени потратишь на обработку этих ответов и как много параметров будешь запрашивать? Запросы надо посылать в цикле и в зависимости от длительности периода получаешь динамику изменения параметров.
-
Re: OBD-II диагностика на Carduino (Arduino)
А можно с k-line при подключенном бортовом компьютере Мультитроникс параллельно еще и ардуину прицепить? не будут они друг дружке мешать?