Page 1 of 1

ODB-II Adapter with Arduino Serial Monitor

Posted: Mon Apr 10, 2017 4:46 am
by td1973
Hello Everyone,

I recently purchased a Freematics ONE (OBD-II) Adapter that connects to serial TX1/RX1 of the Arduino Mega.

I'm trying to make the code work with the Arduino Serial monitor because I do not have an LCD. I'd like to simply
use my laptop as the dispLAY.

The following is my code and the output generated. I'm not very good at programming as you will see, but I know a tiny
bit. Please help explain my errors. Thank you.

[quote]
/*************************************************************************
* Tester sketch for Freematics OBD-II Adapter for Arduino
* Visit http://freematics.com for more information
* Distributed under BSD license
* Written by Stanley Huang <support@freematics.com.au>
*************************************************************************/

#include <Arduino.h>
#include <OBD.h>
#include <SPI.h>
#include <Wire.h>
//#include "MultiLCD.h"
#include "config.h"
#if ENABLE_DATA_LOG
#include <SD.h>
#endif
#include "datalogger.h"

#define OBD_MODEL_UART 0
#define OBD_MODEL_I2C 1

#define STATE_MEMS_READY 1
#define STATE_INIT_DONE 2

typedef struct {
uint16_t left;
uint16_t right;
uint16_t bottom;
uint16_t height;
uint16_t pos;
} CHART_DATA;

CHART_DATA chartRPM = {24, 319, 239, 100, 24};
void chartUpdate(CHART_DATA* chart, int value);

void(* resetFunc) (void) = 0; //declare reset function at address 0

static uint32_t lastFileSize = 0;
static int speed = 0;
static uint32_t distance = 0;
static uint16_t fileIndex = 0;
static uint32_t startTime = 0;
static uint16_t elapsed = 0;
static uint8_t lastPid = 0;
static int lastValue = 0;



#if OBD_MODEL == OBD_MODEL_UART
class COBDDevice : public COBD, public CDataLogger
#else
class COBDDevice : public COBDI2C, public CDataLogger
#endif

