hello and thank you for taking the time to read this.
i am working on a project for something i have always wanted to do.
the overall goal of the project is to have a stand alone display which read information of the CAN bus in my car, and display it on an OLED or LCD.
so far i have started with some sketches that already exist for CAN and OBD. i have started with an OBD PID Request sketch.
what the sketch does: sends a "request" message to the car's ECM. then using the serial monitor the sketch displays all the CAN data received.
so far so good.
i want to send requests for multiple parameters to the ECM. Which i have accomplished.
i also want to display this information onto an OLED or LCD. I am comfortable using the displays.
here is the missing link:
after i send a PID request, i want to filter the CAN messages received, look for a specific message, and save only that message to somewhere in the RAM.
this program so far, will read all the CAN data on the bus. which is great but i am at a loss on how to filter out what i want in software.
Example:
send message 7DF 02 01 05 55 55 55 55 55 (this is the message to request coolant temp from the ECM)
i want to filter the incoming messages to be left with only the one message
what i am trying to filter for: 7E8 03 41 05 40 XX XX XX XX
i would like to be able to take byte 3 (the 40) and store it somewhere in ram
then, do the same thing for the next message that i send, and so on.
i have tried a couple of things, but have had no luck.
i have attached what some of the data looks like on the serial monitor in the picture
please let me know if there is any other information that i can provide to help in my quest for knowledge.
here is my code
i am not going to take credit for writing all of this. It came from one of the CAN libraries. I have made some small modifications to it.
#include <mcp_can.h>
#include <SPI.h>
#define standard 1 ///changed standard from 0 to 1
// 7E0/8 = Engine ECM
// 7E1/9 = Transmission ECM
#if standard == 1
#define LISTEN_ID 0x7EA
#define REPLY_ID 0x7E0
#define FUNCTIONAL_ID 0x7DF
#define FUNCTIONAL_ID_1 0x7DE //i added this one
#else
#define LISTEN_ID 0x98DAF101
#define REPLY_ID 0x98DA01F1
#define FUNCTIONAL_ID 0x98DB33F1
#endif
// CAN TX Variables
unsigned long prevTx = 0;
unsigned int invlTx = 1000;
byte txData[] = {0x02,0x01,0x00,0x55,0x55,0x55,0x55,0x55};
byte txData1[] = {0x02,0x01,0x05,0x55,0x55,0x55,0x55,0x55};//i added this
// CAN RX Variables
unsigned long rxID;
byte dlc;
byte rxBuf[8];
char msgString[128]; // Array to store serial string
// CAN Interrupt and Chip Select Pins
#define CAN0_INT 2 /* Set INT to pin 2 (This rarely changes) */
MCP_CAN CAN0(9); /* Set CS to pin 9 (Old shields use pin 10) */
void setup(){
Serial.begin(115200);
while(!Serial);
// Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
if(CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
Serial.println("MCP2515 Initialized Successfully!");
else{
Serial.println("Error Initializing MCP2515... Permanent failure! Check your code & connections");
while(1);
}
//
// // Allow all Standard IDs
// CAN0.init_Mask(0,0x00000000); // Init first mask...
// CAN0.init_Filt(0,0x00000000); // Init first filter...
// CAN0.init_Filt(1,0x00000000); // Init second filter...
// // Allow all Extended IDs
// CAN0.init_Mask(1,0x80000000); // Init second mask...
// CAN0.init_Filt(2,0x80000000); // Init third filter...
// CAN0.init_Filt(3,0x80000000); // Init fouth filter...
// CAN0.init_Filt(4,0x80000000); // Init fifth filter...
// CAN0.init_Filt(5,0x80000000); // Init sixth filter...
#if standard == 1
// Standard ID Filters
CAN0.init_Mask(0,0x7F00000); // Init first mask...
CAN0.init_Filt(0,0x7DF0000); // Init first filter...
CAN0.init_Filt(1,0x7E10000); // Init second filter...
CAN0.init_Mask(1,0x7F00000); // Init second mask...
CAN0.init_Filt(2,0x7DF0000); // Init third filter...
CAN0.init_Filt(3,0x7E10000); // Init fouth filter...
CAN0.init_Filt(4,0x7DF0000); // Init fifth filter...
CAN0.init_Filt(5,0x7E10000); // Init sixth filter...
#else
// Extended ID Filters
CAN0.init_Mask(0,0x90FF0000); // Init first mask...
CAN0.init_Filt(0,0x90DA0000); // Init first filter...
CAN0.init_Filt(1,0x90DB0000); // Init second filter...
CAN0.init_Mask(1,0x90FF0000); // Init second mask...
CAN0.init_Filt(2,0x90DA0000); // Init third filter...
CAN0.init_Filt(3,0x90DB0000); // Init fouth filter...
CAN0.init_Filt(4,0x90DA0000); // Init fifth filter...
CAN0.init_Filt(5,0x90DB0000); // Init sixth filter...
#endif
CAN0.setMode(MCP_NORMAL); // Set operation mode to normal so the MCP2515 sends acks to received data.
// Having problems? ======================================================
// If you are not receiving any messages, uncomment the setMode line below
// to test the wiring between the Ardunio and the protocol controller.
// The message that this sketch sends should be instantly received.
// ========================================================================
//CAN0.setMode(MCP_LOOPBACK);
pinMode(CAN0_INT, INPUT); // Configuring pin for /INT input
Serial.println("Simple CAN OBD-II PID Request");
}
void loop(){
if(!digitalRead(CAN0_INT)){ // If CAN0_INT pin is low, read receive buffer
CAN0.readMsgBuf(&rxID, &dlc, rxBuf); // Get CAN data
// Display received CAN data as we receive it.
if((rxID & 0x80000000) == 0x80000000) // Determine if ID is standard (11 bits) or extended (29 bits)
sprintf(msgString, "Extended ID: 0x%.8lX DLC: %1d Data:", (rxID & 0x1FFFFFFF), dlc);
else
sprintf(msgString, "Standard ID: 0x%.3lX DLC: %1d Data:", rxID, dlc);
Serial.print(msgString);
if((rxID & 0x40000000) == 0x40000000){ // Determine if message is a remote request frame.
sprintf(msgString, " REMOTE REQUEST FRAME");
Serial.print(msgString);
} else {
for(byte i = 0; i<dlc; i++){
sprintf(msgString, " 0x%.2X", rxBuf[i]);
Serial.print(msgString);
}
}
Serial.println();
}
/* Every 1000ms (One Second) send a request for PID 00 *
* This PID responds back with 4 data bytes indicating the PIDs *
* between 0x01 and 0x20 that are supported by the vehicle. */
if((millis() - prevTx) >= invlTx){
prevTx = millis();
if(CAN0.sendMsgBuf(FUNCTIONAL_ID, 8, txData) == CAN_OK){
Serial.println("Message Sent Successfully!");
} else {
Serial.println("Error Sending Message...");
}
delay(500);
if(CAN0.sendMsgBuf(FUNCTIONAL_ID, 8, txData1) == CAN_OK){
Serial.println("Message Sent Successfully!");
} else {
Serial.println("Error Sending Message...");
}
}
}


