diff options
-rw-r--r-- | libraries/OBD/OBD.cpp | 135 | ||||
-rw-r--r-- | libraries/OBD/OBD.h | 14 |
2 files changed, 69 insertions, 80 deletions
diff --git a/libraries/OBD/OBD.cpp b/libraries/OBD/OBD.cpp index 267f436..fcb3c92 100644 --- a/libraries/OBD/OBD.cpp +++ b/libraries/OBD/OBD.cpp @@ -9,15 +9,13 @@ #include <avr/pgmspace.h> #include "OBD.h" -//#define DEBUG -#define DEBUG_SERIAL Serial - #define MAX_CMD_LEN 6 -const char PROGMEM s_initcmd[][MAX_CMD_LEN] = {"ATZ\r","ATE0\r","ATL1\r","0902\r"}; +const char PROGMEM s_initcmd[][MAX_CMD_LEN] = {"ATZ\r","ATE0\r","ATL1\r"}; +const char PROGMEM s_searching[] = "SEARCHING"; const char PROGMEM s_cmd_fmt[] = "%02X%02X 1\r"; const char PROGMEM s_cmd_sleep[] = "atlp\r"; -#define STR_SEARCHING "SEARCHING..." +const char PROGMEM s_cmd_vin[] = "0902\r"; unsigned int hex2uint16(const char *p) { @@ -64,9 +62,6 @@ void COBD::sendQuery(unsigned char pid) { char cmd[8]; sprintf_P(cmd, s_cmd_fmt, dataMode, pid); -#ifdef DEBUG - debugOutput(cmd); -#endif write(cmd); } @@ -81,6 +76,7 @@ bool COBD::readSensor(byte pid, int& result, bool passive) dataIdleLoop(); } while (!(hasData = available()) && millis() - tick < OBD_TIMEOUT_SHORT); if (!hasData) { + write('\r'); errors++; return false; } @@ -96,9 +92,6 @@ bool COBD::available() char COBD::read() { char c = OBDUART.read(); -#ifdef DEBUG - DEBUG_SERIAL.print(c); -#endif return c; } @@ -153,10 +146,43 @@ int COBD::normalizeData(byte pid, char* data) char* COBD::getResponse(byte& pid, char* buffer) { - byte n = receive(buffer); - if (n > 6) { + unsigned long startTime = millis(); + static const char responseSign[3] = {'4', '1', ' '}; + byte i = 0; + + for (;;) { + if (available()) { + char c = read(); + buffer[i] = c; + if (++i == OBD_RECV_BUF_SIZE - 1) { + // buffer overflow + break; + } + if (c == '>' && i > 6) { + // prompt char reached + break; + } + } else { + buffer[i] = 0; + unsigned int timeout; + if (dataMode != 1 || strstr_P(buffer, s_searching)) { + timeout = OBD_TIMEOUT_LONG; + } else { + timeout = OBD_TIMEOUT_SHORT; + } + if (millis() - startTime > timeout) { + // timeout + errors++; + break; + } + dataIdleLoop(); + } + } + buffer[i] = 0; + + if (i > 6) { char *p = buffer; - while ((p = strstr(p, "41 "))) { + while ((p = strstr(p, responseSign))) { p += 3; byte curpid = hex2uint8(p); if (pid == 0) pid = curpid; @@ -210,62 +236,42 @@ void COBD::begin() OBDUART.begin(OBD_SERIAL_BAUDRATE); } -byte COBD::receive(char* buffer) -{ - unsigned long startTime = millis(); - unsigned char n = 0; - int timeout = OBD_TIMEOUT_SHORT; - - buffer[0] = 0; - for (;;) { - if (available()) { - char c = read(); - if (n > 2 && c == '>') { - // prompt char received - break; - } else if (n < OBD_RECV_BUF_SIZE - 1) { - buffer[n++] = c; - buffer[n] = 0; - } - if (strstr(buffer, STR_SEARCHING)) { - strcpy(buffer, buffer + sizeof(STR_SEARCHING)); - n -= sizeof(STR_SEARCHING); - timeout = OBD_TIMEOUT_LONG; - } - } else { - if (millis() - startTime > timeout) { - // timeout - return 0; - } - dataIdleLoop(); - } - } - - return n; -} - bool COBD::init(bool passive) { unsigned long currentMillis; + unsigned char n; + char prompted; char buffer[OBD_RECV_BUF_SIZE]; - state = STATE_CONNECTING; - - write('\r'); - delay(100); - while (available()) read(); - for (unsigned char i = 0; i < sizeof(s_initcmd) / sizeof(s_initcmd[0]); i++) { if (!passive) { char cmd[MAX_CMD_LEN]; strcpy_P(cmd, s_initcmd[i]); -#ifdef DEBUG - debugOutput(cmd); -#endif write(cmd); } - if (receive(buffer) == 0) { - return false; + n = 0; + prompted = 0; + currentMillis = millis(); + for (;;) { + if (available()) { + char c = read(); + if (n > 2 && c == '>') { + buffer[n] = 0; + prompted++; + } else if (n < OBD_RECV_BUF_SIZE - 1) { + buffer[n++] = c; + } + } else if (prompted) { + break; + } else { + unsigned long elapsed = millis() - currentMillis; + if (elapsed > OBD_TIMEOUT_INIT) { + // init timeout + //WriteData("\r"); + return false; + } + initIdleLoop(); + } } } while (available()) read(); @@ -286,17 +292,6 @@ bool COBD::init(bool passive) } while (available()) read(); - state = STATE_CONNECTED; errors = 0; return true; } - -#ifdef DEBUG -void COBD::debugOutput(const char *s) -{ - DEBUG_SERIAL.print('['); - DEBUG_SERIAL.print(millis()); - DEBUG_SERIAL.print(']'); - DEBUG_SERIAL.print(s); -} -#endif diff --git a/libraries/OBD/OBD.h b/libraries/OBD/OBD.h index e75a26f..b13056d 100644 --- a/libraries/OBD/OBD.h +++ b/libraries/OBD/OBD.h @@ -7,8 +7,9 @@ #define OBD_TIMEOUT_SHORT 2000 /* ms */ #define OBD_TIMEOUT_LONG 7000 /* ms */ +#define OBD_TIMEOUT_INIT 3000 /* ms */ #define OBD_SERIAL_BAUDRATE 38400 -#define OBD_RECV_BUF_SIZE 128 +#define OBD_RECV_BUF_SIZE 64 #ifndef OBDUART #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega644P__) @@ -36,18 +37,13 @@ #define PID_RUNTIME 0x1F #define PID_DISTANCE 0x31 -// states -#define STATE_DISCONNECTED 0 -#define STATE_CONNECTING 1 -#define STATE_CONNECTED 2 - unsigned int hex2uint16(const char *p); unsigned char hex2uint8(const char *p); class COBD { public: - COBD():dataMode(1),errors(0),state(STATE_DISCONNECTED) {} + COBD():dataMode(1),errors(0) {} void begin(); bool init(bool passive = false); bool readSensor(byte pid, int& result, bool passive = false); @@ -61,11 +57,8 @@ public: byte errors; byte pidmap[4 * 4]; byte vin[17]; - byte state; //char recvBuf[OBD_RECV_BUF_SIZE]; protected: - byte receive(char* buffer); - void debugOutput(const char* s); static int normalizeData(byte pid, char* data); static int getPercentageValue(char* data) { @@ -87,5 +80,6 @@ protected: virtual char read(); virtual void write(const char* s); virtual void write(const char c); + virtual void initIdleLoop() {} virtual void dataIdleLoop() {} }; |