stanleyhuangyc/ArduinoOBD

How to check if the vehicle is running?

Opened this issue · 4 comments

What is the easiest way to check if the vehicle is still running? I noticed that if I poll data after the vehicle is off, the most recent value is returned, and the OBD state does not change because of this.

I recalled tried recalling obd.init() and obd.end() followed by obd.begin() again, but obd.getState() still returned that it was connected. Why?

The easiest way to know if the car is on is by checking the rpms. The value for this comes from the crank sensor so if it's failing you'll know it because it won't show revs and you also know the car is on. When you tried calling obd.getState() was the key in the "run" position? The ecu will still connect if its on this. Usually if its not on run, it wont connect and it will throw an error. I'll look into the code in a bit to see if you can clear the states and sensor values after you turn off the car or change the key position.

Well, I was looking to count the number of times the vehicle is turned on and off (and trigger events as states change). For example, I want to call this function each time the vehicle is turned on:

void incrementWarmups() {
  byte lowerByte = EEPROM.read(0);
  byte upperByte = EEPROM.read(1);
  warmups = (unsigned int) (upperByte << 8) + lowerByte;
  warmups++;
  EEPROM.write(0, (byte) ((warmups << 8) >> 8));
  EEPROM.write(1, (byte) (warmups >> 8));
}

Right now, my loop function looks something like this, where I check the previous state against the current state and check different things based on that state. Unfortunately, the state does not change when the vehicle is turned off.

void loop() {
  lastState = state;
  state = obd.getState();
  timer = millis();

  switch(state) {
    case OBD_CONNECTED:
      if(lastState == OBD_DISONNECTED) {
        //vehicle started
        ...
      }
      else if(Serial.available()) {
        //send requested data over serial to phone (android app)
        ...
      }
      else if(timer - lastUpdate >= 500) updateData();
      break;
    case OBD_DISCONNECTED:
      if(lastState == OBD_CONNECTED) {
        //vehicle stopped
        ...
      }
      else if(Serial.available()) {
        //manually attempt reconnect by phone request
        ...
      }
      else if(timer - lastReconnectTry >= 10000) tryReconnect();
      break;
    case OBD_CONNECTING:

      break;
    case OBD_FAILED:

      break;
}

I thought maybe the OBD-II port was still active when the vehicle was off, but the Arduino cannot connect to the OBD-II from power on when the vehicle is off and returned values from readPID() do not appear updated. This adds to the confusion of what the OBD_STATES actually mean about the device's connection condition.

However, if there is another method to manage vehicle state other than getState(), I a all for it.

So what happens is that the Arduino is always receiving power from the port so it never really "turns off", it only disconnects because the key is no longer on run and the ecu power is cut. After that, all the values are still stored in the Arduino but not cleared, that's why the states don't change. Also, it doesn't change the state because of that like you said. I looked a bit through the library and it seems as if it returns the values as integers.
OBD_DISCONNECTED = 0, OBD_CONNECTING = 1, OBD_CONNECTED = 2, OBD_FAILED = 3
Have you set the variables to be ints? also, if you want to know if the car HAS ACTUALLY been turned on, I would suggest you poll the PID_RPM pid so that if it equals 0, you know that the engine is off and it doesn't consider it a "warm up." If you leave it like that, what would happen is that every time you turn on the key to run but don't actually start the car, it'll register it as a "warm-up" and it will be inaccurate.

Edit: I forgot to mention that you could also try obd. reset(); to reset the connection and see if that erases any old data.