CAN comms for other stuff

Started by Rx7man, July 16, 2017, 01:34:00 PM

Rx7man

Well, I'm at the point in this project where I'm either going to have too much of a rats nest of wiring, or going to run out of IO's on the Mega.. So I want to have daughter-boxes and offload some duties to them.. Since I need CAN comms anyhow, I'll have everything communicate over that... That should also relieve some load from the main processor.

Now, How should I go about setting up the software side of it?  Addresses, PID's, etc
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

You want to use CANN to communicate between Arduinos ?
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

Yes, especially for some of the sensory network.. I could offload the turbine shaft speed, engine speed, and 4 pyro inputs to one unit stationed near the ECM for example, I could have a second unit on the drivers side reading TPS, fuel pressure, brake pressure, oil pressure.. and finally one in the cab reading manual inputs and taking care of the display.. it would save me massive amounts of ratsnest wiring
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

well there's plenty of room in the canbus for writing, you could use multiple addresses for specific sensors, if their data is larger than the word you can use...

then just of course listen with your main arduino to do all the fun display stuff. You can check the common code canbus area for how I listen to the bus (25ms) and only listen to a specific address
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

I'm going to convert the data to a floating point number and transfer it that way... Using a union makes that very easy and eliminates conversions... a 4 byte array to be transferred over CAN would just be transferring the binary version of the floating point number.. at the other end you do it backward.  I got that part of it figured out fine

My question is more how the addresses relate to OBD2 PID's, etc
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

Rx7man

Just for shits and giggles, here's a rough draft of the code.. the ISR's for reading RPM and turbine shaft speed are not yet implemented... the "pindefs.h" file will be a project-wide used file so every project uses the same definitions... Also putting in some compiler directives so it's possible to change pin definitions based on the platform (I2C, SPI pins, etc)


#include "SPI.h"
#include "CANLibrarymaster\can.h"
//#include "everytime\src\everytime.h"
#include "PIDdefs.h" //THis is where all the PID's are listed for the entire Big black box project as they must all match
#include "TimerOne\TimerOne.h"

#define ProMini


//the following are available Pro Mini pins
#ifdef ProMini
const byte Pyro1Pin = 6;
const byte Pyro2Pin = 7;
const byte Pyro3Pin = 8;
const byte Pyro4Pin = 9;
const byte CAN1pin = 10;
const byte COPpin = A0;
const byte EGPpin = A1;



MCP CAN1(CAN1pin);





//A4 = I2C SDA
//A5 = I2C SCL
//D10 = SPI CS
//D11 = SPI MOSI
//D12 = SPI MISO
//D13 = SPI SCLK
//D2 = INT0
//D3 = INT1
//A0-A3, A6, A7 and D4-D9 are available for user IO while retaining comms

#endif





union u4 {
byte b4[4];
float f;
};
class PIDvaluePair {
public:
u4 Value;
unsigned long PID;

PIDvaluePair::PIDvaluePair(unsigned long pid) {
PID = pid;
}
};

PIDvaluePair EGT(EgtPID);
PIDvaluePair CLT(CltPID);
PIDvaluePair IAT(IatPID);
PIDvaluePair COT(CotPID);
PIDvaluePair RPM(RpmPID); //from interrupt
PIDvaluePair TSS(TssPID); //from interrupt
PIDvaluePair COP(CopPID); //from analog
PIDvaluePair EGP(EgpPID); //from analog


//List all the PIDs that this unit is responsible for responding to
PIDvaluePair PidList[] = {RPM, TSS, EGT, CLT,IAT, COT, COP, EGP};
byte MyListCount = 8; //total PID's we look at





void setup()
{
Serial.begin(115200);
Serial.println("Setup starting");
SPI.begin();
CAN1.begin(NORMAL, 250);

pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);


EGT.Value.f = 1.1f;
CLT.Value.f = 2.2f;
IAT.Value.f = 3.3f;
COT.Value.f = 4.4f;
RPM.Value.f = 750;
TSS.Value.f = 125000;

Timer1.initialize(1000);
Timer1.attachInterrupt(T1ISR);


delay(100);
Serial.println("Setup finished");
}

void loop()
{
ReadCan();
}
void ReadCan() {
while (CAN1.msgAvailable()) {
unsigned long ID;
byte length;
byte* data;
CAN1.read(&ID, &length, data);
SendCANreply(ID);
}
}

void SendCANreply(unsigned long ID) {
for (int i = 0; i<MyListCount; i++){

if (ID == PidList[i].PID) {
PIDvaluePair thisPID = PidList[i];

Serial.print("Got PID 0x");
Serial.print(ID, HEX);
Serial.print("   Returning ");
Serial.print(thisPID.Value.f);
Serial.println("");

CAN1.send(thisPID.PID, extID, 4, thisPID.Value.b4);
return;
}
}
}

void T1ISR() {
static unsigned long counts;
static boolean LEDstate;
counts++;
if (counts % 5 == 0) {
//read analog sensors
COP.Value.f = float(analogRead(COPpin));
EGP.Value.f = float(analogRead(EGPpin));
}
if (counts % 20 == 0) {
//calculate TSS
}
if (counts % 50 == 0){//100 ms interval
//calculate RPM


}
if(counts % 1000 == 0) {//1s interval
Serial.println("T1 x1000");
LEDstate = !LEDstate;
digitalWrite(13, LEDstate);
}
}
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

Rx7man

What happens is the master unit requests an update for a parameter and the slave replies...
I think some of the filtering logic could be done directly by the MCP chip with message handling, but for now this ought to work..
Now I need to set up two units and see if they talk to each other correctly.
There's a demo of the "union" I was talking about as well, also an inline class definition which makes things a little easier to pair together
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

Rx7man

Having some real issues communicating with the MCP chip from the Pro Mini.. not sure what's going on.. grrrr.. frustrating!
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

hakcenter

you setup a catch all / parse all ?
TS2009 Deḇarim 8:2
"And you shall remember that יהוה your Elohim led you all the way these forty years in the wilderness, to humble you, prove you, to know what is in your heart, whether you guard His commands or not.

Rx7man

I got it figured out... due to ambiguous labeling on the CAN module I had MISO/MOSI backward..

In its basic form it is working now.. 1.4ms turnaround time from a request to a reply isn't bad

Now I'm going to see if I can design a breadboard around this and add a VR interface, some analog inputs, and my 4 channel thermocouple board.. and stuff it into a small, sealed box... Should only need a 4 or 5 pin connector (12V,5V, GND, CANH, CANL) which will simplify wiring a whole lot
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles

Rx7man

at 2mhz CAN speed the turnaround time is 840 micros.. I might have a separate CAN channel for the turbo so it doesn't slow everything else down.. I'll try and make it transparent so anything can read/write to it
'94 dually,  67/67 HE351VE, NV5600, ~600hp
'93 ECLB 47RH, new toy truck, H pump project, 1000hp goal, 300K miles
93 XCLB auto, bone stock, 350K miles
93 XCLB 5spd, bone stock, 100K miles