ARDU MEGA2560
SEEED CAN Shield
ADRU IDE 1.8
Library: https://travis-ci.com/Seeed-Studio/CAN_BUS_Shield.svg?branch=master
Hello all,
I'm stuck on what seems to be an easy issue, however not so easy for me. My Hadrware
and program are working fine when requesting a single PID (0x0C, engine RPM).
The problem begins when I try to access multiple PIDs; the data becomes erratic.
Single PID Code and Output are perfect:
#include <SPI.h>
#include "mcp_can.h"
int pidCounter;
unsigned char len = 0;
unsigned char buf[8];
MCP_CAN CAN(9); // Set CS pin
#define PID_ENGIN_PRM 0x0C
#define PID_VEHICLE_SPEED 0x0D
#define PID_COOLANT_TEMP 0x05
#define CAN_ID_PID 0x7DF
void set_mask_filt(){
// set mask, set both the mask to 0x3ff
CAN.init_Mask(0, 0, 0x7FC);
CAN.init_Mask(1, 0, 0x7FC);
// set filter, we can receive id from 0x04 ~ 0x09
CAN.init_Filt(0, 0, 0x7E8);
CAN.init_Filt(1, 0, 0x7E8);
CAN.init_Filt(2, 0, 0x7E8);
CAN.init_Filt(3, 0, 0x7E8);
CAN.init_Filt(4, 0, 0x7E8);
CAN.init_Filt(5, 0, 0x7E8);
}
void setup() {
Serial.begin(115200);
CAN.begin(CAN_500KBPS);
set_mask_filt();
}
void loop() {
unsigned char tmp[8] = {0x02, 0x01, 0x0C, 0, 0, 0, 0, 0}; //engine RPM
CAN.sendMsgBuf(0x7DF, 0, 8, tmp);
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
Serial.print(pidCounter); Serial.print(',');
Serial.print(buf[0], DEC); Serial.print(',');
Serial.print(buf[1], DEC); Serial.print(',');
Serial.print(buf[2], DEC); Serial.print(',');
Serial.print(buf[3], DEC); Serial.print(',');
Serial.print(buf[4], DEC); Serial.print(',');
Serial.print(buf[5], DEC); Serial.print(',');
Serial.print(buf[6], DEC); Serial.print(',');
Serial.println(buf[7], DEC);
}
Serial Monitor Output:
0 4 12 14
0 4 12 14
0 4 12 14
0 4 12 14
0 4 12 14
This is the code for multi-PID requests
#include <SPI.h>
#include "mcp_can.h"
int pidCounter;
unsigned char len = 0;
unsigned char buf[8];
unsigned char PID_INPUT;
unsigned char getPid = 0;
MCP_CAN CAN(9); // Set CS pin
#define PID_ENGIN_PRM 0x0C
#define PID_VEHICLE_SPEED 0x0D
#define PID_COOLANT_TEMP 0x05
#define CAN_ID_PID 0x7DF
void set_mask_filt() {
/*
set mask, set both the mask to 0x3ff
*/
CAN.init_Mask(0, 0, 0x7FC);
CAN.init_Mask(1, 0, 0x7FC);
/*
set filter, we can receive id from 0x04 ~ 0x09
*/
CAN.init_Filt(0, 0, 0x7E8);
CAN.init_Filt(1, 0, 0x7E8);
CAN.init_Filt(2, 0, 0x7E8);
CAN.init_Filt(3, 0, 0x7E8);
CAN.init_Filt(4, 0, 0x7E8);
CAN.init_Filt(5, 0, 0x7E8);
}
void setup(){
Serial.begin(115200);
CAN.begin(CAN_500KBPS);
set_mask_filt();
}
void loop() {
if(pidCounter == 1){ unsigned char tmp[8] = {0x02, 0x01, 0x0C, 0, 0, 0, 0, 0}; CAN.sendMsgBuf(0x7DF, 0, 8, tmp); }
else if(pidCounter == 2){ unsigned char tmp[8] = {0x02, 0x01, 0x00, 0, 0, 0, 0, 0}; clearBuf(); }
else if(pidCounter == 3){ unsigned char tmp[8] = {0x02, 0x01, 0x0D, 0, 0, 0, 0, 0}; CAN.sendMsgBuf(0x7DF, 0, 8, tmp); }
else if(pidCounter == 4){ unsigned char tmp[8] = {0x02, 0x01, 0x00, 0, 0, 0, 0, 0}; clearBuf(); }
else if(pidCounter == 5){ unsigned char tmp[8] = {0x02, 0x01, 0x05, 0, 0, 0, 0, 0}; CAN.sendMsgBuf(0x7DF, 0, 8, tmp); }
else if(pidCounter == 6){ unsigned char tmp[8] = {0x02, 0x01, 0x00, 0, 0, 0, 0, 0}; clearBuf(); }
else clearBuf();
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
Serial.print(pidCounter); Serial.print(',');
Serial.print(buf[0], DEC); Serial.print(',');
Serial.print(buf[1], DEC); Serial.print(',');
Serial.print(buf[2], DEC); Serial.print(',');
Serial.print(buf[3], DEC); Serial.print(',');
Serial.print(buf[4], DEC); Serial.print(',');
Serial.print(buf[5], DEC); Serial.print(',');
Serial.print(buf[6], DEC); Serial.print(',');
Serial.println(buf[7], DEC);
pidCounter++;
if(pidCounter > 6) pidCounter = 0;
clearBuf();
}
void clearBuf(){
buf[0] = '0';
buf[1] = '0';
buf[2] = '0';
buf[3] = '0';
buf[4] = '0';
buf[5] = '0';
buf[6] = '0';
buf[7] = '0';
}
Now the array elements begin to shift as you see in this output scan:
1,48,48,48,48,48,48,48,48
1,3,65,5,123,170,170,170,170
1,3,65,5,123,170,170,170,170
1,3,65,5,123,170,170,170,170
1,48,48,48,48,48,48,48,48
1,3,65,5,123,170,170,170,170
every time pidCounter == 1, the 0x0C PID is sent, then buf is read and printed.
The next pidCounter cycle attempts to send 0x00, the clearBuf() sets the array to zeros.
You will notice I tried to add my own function to clear the buffer [clearBuf()].
Then an attempt was made to add rows to call a PID of 0x00 to wipe the contents
I even tried increasing the counter "spacing" to give the Engine ECU time to respond.
Nothing I've tried is working, and I'm out of ideas and programming knowledge.
Even if I simplify to the following, I get a similar random output:
if(pidCounter == 1){ unsigned char tmp[8] = {0x02, 0x01, 0x0C, 0, 0, 0, 0, 0}; CAN.sendMsgBuf(0x7DF, 0, 8, tmp); }
else if(pidCounter == 3){ unsigned char tmp[8] = {0x02, 0x01, 0x0D, 0, 0, 0, 0, 0}; CAN.sendMsgBuf(0x7DF, 0, 8, tmp); }
else if(pidCounter == 5){ unsigned char tmp[8] = {0x02, 0x01, 0x05, 0, 0, 0, 0, 0}; CAN.sendMsgBuf(0x7DF, 0, 8, tmp); }
else clearBuf();
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
I know I can use an array and counter to change the PID, instead of assigning the char array for each PID send, but that doesn't solve the problem.
Any tips in the proper direction would be appreciated.
Thanks!