Thanks for your reply. I can't read any value for this PID. But I commemorated another concept thus I won't need this PID anymore. Since this is a project for my master's thesis and I'm not a developer / engineer I won't be going to do heavy math because it isn't the scope of my thesis.
But I will continue to use the carloop in my project. But now I've a new question. Is there a way to read if the car is running / ignition is on. I've tried to turn on the D7 led when RPM is above 300 rpm and off when the motor is of and it's below 300rpm but the carloop isn't reading pid anymore when the ignition is off so this didn't work.
Any ideas?
This is the code I'm using now
// This #include statement was automatically added by the Particle IDE.
#include <carloop.h>
#include <blynk.h>
#include "base85.h"
SYSTEM_MODE(AUTOMATIC);
SYSTEM_THREAD(ENABLED);
void sendObdRequest();
void waitForObdResponse();
void delayUntilNextRequest();
void printValuesAtInterval();
void publishValuesAtInterval();
void printValues();
void getEngineLoad();
void receiveObdRequestVIN();
void sendObdRequestVIN();
//PLACE YOUR BLYNK AUTHENTICATION KEY IN BELOW AS SHOWN IN EXAMPLE BELOW:
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String dumpMessage(const CANMessage &message);
bool byteArray8Equal(uint8_t a1[8], uint8_t a2[8]);
Carloop<CarloopRevision2> carloop;
int canMessageCount = 0;
float DISTANCE_TRAVELED_SINCE_CODES_CLEARED;
float ENGINE_RPM;
//GLOBAL INTEGERS FOR USE IN PERFORMING MATH AND EXTRACTION OF OBDII DATA//
int data0;
int data1;
int data2;
int data3;
int data4;
int data5;
int data6;
int data7;
// OBD CAN MESSAGE IDs
const auto OBD_CAN_BROADCAST_ID = 0X7DF;
const auto OBD_CAN_REQUEST_ID = 0x7E0;
const auto OBD_CAN_REPLY_ID_MIN = 0x7E8;
const auto OBD_CAN_REPLY_ID_MAX = 0x7EF;
const String key = "XXXXXXXXXXXXXXXXX";
// OBD MODES
const auto OBD_MODE_CURRENT_DATA = 0x01;
//LIST OF ALL (Almost) MODE 1 PIDS THAT YOU ARE CAPABLE OF POLLING. NOT ALL WILL BE AVAILABLE TO YOU.//
const auto OBD_PID_DISTANCE_TRAVELED_SINCE_CODES_CLEARED = 0x31;
const auto OBD_PID_ENGINE_RPM = 0x0c;
//SUM THE TOTAL AMOUNT OF PIDS YOU WOULD LIKE TO REQUEST AND PLACE THAT IN const size_t NUM_PIDS_TO_REQUEST//
const size_t NUM_PIDS_TO_REQUEST = 2;
//COMMENT OUT OR REMOVE THE PIDS THAT YOU DO NOT HAVE TO INCREASE EFFECIENCY BUT BE SURE TO UPDATE THE ABOVE CONSTANT//
const uint8_t pidsToRequest[NUM_PIDS_TO_REQUEST] = {
OBD_PID_DISTANCE_TRAVELED_SINCE_CODES_CLEARED,
OBD_PID_ENGINE_RPM
};
uint8_t pidIndex = NUM_PIDS_TO_REQUEST - 1;
String dumpForPublish;
auto *obdLoopFunction = sendObdRequest;
unsigned long transitionTime = 0;
uint8_t lastMessageData[8];
void setup() {
Blynk.begin(auth);
Serial.begin(115200);
carloop.begin();
Particle.connect();
transitionTime = millis();
pinMode(7,OUTPUT);
}
void loop() {
carloop.update();
printValuesAtInterval();
publishValuesAtInterval();
obdLoopFunction();
waitForObdResponse();
math();
}
void sendObdRequest() {
pidIndex = (pidIndex + 1) % NUM_PIDS_TO_REQUEST;
CANMessage message;
message.id = OBD_CAN_BROADCAST_ID;
message.len = 8; // just always use 8
message.data[0] = 0x02; // 0 = single-frame format, 2 = num data bytes
message.data[1] = OBD_MODE_CURRENT_DATA; // OBD MODE
message.data[2] = pidsToRequest[pidIndex]; // OBD PID
carloop.can().transmit(message);
obdLoopFunction = waitForObdResponse;
transitionTime = millis();
}
void waitForObdResponse() {
if (millis() - transitionTime >= 10) {
obdLoopFunction = delayUntilNextRequest;
transitionTime = millis();
return;
}
bool responseReceived = false;
String dump;
CANMessage message;
while (carloop.can().receive(message)) {
canMessageCount++;
if (message.id == 0x130) {
if (!byteArray8Equal(message.data, lastMessageData)) {
memcpy(lastMessageData, message.data, 8);
}
} else {
if (message.id >= OBD_CAN_REPLY_ID_MIN &&
message.id <= OBD_CAN_REPLY_ID_MAX &&
message.data[2] == pidsToRequest[pidIndex]) {
responseReceived = true;
data0 = message.data[0];
data1 = message.data[1];
data2 = message.data[2];
data3 = message.data[3];
data4 = message.data[4];
data5 = message.data[5];
data6 = message.data[6];
data7 = message.data[7];
return;
}
return;
}
return;
}
}
void delayUntilNextRequest() {
if (millis() - transitionTime >= 8) {
obdLoopFunction = sendObdRequest;
transitionTime = millis();
}
}
/*************** End: OBD Loop Functions ****************/
void printValuesAtInterval() {
static const unsigned long interval = 500;
static unsigned long lastDisplay = 0;
if (millis() - lastDisplay < interval) {
return;
}
lastDisplay = millis();
printValues();
}
void printValues() {
//PRINT VALUES FOR DEBUGING//
//Serial.print("Engine Load: ");
//Serial.println(ENGINE_LOAD);
}
void publishValuesAtInterval() {
static const unsigned long interval2 = 3000;
static unsigned long lastDisplay2 = 0;
if(millis() - lastDisplay2 < interval2) {
return;
}
lastDisplay2 = millis();
publishValuesAtInterval();
blynkValues();
}
void blynkValues() {
if(ENGINE_RPM > 300){
digitalWrite(7,HIGH);
}else if(ENGINE_RPM < 100){
digitalWrite(7,LOW);
}
//TODO: ONLY SEND DATA WHEN THE ENGINE IS ON
Blynk.run();
String StringDISTANCE_TRAVELED_SINCE_CODES_CLEARED = String(DISTANCE_TRAVELED_SINCE_CODES_CLEARED);
String StringENGINE_RPM = String(ENGINE_RPM);
//PUBLISH STRINGS TO BLYNK//
Blynk.virtualWrite(V19, StringDISTANCE_TRAVELED_SINCE_CODES_CLEARED);
Blynk.virtualWrite(V7, StringENGINE_RPM);
}
void math() {
//void mathENGINE_RPM() {
if (data2 == 12) {
float RPM1;
float RPM2;
RPM1 = data3;
RPM2 = data4;
ENGINE_RPM = ((RPM1*256)+RPM2)/4;
}
//}
//void mathOBD_PID_DISTANCE_TRAVELED_SINCE_CODES_CLEARED() {
if (data2 == 49) {
float distanceTraveledSinceCodesClearedA;
float distanceTraveledSinceCodesClearedB;
distanceTraveledSinceCodesClearedA = data3;
distanceTraveledSinceCodesClearedB = data4;
DISTANCE_TRAVELED_SINCE_CODES_CLEARED = 256*distanceTraveledSinceCodesClearedA + distanceTraveledSinceCodesClearedB;
}
//}
}
bool byteArray8Equal(uint8_t a1[8], uint8_t a2[8]) {
for (int i = 0; i < 8; i++) {
if (a1[i] != a2[i]) return false;
}
return true;
}