Inconsistent OBD data

I’m testing my sketch in 3 different cars :

  • Seat Toledo 2015
  • Mazda 3 2015
  • Hyundai elantra 2017

And I have consistent data in the Seat toledo (meaning that the data I ask for, the data I got from the car - RPM, Speed, Module Voltage-), but when I test the same sketch on the Mazda and Toledo, most of the time the cars doesn’t give me the data I asked (few times the car gives me the module voltage, or the speed, and ALWAYS the RPMS).

I changed the timing between the send and receive function, and the behaviour is almost the same in the Mazda and Hyundai.

My sketch is :

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

#include <carloop.h>

Carloop<CarloopRevision2> carloop;

void sendObdRequest();
void waitForObdResponse();

int maxUnreadMessage = 5;
int currentPid;
int currentPidIndex = 0;

const auto OBD_REQUEST_ID      = 0x7E0;
const auto OBD_REPLY_ID        = 0x7E8;
const auto OBD_PID_SERVICE     = 0x01;

const auto PID_ENGINE_RPM = 0x0C ;
const auto PID_VEHICLE_SPEED = 0x0D ;
const auto PID_CONTROL_MODULE_VOLTAGE = 0x42;

const byte PIDS[] = { 
    PID_ENGINE_RPM,
    PID_VEHICLE_SPEED,
    PID_DISTANCE_TRAVELED_SINCE_CODES_CLEARED,
    PID_CONTROL_MODULE_VOLTAGE
};

float ENGINE_RPM = 0;
int VEHICLE_SPEED = 0;
float CONTROL_MODULE_VOLTAGE = 0;

void setup() {
    
    Serial.begin(9600);    
    
    carloop.begin();

    maxUnreadMessage = sizeof(PIDS);

    parseConfig();    
}

void loop() {
    carloop.update();
    sendObdRequest();
    
    delay(100);
    
    waitForObdResponse();
}

void sendObdRequest() {
    if(currentPidIndex == sizeof(PIDS)) {
        currentPidIndex = 0;
    }

    currentPid = PIDS[currentPidIndex];
    currentPidIndex++;

    CANMessage message;
    message.id = OBD_REQUEST_ID;
    message.len = 8;
    message.data[0] = 0x02;
    message.data[1] = OBD_PID_SERVICE;
    message.data[2] = currentPid;//This is the data we want to ask to the car
    carloop.can().transmit(message);

}

void waitForObdResponse() {
    bool responseReceived = false;
    CANMessage message;
    
    while (carloop.can().receive(message)) {
        if(message.id == OBD_REPLY_ID && message.data[2] == currentPid) {
            parseMessage(message.data);
            break;
        }
    }
}

void parseMessage(byte data[]) {

    if (data[2] == 12) {
        ENGINE_RPM = ((data[3] * 256) + data[4]) / 4;
    }

    if (data[2] == 13) {
        VEHICLE_SPEED =(int) data[3];
    }

    if (data[2] == 66) {
        CONTROL_MODULE_VOLTAGE = (256 * data[3] + data[4])/1000;
    }    
}

Any ideas ? I’m changed the delay(100) to delay(1000) (and some values in between) and I got better results, but not consistent results yet.

Is there any issue I have to consider in terms of timing between send/receive responses?

Thanks

@maleficarum,

I am not sure exactly what is at play to cause these results. Your information is limited, so I will take a few guesses on what to investigate.

One thing to try is the VIN number reader sample app. If this sample app is able to read the VIN number on all the cars, then it narrows it down to your code. If the VIN number sample does not work, I would check out this issue in case some of your cars use extended format:
https://community.carloop.io/t/handling-29-bit-extended-format/239

Another possibility, is that the module in the car responding to your request might have a different ID number. See the Response of this Wikipedia page; there are a few IDs that could respond, not just 0x7E8:

Besides that, I would suggest for debugging that you print out the complete response message, in addition to the decoded PID. The raw message data might offer some clues to help you out.

Thanks again for the response. As far as I can access to those other cars, I’ll try that suggestions.

I’ve tested again and I noticed that if I only ask for the speed and rpm and decrease the delay between send and parse message I get a response, but if I ask for more data even with a higher delay (1500 ms) the car doesn’t responds to the speed request (the other pids are provided by the car without a problem). That point me that the issues is not related (as I can deduce) with the message format nor the module id.

Is there any known implication related to the delay or pids asked that I have to keep in mind?

@maleficarum,

Thanks for the update. It sounds like the modules of your car are not responding quickly, rather than it being a problem with Carloop.

Are you firing off more than one request at a time? You might have to experiment to see if your car can handle lots of requests, or if your car can only handle another request only after it has finished responding to the first request. Try a few things and see what your car is happy with, and what it is not happy with.

I perform a test in the two “other” cars and I noticed that de ECU is responding to the speed and voltage module request, but, sometimes I can get a proper response but sometimes dont … I noticed that when I ask for those codes , when I don’t get a proper response code from the car I get the next “random” codes in the 3th byte of the message (message.data[2]) which has the response code I asked; I got the next data in that byte :

First loop :

Byte [2] 0
Byte [2] 0
Byte [2] 7
Byte [2] 7
Byte [2] 255
Byte [2] 39
Byte [2] 0
Byte [2] 0
Byte [2] 255
Byte [2] 0
Byte [2] 64
Byte [2] 0
Byte [2] 112
Byte [2] 21
Byte [2] 52
Byte [2] 128
Byte [2] 0
Byte [2] 208
Byte [2] 21
Byte [2] 52
Byte [2] 128
Byte [2] 0
Byte [2] 0
Byte [2] 7
Byte [2] 7
Byte [2] 1
Byte [2] 0
Byte [2] 0
Byte [2] 255
Byte [2] 176
Byte [2] 39
Byte [2] 116
Byte [2] 0
Byte [2] 255
Byte [2] 0

Second loop :

Byte [2] 240
Byte [2] 255
Byte [2] 128
Byte [2] 0
Byte [2] 0

but sometimes I can get the speed and voltage module. It’s important to mention that I’m requesting also the RPM, throttle position, distance since codes cleared and all of those code are provided by the car without problems.

The basic code (where the issue would be present) is :

carloop.update();
sendObdRequest();

delay(1000);//Or 2000 sometimes in one of the car, and event that I cannot get a consistent data
    
waitForObdResponse();

Thanks for the help.