Hi!
I'm working on a project that displays engine data from my 1996 Saab onto a small TFT touch screen. Everything is coming along nicely, but for some reason I'm not getting the correct data on all the 8 bytes from the car.
To be able to read from the EMS, Trionic 5, in the Saab a request has to be sent, which is done with 0xC7, 0x00, 0x00, (address low), (address high), 0x00, 0x00, 0x00.
The response is 0xC6, 0x0C, (data1), (data2), (data3), (data4), (data5), (data6).
For some reason I am only getting valid data on byte 2 or (data1), so it works fine when I'm reading parameters which are 1 byte long, but many parameters are 2 or more bytes long.
I am getting the same incorrect data everytime I send a read command. They are not different every time, just wrong.
I am using a Sparkfun can bus shield, a Mega2560 and Cory J Fowlers MCP CAN library and added support for 615 kbit/s according to this post by Cory J Fowler.
I've made a simplified sketch to rule out any faults within my primary sketch.
#include <mcp_can.h>
#define CAN0_INT 2 // Set INT to pin 2 for the Sparkfun CAN BUS shield
MCP_CAN CAN0(53); // Set CS to pin 10 for Uno or 53 for Mega 2560 for the Sparkfun CAN BUS shield
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
char msgString[128]; // Array to store Serial string
byte data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
byte sndStat;
byte Rpm_max[8] = {0xC7, 0x00, 0x00, 0x65, 0x92, 0x00, 0x00, 0x00};
void setup() {
Serial.begin(115200);
// Initialize MCP2515 running at 16MHz with a baudrate of 615kb/s and the masks and filters disabled.
if (CAN0.begin(MCP_ANY, CAN_615KBPS, MCP_16MHZ) == CAN_OK)
Serial.println("MCP2515 Initialized Successfully!");
else
Serial.println("Error Initializing MCP2515...");
CAN0.setMode(MCP_NORMAL); // Change to normal mode to allow messages to be transmitted
pinMode(CAN0_INT, INPUT); // Configuring pin for /INT input
}
void loop() {
for (int i = 0; i < 8; i++) {
(data[i] = Rpm_max[i]);
}
Send_msg();
delay(500);
PrintHex8(data, 8); Serial.print("\n"); //Prints the sent data to the Seria1 monitor, just to be sure the correct data is being sent
Read_msg();
delay(30000);
}
void Send_msg() {
sndStat = CAN0.sendMsgBuf(0x05, 0, 8, data);
}
void Read_msg() {
if (!digitalRead(CAN0_INT)) // If CAN0_INT pin is low, read receive buffer
{
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
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), len);
else
sprintf(msgString, "Standard ID: 0x%.3lX DLC: %1d Data:", rxId, len);
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 < len; i++) {
sprintf(msgString, " 0x%.2X", rxBuf[i]);
Serial.print(msgString);
}
}
Serial.println();
}
}
void PrintHex8(uint8_t *ddata, uint8_t length) // prints 8-bit data in hex with leading zeroes
{
for (int i = 0; i < length; i++) {
Serial.print("0x");
if (ddata[i] < 0x10) {
Serial.print("0");
}
Serial.print(ddata[i], HEX);
Serial.print(" ");
}
}
The response to this request, which is to read the maximum engine rpm, is:
Standard ID: 0x00C DLC: 8 Data: 0xC7 0x00 0x02 0xFF 0x03 0xDB 0xCE 0xC3
Bytes 0, 1 and 2 are correct, but 3 is not. It is supposed to be 0xD0, not 0xFF. Bytes 4-7 are supposed to be 0x00 I guess.
There is a software called T5Suite which can communicate with the EMS via CAN along with a CAN to USB adapter, and this works fine and has been for many years. With this I have double checked that the parameter for maximum engine rpm is 02D0 in hex.
I've gone through this troubleshooting guide, and everything checks out. No measurements are out of spec.
I have tried with another Arduino. I have tried with another can bus shield. I have tried with another ECU. I have tried both in the car and on the desk. The result is always the same.
I don't know how to move on with the troubleshooting and would love to get some help if anybody has got any ideas.
Regards,
Christian