#include <U8x8lib.h>
#include <mcp_can.h>
#include <SparkFun_I2C_Mux_Arduino_Library.h>
#include "Variables.h"
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE);
QWIICMUX I2Cmux;
/*
OLED Screen Layout
_____ _____ _____
| | | | | |
| 1 | | 2 | | 3 |
|_____| |_____| |_____|
_____ _____ _____
| | | | | |
| 0 | | 5 | | 4 |
|_____| |_____| |_____|
_____ _____ _____
| | | | | |
| 8 | | 7 | | 6 |
|_____| |_____| |_____|
*/
// Analog
#define BAT 1 // Battery Voltgae Sensor
#define ECT 2 // Engine Coolant Temperatur Sensor
#define EOT 5 // Enigne Oil Temperature Sensor
#define FTL 8 // Fuel Tank Level Sensor
#define EGT 4 // Exhaust Gas Temperature Sensor
#define TOT 7 // Transmission Oil Temperature Sensor
#define MGP 6 // Manifold Gauge Pressure Sensor
#define EOP 3 // Engine Oil Pressure Sensor
#define FPS 0 // Fuel Pressure Sensor
#define TRS 9 // Transmission Range Sensor
#define HS_CAN_INT 2 // Set CAN INT Input
MCP_CAN HS_CAN(10); // Set CS to pin 10
void setup(){
// Serial.begin(500000);
pinMode(HS_CAN_INT, INPUT); // Configuring pin for /INT input
// Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s, masks and filters disabled.
HS_CAN.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ);
HS_CAN.setMode(MCP_NORMAL); // Set operation mode to normal so the MCP2515 sends acks to received data.
Wire.begin();
I2Cmux.begin();
I2Cmux.setPortState(0xFF); // Turn on all I2Cmux ports
u8x8.begin(); // Initialize 8 OLED displays at once on I2C Mux
u8x8.setI2CAddress(0x7A); // Change I2C address to 0x7A
u8x8.begin(); // Initialize OLED display on address 0x7A
u8x8.setBusClock(1000000); // Set I2C Bus to 1Mhz (overclocked from 400Khz)
u8x8.setFont(u8x8_font_8x13_1x2_r); // Set Font to 8x13 pixels
u8x8.drawString(2,0,"FUEL LEVEL %"); // Print characters
u8x8.setI2CAddress(0x78); // Change I2C address to 0x78
I2Cmux.setPort(ECT); // Switch I2Cmux port
u8x8.drawString(3,0,"COOLANT C"); // Print characters
I2Cmux.setPort(EOT); // Switch I2Cmux port
u8x8.drawString(6,0,"OIL C"); // Print characters
I2Cmux.setPort(EOP); // Switch I2Cmux port
u8x8.drawString(5,0,"OIL PSI"); // Print characters
I2Cmux.setPort(FTL); // Switch I2Cmux port
u8x8.drawString(2,0,"FUEL LEVEL %"); // Print characters
I2Cmux.setPort(BAT); // Switch I2Cmux port
u8x8.drawString(4,0,"BATTERY V"); // Print characters
I2Cmux.setPort(EGT); // Switch I2Cmux port
u8x8.drawString(2,0,"EXHUAST GAS F"); // Print characters
I2Cmux.setPort(MGP); // Switch I2Cmux port
u8x8.drawString(4,0,"BOOST PSI"); // Print characters
I2Cmux.setPort(TOT); // Switch I2Cmux port
u8x8.drawString(1,0,"TRANSMISSION C"); // Print characters
I2Cmux.setPort(FPS); // Switch I2Cmux port
u8x8.drawString(4,0,"FUEL PSI"); // Print characters
u8x8.setFont(u8x8_font_inr33_3x6_n); // Set Font to inr33 3x6 numbers
// Not implemented yet
// I2Cmux.setPort(TRS); // Switch I2Cmux port
// u8x8.setFont(u8x8_font_inr21_2x4_r); // Set Font to inr21 2x4 reduced
// u8x8.drawString(0,4,"P R N D 2 1"); // Print characters
}
void loop(){
if(!digitalRead(HS_CAN_INT)){ // If HS_CAN_INT pin is low, read receive buffer
HS_CAN.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
if(rxId == 0x422){ // From PCM packet ID:422
while(len--) * (data422 + len) =* (rxBuf + len); // Move data from CAN packet to memory
}
if(rxId == 0x423){ // From PCM packet ID:423
while(len--) * (data423 + len) =* (rxBuf + len); // Move data from CAN packet to memory
}
} // End of CAN Receive
bat = can_bat_h << 8 | can_bat_l; // Recombine data (8B + 8B = 16B)
bat /= 10; // Remove offset (123 -> 12.3)
if(bat != old_bat){ // If value hasn't changed, don't update display
old_bat = bat; // Move new value to old value for compare next loop
I2Cmux.setPort(BAT); // Switch I2Cmux port
drawScreen(bat); // Print characters
}
ect = can_ect - 40; // Remove offset (140 -> 100)
if(ect != old_ect){ // If value hasn't changed, don't update display
old_ect = ect; // Move new value to old value for compare next loop
I2Cmux.setPort(ECT); // Switch I2Cmux port
drawScreen(ect); // Print characters
}
eot = can_eot - 40; // Remove offset (140 -> 100)
if(eot != old_eot){ // If value hasn't changed, don't update display
old_eot = eot; // Move new value to old value for compare next loop
I2Cmux.setPort(EOT); // Switch I2Cmux port
drawScreen(eot); // Print characters
}
eop = can_eop;
if(eop != old_eop){ // If value hasn't changed, don't update display
old_eop = eop; // Move new value to old value for compare next loop
I2Cmux.setPort(EOP); // Switch I2Cmux port
drawScreen(eop); // Print characters
}
tot = can_tot - 40; // Remove offset (140 -> 100)
if(tot != old_tot){ // If value hasn't changed, don't update display
old_tot = tot; // Move new value to old value for compare next loop
I2Cmux.setPort(TOT); // Switch I2Cmux port
drawScreen(tot); // Print characters
}
// Not implemented yet
trs = can_trs;
if(trs != old_trs){ // If value hasn't changed, don't update display
old_trs = trs; // Move new value to old value for compare next loop
I2Cmux.setPort(TRS); // Switch I2Cmux port
// drawScreen(trs); // Print characters
}
ftls = can_ftls / 2.55; // Remove offset (255 -> 100%)
if(ftls != old_ftls){ // If value hasn't changed, don't update display
old_ftls = ftls; // Move new value to old value for compare next loop
I2Cmux.setPort(255); // Turn off MUX
u8x8.setI2CAddress(0x7A); // Change I2C address to 0x7A
drawScreen(ftls); // Print characters
u8x8.setI2CAddress(0x78); // Change I2C address to 0x78
}
fps = can_fps_h << 8 | can_fps_l; // Recombine data (8B + 8B = 16B)
fps /= 10; // Remove offset (123 -> 12.3)
if(fps != old_fps){ // If value hasn't changed, don't update display
old_fps = fps; // Move new value to old value for compare next loop
I2Cmux.setPort(FPS); // Switch I2Cmux port
drawScreen(fps); // Print characters
}
egt = can_egt_h << 8 | can_egt_l; // Recombine data (8B + 8B = 16B)
if(egt != old_egt){ // If value hasn't changed, don't update display
old_egt = egt; // Move new value to old value for compare next loop
I2Cmux.setPort(EGT); // Switch I2Cmux port
drawScreen(egt); // Print characters
}
mgp = can_mgp_h << 8 | can_mgp_l; // Recombine data (8B + 8B = 16B)
mgp /= 10; // Remove offset (123 -> 12.3)
if(mgp != old_mgp){ // If value hasn't changed, don't update display
old_mgp = mgp; // Move new value to old value for compare next loop
I2Cmux.setPort(MGP); // Switch I2Cmux port
drawScreen(mgp); // Print characters
}
}// End of Loop
void drawScreen(int i){
byte j = I2Cmux.getPort(); // Move current selected I2C mux port for later evaluation
char abc[4]; // variable array
sprintf(abc, "%04d", i); // convert int to char
if(i < -99); // do nothing
else if(i < -9)abc[0] = 0x20, abc[1] = 0x2D; // Blank digit 1 spot
else if(i < 0)abc[0] = 0x20, abc[1] = 0x20, abc[2] = 0x2D; // Blank digit 1 spot
else if(i < 10)abc[0] = 0x20, abc[1] = 0x20, abc[2] = 0x20; // Blank digit 2 spot
else if(i < 100)abc[0] = 0x20, abc[1] = 0x20; // Blank digit 1 spot
else if(i < 1000)abc[0] = 0x20; // Blank digit 1 spot
if(j == MGP || j == BAT || j == FPS)abc[4] = abc[3], abc[3] = 0x2E; // Insert decimal (123 = 12.3)
u8x8.drawString(0,2,abc); // Print characters
}// End of drawScreen function
//********************************Variables.h file**************************************
// Variables:
long unsigned int rxId; // CAN Bus Receive Message ID (0x00 - 0x7FF)
unsigned char len; // CAN Bus Receive Message Length (8 bytes)
unsigned char rxBuf[8]; // CAN Bus Receive Buffer array (8 bytes deep)
int ect; // Engine Coolant Temperature
int eot; // Engine Oil Temperature
int tot; // Transmission Oil Temperature
int egt; // Exhaust Gas Temperature
int mgp; // Manifold Guage Pressure (Boost)
int eop; // Engine Oil Pressure
int fps; // Fuel Pressure Sensor
int bat; // Battery Voltage
int ftls; // Fuel Tank Level Sensor
int trs; // Transmission Range Sensor
int old_ect = 1; // Store old Engine Coolant Temperature value, set to 1 so it updates at power on
int old_eot = 1; // Store old Engine Oil Temperature, set to 1 so it updates at power on
int old_tot = 1; // Store old Transmission Oil Temperature, set to 1 so it updates at power on
int old_egt = 1; // Store old Exhaust Gas Temperature, set to 1 so it updates at power on
int old_mgp = 1; // Store old Manifold Guage Pressure (Boost), set to 1 so it updates at power on
int old_eop = 1; // Store old Engine Oil Pressure, set to 1 so it updates at power on
int old_fps = 1; // Store old Fuel Pressure Sensor, set to 1 so it updates at power on
int old_bat = 1; // Store old Battery Voltage value, set to 1 so it updates at power on
int old_ftls = 1; // Store old Fuel Tank Level Sensor, set to 1 so it updates at power on
int old_trs = 1; // Store old Transmission Range Sensor, set to 1 so it updates at power on
// CAN Bus Packets Decode
// EGT1 EGT1 MAP MAP
// Rx ECT EOT TOT HIGH LOW HIGH LOW EOP
byte data422[8] = {0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00}; // should receive every 100mS
//byte data422[8] = {0x81, 0x81, 0x64, 0x03, 0x52, 0x04, 0xE2, 0x2D}; // for testing without CAN network
// FPS FPS BATT BATT
// Rx HIGH LOW HIGH LOW FTLS TRS
byte data423[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // should receive every 100mS
//byte data423[8] = {0x01, 0x5E, 0x05, 0xA0, 0xBF, 0x00, 0x00, 0x00}; // for testing without CAN network
#define can_ect data422[0] // Engine Coolant Temperature
#define can_eot data422[1] // Engine Oil Temperature
#define can_tot data422[2] // Transmission Oil Temperature
#define can_egt_h data422[3] // Exhaust Gas Temperature High Byte
#define can_egt_l data422[4] // Exhaust Gas Temperature Low Byte
#define can_mgp_h data422[5] // Manifold Gauge Pressure High Byte
#define can_mgp_l data422[6] // Manifold Gauge Pressure Low Byte
#define can_eop data422[7] // Engine Oil Pressure
#define can_fps_h data423[0] // Fuel Pressure High Byte
#define can_fps_l data423[1] // Fuel Pressure Low Byte
#define can_bat_h data423[2] // Battery Voltage High Byte
#define can_bat_l data423[3] // Battery Voltage Low Byte
#define can_ftls data423[4] // Fuel Tank Level Percent
#define can_trs data423[5] // Transmission Range Sensor
// End of Variables.h file