summaryrefslogtreecommitdiff
path: root/libraries/OBD
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/OBD')
-rw-r--r--libraries/OBD/OBD.cpp135
-rw-r--r--libraries/OBD/OBD.h14
2 files changed, 80 insertions, 69 deletions
diff --git a/libraries/OBD/OBD.cpp b/libraries/OBD/OBD.cpp
index fcb3c92..267f436 100644
--- a/libraries/OBD/OBD.cpp
+++ b/libraries/OBD/OBD.cpp
@@ -9,13 +9,15 @@
#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"};
-const char PROGMEM s_searching[] = "SEARCHING";
+const char PROGMEM s_initcmd[][MAX_CMD_LEN] = {"ATZ\r","ATE0\r","ATL1\r","0902\r"};
const char PROGMEM s_cmd_fmt[] = "%02X%02X 1\r";
const char PROGMEM s_cmd_sleep[] = "atlp\r";
-const char PROGMEM s_cmd_vin[] = "0902\r";
+#define STR_SEARCHING "SEARCHING..."
unsigned int hex2uint16(const char *p)
{
@@ -62,6 +64,9 @@ void COBD::sendQuery(unsigned char pid)
{
char cmd[8];
sprintf_P(cmd, s_cmd_fmt, dataMode, pid);
+#ifdef DEBUG
+ debugOutput(cmd);
+#endif
write(cmd);
}
@@ -76,7 +81,6 @@ 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;
}
@@ -92,6 +96,9 @@ bool COBD::available()
char COBD::read()
{
char c = OBDUART.read();
+#ifdef DEBUG
+ DEBUG_SERIAL.print(c);
+#endif
return c;
}
@@ -146,43 +153,10 @@ int COBD::normalizeData(byte pid, char* data)
char* COBD::getResponse(byte& pid, char* buffer)
{
- 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) {
+ byte n = receive(buffer);
+ if (n > 6) {
char *p = buffer;
- while ((p = strstr(p, responseSign))) {
+ while ((p = strstr(p, "41 "))) {
p += 3;
byte curpid = hex2uint8(p);
if (pid == 0) pid = curpid;
@@ -236,42 +210,62 @@ 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);
}
- 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();
- }
+ if (receive(buffer) == 0) {
+ return false;
}
}
while (available()) read();
@@ -292,6 +286,17 @@ 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 b13056d..e75a26f 100644
--- a/libraries/OBD/OBD.h
+++ b/libraries/OBD/OBD.h
@@ -7,9 +7,8 @@
#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 64
+#define OBD_RECV_BUF_SIZE 128
#ifndef OBDUART
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega644P__)
@@ -37,13 +36,18 @@
#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) {}
+ COBD():dataMode(1),errors(0),state(STATE_DISCONNECTED) {}
void begin();
bool init(bool passive = false);
bool readSensor(byte pid, int& result, bool passive = false);
@@ -57,8 +61,11 @@ 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)
{
@@ -80,6 +87,5 @@ protected:
virtual char read();
virtual void write(const char* s);
virtual void write(const char c);
- virtual void initIdleLoop() {}
virtual void dataIdleLoop() {}
};