summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libraries/OBD/OBD.cpp162
-rw-r--r--libraries/OBD/OBD.h28
2 files changed, 90 insertions, 100 deletions
diff --git a/libraries/OBD/OBD.cpp b/libraries/OBD/OBD.cpp
index 5ea4c47..9d457bc 100644
--- a/libraries/OBD/OBD.cpp
+++ b/libraries/OBD/OBD.cpp
@@ -64,53 +64,94 @@ void COBD::Query(unsigned char pid)
{
char cmd[8];
sprintf_P(cmd, s_cmd_fmt, dataMode, pid);
- WriteData(cmd);
+ write(cmd);
}
bool COBD::ReadSensor(byte pid, int& result, bool passive)
{
- if (passive) {
- bool hasData;
- unsigned long tick = millis();
- while (!(hasData = DataAvailable()) && millis() - tick < OBD_TIMEOUT_SHORT);
- if (!hasData) {
- errors++;
- return false;
- }
- } else {
- Query(pid);
+ // send a query command
+ Query(pid);
+ // wait for reponse
+ bool hasData;
+ unsigned long tick = millis();
+ do {
+ DataIdleLoop();
+ } while (!(hasData = available()) && millis() - tick < OBD_TIMEOUT_SHORT);
+ if (!hasData) {
+ errors++;
+ return false;
}
- return GetResponse(pid, result);
+ // receive and parse the response
+ return GetResponseParsed(pid, result);
}
-bool COBD::DataAvailable()
+bool COBD::available()
{
return OBDUART.available();
}
-char COBD::ReadData()
+char COBD::read()
{
return OBDUART.read();
}
-void COBD::WriteData(const char* s)
+void COBD::write(const char* s)
{
OBDUART.write(s);
}
-void COBD::WriteData(const char c)
+void COBD::write(const char c)
{
OBDUART.write(c);
}
-char* COBD::GetResponse(byte pid, char* buffer)
+int COBD::GetConvertedValue(byte pid, char* data)
+{
+ int result;
+ switch (pid) {
+ case PID_RPM:
+ result = GetLargeValue(data) >> 2;
+ break;
+ case PID_FUEL_PRESSURE:
+ result = GetSmallValue(data) * 3;
+ break;
+ case PID_COOLANT_TEMP:
+ case PID_INTAKE_TEMP:
+ case PID_AMBIENT_TEMP:
+ result = GetTemperatureValue(data);
+ break;
+ case PID_ABS_ENGINE_LOAD:
+ result = GetLargeValue(data) * 100 / 255;
+ break;
+ case PID_MAF_FLOW:
+ result = GetLargeValue(data) / 100;
+ break;
+ case PID_THROTTLE:
+ case PID_ENGINE_LOAD:
+ case PID_FUEL_LEVEL:
+ result = GetPercentageValue(data);
+ break;
+ case PID_TIMING_ADVANCE:
+ result = (GetSmallValue(data) - 128) >> 1;
+ break;
+ case PID_DISTANCE:
+ case PID_RUNTIME:
+ result = GetLargeValue(data);
+ break;
+ default:
+ result = GetSmallValue(data);
+ }
+ return result;
+}
+
+char* COBD::GetResponse(byte& pid, char* buffer)
{
unsigned long startTime = millis();
byte i = 0;
for (;;) {
- if (DataAvailable()) {
- char c = ReadData();
+ if (available()) {
+ char c = read();
buffer[i] = c;
if (++i == OBD_RECV_BUF_SIZE - 1) {
// buffer overflow
@@ -140,7 +181,9 @@ char* COBD::GetResponse(byte pid, char* buffer)
char *p = buffer;
while ((p = strstr_P(p, s_response_begin))) {
p += 3;
- if (pid == 0 || hex2uint8(p) == pid) {
+ byte curpid = hex2uint8(p);
+ if (pid == 0) pid = curpid;
+ if (curpid == pid) {
errors = 0;
p += 2;
if (*p == ' ')
@@ -150,81 +193,27 @@ char* COBD::GetResponse(byte pid, char* buffer)
return 0;
}
-bool COBD::GetParsedData(byte pid, char* data, int& result)
-{
- switch (pid) {
- case PID_RPM:
- result = GetLargeValue(data) >> 2;
- break;
- case PID_FUEL_PRESSURE:
- result = GetSmallValue(data) * 3;
- break;
- case PID_COOLANT_TEMP:
- case PID_INTAKE_TEMP:
- case PID_AMBIENT_TEMP:
- result = GetTemperatureValue(data);
- break;
- case PID_ABS_ENGINE_LOAD:
- result = GetLargeValue(data) * 100 / 255;
- break;
- case PID_MAF_FLOW:
- result = GetLargeValue(data) / 100;
- break;
- case PID_THROTTLE:
- case PID_ENGINE_LOAD:
- case PID_FUEL_LEVEL:
- result = GetPercentageValue(data);
- break;
- case PID_SPEED:
- case PID_BAROMETRIC:
- case PID_INTAKE_MAP:
- result = GetSmallValue(data);
- break;
- case PID_TIMING_ADVANCE:
- result = (GetSmallValue(data) - 128) >> 1;
- break;
- case PID_DISTANCE:
- case PID_RUNTIME:
- result = GetLargeValue(data);
- break;
- default:
- return false;
- }
- return true;
-}
-
-bool COBD::GetResponse(byte pid, int& result)
+bool COBD::GetResponseParsed(byte& pid, int& result)
{
char buffer[OBD_RECV_BUF_SIZE];
char* data = GetResponse(pid, buffer);
if (!data) {
// try recover next time
- WriteData('\r');
+ write('\r');
return false;
}
- return GetParsedData(pid, data, result);
-}
-
-bool COBD::GetResponsePassive(byte& pid, int& result)
-{
- char buffer[OBD_RECV_BUF_SIZE];
- char* data = GetResponse(0, buffer);
- if (!data) {
- // try recover next time
- return false;
- }
- pid = hex2uint8(data - 3);
- return GetParsedData(pid, data, result);
+ result = GetConvertedValue(pid, data);
+ return true;
}
void COBD::Sleep(int seconds)
{
char cmd[MAX_CMD_LEN];
strcpy_P(cmd, s_cmd_sleep);
- WriteData(cmd);
+ write(cmd);
if (seconds) {
delay((unsigned long)seconds << 10);
- WriteData('\r');
+ write('\r');
}
}
@@ -249,14 +238,14 @@ bool COBD::Init(bool passive)
if (!passive) {
char cmd[MAX_CMD_LEN];
strcpy_P(cmd, s_initcmd[i]);
- WriteData(cmd);
+ write(cmd);
}
n = 0;
prompted = 0;
currentMillis = millis();
for (;;) {
- if (DataAvailable()) {
- char c = ReadData();
+ if (available()) {
+ char c = read();
if (c == '>') {
buffer[n] = 0;
prompted++;
@@ -272,7 +261,7 @@ bool COBD::Init(bool passive)
//WriteData("\r");
return false;
}
- DataTimeout();
+ InitIdleLoop();
}
}
}
@@ -280,8 +269,9 @@ bool COBD::Init(bool passive)
// load pid map
memset(pidmap, 0, sizeof(pidmap));
for (byte i = 0; i < 4; i++) {
- Query(i * 0x20);
- char* data = GetResponse(i * 0x20, buffer);
+ byte pid = i * 0x20;
+ Query(pid);
+ char* data = GetResponse(pid, buffer);
if (!data) break;
data--;
for (byte n = 0; n < 4; n++) {
diff --git a/libraries/OBD/OBD.h b/libraries/OBD/OBD.h
index acc6735..e97ab67 100644
--- a/libraries/OBD/OBD.h
+++ b/libraries/OBD/OBD.h
@@ -1,8 +1,7 @@
/*************************************************************************
-* Arduino OBD-II UART Adapter Library
-* http://www.arduinodev.com/hardware/obd-kit
+* OBD-II (ELM327) data accessing library for Arduino
* Distributed under GPL v2.0
-* (C)2012~2013 Written by Stanley Huang <stanleyhuangyc@gmail.com>
+* Copyright (c) 2012 Stanley Huang <stanleyhuangyc@gmail.com>
* All rights reserved.
*************************************************************************/
@@ -13,7 +12,7 @@
#define OBD_RECV_BUF_SIZE 64
#ifndef OBDUART
-#ifdef __AVR_ATmega32U4__ /* for Leonardo */
+#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
#define OBDUART Serial1
#else
#define OBDUART Serial
@@ -49,19 +48,15 @@ public:
bool ReadSensor(byte pid, int& result, bool passive = false);
bool IsValidPID(byte pid);
void Sleep(int seconds);
- // following APIs are for advanced usages only
+ // Query and GetResponse for advanced usage only
void Query(byte pid);
- bool GetParsedData(byte pid, char* data, int& result);
- virtual char* GetResponse(byte pid, char* buffer);
- virtual bool GetResponse(byte pid, int& result);
- virtual bool GetResponsePassive(byte& pid, int& result);
- virtual bool DataAvailable();
- virtual char ReadData();
- virtual void WriteData(const char* s);
- virtual void WriteData(const char c);
+ char* GetResponse(byte& pid, char* buffer);
+ bool GetResponseParsed(byte& pid, int& result);
byte dataMode;
byte errors;
+ //char recvBuf[OBD_RECV_BUF_SIZE];
protected:
+ static int GetConvertedValue(byte pid, char* data);
static int GetPercentageValue(char* data)
{
return (int)hex2uint8(data) * 100 / 255;
@@ -78,6 +73,11 @@ protected:
{
return (int)hex2uint8(data) - 40;
}
- virtual void DataTimeout() {}
+ virtual bool available();
+ virtual char read();
+ virtual void write(const char* s);
+ virtual void write(const char c);
+ virtual void InitIdleLoop() {}
+ virtual void DataIdleLoop() {}
byte pidmap[4 * 4];
};