PDA

Просмотр полной версии : Obd1 toyota+arduino+android


Ajlewka
23.08.2015, 07:45
Всем доброго времени суток. Так как я рассматривал считывание показаний с диагностического разъема и выводом их на андроид, создаю тему здесь. Выкладываю вариант считывания оборотов двигателя, скорости, температуры ОЖ, времени инжекции, и еще некоторых моментов (зависит от машины в большей степени).
Скетч не мой, я только немного адаптировал его под себя. Можно просто подключить экран и кнопку к ардуино, и все будет показывать. Либо через COM порт к андроиду, и считывать показания. Вывод мгновенного расхода топлива, и расхода на 100 км у меня вывести не получилось, может быть кто и подскажет что у меня не так.
Принцип работы (в моем случае) следующий:
Заливаем скетч (приложу в конце) в ардуино,
Собираем вот такой кабель, желательно из витой пары
http://www.pccar.ru/attachment.php?attachmentid=40827&stc=1&d=1440300010
Сигнальный провод с VF1 цепляем на 2 контакт ардуино, с перемычки Е1-Те2 на gnd ардуино.
Ардуинку запитываем любым известным способом, главное до 9 вольт (есть специальные ардуино, которые питаются от 12В). У меня она питается от хаба 5В.

У меня данные идут по каналу блютуза, поэтому к ардуино прицеплен дополнительный модуль. Но можно снимать показания и с USB через serial соединение.

ардуино принимает данные с диагностики, преобразует их в строку, и отправляет в планшет. Таскером принятую переменную я разбиваю на несколько отдельных значений, и вывожу через zooper widget на экран. Может быть путь слегка длинный, но покороче сделать пока не получилось.
Строка данных следующая
OBD_SPD, OBD_RPM, OBD_INJ, OBD_IGN, OBD_IAC, OBD_MAP, OBD_ECT, OBD_TPS, Lh, L100.

Может быть есть возможность преобразовать данные в протокол, который понимает Torque. Тогда можно все сделать покрасивше.
Надеюсь на совместную адаптацию данного вида считывания.

Maniac82
23.08.2015, 10:17
А можно подробности как данные с ардуино передавать в таскер?

Ajlewka
23.08.2015, 11:46
А можно подробности как данные с ардуино передавать в таскер?

Я скачивал вот это приложение (https://play.google.com/store/apps/details?id=appinventor.ai_rblackmore245.Arduino_Bl uetooth), т.к. связь через блютуз. При соединении оно создает в корне файл rectmp.txt. Таскером прочитать файл rectmp.txt в переменную %OBD, Расчленить переменную %OBD разделитель "," передать необходимую из переменных в zooper widget, ждать 0,5сек, повторить пункт 1. Как то так.

Maniac82
23.08.2015, 16:23
Спасибо. Пригодится думаю когда bt модуль будет. А случайно наоборот с планшета в ардуино данные не передаются? :)

Ajlewka
23.08.2015, 16:26
Спасибо. Пригодится думаю когда bt модуль будет. А случайно наоборот с планшета в ардуино данные не передаются? :)

Было бы желание и смысл... Я для себя такого не вижу. Но передать можно конечно

Ajlewka
23.08.2015, 17:53
http://www.pccar.ru/attachment.php?attachmentid=40838&stc=1&d=1440337960

