Skip to content

Commit

Permalink
Merge pull request #3 from waal70/OILBoostMonitor
Browse files Browse the repository at this point in the history
OIL temp & boost pressure monitor
  • Loading branch information
waal70 committed Sep 10, 2015
2 parents 2857447 + 92d45ef commit dd5ad9c
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 59 deletions.
76 changes: 41 additions & 35 deletions s60can/s60can.ino
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
**
** Copyright (c) 2015 André de Waal
**
**
** Large portions copied from Olaf @ hackingvolvo.blogspot.com
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published
** by the Free Software Foundation, either version 3 of the License, or (at
Expand All @@ -20,11 +20,18 @@
** 24-08-2015: Start of dpfmonitor branch
** 26-08-2015: Start of EGRMonitor branch
** 08-09-2015: New display, 20x4
** 09-09-2015: Implemented oil and boost pressure readings
*
* Memory footprint (last updated: 09-09-2015):
* Global variables use 1,432 bytes (69%) of dynamic memory, leaving 616 bytes for local variables. Maximum is 2,048 bytes.
*/

//TODO:
// * Move all USBCAN-related functionality to USBCAN.CPP
// * Currently ifdefs are being misused. Clean up
//
//
// * Way-over-yonder: make the list of sensors to read dynamic

//#define DEBUG_MAIN
//#define DEBUG_FREE_MEM
Expand Down Expand Up @@ -256,7 +263,7 @@ void write_DPF_msg_on_LCD (tCAN *message) {
lcd.print(msg);
}
else
lcd.print(F("DPF: 0 \337C"));
lcd.print(F("DPF: ERR \337C"));

lcd.setCursor(16,3);
lcd.print(globalMessageCounter);
Expand All @@ -268,26 +275,26 @@ void write_DPF_msg_on_LCD (tCAN *message) {

void write_EGR_msg_on_LCD (tCAN *message) {

//pre-condition isDPFMessage is true (1)
//pre-condition isEGRMessage is true (1)
//lcd.clearLine(0);
//lcd.backlight();
lcd.setCursor(0,1);
lcd.write(" ");
lcd.write(" "); //we do this because initialization leaves characters on line 2
lcd.setCursor(0,1);
char temp[7];
char temp[6];
char msg[16];
float factor = 0.01220703125;
uint16_t value;
// CD 11 E6 01 96 0B D4 00
// This gets the 6th and 7th element from the DPF response message (tested through isDPFMessage())
// And calculates the temperature as follows:
// Decimal value is temperature in tenths of degrees Kelvin. Therefore:
// decimal value /10 - 273.15 = degrees celsius:
// This gets the 6th and 7th element from the EGR response message (tested through isEGRMessage())
// And calculates the percentage as follows:
// Decimal value is 8192 (hex: 2000)-based, meaning 8192 corresponds with 100%
// Lower value is XXX, so the factor becomes 0.0122 (more or less)
value = (uint16_t)(((message->data[5] << 8) | (message->data[6])) & 0xFFFF);

// Check for a valid temperature, between 0 and 2000 degrees celsius
// Check for a valid value, between 0 and 8193 decimal
// Character buffers need to be at least 1 character longer than the number of characters you are writing to them
// As we are writing 0.1 to maximum 2000.0 this means a buffer of 6+1
// As we are writing 0.1 to maximum 100.0 this means a buffer of 5+1
if (((double)value > 0) && ((double)value < 8193) )
{
dtostrf((double)value*factor,3,1,temp);
Expand All @@ -296,66 +303,65 @@ void write_EGR_msg_on_LCD (tCAN *message) {
lcd.print(msg);
}
else
lcd.print(F("EGR: 0 %"));
lcd.print(F("EGR: ERR %"));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void write_OIL_msg_on_LCD (tCAN *message) {

//pre-condition isOILMessage is true (1)
lcd.setCursor(0,2);
char temp[7];
char temp[6];
char msg[16];
float factor = 0.01220703125;
uint16_t value;
// CD 11 E6 01 96 0B D4 00
// This gets the 6th and 7th element from the DPF response message (tested through isDPFMessage())
// CD 11 E6 00 ED 0E 3C 00
// This gets the 6th and 7th element from the OIL response message (tested through isOILMessage())
// 0E3C (3644) = 91.66, 0E39 (3641) = 90.96
// And calculates the temperature as follows:
// Decimal value is temperature in tenths of degrees Kelvin. Therefore:
// decimal value /10 - 273.15 = degrees celsius:
// decimal value / 10 - 273.15 = degrees celsius:
value = (uint16_t)(((message->data[5] << 8) | (message->data[6])) & 0xFFFF);

// Check for a valid temperature, between 0 and 2000 degrees celsius
// Check for a valid temperature, between 0 and 999.9 degrees celsius
// Character buffers need to be at least 1 character longer than the number of characters you are writing to them
// As we are writing 0.1 to maximum 2000.0 this means a buffer of 6+1
if (((double)value > 0) && ((double)value < 8193) )
// As we are writing 0.1 to maximum 999.9 this means a buffer of 5+1
if (((double)value > 0) && ((double)value < 3732) )
{
dtostrf((double)value*factor-12.3,3,1,temp);
dtostrf((value-2731.5)/10,3,1,temp);
//337 is the degree symbol
sprintf(msg, "OIL: %s \337C", temp);
lcd.print(msg);
}
else
lcd.print(F("OIL: NaN"));
lcd.print(F("OIL: ERR \337C"));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void write_BOOST_msg_on_LCD (tCAN *message) {

lcd.setCursor(0,3);
char temp[7];
char temp[5];
char msg[16];
float factor = 0.0001220703125;
float factor = 0.001;
uint16_t value;
// CD 11 E6 01 96 0B D4 00
// This gets the 6th and 7th element from the DPF response message (tested through isDPFMessage())
// And calculates the temperature as follows:
// Decimal value is temperature in tenths of degrees Kelvin. Therefore:
// decimal value /10 - 273.15 = degrees celsius:
// CD 11 E6 01 76 04 0D 00
// 040D (1037) = 1037 hPa, 0409 (1033) = 1033 hPa
// This gets the 6th and 7th element from the BOOST response message (tested through isBOOSTMessage())
// And calculates the boost pressure as follows:
// Decimal value is boost pressure in hectoPascals (1hPa = 1/1000 bar)
value = (uint16_t)(((message->data[5] << 8) | (message->data[6])) & 0xFFFF);

// Check for a valid temperature, between 0 and 2000 degrees celsius
// Check for a valid pressure, between 0 and 4500 hPA
// Character buffers need to be at least 1 character longer than the number of characters you are writing to them
// As we are writing 0.1 to maximum 2000.0 this means a buffer of 6+1
// As we are writing 1.00 to maximum 4.00 this means a buffer of 4+1
if (((double)value > 0) && ((double)value < 8193) )
{
dtostrf((double)value*factor+.65,2,2,temp);
//337 is the degree symbol
dtostrf((double)value*factor,1,2,temp);
sprintf(msg, "TRB: %s bar", temp);
lcd.print(msg);
}
else
lcd.print(F("TRB: 0 %"));
lcd.print(F("TRB: ERR bar"));
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -628,7 +634,7 @@ void setup() {
#endif //KEEPALIVE

#ifdef DPFMONITOR
init_dpf(LOOPBACKMODE);
init_monitoring(LOOPBACKMODE);
#endif

//set the filters for the messages
Expand Down
107 changes: 84 additions & 23 deletions s60can/s60can_msgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
** Changelog:
** 24-08-2015: Start of dpfmonitor branch
** 26-08-2015: Start of EGRMonitor branch
** 08-09-2015: New display, 20x4
** 09-09-2015: Implemented oil and boost pressure readings
**
*/
#include <Arduino.h>
Expand All @@ -27,38 +29,49 @@
#define KEEPALIVE_MSG 0
#define DPF_MSG 0x0196
#define EGR_MSG 0x002C
#define OIL_MSG 0x00ED
#define BOOST_MSG 0x0176

int LOOPBACKMODE = 0;
unsigned long last_keepalive_msg;
unsigned long keepalive_timeout; // timeout in 1/10 seconds. 0=keepalive messaging disabled

unsigned long last_keepalive_msg2;
unsigned long keepalive_timeout2; // timeout in 1/10 seconds. 0=keepalive messaging disabled

unsigned long last_dpf_msg;
unsigned long last_dpf_frequency; //frequency in 1/10 seconds. 0=diagnostic messaging disabled

unsigned long last_egr_msg;
unsigned long last_egr_frequency; //frequency in 1/10 seconds. 0=diagnostic messaging disabled

unsigned long last_oil_msg;
unsigned long last_oil_frequency; //frequency in 1/10 seconds. 0=diagnostic messaging disabled

unsigned long last_boost_msg;
unsigned long last_boost_frequency; //frequency in 1/10 seconds. 0=diagnostic messaging disabled

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void init_keepalive(int blnLBM) {
LOOPBACKMODE = blnLBM;
last_keepalive_msg=millis();
// initialize the keep-alive message
last_keepalive_msg2=millis();
keepalive_timeout = 40;
keepalive_timeout2 = 0;
}

void init_dpf(int blnLBM) {
void init_monitoring(int blnLBM) {
LOOPBACKMODE = blnLBM;
// initialize the dpf monitoring message
last_dpf_msg=millis();
last_dpf_frequency = 35; //every 3.5 seconds


// initialize the egr monitoring message
last_egr_msg=last_dpf_msg;
last_egr_frequency = 10; //every second

// initialize the oil monitoring message
last_oil_msg=last_dpf_msg;
last_oil_frequency = 50; //every 5 seconds

// initialize the boost monitoring message
last_boost_msg=last_dpf_msg;
last_boost_frequency = 5; //every half a second
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -92,25 +105,25 @@ int isEGRMessage(tCAN * message) {
int isOILMessage(tCAN * message) {

// Ignore canid. Different cars may send different diagnostic id's
// DPF-return message contains: CE 11 E6 01 96 xx yy 00. 11 E6 01 96 are relevant
// DPF-return message contains: CE 11 E6 00 ED xx yy 00. 11 E6 00 ED are relevant
//loopback testing:
if (LOOPBACKMODE)
return ((message->data[1] == 0x11) && (message->data[2] == 0xA6) && (message->data[3] == 0x00) && (message->data[4] == 0x2C));
return ((message->data[1] == 0x11) && (message->data[2] == 0xA6) && (message->data[3] == 0x00) && (message->data[4] == 0xED));
else
return ((message->data[1] == 0x11) && (message->data[2] == 0xE6) && (message->data[3] == 0x00) && (message->data[4] == 0x2C));
return ((message->data[1] == 0x11) && (message->data[2] == 0xE6) && (message->data[3] == 0x00) && (message->data[4] == 0xED));

}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 1 = succes, 0 = fail
int isBOOSTMessage(tCAN * message) {

// Ignore canid. Different cars may send different diagnostic id's
// DPF-return message contains: CE 11 E6 01 96 xx yy 00. 11 E6 01 96 are relevant
// DPF-return message contains: CE 11 E6 01 76 xx yy 00. 11 E6 01 76 are relevant
//loopback testing:
if (LOOPBACKMODE)
return ((message->data[1] == 0x11) && (message->data[2] == 0xA6) && (message->data[3] == 0x00) && (message->data[4] == 0x2C));
return ((message->data[1] == 0x11) && (message->data[2] == 0xA6) && (message->data[3] == 0x01) && (message->data[4] == 0x76));
else
return ((message->data[1] == 0x11) && (message->data[2] == 0xE6) && (message->data[3] == 0x00) && (message->data[4] == 0x2C));
return ((message->data[1] == 0x11) && (message->data[2] == 0xE6) && (message->data[3] == 0x01) && (message->data[4] == 0x76));

}

Expand All @@ -122,7 +135,6 @@ tCAN construct_CAN_msg(int msgType) {
case KEEPALIVE_MSG:
//live keepalive message:
//000FFFFE 8 D8 00 00 00 00 00 00 00

// initialize the keep-alive message
message.header.rtr = 0;
message.header.eid = 1;
Expand All @@ -131,14 +143,6 @@ tCAN construct_CAN_msg(int msgType) {
message.data[0] = 0xd8;
for (int i=1;i<8;i++)
message.data[i] = 0x00;
/* keepalive_msg2.header.rtr = 0;
keepalive_msg2.header.eid = 1;
keepalive_msg2.header.length = 8;
keepalive_msg2.id = 0x01017ffc;
for (int i=0;i<8;i++)
keepalive_msg2.data[i] = 0x00;
keepalive_msg2.data[4] = 0x1f;
keepalive_msg2.data[5] = 0x40;*/
return message;
break;
case (DPF_MSG):
Expand Down Expand Up @@ -181,6 +185,46 @@ tCAN construct_CAN_msg(int msgType) {
message.data[7] = 0x00;
return message;
break;
case (OIL_MSG):
message.header.rtr = 0;
message.header.eid = 1;
message.header.length = 8;
message.id = 0x000ffffe; //default diagnostic id
message.data[0] = 0xCD;
message.data[1] = 0x11;
message.data[2] = 0xA6;
message.data[3] = 0x00;
message.data[4] = 0xED;
message.data[5] = 0x01;
message.data[6] = 0x00;
//for loopback testing:
if (LOOPBACKMODE) {
message.data[5] = 0x0E;
message.data[6] = 0x3C; // 0E3C = 91.66 degrees C, 0E39 = 90.96
}
message.data[7] = 0x00;
return message;
break;
case (BOOST_MSG):
message.header.rtr = 0;
message.header.eid = 1;
message.header.length = 8;
message.id = 0x000ffffe; //default diagnostic id
message.data[0] = 0xCD;
message.data[1] = 0x11;
message.data[2] = 0xA6;
message.data[3] = 0x01;
message.data[4] = 0x76;
message.data[5] = 0x01;
message.data[6] = 0x00;
//for loopback testing:
if (LOOPBACKMODE) {
message.data[5] = 0x04;
message.data[6] = 0x09; // 0409 = 1033 hPa, 040D = 1037 hPa
}
message.data[7] = 0x00;
return message;
break;
default:
break;
return message;
Expand Down Expand Up @@ -214,6 +258,23 @@ tCAN sendMessage;
last_egr_msg = millis();
}

if (last_oil_frequency>0)
if (millis()-last_oil_msg > last_oil_frequency *100)
{
sendMessage = construct_CAN_msg(OIL_MSG);
send_CAN_msg(&sendMessage);
last_oil_msg = millis();
}

if (last_boost_frequency>0)
if (millis()-last_boost_msg > last_boost_frequency *100)
{
sendMessage = construct_CAN_msg(BOOST_MSG);
send_CAN_msg(&sendMessage);
last_boost_msg = millis();
}



}

4 changes: 3 additions & 1 deletion s60can/s60can_msgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
** Changelog:
** 24-08-2015: Start of dpfmonitor branch
** 26-08-2015: Start of EGRMonitor branch
** 08-09-2015: New display, 20x4
** 09-09-2015: Implemented oil and boost pressure readings
**
*/

#include "usbcan.h"
#include "s60can.h"

void init_keepalive(int blnLBM);
void init_dpf(int blnLBM);
void init_monitoring(int blnLBM);
int isEGRMessage(tCAN * message);
int isDPFMessage(tCAN * message);
int isOILMessage(tCAN * message);
Expand Down

0 comments on commit dd5ad9c

Please sign in to comment.