mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-05 10:49:42 +02:00
Addition of transmit_obd_can_frame and handle_obd_frame functions
- Addition of transmit_obd_can_frame and handle_obd_frame functions - Use dump_can_frame function in comm_can.cpp as well. - Fix code formatting of dump_can_frame function
This commit is contained in:
parent
ce949b2162
commit
7b69f9e9a8
4 changed files with 194 additions and 63 deletions
|
@ -282,38 +282,7 @@ void print_can_frame(CAN_frame frame, frameDirection msgDir) {
|
|||
#endif // DEBUG_CAN_DATA
|
||||
|
||||
if (datalayer.system.info.can_logging_active) { // If user clicked on CAN Logging page in webserver, start recording
|
||||
char* message_string = datalayer.system.info.logged_can_messages;
|
||||
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
|
||||
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
|
||||
|
||||
if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) {
|
||||
// Not enough space, reset and start from the beginning
|
||||
offset = 0;
|
||||
}
|
||||
unsigned long currentTime = millis();
|
||||
// Add timestamp
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "(%lu.%03lu) ", currentTime / 1000,
|
||||
currentTime % 1000);
|
||||
|
||||
// Add direction. The 0 and 1 after RX and TX ensures that SavvyCAN puts TX and RX in a different bus.
|
||||
offset +=
|
||||
snprintf(message_string + offset, message_string_size - offset, "%s ", (msgDir == MSG_RX) ? "RX0" : "TX1");
|
||||
|
||||
// Add ID and DLC
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%X [%u] ", frame.ID, frame.DLC);
|
||||
|
||||
// Add data bytes
|
||||
for (uint8_t i = 0; i < frame.DLC; i++) {
|
||||
if (i < frame.DLC - 1) {
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%02X ", frame.data.u8[i]);
|
||||
} else {
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%02X", frame.data.u8[i]);
|
||||
}
|
||||
}
|
||||
// Add linebreak
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "\n");
|
||||
|
||||
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
|
||||
dump_can_frame(frame, msgDir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,37 +320,37 @@ void map_can_frame_to_variable(CAN_frame* rx_frame, int interface) {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
void dump_frame(CAN_frame &frame, frameDirection msgDir){
|
||||
char* message_string = datalayer.system.info.logged_can_messages;
|
||||
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
|
||||
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
|
||||
void dump_can_frame(CAN_frame &frame, frameDirection msgDir) {
|
||||
char* message_string = datalayer.system.info.logged_can_messages;
|
||||
int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
|
||||
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
|
||||
|
||||
if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) {
|
||||
// Not enough space, reset and start from the beginning
|
||||
offset = 0;
|
||||
if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) {
|
||||
// Not enough space, reset and start from the beginning
|
||||
offset = 0;
|
||||
}
|
||||
unsigned long currentTime = millis();
|
||||
// Add timestamp
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "(%lu.%03lu) ", currentTime / 1000,
|
||||
currentTime % 1000);
|
||||
|
||||
// Add direction. The 0 and 1 after RX and TX ensures that SavvyCAN puts TX and RX in a different bus.
|
||||
offset +=
|
||||
snprintf(message_string + offset, message_string_size - offset, "%s ", (msgDir == MSG_RX) ? "RX0" : "TX1");
|
||||
|
||||
// Add ID and DLC
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%X [%u] ", frame.ID, frame.DLC);
|
||||
|
||||
// Add data bytes
|
||||
for (uint8_t i = 0; i < frame.DLC; i++) {
|
||||
if (i < frame.DLC - 1) {
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%02X ", frame.data.u8[i]);
|
||||
} else {
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%02X", frame.data.u8[i]);
|
||||
}
|
||||
unsigned long currentTime = millis();
|
||||
// Add timestamp
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "(%lu.%03lu) ", currentTime / 1000,
|
||||
currentTime % 1000);
|
||||
}
|
||||
// Add linebreak
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "\n");
|
||||
|
||||
// Add direction. The 0 and 1 after RX and TX ensures that SavvyCAN puts TX and RX in a different bus.
|
||||
offset +=
|
||||
snprintf(message_string + offset, message_string_size - offset, "%s ", (msgDir == MSG_RX) ? "RX0" : "TX1");
|
||||
|
||||
// Add ID and DLC
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%X [%u] ", frame.ID, frame.DLC);
|
||||
|
||||
// Add data bytes
|
||||
for (uint8_t i = 0; i < frame.DLC; i++) {
|
||||
if (i < frame.DLC - 1) {
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%02X ", frame.data.u8[i]);
|
||||
} else {
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "%02X", frame.data.u8[i]);
|
||||
}
|
||||
}
|
||||
// Add linebreak
|
||||
offset += snprintf(message_string + offset, message_string_size - offset, "\n");
|
||||
|
||||
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
|
||||
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "../../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h"
|
||||
#endif //CANFD_ADDON
|
||||
|
||||
void dump_frame(CAN_frame &frame, frameDirection msgDir);
|
||||
void dump_can_frame(CAN_frame &frame, frameDirection msgDir);
|
||||
|
||||
/**
|
||||
* @brief Initialization function for CAN.
|
||||
|
|
151
Software/src/communication/can/obd.cpp
Normal file
151
Software/src/communication/can/obd.cpp
Normal file
|
@ -0,0 +1,151 @@
|
|||
#include "obd.h"
|
||||
#include "comm_can.h"
|
||||
|
||||
void show_dtc(uint8_t byte0, uint8_t byte1);
|
||||
|
||||
void show_dtc(uint8_t byte0, uint8_t byte1) {
|
||||
char letter;
|
||||
switch (byte0 >> 6){
|
||||
case 0:
|
||||
letter = 'P';
|
||||
break;
|
||||
case 1:
|
||||
letter = 'C';
|
||||
break;
|
||||
case 2:
|
||||
letter = 'B';
|
||||
break;
|
||||
case 3:
|
||||
letter = 'U';
|
||||
break;
|
||||
}
|
||||
logging.printf("%c%d\n", letter, ((byte0 & 0x3F) << 8) | byte1);
|
||||
}
|
||||
|
||||
void handle_obd_frame(CAN_frame &rx_frame) {
|
||||
if (rx_frame.data.u8[1] == 0x7F) {
|
||||
const char *error_str = "?";
|
||||
switch (rx_frame.data.u8[3]) { // See https://automotive.wiki/index.php/ISO_14229
|
||||
case 0x10:
|
||||
error_str = "generalReject";
|
||||
break;
|
||||
case 0x11:
|
||||
error_str = "serviceNotSupported";
|
||||
break;
|
||||
case 0x12:
|
||||
error_str = "subFunctionNotSupported";
|
||||
break;
|
||||
case 0x13:
|
||||
error_str = "incorrectMessageLengthOrInvalidFormat";
|
||||
break;
|
||||
case 0x14:
|
||||
error_str = "responseTooLong";
|
||||
break;
|
||||
case 0x21:
|
||||
error_str = "busyRepeatReques";
|
||||
break;
|
||||
case 0x22:
|
||||
error_str = "conditionsNotCorrect";
|
||||
break;
|
||||
case 0x24:
|
||||
error_str = "requestSequenceError";
|
||||
break;
|
||||
case 0x31:
|
||||
error_str = "requestOutOfRange";
|
||||
break;
|
||||
case 0x33:
|
||||
error_str = "securityAccessDenied";
|
||||
break;
|
||||
case 0x35:
|
||||
error_str = "invalidKey";
|
||||
break;
|
||||
case 0x36:
|
||||
error_str = "exceedNumberOfAttempts";
|
||||
break;
|
||||
case 0x37:
|
||||
error_str = "requiredTimeDelayNotExpired";
|
||||
break;
|
||||
case 0x70:
|
||||
error_str = "uploadDownloadNotAccepted";
|
||||
break;
|
||||
case 0x71:
|
||||
error_str = "transferDataSuspended";
|
||||
break;
|
||||
case 0x72:
|
||||
error_str = "generalProgrammingFailure";
|
||||
break;
|
||||
case 0x73:
|
||||
error_str = "wrongBlockSequenceCounter";
|
||||
break;
|
||||
case 0x78:
|
||||
error_str = "requestCorrectlyReceived-ResponsePending";
|
||||
break;
|
||||
case 0x7E:
|
||||
error_str = "subFunctionNotSupportedInActiveSession";
|
||||
break;
|
||||
case 0x7F:
|
||||
error_str = "serviceNotSupportedInActiveSession";
|
||||
break;
|
||||
|
||||
}
|
||||
logging.printf("ODB reply Request for service 0x%02X: %s\n", rx_frame.data.u8[2], error_str);
|
||||
} else {
|
||||
switch (rx_frame.data.u8[1] & 0x3F) {
|
||||
case 3:
|
||||
logging.printf("ODB reply service 03: Show stored DTCs, %d present:\n", rx_frame.data.u8[2]);
|
||||
for (int i = 0; i < rx_frame.data.u8[2]; i++)
|
||||
show_dtc(rx_frame.data.u8[3+2*i], rx_frame.data.u8[4+2*i]);
|
||||
break;
|
||||
case 7:
|
||||
logging.printf("ODB reply service 07: Show pending DTCs, %d present:\n", rx_frame.data.u8[2]);
|
||||
for (int i = 0; i < rx_frame.data.u8[2]; i++)
|
||||
show_dtc(rx_frame.data.u8[3+2*i], rx_frame.data.u8[4+2*i]);
|
||||
break;
|
||||
default:
|
||||
logging.printf("ODBx reply frame received:\n");
|
||||
}
|
||||
}
|
||||
dump_can_frame(rx_frame, MSG_RX);
|
||||
}
|
||||
|
||||
void transmit_obd_can_frame(unsigned int address, int interface){
|
||||
static CAN_frame OBD_frame = {.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x700,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
OBD_frame.ID = address;
|
||||
OBD_frame.ext_ID = address > 0x7FF;
|
||||
OBD_frame.DLC = 8;
|
||||
OBD_frame.data.u8[0]=0x01;
|
||||
OBD_frame.data.u8[1]=0x03;
|
||||
OBD_frame.data.u8[2]=0xAA;
|
||||
OBD_frame.data.u8[3]=0xAA;
|
||||
OBD_frame.data.u8[4]=0xAA;
|
||||
OBD_frame.data.u8[5]=0xAA;
|
||||
OBD_frame.data.u8[6]=0xAA;
|
||||
OBD_frame.data.u8[7]=0xAA;
|
||||
static int cnt = 0;
|
||||
switch (cnt) {
|
||||
case 2:
|
||||
transmit_can_frame(&OBD_frame, interface); // DTC TP-ISO
|
||||
break;
|
||||
case 3:
|
||||
OBD_frame.data.u8[1]=0x07;
|
||||
transmit_can_frame(&OBD_frame, interface); // DTC TP-ISO
|
||||
break;
|
||||
case 4:
|
||||
OBD_frame.data.u8[1]=0x0A;
|
||||
transmit_can_frame(&OBD_frame, interface); // DTC TP-ISO
|
||||
break;
|
||||
case 5:
|
||||
OBD_frame.data.u8[0]=0x02;
|
||||
OBD_frame.data.u8[1]=0x01;
|
||||
OBD_frame.data.u8[2]=0x1C;
|
||||
transmit_can_frame(&OBD_frame, interface); // DTC TP-ISO
|
||||
break;
|
||||
}
|
||||
cnt++;
|
||||
if (cnt == 3600)
|
||||
cnt = 0;
|
||||
}
|
11
Software/src/communication/can/obd.h
Normal file
11
Software/src/communication/can/obd.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef _OBD_H_
|
||||
#define _OBD_H_
|
||||
|
||||
#include "../../include.h"
|
||||
#include "../../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
|
||||
|
||||
void handle_obd_frame(CAN_frame &rx_frame);
|
||||
|
||||
void transmit_obd_can_frame(unsigned int address, int interface);
|
||||
|
||||
#endif // _OBD_H_
|
Loading…
Add table
Add a link
Reference in a new issue