Arduino (2)
A1: Read File [ Файл:rectmp.txt В переменную:%SPEED ]
A2: Расчленить перем. [ Имя:%SPEED Разделитель:, Удалить исходную базу:Выключить ]
A3: Zooper Widget Pro Variable [ Конфигурация:#T1# = %SPEED2 Package:org.zooper.zwpro Имя:Zooper Widget Pro Variable Задержка (сек.):0 ]
A4: Zooper Widget Pro Variable [ Конфигурация:#TR# = %SPEED1 Package:org.zooper.zwpro Имя:Zooper Widget Pro Variable Задержка (сек.):0 ]
A5: Ждать [ Мсек.:76 Секунды:0 Минуты:0 Час.:0 Дни:0 ]
A6: Перейти к действию [ Тип:Action Number Номер (число):1 Этикетка: ]


Вот так это выглядит

Ajlewka
24.08.2015, 14:02
В общем, никак не получается принятые данные, преобразовать и передать в программу torque. Встал на этом моменте колом

macau
26.08.2015, 09:21
Но зачем весь этот огород втридорога, когда на али можно взять за 5 баксов нормальный бт-обд адаптер и тем же таскером через кариес таскать и парсить данные

Ajlewka
26.08.2015, 12:38
Но зачем весь этот огород втридорога, когда на али можно взять за 5 баксов нормальный бт-обд адаптер и тем же таскером через кариес таскать и парсить данные

Не у всех OBDii

Ajlewka
26.08.2015, 12:50
Немного обновил код. Теперь от выглядит слегка иначе.
#define ENGINE_DATA_PIN 2 // pin 2
#define ENGINE_DATA_INT 0 // for attachInterrupt
#define OBD_DATA true
#define MY_HIGH HIGH //LOW
#define MY_LOW LOW //HIGH

#define TOYOTA_MAX_BYTES 24
volatile uint8_t ToyotaNumBytes, ToyotaID;
volatile uint8_t ToyotaData[TOYOTA_MAX_BYTES];
volatile uint16_t ToyotaFailBit = 0;


// "names" for the OND data to make life easier
#define OBD_INJ 1 //Injector pulse width (INJ)
#define OBD_IGN 2 //Ignition timing angle (IGN)
#define OBD_IAC 3 //Idle Air Control (IAC)
#define OBD_RPM 4 //Engine speed (RPM)
#define OBD_MAP 5 //Manifold Absolute Pressure (MAP)
#define OBD_ECT 6 //Engine Coolant Temperature (ECT)
#define OBD_TPS 7 // Throttle Position Sensor (TPS)
#define OBD_SPD 8 //Speed (SPD)

// dfeine connection flag and last success packet - for lost connection function.
boolean OBDConnected;
unsigned long OBDLastSuccessPacket;

// VOID SETUP
void setup() {
Serial.begin(115200);
Serial.println("system Started");

// setup input and output pins
pinMode(ENGINE_DATA_PIN, INPUT); // _PULLUP
//setup Interrupt for data line
attachInterrupt(ENGINE_DATA_INT, ChangeState, CHANGE);

} // END VOID SETUP


// VOID LOOP
void loop() {

if (ToyotaNumBytes > 0) {
if (OBD_DATA) {
debugdataoutput(); }

// set last success
OBDLastSuccessPacket = millis();
// set connected to true
OBDConnected = true;
// reset the counter.
ToyotaNumBytes = 0;
} // end if (ToyotaNumBytes > 0)

// if found FAILBIT and dbug
if (ToyotaFailBit > 0) { debugfaildataoutput(); }

//check for lost connection
if (OBDLastSuccessPacket + 3500 < millis() && OBDConnected) {
OBDConnected = false;
} // end if loas conntcion
} // end void loop


// GET DATA FROM OBD
float getOBDdata(int OBDdataIDX) {
// define return value
float returnValue;
switch (OBDdataIDX) {
case 0:// UNKNOWN
returnValue = ToyotaData[0];
break;
case OBD_INJ: // Injector pulse width (INJ) - in milisec
returnValue = ToyotaData[OBD_INJ]/10;
break;
case OBD_IGN: // Ignition timing angle (IGN) - degree- BTDC
returnValue = ToyotaData[OBD_IGN]-90;
break;
case OBD_IAC: //Idle Air Control (IAC) - Step # X = 125 = open 100%
returnValue = ToyotaData[OBD_IAC]/125*100;
break;
case OBD_RPM: //Engine speed (RPM)
returnValue = ToyotaData[OBD_RPM]*25;
break;
case OBD_MAP: //Manifold Absolute Pressure (MAP) - kPa Abs
returnValue = ToyotaData[OBD_MAP];
break;
case OBD_ECT: // Engine Coolant Temperature (ECT)
if (ToyotaData[OBD_ECT] >= 244)
returnValue = ((float)(ToyotaData[OBD_ECT] - 244) * 10.0) + 132.0;
else if (ToyotaData[OBD_ECT] >= 238)
returnValue = ((float)(ToyotaData[OBD_ECT] - 238) * 4.0) + 103.0;
else if (ToyotaData[OBD_ECT] >= 228)
returnValue = ((float)(ToyotaData[OBD_ECT] - 228) * 2.1) + 80.0;
else if (ToyotaData[OBD_ECT] >= 210)
returnValue = ((float)(ToyotaData[OBD_ECT] - 210) * 1.11) + 60.0;
else if (ToyotaData[OBD_ECT] >= 180)
returnValue = ((float)(ToyotaData[OBD_ECT] - 180) * 0.666) + 40.0;
else if (ToyotaData[OBD_ECT] >= 135)
returnValue = ((float)(ToyotaData[OBD_ECT] - 135) * 0.444) + 20.0;
else if (ToyotaData[OBD_ECT] >= 82)
returnValue = ((float)(ToyotaData[OBD_ECT] - 82) * 0.377) + 0.0;
else if (ToyotaData[OBD_ECT] >= 39)
returnValue = ((float)(ToyotaData[OBD_ECT] - 39) * 0.465) + (-20.0);
else if (ToyotaData[OBD_ECT] >= 15)
returnValue = ((float)(ToyotaData[OBD_ECT] - 15) * 0.833) + (-40.0);
else
returnValue = ((float)ToyotaData[OBD_ECT] * 2.0) + (-70.0);

break;
case OBD_TPS: // Throttle Position Sensor (TPS) - DEGREE
returnValue = ToyotaData[OBD_TPS]/2;
break;
case OBD_SPD: // Speed (SPD) - km/h
returnValue = ToyotaData[OBD_SPD];
break;
case 9:// UNKNOWN
returnValue = ToyotaData[9];
break;
case 10:// UNKNOWN
returnValue = ToyotaData[10];
break;
case 11:// FLAG #1
returnValue = ToyotaData[11];
break;
case 12:// FLAG # 2
returnValue = ToyotaData[12];
break;
default: // DEFAULT CASE (in no match to number)
// send "error" value
returnValue = 9999.99;
} // end switch
// send value back
return returnValue;
} // end void getOBDdata

// VOID CHANGE
void ChangeState()
{
//Serial.print(digitalRead(ENGINE_DATA_PIN));
static uint8_t ID, EData[TOYOTA_MAX_BYTES];
static boolean InPacket = false;
static unsigned long StartMS;
static uint16_t BitCount;

int state = digitalRead(ENGINE_DATA_PIN);

if (InPacket == false) {
if (state == MY_HIGH) {
StartMS = millis();
} else { // else if (state == MY_HIGH)
if ((millis() - StartMS) > (15 * 8)) {
StartMS = millis();
InPacket = true;
BitCount = 0;
} // end if ((millis() - StartMS) > (15 * 8))
} // end if (state == MY_HIGH)
} else { // else if (InPacket == false)
uint16_t bits = ((millis() - StartMS)+1 ) / 8; // The +1 is to cope with slight time errors
StartMS = millis();
// process bits
while (bits > 0) {
if (BitCount < 4) {
if (BitCount == 0)
ID = 0;
ID >>= 1;
if (state == MY_LOW) // inverse state as we are detecting the change!
ID |= 0x08;
} else { // else if (BitCount < 4)
uint16_t bitpos = (BitCount - 4) % 11;
uint16_t bytepos = (BitCount - 4) / 11;
if (bitpos == 0) {

// Start bit, should be LOW
if ((BitCount > 4) && (state != MY_HIGH)) { // inverse state as we are detecting the change!
ToyotaFailBit = BitCount;
InPacket = false;
break;
} // end if ((BitCount > 4) && (state != MY_HIGH))

} else if (bitpos < 9) { //else TO if (bitpos == 0)

EData[bytepos] >>= 1;
if (state == MY_LOW) // inverse state as we are detecting the change!
EData[bytepos] |= 0x80;

} else { // else if (bitpos == 0)

// Stop bits, should be HIGH
if (state != MY_LOW) { // inverse state as we are detecting the change!
ToyotaFailBit = BitCount;
InPacket = false;
break;
} // end if (state != MY_LOW)

if ( (bitpos == 10) && ((bits > 1) || (bytepos == (TOYOTA_MAX_BYTES - 1))) ) {
ToyotaNumBytes = 0;
ToyotaID = ID;
for (int i=0; i<=bytepos; i++)
ToyotaData[i] = EData[i];
ToyotaNumBytes = bytepos + 1;
if (bits >= 16) // Stop bits of last byte were 1's so detect preamble for next packet
BitCount = 0;
else {
ToyotaFailBit = BitCount;
InPacket = false;
}
break;
}
}
}
++BitCount;
--bits;
} // end while
} // end (InPacket == false)
} // end void change




// DEBUG OUTPUT VOIDS


void debugdataoutput() {
Serial.print((float)ToyotaData[OBD_INJ]/10);
Serial.print(",");
Serial.print(ToyotaData[OBD_RPM]*25);
Serial.print(",");
Serial.print(ToyotaData[OBD_IGN]-90);
Serial.print(",");
Serial.print(ToyotaData[OBD_IAC]/125*100);
Serial.print(",");
Serial.print(ToyotaData[OBD_MAP]);
Serial.print(",");
int OBD_ECTi;
if (ToyotaData[OBD_ECT] >= 244)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 244) * 10.0) + 132.0;
else if (ToyotaData[OBD_ECT] >= 238)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 238) * 4.0) + 103.0;
else if (ToyotaData[OBD_ECT] >= 228)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 228) * 2.1) + 80.0;
else if (ToyotaData[OBD_ECT] >= 210)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 210) * 1.11) + 60.0;
else if (ToyotaData[OBD_ECT] >= 180)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 180) * 0.666) + 40.0;
else if (ToyotaData[OBD_ECT] >= 135)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 135) * 0.444) + 20.0;
else if (ToyotaData[OBD_ECT] >= 82)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 82) * 0.377) + 0.0;
else if (ToyotaData[OBD_ECT] >= 39)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 39) * 0.465) + (-20.0);
else if (ToyotaData[OBD_ECT] >= 15)
OBD_ECTi = ((ToyotaData[OBD_ECT] - 15) * 0.833) + (-40.0);
else
OBD_ECTi = (ToyotaData[OBD_ECT] * 2.0) + (-70.0);
Serial.print(OBD_ECTi);
Serial.print(",");
Serial.print(ToyotaData[OBD_SPD]);
Serial.print(",");
Serial.print(ToyotaData[OBD_TPS]/2);
Serial.println(" ");




} // end void

void debugfaildataoutput() {
Serial.print("FAIL = ");
Serial.print(ToyotaFailBit);
if (((ToyotaFailBit - 4) % 11) == 0)
Serial.print(" (StartBit)");
else if (((ToyotaFailBit - 4) % 11) > 8)
Serial.print(" (StopBit)");
Serial.println(".");
ToyotaFailBit = 0;
} // end void

macau
26.08.2015, 23:27
Тем более. Та же затычка как правило идет на PIC`е, достаточно просто перепрошить его своим кодом

Ajlewka
14.09.2015, 01:33
Наверно можно сказать, что я это сделал. Дублировать не буду, оставлю только ссылку
http://www.drive2.ru/l/7650414/

BatrakovSV
20.07.2017, 16:59
Отличная работа!