ODB-II Adapter with Arduino Serial Monitor

Inquiry and support for Freematics products
Post Reply
td1973
Posts: 17
Joined: Mon Apr 10, 2017 4:35 am

ODB-II Adapter with Arduino Serial Monitor

Post 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();
}
stanley
Site Admin
Posts: 1018
Joined: Sat Mar 01, 2014 3:15 am

Re: ODB-II Adapter with Arduino Serial Monitor

Post by stanley »

On Arduino MEGA, please connect OBD-II adapter to Serial1 (Rx1 and Tx1).
td1973
Posts: 17
Joined: Mon Apr 10, 2017 4:35 am

Re: ODB-II Adapter with Arduino Serial Monitor

Post 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.
td1973
Posts: 17
Joined: Mon Apr 10, 2017 4:35 am

Re: ODB-II Adapter with Arduino Serial Monitor

Post 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 .
td1973
Posts: 17
Joined: Mon Apr 10, 2017 4:35 am

Re: ODB-II Adapter with Arduino Serial Monitor

Post 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
Post Reply