Hi,
I'm trying to modyfi my OBD2 data logger which is based on Freematics OBD-II Adapter for Arduino | ArduinoDev.com. Everything works fine, that means all data are correctly gater and displaying on LCD, but when I try log them to a file, then I've got only empty file. Can you help mi how can I get all of those data using this OBD library?
Here is my code:
//include libraries
#include <arduino.h>
#include <LCD4Bit_mod.h>
#include <OBD.h>
#include <SdFat.h>
//create object to control LCD
LCD4Bit_mod lcd = LCD4Bit_mod(2);
//create object to control OBD
COBD obd;
SdFat sd;
//key message
unsigned int adc_key_val[5] = {30, 150, 360, 535, 760};
int NUM_KEYS = 5;
int adc_key_in;
char key =- 1;
char oldkey =- 1;
unsigned long lastTick = millis();
uint8_t modes[2] = {0, 2};
const int chipSelect = 3;
ArduinoOutStream cout(Serial);
#define error(s) sd.errorHalt_P(PSTR(s))
const char modePids[] = {PID_RPM, PID_SPEED, PID_THROTTLE, PID_ENGINE_LOAD,
PID_COOLANT_TEMP, PID_INTAKE_TEMP, PID_AMBIENT_TEMP, PID_MAF_FLOW,
PID_ABS_ENGINE_LOAD, PID_FUEL_PRESSURE, PID_INTAKE_PRESSURE, PID_BAROMETRIC,
PID_TIMING_ADVANCE, PID_FUEL_LEVEL, PID_RUNTIME, PID_DISTANCE};
const char* modeLabels[] = {
"Engine rpm", "Speed km/h", "Throttle %", "Engine Load %",
"Coolant C", "Intake Air C", "Env. Temp C", "MAF Flow kpa",
"Abs. Load %", "Fuel kpa", "Intake kpa", "Barometer kpa",
"Timing Adv. ", "Fuel Level %", "Run Time", "Distance km"};
const char modePos[] = {8, 8, 11, 12,
11, 11, 11, 9,
11, 9, 9, 10,
12, 11, 8, 10};
const char* modeFmts[] = {"%4u", "%3u", "%3u", "%u",
"%3d", "%3d", "%3d", "%3u",
"%3u", "%3u", "%3u", "%u",
"%3d", "%3u", "%4u:%02u", "%04u"};
#define TOTAL_PIDS (sizeof(modePids) / sizeof(modePids[0]))
//functions
void updateMode()
{
lcd.cursorTo(1, 0);
lcd.printIn((char*)modeLabels[modes[0]]);//wyswietla nazwe parametru
lcd.cursorTo(2, 0);
lcd.printIn((char*)modeLabels[modes[1]]);//wyswietla nazwe parametru
}
bool showData(int index)
{
char buf[16];
int value;
uint8_t mode = modes[index];
uint8_t pid = modePids[mode];
digitalWrite(13, HIGH); // set the LED on
if (!obd.ReadSensor(pid, value)) {
// display received data on error
lcd.cursorTo(index + 1, 0);
lcd.printIn("Error");
delay(2000);
updateMode();
return false;
}
digitalWrite(13, LOW); // set the LED off
if (pid == PID_RUNTIME) {
sprintf(buf, modeFmts[mode], (unsigned int)value / 60, (unsigned int)value % 60); // zapisuje do buf wartosc z pomiaru
} else {
sprintf(buf, modeFmts[mode], value); // zapisuje do buf wartosc z pomiaru
}
lcd.cursorTo(index + 1, modePos[mode]); // pozycjonuje kursor na wybranej pozycji
lcd.printIn(buf); // wysietla buf
return true;
}
void saveData()
{
char buf[16];
int value;
uint8_t pomiar;
char name[] = "logs.txt";
// open stream for append
ofstream sdout(name, ios::out | ios::app);
if (!sdout) error("open failed");
String linia = "PID_RPM:";
pomiar = obd.ReadSensor(PID_RPM, value);
sprintf(buf, "%4u", pomiar); // PID_RPM
linia += buf;
linia += ";PID_SPEED:"; // PID_SPPEED
pomiar = obd.ReadSensor(PID_SPEED, value);
sprintf(buf, "%3u", pomiar);
linia += buf;
linia += ";PID_THROTTLE:"; // PID_THROTTLE
pomiar = obd.ReadSensor(PID_THROTTLE, value);
sprintf(buf, "%3u", pomiar);
linia += buf;
linia += ";PID_ENGINE_LOAD:"; // PID_ENGINE_LOAD
pomiar = obd.ReadSensor(PID_ENGINE_LOAD, value);
sprintf(buf, "%u", pomiar);
linia += buf;
linia += ";PID_ABS_ENGINE_LOAD:"; // PID_ABS_ENGINE_LOAD
pomiar = obd.ReadSensor(PID_ABS_ENGINE_LOAD, value);
sprintf(buf, "%3u", pomiar);
linia += buf;
linia += ";PID_FUEL_LEVEL:"; // PID_FUEL_LEVEL
pomiar = obd.ReadSensor(PID_FUEL_LEVEL, value);
sprintf(buf, "%3u", pomiar);
linia += buf;
linia += ";PID_DISTANCE:"; // PID_DISTANCE
pomiar = obd.ReadSensor(PID_DISTANCE, value);
sprintf(buf, "%04u", pomiar);
linia += buf;
sdout << linia << endl;
Serial.println(linia);
sdout.close();
}
bool setupConnection()
{
uint8_t errors = 0;
char buf[16];
lcd.clear();
lcd.printIn("Connecting...");
while (!obd.Init())
{
lcd.cursorTo(2, 0);
sprintf(buf, "Attempts #%d", ++errors);
lcd.printIn(buf);
}
lcd.clear();
lcd.printIn("Connected!");
lcd.cursorTo(2, 0);
sprintf(buf, "Rev. %d", obd.revision);
lcd.printIn(buf);
delay(1000);
updateMode();
return true;
}
void setup()
{
pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat
lcd.init();
Serial.begin(OBD_SERIAL_BAUDRATE);
setupConnection(); // ustanawia polaczeniz z obd
Serial.begin(9600); // polacznei serial
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();
}
void loop()
{
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{
delay(50); // wait for debounce time
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{
oldkey = key;
if (key >=0)
{
switch (key)
{
case 3: // left key
do
{
modes[0] = modes[0] > 0 ? modes[0] - 1 : TOTAL_PIDS - 1;
} while (modes[0] == modes[1]);
break;
case 0: // right key
do
{
modes[0] = modes[0] < TOTAL_PIDS - 1 ? modes[0] + 1 : 0;
} while (modes[0] == modes[1]);
break;
case 1: // up key
do
{
modes[1] = modes[1] > 0 ? modes[1] - 1 : TOTAL_PIDS - 1;
} while (modes[0] == modes[1]);
break;
case 2: // down key
do
{
modes[1] = modes[1] < TOTAL_PIDS - 1 ? modes[1] + 1 : 0;
} while (modes[0] == modes[1]);
break;
}
updateMode();
}
}
}
unsigned long curTick = millis();
if (curTick - lastTick > 500)
{
showData(0);
showData(1);
saveData();
if (obd.errors > 10)
{
setupConnection();
}
lastTick = curTick;
}
}
// Convert ADC value to key number
char get_key(unsigned int input)
{
char k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
return k;
}
return -1;
}