From 3df4070034d4fc9dc8464d08fab53b65e3729a2e Mon Sep 17 00:00:00 2001 From: Stanley Huang Date: Fri, 26 Feb 2016 13:42:19 +1100 Subject: Added multiple OBD-II PIDs reading API --- libraries/OBD/OBD.cpp | 60 ++++++++++++++++++++++++++++++++++++++++----------- libraries/OBD/OBD.h | 19 +++++++++------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/libraries/OBD/OBD.cpp b/libraries/OBD/OBD.cpp index e4d546c..6ede386 100644 --- a/libraries/OBD/OBD.cpp +++ b/libraries/OBD/OBD.cpp @@ -1,8 +1,8 @@ /************************************************************************* * Arduino Library for OBD-II UART/I2C Adapter -* Distributed under GPL v2.0 +* Distributed under BSD License * Visit http://freematics.com for more information -* (C)2012-2015 Stanley Huang +* (C)2012-2016 Stanley Huang *************************************************************************/ #include @@ -81,6 +81,25 @@ bool COBD::read(byte pid, int& result) return getResult(pid, result); } +byte COBD::read(const byte pid[], byte count, int result[]) +{ + // send a multiple query command + char buffer[128]; + char *p = buffer; + byte results = 0; + for (byte n = 0; n < count; n++) { + p += sprintf(p, "%02X%02X\r\n", dataMode, pid[n]); + } + write(buffer); + // receive and parse the response + for (byte n = 0; n < count; n++) { + byte curpid = pid[n]; + if (getResult(curpid, result[n])) + results++; + } + return results; +} + void COBD::clearDTC() { char buffer[32]; @@ -239,7 +258,7 @@ float COBD::getVoltage() bool COBD::getVIN(char* buffer, byte bufsize) { if (sendCommand("0902\r", buffer, bufsize)) { - char *p = strstr(buffer, "49 02"); + char *p = strstr(buffer, "0: 49 02"); if (p) { char *q = buffer; p += 10; @@ -321,23 +340,30 @@ bool COBD::init(OBD_PROTOCOLS protocol) m_state = OBD_CONNECTING; + write("ATI\r"); + if (receive(buffer, sizeof(buffer), 100)) { + char *p = strstr(buffer, "OBDUART"); + if (p) { + p += 9; + version = (*p - '0') * 10 + (*(p + 2) - '0'); + } + } + if (version == 0) { + m_state = OBD_FAILED; + return false; + } + for (unsigned char i = 0; i < sizeof(initcmd) / sizeof(initcmd[0]); i++) { #ifdef DEBUG debugOutput(initcmd[i]); #endif write(initcmd[i]); if (receive(buffer, sizeof(buffer), OBD_TIMEOUT_LONG) == 0) { - if (i == 0) { - // workaround for longer initialization time - delay(2000); - } else { - m_state = OBD_DISCONNECTED; - return false; - } + m_state = OBD_DISCONNECTED; + return false; } delay(50); } - //while (available()) read(); if (protocol != PROTO_AUTO) { setProtocol(protocol); @@ -358,7 +384,6 @@ bool COBD::init(OBD_PROTOCOLS protocol) } delay(100); } - //while (available()) read(); m_state = OBD_CONNECTED; errors = 0; @@ -471,6 +496,17 @@ byte COBDI2C::receive(char* buffer, byte bufsize, int timeout) return 0; } +byte COBDI2C::read(const byte pid[], byte count, int result[]) +{ + byte results = 0; + for (byte n = 0; n < count; n++) { + if (read(pid[n], result[n])) { + results++; + } + } + return results; +} + void COBDI2C::setPID(byte pid, byte obdPid[]) { byte n = 0; diff --git a/libraries/OBD/OBD.h b/libraries/OBD/OBD.h index dd1cbf6..c42b450 100644 --- a/libraries/OBD/OBD.h +++ b/libraries/OBD/OBD.h @@ -1,8 +1,8 @@ /************************************************************************* * Arduino Library for OBD-II UART/I2C Adapter -* Distributed under GPL v2.0 +* Distributed under BSD License * Visit http://freematics.com for more information -* (C)2012-2015 Stanley Huang +* (C)2012-2016 Stanley Huang *************************************************************************/ #include @@ -11,7 +11,7 @@ #define OBD_MODEL_I2C 1 #define OBD_TIMEOUT_SHORT 1000 /* ms */ -#define OBD_TIMEOUT_LONG 10000 /* ms */ +#define OBD_TIMEOUT_LONG 15000 /* ms */ #define OBD_TIMEOUT_GPS 200 /* ms */ #define OBD_SERIAL_BAUDRATE 38400 @@ -90,7 +90,8 @@ typedef enum { typedef enum { OBD_DISCONNECTED = 0, OBD_CONNECTING = 1, - OBD_CONNECTED = 2 + OBD_CONNECTED = 2, + OBD_FAILED = 3 } OBD_STATES; uint16_t hex2uint16(const char *p); @@ -100,10 +101,7 @@ class COBD { public: COBD():dataMode(1),errors(0),m_state(OBD_DISCONNECTED) {} - /* - Serial baudrate is only adjustable for Arduino OBD-II Adapters V2 - Check out http://freematics.com/pages/products/arduino-obd-adapter - */ + // begin serial UART virtual void begin(); // initialize OBD-II connection virtual bool init(OBD_PROTOCOLS protocol = PROTO_AUTO); @@ -115,6 +113,8 @@ public: virtual OBD_STATES getState() { return m_state; } // read specified OBD-II PID value virtual bool read(byte pid, int& result); + // read multiple (up to 8) OBD-II PID values, return number of values obtained + virtual byte read(const byte pid[], byte count, int result[]); // set device into virtual void sleep(); // set working protocol (default auto) @@ -141,6 +141,8 @@ public: byte errors; // bit map of supported PIDs byte pidmap[4 * 4]; + // adapter version + byte version; protected: virtual char* getResponse(byte& pid, char* buffer, byte bufsize); virtual byte receive(char* buffer, byte bufsize, int timeout = OBD_TIMEOUT_SHORT); @@ -197,6 +199,7 @@ public: void begin(); void end(); bool read(byte pid, int& result); + byte read(const byte pid[], byte count, int result[]); void write(const char* s); // API not applicable bool setBaudRate(unsigned long baudrate) { return false; } -- cgit v1.2.3