In this project i want to have a display to show the information that the car doesnt show me HV battery charge in % and Cº water temp oil temp
Im open for any feedback
#include <mcp2515.h>
#include <SPI.h>
#include <Wire.h>
// Definição dos pinos para o MCP2515
#define CAN_CS_PIN 5 // Chip Select pin
#define CAN_INT_PIN 4 // Interrupt pin
// PIDs Standard OBD-II
#define PID_SPEED 0x0D
#define PID_RPM 0x0C
#define PID_COOLANT 0x05
#define PID_OIL_TEMP 0x5C
#define PID_VOLTAGE 0x42
// PIDs Toyota Hybrid
#define PID_HV_BAT_LEVEL 0x5B
#define PID_HV_BAT_TEMP 0x5C
#define PID_HV_BAT_CURRENT 0x5D
// Inicialização do objeto MCP2515
MCP2515 mcp2515(CAN_CS_PIN);
struct can_frame canMsg;
// Estrutura para armazenar dados do veículo
struct HybridCarData {
int speed; // km/h
int rpm; // RPM
float coolantTemp; // °C
float oilTemp; // °C
float voltage12V; // V
float hvBatteryLevel; // %
float hvBatteryTemp; // °C
float hvBatteryCurrent;// A
} carData;
void setup() {
Serial.begin(115200);
while (!Serial) delay(100);
SPI.begin();
// Inicializa o MCP2515
if (mcp2515.reset() != MCP2515::ERROR_OK) {
Serial.println("Erro ao inicializar MCP2515!");
while (1);
}
mcp2515.setBitrate(CAN_500KBPS);
mcp2515.setNormalMode();
Serial.println("Sistema iniciado com sucesso!");
// Inicializa a estrutura de dados
memset(&carData, 0, sizeof(carData));
}
void requestPID(uint8_t pid) {
struct can_frame frame;
frame.can_id = 0x7DF;
frame.can_dlc = 8;
frame.data[0] = 0x02;
frame.data[1] = 0x01; // Modo 01 standard OBD-II
frame.data[2] = pid;
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
mcp2515.sendMessage(&frame);
delay(50); // Pequeno delay para não sobrecarregar o barramento
}
void requestToyotaHybridData() {
struct can_frame frame;
frame.can_id = 0x7DF;
frame.can_dlc = 8;
frame.data[0] = 0x02;
frame.data[1] = 0x21; // Modo 21 Toyota
frame.data[2] = 0x01; // PID específico Toyota
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
mcp2515.sendMessage(&frame);
delay(50);
}
void processCANMessage(struct can_frame *frame) {
if(frame->can_id == 0x7E8) { // ID típico de resposta OBD-II
uint8_t pid = frame->data[2];
switch(pid) {
case PID_SPEED:
carData.speed = frame->data[3];
Serial.print("Velocidade: ");
Serial.println(carData.speed);
break;
case PID_RPM:
carData.rpm = ((frame->data[3] * 256) + frame->data[4]) / 4;
Serial.print("RPM: ");
Serial.println(carData.rpm);
break;
case PID_COOLANT:
carData.coolantTemp = frame->data[3] - 40;
Serial.print("Temp. Líquido: ");
Serial.println(carData.coolantTemp);
break;
case PID_OIL_TEMP:
carData.oilTemp = frame->data[3] - 40;
Serial.print("Temp. Óleo: ");
Serial.println(carData.oilTemp);
break;
case PID_VOLTAGE:
carData.voltage12V = ((frame->data[3] * 256) + frame->data[4]) / 1000.0;
Serial.print("Tensão 12V: ");
Serial.println(carData.voltage12V);
break;
}
}
}
void requestAllData() {
requestPID(PID_SPEED);
requestPID(PID_RPM);
requestPID(PID_COOLANT);
requestPID(PID_OIL_TEMP);
requestPID(PID_VOLTAGE);
requestToyotaHybridData();
}
void loop() {
static unsigned long lastRequest = 0;
const unsigned long REQUEST_INTERVAL = 1000; // 1 segundo entre requisições
// Faz nova requisição a cada segundo
if (millis() - lastRequest >= REQUEST_INTERVAL) {
requestAllData();
lastRequest = millis();
}
// Verifica se há mensagens disponíveis
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
processCANMessage(&canMsg);
}
}