outMsg.buf[1]=BIT_CHECK(currentStatus.engine,BIT_ENGINE_RUN)?0x1:0x0;// Enable heater once engine is running (ie. above cranking rpm), this condition can be changed to CLT above certain temp and so on.
inLambda=(word(inMsg.buf[3],inMsg.buf[2]));// Combining 2 bytes of data into single variable factor is 0.0001 so lambda 1 comes in as 10K
if(inMsg.buf[1]==0x1)// Checking if lambda is valid
{
switch(inMsg.id)
{
case0x190:
if((inLambda*configPage2.stoich/10000)>250){//Check if we dont overflow the 8bit O2 variable
currentStatus.O2=250;
break;
}
currentStatus.O2=(unsignedint)(inLambda*configPage2.stoich/10000);// Multiplying lambda by stoich ratio to get AFR and dividing it by 10000 to get correct value
break;
case0x192:
if((inLambda*configPage2.stoich/10000)>250){//Check if we dont overflow the 8bit O2 variable
currentStatus.O2=250;
break;
}
currentStatus.O2_2=(unsignedint)(inLambda*configPage2.stoich/10000);// Multiplying lambda by stoich ratio to get AFR and dividing it by 10000 to get correct value
// switch case for gathering all data to message based on CAN Id.
voidDashMessage(uint16_tDashMessageID)
{
switch(DashMessageID)
{
caseCAN_BMW_DME1:
uint32_ttemp_RPM;
temp_RPM=currentStatus.RPM*64;//RPM conversion is currentStatus.RPM * 6.4, but this does it without floats.
temp_RPM=temp_RPM/10;
outMsg.id=DashMessageID;
outMsg.len=8;
outMsg.buf[0]=0x05;//bitfield, Bit0 = 1 = terminal 15 on detected, Bit2 = 1 = the ASC message ASC1 was received within the last 500 ms and contains no plausibility errors
outMsg.buf[1]=0x0C;//Indexed Engine Torque in % of C_TQ_STND TBD do torque calculation.
// This routine builds the realtime data into packets that the obd requesting device can understand. This is only used by teensy and stm32 with onboard canbus
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x00;// PID code
outMsg.buf[3]=0x08;//B0000 1000 1-8
outMsg.buf[4]=B01111110;//9-16
outMsg.buf[5]=B10100000;//17-24
outMsg.buf[6]=B00010001;//17-32
outMsg.buf[7]=B00000000;
break;
case5://PID-0x05 Engine coolant temperature , range is -40 to 215 deg C , formula == A-40
outMsg.buf[0]=0x03;// sending 3 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x05;// pid code
outMsg.buf[3]=(byte)(currentStatus.coolant+CALIBRATION_TEMPERATURE_OFFSET);//the data value A
outMsg.buf[4]=0x00;//the data value B which is 0 as unused
outMsg.buf[5]=0x00;
outMsg.buf[6]=0x00;
outMsg.buf[7]=0x00;
break;
case10:// PID-0x0A , Fuel Pressure (Gauge) , range is 0 to 765 kPa , formula == A / 3)
uint16_ttemp_fuelpressure;
// Fuel pressure is in PSI. PSI to kPa is 6.89475729, but that needs to be divided by 3 for OBD2 formula. So 2.298.... 2.3 is close enough, so that in fraction.
O2present=B00000011;//realtimebufferA[24]; TEST VALUE !!!!!
outMsg.buf[0]=0x03;// sending 3 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x13;// pid code
outMsg.buf[3]=O2present;// A
outMsg.buf[4]=0x00;// B
outMsg.buf[5]=0x00;
outMsg.buf[6]=0x00;
outMsg.buf[7]=0x00;
break;
case28:// PID-0x1C obd standard
uint16_tobdstandard;
obdstandard=7;// This is OBD2 / EOBD
outMsg.buf[0]=0x03;// sending 3 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x1C;// pid code
outMsg.buf[3]=obdstandard;// A
outMsg.buf[4]=0x00;// B
outMsg.buf[5]=0x00;
outMsg.buf[6]=0x00;
outMsg.buf[7]=0x00;
break;
case32:// PID-0x20 PIDs supported [21-40]
outMsg.buf[0]=0x06;// sending 4 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x20;// pid code
outMsg.buf[3]=B00011000;// 33-40
outMsg.buf[4]=B00000000;//41 - 48
outMsg.buf[5]=B00100000;//49-56
outMsg.buf[6]=B00000001;//57-64
outMsg.buf[7]=0x00;
break;
case36:// PID-0x24 O2 sensor2, AB: fuel/air equivalence ratio, CD: voltage , Formula == (2/65536)(256A +B) , 8/65536(256C+D) , Range is 0 to <2 and 0 to >8V
//uint16_t O2_1e ;
//int16_t O2_1v ;
obdcalcH16=configPage2.stoich/10;// configPage2.stoich(is *10 so 14.7 is 147)
obdcalcE32=currentStatus.O2/10;// afr(is *10 so 25.5 is 255) , needs a 32bit else will overflow
obdcalcF32=(obdcalcE32<<8)/obdcalcH16;//this is same as (obdcalcE32/256) / obdcalcH16 . this calculates the ratio
obdcalcG16=(obdcalcF32*32768)>>8;
obdcalcA=highByte(obdcalcG16);
obdcalcB=lowByte(obdcalcG16);
obdcalcF32=currentStatus.O2ADC;//o2ADC is wideband volts to send *100
obdcalcG16=(obdcalcF32*20971)>>8;
obdcalcC=highByte(obdcalcG16);
obdcalcD=lowByte(obdcalcG16);
outMsg.buf[0]=0x06;// sending 4 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x24;// pid code
outMsg.buf[3]=obdcalcA;// A
outMsg.buf[4]=obdcalcB;// B
outMsg.buf[5]=obdcalcC;// C
outMsg.buf[6]=obdcalcD;// D
outMsg.buf[7]=0x00;
break;
case37://O2 sensor2, AB fuel/air equivalence ratio, CD voltage , 2/65536(256A +B) ,8/65536(256C+D) , range is 0 to <2 and 0 to >8V
//uint16_t O2_2e ;
//int16_t O2_2V ;
obdcalcH16=configPage2.stoich/10;// configPage2.stoich(is *10 so 14.7 is 147)
obdcalcE32=currentStatus.O2_2/10;// afr(is *10 so 25.5 is 255) , needs a 32bit else will overflow
obdcalcF32=(obdcalcE32<<8)/obdcalcH16;//this is same as (obdcalcE32/256) / obdcalcH16 . this calculates the ratio
obdcalcG16=(obdcalcF32*32768)>>8;
obdcalcA=highByte(obdcalcG16);
obdcalcB=lowByte(obdcalcG16);
obdcalcF32=currentStatus.O2_2ADC;//o2_2ADC is wideband volts to send *100
obdcalcG16=(obdcalcF32*20971)>>8;
obdcalcC=highByte(obdcalcG16);
obdcalcD=lowByte(obdcalcG16);
outMsg.buf[0]=0x06;// sending 4 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x25;// pid code
outMsg.buf[3]=obdcalcA;// A
outMsg.buf[4]=obdcalcB;// B
outMsg.buf[5]=obdcalcC;// C
outMsg.buf[6]=obdcalcD;// D
outMsg.buf[7]=0x00;
break;
case51://PID-0x33 Absolute Barometric pressure , range is 0 to 255 kPa , formula == A
outMsg.buf[0]=0x03;// sending 3 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x33;// pid code
outMsg.buf[3]=currentStatus.baro;// A
outMsg.buf[4]=0x00;// B which is 0 as unused
outMsg.buf[5]=0x00;
outMsg.buf[6]=0x00;
outMsg.buf[7]=0x00;
break;
case64:// PIDs supported [41-60]
outMsg.buf[0]=0x06;// sending 4 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x40;// pid code
outMsg.buf[3]=B01000100;// 65-72dec
outMsg.buf[4]=B00000000;// 73-80
outMsg.buf[5]=B01000000;// 81-88
outMsg.buf[6]=B00010000;// 89-96
outMsg.buf[7]=0x00;
break;
case66://control module voltage, 256A+B / 1000 , range is 0 to 65.535v
uint16_ttemp_ecuBatt;
temp_ecuBatt=currentStatus.battery10;// create a 16bit temp variable to do the math
obdcalcA=temp_ecuBatt*100;// should be *1000 but ecuBatt is already *10
outMsg.buf[0]=0x04;// sending 4 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x42;// pid code
outMsg.buf[3]=highByte(obdcalcA);// A
outMsg.buf[4]=lowByte(obdcalcA);// B
outMsg.buf[5]=0x00;
outMsg.buf[6]=0x00;
outMsg.buf[7]=0x00;
break;
case70://PID-0x46 Ambient Air Temperature , range is -40 to 215 deg C , formula == A-40
uint16_ttemp_ambientair;
temp_ambientair=11;// TEST VALUE !!!!!!!!!!
obdcalcA=temp_ambientair+40;// maybe later will be (byte)(currentStatus.AAT + CALIBRATION_TEMPERATURE_OFFSET)
outMsg.buf[0]=0x03;// sending 3 byte
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x46;// pid code
outMsg.buf[3]=obdcalcA;// A
outMsg.buf[4]=0x00;
outMsg.buf[5]=0x00;
outMsg.buf[6]=0x00;
outMsg.buf[7]=0x00;
break;
case82://PID-0x52 Ethanol fuel % , range is 0 to 100% , formula == (100/255)A
outMsg.buf[0]=0x03;// sending 3 byte
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x52;// pid code
outMsg.buf[3]=currentStatus.ethanolPct;// A
outMsg.buf[4]=0x00;
outMsg.buf[5]=0x00;
outMsg.buf[6]=0x00;
outMsg.buf[7]=0x00;
break;
case92://PID-0x5C Engine oil temperature , range is -40 to 210 deg C , formula == A-40
uint16_ttemp_engineoiltemp;
temp_engineoiltemp=40;// TEST VALUE !!!!!!!!!!
obdcalcA=temp_engineoiltemp+40;// maybe later will be (byte)(currentStatus.EOT + CALIBRATION_TEMPERATURE_OFFSET)
outMsg.buf[0]=0x03;// sending 3 byte
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.
outMsg.buf[2]=0x5C;// pid code
outMsg.buf[3]=obdcalcA;// A
outMsg.buf[4]=0x00;
outMsg.buf[5]=0x00;
outMsg.buf[6]=0x00;
outMsg.buf[7]=0x00;
break;
case96://PIDs supported [61-80]
outMsg.buf[0]=0x06;// sending 4 bytes
outMsg.buf[1]=0x41;// Same as query, except that 40h is added to the mode value. So:41h = show current data ,42h = freeze frame ,etc.