{
public:
COBDDevice():state(0) {}
void setup()
{
#if ENABLE_DATA_LOG
lcd.setFontSize(FONT_SIZE_SMALL);
lcd.setColor(RGB16_WHITE);
lcd.setCursor(0, 3);
checkSD();
#endif

#ifdef OBD_ADAPTER_I2C
Wire.begin();
#endif
if (memsInit())
state |= STATE_MEMS_READY;

testOut();

while (!init());

showVIN();
showDTC();
delay(3000);

initScreen();

state |= STATE_INIT_DONE;
}


void testOut()
{
static const char PROGMEM cmds[][6] = {"ATZ\r", "ATH1\r", "ATRV\r", "0100\r", "010C\r", "0902\r"};
char buf[128];


// recover from possible previous incomplete communication
recover();
for (byte i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) {
char cmd[6];
memcpy_P(cmd, cmds[i], sizeof(cmd));
Serial.print("Sending ");
Serial.println(cmd);

if (sendCommand(cmd, buf, sizeof(buf))) {
char *p = strstr(buf, cmd);
if (p)
p += strlen(cmd);
else
p = buf;
while (*p == '\r') p++;
while (*p) {
Serial.write(*p);
if (*p == '\r')
Serial.write('\n');
p++;
}
Serial.println();
} else {
Serial.println("Timeout");
}
delay(500);
}
Serial.println();
}
void showVIN()
{
char buf[255];

if (getVIN(buf, sizeof(buf))) {
Serial.print("VIN:");
Serial.println(buf);
}
}
void showDTC()
{
uint16_t dtc[6];
int num = readDTC(dtc, sizeof(dtc) / sizeof(dtc[0]));
Serial.print(num);
Serial.println(" DTC found");
if (num > 0) {

for (byte i = 0; i < num; i++) {
Serial.print(dtc[i], HEX);
Serial.print(' ');
}
}
}


void loop()
{
static byte index2 = 0;
const byte pids[]= {PID_RPM, PID_SPEED, PID_THROTTLE, PID_ENGINE_LOAD, PID_COOLANT_TEMP, PID_INTAKE_TEMP, PID_AMBIENT_TEMP, PID_DISTANCE};
//const byte pids[]= {PID_RPM, PID_SPEED, PID_THROTTLE, PID_ENGINE_LOAD};
int values[sizeof(pids)];

// read multiple OBD-II PIDs
if (readPID(pids, sizeof(pids), values) == sizeof(pids)) {
dataTime = millis();
for (byte n = 0; n < sizeof(pids); n++) {
logData((uint16_t)pids[n] | 0x100, values[n]);
showData(pids[n], values[n]);
}
}
static byte lastSec = 0;
const byte pids2[] = {PID_COOLANT_TEMP, PID_INTAKE_TEMP, PID_AMBIENT_TEMP, PID_DISTANCE};
byte sec = (uint8_t)(millis() >> 10);
if (sec != lastSec) {

// goes in every other second
int value;
byte pid = pids2[index2 = (index2 + 1) % (sizeof(pids2))];


// read single OBD-II PID
if (isValidPID(pid) && readPID(pid, value)) {
dataTime = millis();
logData((uint16_t)pid | 0x100, value);
showData(pid, value);
lastSec = sec;
}
}
if (errors >= 5) {
reconnect();
}
if (state & STATE_MEMS_READY) {
processMEMS();
}
}
void processMEMS()
{
int acc[3];
int gyro[3];
int temp;

if (!memsRead(acc, gyro, 0, &temp)) return;

dataTime = millis();

acc[0] /= ACC_DATA_RATIO;
acc[1] /= ACC_DATA_RATIO;
acc[2] /= ACC_DATA_RATIO;
gyro[0] /= GYRO_DATA_RATIO;
gyro[1] /= GYRO_DATA_RATIO;
gyro[2] /= GYRO_DATA_RATIO;

Serial.print("ACCELEROMTER: ");
Serial.print(acc[0]);
Serial.print('/');
Serial.print(acc[1]);
Serial.print('/');
Serial.print(acc[2]);
Serial.println(' ');

Serial.print("GYRO: ");
Serial.print(gyro[0]);
Serial.print('/');
Serial.print(gyro[1]);
Serial.print('/');
Serial.print(gyro[2]);
Serial.print(' ');
Serial.println(' ');



// log x/y/z of accelerometer
logData(PID_ACC, acc[0], acc[1], acc[2]);
// log x/y/z of gyro meter
logData(PID_GYRO, gyro[0], gyro[1], gyro[2]);
}
void reconnect()
{
Serial.print("Reconnecting");
startTime = millis();
//digitalWrite(SD_CS_PIN, LOW);
for (uint16_t i = 0; ; i++) {
if (i == 5) {
Serial.print("Clear");
}
if (init()) {
Serial.print("Reseting...");
// reset Arduino
resetFunc();
}
}
}


//NOTES:
//COMPARE program value with Serial.print(value) vs. my println(value)

void showData(byte pid, int value)
{
switch (pid) {
case PID_RPM:
Serial.print("Freematics RPM: ");
Serial.println((unsigned int)value % 10000, 4);
showChart(value);

Serial.print("My RPM VALUE: ");
Serial.println(value);

break;

case PID_SPEED:
Serial.print("Freematics Speed: ");
Serial.println((unsigned int)value % 1000, 3);

Serial.print("My Speed VALUE: ");
Serial.println(value);

break;

case PID_ENGINE_LOAD:
Serial.print("Freematics ENG. LOAD: ");
Serial.println(value % 100, 3);

Serial.print("My Engine Load VALUE: ");
Serial.println(value);

break;

case PID_INTAKE_TEMP:
if (value < 0) value = 0;
Serial.print("Freematics IAT: ");
Serial.println(value, 3);

Serial.print("My IAT VALUE: ");
Serial.println(value, 3);

break;

case PID_INTAKE_MAP:
Serial.print("Freematics MAP: "); //change to Println from print
Serial.println((uint16_t)value % 1000, 3); //change to Println from print

Serial.print("My MAP VALUE: ");
Serial.println(value);


break;

case PID_COOLANT_TEMP:
Serial.print("Freematics ECT: ");
Serial.println((uint16_t)value % 1000, 3);

Serial.print("My ECT VALUE: ");
Serial.println(value);


break;

case PID_DISTANCE:
Serial.print("Freematics DISTANCE: ");
Serial.println((uint16_t)value % 1000, 3);

Serial.print("My DISTANCE VALUE: ");
Serial.println(value);

break;
}
}
void ShowVoltage(float v)
{
Serial.print("Freematics Voltage: ");
Serial.println(v);

Serial.print("My Voltage: ");
Serial.println(v);

}
void showChart(int value)
{
uint16_t height;
if (value >= 560) {
height = (value - 500) / 60;
} else {
height = 1;
}
chartUpdate(&chartRPM, height);
}
void initScreen()
{
Serial.print("ENGINE RPM");

Serial.print("SPEED");

Serial.print("ENGINE LOAD");

Serial.print("INTAKE TEMP");


Serial.print("COOLANT TEMP");

Serial.print("DISTANCE");

Serial.print("INTAKE MAP");

Serial.print("BATTERY");

Serial.print("ACC");

Serial.print("GYRO");

Serial.print("rpm");

Serial.print("km/h");
Serial.print("C");
Serial.print("C");
Serial.print("km");
Serial.print("kpa");
Serial.print("V");

}
byte state;
};

