From 2dcc86309bff8eeeb90c9a58b60c5e8ce0d8aa53 Mon Sep 17 00:00:00 2001 From: Stanley Huang Date: Fri, 22 May 2015 22:16:53 +1000 Subject: Some optimizations --- libraries/OBD/OBD.cpp | 129 ++++++++++++++++++++++++-------------------------- libraries/OBD/OBD.h | 31 +++++------- 2 files changed, 74 insertions(+), 86 deletions(-) (limited to 'libraries/OBD') diff --git a/libraries/OBD/OBD.cpp b/libraries/OBD/OBD.cpp index 42fa1c5..c28c1f2 100644 --- a/libraries/OBD/OBD.cpp +++ b/libraries/OBD/OBD.cpp @@ -6,6 +6,7 @@ *************************************************************************/ #include +#include #include "OBD.h" //#define DEBUG Serial @@ -54,12 +55,12 @@ byte hex2uint8(const char *p) /************************************************************************* * OBD-II UART Adapter *************************************************************************/ -#include byte COBD::sendCommand(const char* cmd, char* buf) { - write(cmd); - return receive(buf); + write(cmd); + dataIdleLoop(); + return receive(buf); } void COBD::sendQuery(byte pid) @@ -244,12 +245,6 @@ void COBD::sleep() receive(); } -void COBD::wakeup() -{ - write('\r'); - receive(); -} - float COBD::getVoltage() { char buf[OBD_RECV_BUF_SIZE]; @@ -295,46 +290,48 @@ void COBD::begin() { OBDUART.begin(OBD_SERIAL_BAUDRATE); #ifdef DEBUG - DEBUG.begin(115200); + DEBUG.begin(115200); #endif + recover(); } byte COBD::receive(char* buffer, int timeout) { unsigned char n = 0; - for (unsigned long startTime = millis();;) { - if (available()) { - char c = read(); - if (n > 2 && c == '>') { - // prompt char received - break; - } else if (!buffer) { - n++; - } else if (n < OBD_RECV_BUF_SIZE - 1) { - if (c == '.' && n > 2 && buffer[n - 1] == '.' && buffer[n - 2] == '.') { - n = 0; - timeout = OBD_TIMEOUT_LONG; - } else { - buffer[n++] = c; - } - } - } else { - if (millis() - startTime > timeout) { - // timeout - return 0; - } - dataIdleLoop(); - } + unsigned long startTime = millis(); + for (;;) { + if (available()) { + char c = read(); + if (n > 2 && c == '>') { + // prompt char received + break; + } else if (!buffer) { + n++; + } else if (n < OBD_RECV_BUF_SIZE - 1) { + if (c == '.' && n > 2 && buffer[n - 1] == '.' && buffer[n - 2] == '.') { + // waiting siginal + n = 0; + timeout = OBD_TIMEOUT_LONG; + } else { + buffer[n++] = c; + } + } + } else { + if (millis() - startTime > timeout) { + // timeout + break; + } + dataIdleLoop(); + } } - if (buffer) buffer[n] = 0; + if (buffer) buffer[n] = 0; return n; } void COBD::recover() { - write('\r'); - delay(100); - while (available()) read(); + write("AT\r"); + receive(0, 1000); } bool COBD::init(OBD_PROTOCOLS protocol) @@ -403,9 +400,7 @@ bool COBD::setBaudRate(unsigned long baudrate) delay(50); OBDUART.end(); OBDUART.begin(baudrate); - OBDUART.print('ATV\r'); - delay(50); - while (available()) read(); + recover(); return true; } @@ -481,11 +476,10 @@ void COBD::debugOutput(const char *s) void COBDI2C::begin() { Wire.begin(); - memset(obdPid, 0, sizeof(obdPid)); - memset(obdInfo, 0, sizeof(obdInfo)); #ifdef DEBUG - DEBUG.begin(115200); + DEBUG.begin(115200); #endif + recover(); } void COBDI2C::end() @@ -523,35 +517,36 @@ byte COBDI2C::receive(char* buffer, int timeout) { uint32_t start = millis(); byte offset = 0; - delay(10); do { Wire.requestFrom((byte)I2C_ADDR, (byte)MAX_PAYLOAD_SIZE, (byte)1); - - bool hasEnd = false; - for (byte i = 0; i < MAX_PAYLOAD_SIZE && Wire.available(); i++) { - char c = Wire.read(); - buffer[offset + i] = c; - if (c == 0) - hasEnd = true; - } - - if (buffer[0] == 0) { - // data not ready + int c = Wire.read(); + if (offset == 0 && (c == 0 || c == -1)) { + // data not ready dataIdleLoop(); - continue; + continue; } - - offset += MAX_PAYLOAD_SIZE; - if (!hasEnd) { - continue; + if (buffer) buffer[offset++] = c; + for (byte i = 1; i < MAX_PAYLOAD_SIZE && Wire.available(); i++) { + char c = Wire.read(); + if (c == '.' && offset > 2 && buffer[offset - 1] == '.' && buffer[offset - 2] == '.') { + // waiting signal + offset = 0; + timeout = OBD_TIMEOUT_LONG; + } else if (c == 0 || offset == OBD_RECV_BUF_SIZE - 1) { + // string terminator encountered or buffer full + if (buffer) buffer[offset] = 0; + // discard the remaining data + while (Wire.available()) Wire.read(); + return offset; + } else { + if (buffer) buffer[offset++] = c; + } } - - return offset; } while(millis() - start < timeout); return 0; } -void COBDI2C::setPID(byte pid) +void COBDI2C::setPID(byte pid, byte obdPid[]) { byte n = 0; for (; n < MAX_PIDS && obdPid[n]; n++) { @@ -565,16 +560,16 @@ void COBDI2C::setPID(byte pid) obdPid[n] = pid; } -void COBDI2C::applyPIDs() +void COBDI2C::applyPIDs(byte obdPid[]) { - sendCommandBlock(CMD_APPLY_OBD_PIDS, 0, (byte*)obdPid, sizeof(obdPid)); + sendCommandBlock(CMD_APPLY_OBD_PIDS, 0, (byte*)obdPid, sizeof(obdPid[0])* MAX_PIDS); delay(200); } -void COBDI2C::loadData() +void COBDI2C::loadData(PID_INFO obdInfo[]) { sendCommandBlock(CMD_LOAD_OBD_DATA); dataIdleLoop(); Wire.requestFrom((byte)I2C_ADDR, (byte)MAX_PAYLOAD_SIZE, (byte)0); - Wire.readBytes((char*)obdInfo, MAX_PAYLOAD_SIZE); + Wire.readBytes((char*)obdInfo, sizeof(obdInfo[0]) * MAX_PIDS); } diff --git a/libraries/OBD/OBD.h b/libraries/OBD/OBD.h index dcd30fb..74e4225 100644 --- a/libraries/OBD/OBD.h +++ b/libraries/OBD/OBD.h @@ -128,12 +128,10 @@ public: virtual bool read(byte pid, int& result); // set device into virtual void sleep(); - // wake up device from previous sleep - virtual void wakeup(); // set working protocol (default auto) virtual bool setProtocol(OBD_PROTOCOLS h = PROTO_AUTO); // send AT command and receive response - virtual byte sendCommand(const char* cmd, char* buf); + virtual byte sendCommand(const char* cmd, char* buf = 0); // clear diagnostic trouble code virtual void clearDTC(); // get battery voltage (in 0.1V, e.g. 125 for 12.5V, works without ECU) @@ -196,8 +194,8 @@ private: #define CMD_SEND_AT_COMMAND 0x11 #define CMD_APPLY_OBD_PIDS 0x12 #define CMD_LOAD_OBD_DATA 0x13 -#define CMD_GPS_SETUP 0x20 -#define CMD_GPS_QUERY 0x22 +#define CMD_GPS_SETUP 0x14 +#define CMD_GPS_QUERY 0x15 typedef struct { uint16_t age; @@ -212,22 +210,17 @@ typedef struct { class COBDI2C : public COBD { public: - void begin(); + void begin(); void end(); - bool read(byte pid, int& result); - void write(const char* s); + bool read(byte pid, int& result); + void write(const char* s); // API not applicable bool setBaudRate(unsigned long baudrate) { return false; } - // Asynchronized access API - void setPID(byte pid); - void applyPIDs(); - void loadData(); - uint16_t getData(byte pid, int& result); + // Asynchronized access API + void setPID(byte pid, byte obdPid[]); + void applyPIDs(byte obdPid[]); + void loadData(PID_INFO obdInfo[]); protected: - byte receive(char* buffer, int timeout = OBD_TIMEOUT_LONG); - byte m_addr; - PID_INFO obdInfo[MAX_PIDS]; - byte obdPid[MAX_PIDS]; -private: - bool sendCommandBlock(byte cmd, uint8_t data = 0, byte* payload = 0, byte payloadBytes = 0); + byte receive(char* buffer = 0, int timeout = OBD_TIMEOUT_SHORT); + bool sendCommandBlock(byte cmd, uint8_t data = 0, byte* payload = 0, byte payloadBytes = 0); }; -- cgit v1.2.3