/*********************************************************************************
* Teensy4.0 + MCP2562 CAN Transceiver + Adafruit OLED
* 500kbps CAN communication speed
* 2021 JAN 30
*
* Service$09 InfoType$04 CALID Read
*
*
********************************************************************************/
#include <FlexCAN_T4.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ADC.h>
#include <ADC_util.h>
#include <Bounce.h> // Bounce library makes button change detection easy
const int channel = 1;
int Req_msgTxid;
int val6, val7, val8, val9;
int Stat_FC=0; // Flow Control request status
int disp_mode;
int seq_Num=0;
int CF_Num;
int CF_Max;
int sid09inftyp=0;
int f_sid09calid_multi;
String str_A;
String dtc_buf6pre;
String calid_buf1, calid_buf2, calid_buf3, calid_buf4, calid_buf5, calid_buf6, calid_buf7, calid_buf8;
String calid_buf9, calid_buf10, calid_buf11, calid_buf12, calid_buf13, calid_buf14, calid_buf15, calid_buf16, calid_buf17;
String cal_buf1, cal_buf2, cal_buf3, cal_buf4, cal_buf5, cal_buf6, cal_buf7, cal_buf8, cal_buf9, cal_buf10;
String cal_buf11,cal_buf12, cal_buf13, cal_buf14, cal_buf15, cal_buf16; // CALID is maximum 16 ASCC characters.
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define NUMFLAKES 10 // Number of snowflakes in the animation example
unsigned long curr, prev, next, interval;
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
CAN_message_t msg;
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000 };
void setup(void) {
prev = 0; // Initialize previous execution time
interval = 1000; // reset execution interval
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
while (!Serial && millis() < 5000);
Serial.begin(115200);
can2.begin();
can2.setBaudRate(500000);
//can2.setMBFilter(REJECT_ALL);
can2.setFIFOFilter(REJECT_ALL);
can2.setFIFOFilter(0, 0x18DAF111, EXT); // Extended CANID Target address F1(Tester), Sender 11(ENG ECU)
can2.setMB(MB10,TX); // Set mailbox as transmit
can2.setMaxMB(16);
can2.mailboxStatus(); // view current configuration
can2.enableFIFO();
can2.enableFIFOInterrupt();
//can2.enableMBInterrupt(MB4);
can2.onReceive(FIFO, canSniff);
}
const long loopDelay1 =500;
unsigned long timeNow1 = 0;
unsigned long timeNow2 = 0;
void loop() {
/*
* Requesting Serivice Identifier routine
*/
if (millis() > timeNow1 + loopDelay1) // Send the request every 100ms
{
timeNow1 = millis();
if(Stat_FC ==0){
can_SID09_TX();
}
}
if(Stat_FC ==1){
delay(10);
can_FC_TX();
}
else if(Stat_FC ==2){
// consider doing something
}
if ( can2.read(msg)) {
Serial.print("CAN2 ");
Serial.print("MB: "); Serial.print(msg.mb);
Serial.print(" ID: 0x"); Serial.print(msg.id, HEX );
Serial.print(" EXT: "); Serial.print(msg.flags.extended );
Serial.print(" LEN: "); Serial.print(msg.len);
Serial.print(" DATA: ");
for ( uint8_t i = 0; i < 8; i++ ) {
Serial.print(msg.buf[i]); Serial.print(" ");
}
Serial.print(" TS: "); Serial.println(msg.timestamp);
}
}
void testdrawchar(void) {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.cp437(true); // Use full 256 char 'Code Page 437' font
// Not all the characters will fit on the display. This is normal.
// Library will draw what it can and the rest will be clipped.
for(int16_t i=0; i<256; i++) {
if(i == '\n') display.write(' ');
else display.write(i);
}
display.display();
}
// Response Message process routine
//
void canSniff (const CAN_message_t &msg){ // Global callback - prints out the received message in HEX + saves TW into a global variable
if(msg.id == 0x18DAF111){
Serial.println(" ");
Serial.print("MB: ");
Serial.print(msg.mb);
Serial.print(" ID: 0x");
Serial.print(msg.id, HEX);
Serial.print(" EXT: ");
Serial.print(msg.flags.extended);
Serial.print(" LEN: ");
Serial.print(msg.len);
Serial.print(" DATA: ");
for (uint8_t i = 0; i < 8; i++)
{
Serial.print(msg.buf[i], HEX);
Serial.print(" ");
}
}
if (msg.buf[0] > 0x0F & msg.buf[2] == 0x49){ // Service$09 Positive Response message and First Frame.
CF_Max = 2;
f_sid09calid_multi = 1; // SID$09 calid process
if(msg.buf[3] == 4){ // Means Info Type == 02 calid. InfoType == 04 CALID.
// ignore msg.buf[4]. because this buffer is always 0x01.Number of data item.
calid_buf1 = msg.buf[5];
calid_buf2 = msg.buf[6];
calid_buf3 = msg.buf[7]; // calid buffer is fixed 17 byte.
Stat_FC = 1;
}
}
else if(f_sid09calid_multi ==1 & msg.buf[0] > 0x20 & Stat_FC ==2 ){ // Means CF: Consecutive Frame and Buf[0] is sequence number
seq_Num = msg.buf[0]; //
if(seq_Num == 0x21){ // Sequence Number is 1.
calid_buf4 = msg.buf[1];
calid_buf5 = msg.buf[2];
calid_buf6 = msg.buf[3];
calid_buf7 = msg.buf[4];
calid_buf8 = msg.buf[5];
calid_buf9 = msg.buf[6];
calid_buf10 = msg.buf[7];
CF_Num = 1;
}
if(seq_Num == 0x22 ){ // Sequence Number is 2.
calid_buf11 = msg.buf[1];
calid_buf12 = msg.buf[2];
calid_buf13 = msg.buf[3];
calid_buf14 = msg.buf[4];
calid_buf15 = msg.buf[5];
calid_buf16 = msg.buf[6];
calid_buf17 = msg.buf[7];
CF_Num = 2;
}
if( CF_Num == CF_Max){
if(Stat_FC == 2){
Stat_FC=0;
CF_Num = 0;
f_sid09calid_multi = 0;
}
}
}
if(msg.id == 0x18DAF111){
display.setTextColor(WHITE);
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("CAN_ID:"));
display.setCursor(60,0);
display.setTextColor(WHITE);
display.print(msg.id, HEX);
}
for ( uint8_t i = 0; i < 8; i++ ) {
display.setCursor(15*i ,15);
display.print(msg.buf[i],HEX); Serial.print(" ");
}
display.display();
display.setCursor(0, 30);
display.print(calid_buf1);
display.setCursor(6, 30);
display.print(calid_buf2);
display.setCursor(12, 30);
display.print(calid_buf3);
display.setCursor(18, 30);
display.print(calid_buf4);
display.setCursor(24, 30);
display.print(calid_buf5);
display.setCursor(30, 30);
display.print(calid_buf6);
display.setCursor(36, 30);
display.print(calid_buf7);
display.setCursor(42, 30);
display.print(calid_buf8);
display.setCursor(48, 30);
display.print(calid_buf9);
display.setCursor(54, 30);
display.print(calid_buf10);
display.setCursor(60, 30);
display.print(calid_buf11);
display.setCursor(66, 30);
display.print(calid_buf12);
display.setCursor(72, 30);
display.print(calid_buf13);
display.setCursor(78, 30);
display.print(calid_buf14);
display.setCursor(84, 30);
display.print(calid_buf15);
display.setCursor(90, 30);
display.print(calid_buf16);
//display.setCursor(96, 30);
//display.print(calid_buf17);
display.display();
}
void can_SID09_TX(){ // Sendo a request to get calid from ECU
CAN_message_t msgTx, msgRx;
msgTx.buf[0] = 0x02;
msgTx.buf[1] = 0x09; // SID$09 Request Info Type$02 calid
msgTx.buf[2] = 0x04; // 02 is Info Type $02 CALID $04
msgTx.buf[3] = 0x55; // 0x55 is padding
msgTx.buf[4] = 0x55;
msgTx.buf[5] = 0x55;
msgTx.buf[6] = 0x55;
msgTx.buf[7] = 0x55;
msgTx.len = 8; // number of bytes in request
msgTx.flags.extended = 1; // 11 bit header, not 29 bit
msgTx.flags.remote = 0;
//msgTx.id = 0x7E0; // requesting Service$09 use only 7E0 for testing Toyota
//msgTx.id = 0x18DA11F1; // Honda
msgTx.id = 0x18DB33F1;
can2.write(msgTx);
}
void can_FC_TX(){ // Flow Control Command
CAN_message_t msgTx, msgRx;
msgTx.buf[0] = 0x30; // Flow Control
msgTx.buf[1] = 0x00; // Block Size
msgTx.buf[2] = 0x00; // STMin
msgTx.buf[3] = 0x00; // Padding
msgTx.buf[4] = 0x00;
msgTx.buf[5] = 0x00;
msgTx.buf[6] = 0x00;
msgTx.buf[7] = 0x00;
msgTx.len = 8; // number of bytes in request
//msgTx.flags.extended = 0; // 11 bit header, not 29 bit
msgTx.flags.extended = 1; // 29 bit header, not 11 bit
msgTx.flags.remote = 0;
//msgTx.id = 0x7E0; // request header for OBD // Physical Addressing Request to Engine ECU
msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
can2.write(msgTx);
Stat_FC = 2; // Flow Control sent
//Serial.println("canTx_OBD FC sent");
}