COBDDevice myOBD;

void setup()
{
myOBD.begin();
myOBD.initSender();
myOBD.setup();
}

void loop()
{
myOBD.loop();
}

Re: ODB-II Adapter with Arduino Serial Monitor

Posted: Tue Apr 11, 2017 1:11 pm
by stanley
On Arduino MEGA, please connect OBD-II adapter to Serial1 (Rx1 and Tx1).

Re: ODB-II Adapter with Arduino Serial Monitor

Posted: Thu Apr 13, 2017 2:55 am
by td1973
td1973 wrote:
" Adapter that connects to serial TX1/RX1 of the Arduino Mega."

Thank you for the reply Stanley. I have already done this as stated above.

I'm getting an initialization response from the adapter, as well as a voltage reading, but I cannot
see the PID's on the serial monitor in the Arduino IDK.

Is there sample code that works specifically with the Serial Monitor as opposed to an LCD display?

My code shown the first post changed all of the "LCD.print" to "Serial.print", but it just shows the
send information, not the response from the CAN bus.

For Example, the Serial Monitor shows the following:

0105
010A
010C
010D

I do not get the response.

Thank you.

Re: ODB-II Adapter with Arduino Serial Monitor

Posted: Fri Apr 14, 2017 1:22 pm
by td1973
I tried other Example programs and nothing seems to work. I tried uninstalling and re-installing the Arduino IDK and the Freematics GITHUB files.

The error I'm receiving is:



obd_uart_test.ino:10:22: fatal error: OBD2UART.h: No such file or directory
compilation terminated.
Error compiling.

or



obd_uart_test.ino:10:22: fatal error: OBD.h: No such file or directory
compilation terminated.
Error compiling.


Please help .

Re: ODB-II Adapter with Arduino Serial Monitor

Posted: Sun Apr 16, 2017 11:27 am
by td1973
I found the problem. The code is not looking for the .h and .cpp files in the proper directory.

You need to move or copy the .h and .cpp files to the library root folder.


IE: ProgramFiles(x86)]\Arduino\libraries\OBD.h
IE: ProgramFiles(x86)]\Arduino\libraries\OBD.cpp

IE: ProgramFiles(x86)]\Arduino\libraries\OBD2UART.h
IE: ProgramFiles(x86)]\Arduino\libraries\OBD2UART.cpp