Skip to content

Commit

Permalink
Merge pull request #916 from KommyKT/master
Browse files Browse the repository at this point in the history
Mitsubishi update
  • Loading branch information
dexterbg committed Jun 18, 2023
2 parents 5573c83 + 8f37874 commit b6c10a5
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 76 deletions.
204 changes: 136 additions & 68 deletions vehicle/OVMS.V3/components/vehicle_mitsubishi/src/mi_can_poll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,82 +25,173 @@
#include "vehicle_mitsubishi.h"

static const char *TAGPOLL = "v-trio-poll";

#define RXB_BYTE(b) m_rxbuf[b]
#define RXB_UINT16(b) (((uint16_t)RXB_BYTE(b) << 8) | RXB_BYTE(b+1))
#define RXB_UINT24b(b) (((uint32_t)RXB_BYTE(b+2) << 16) | ((uint32_t)RXB_BYTE(b+1) << 8) \
| RXB_BYTE(b))
/**
* Incoming poll reply messages
*/
void OvmsVehicleMitsubishi::IncomingPollReply(canbus* bus, uint16_t type, uint16_t pid, uint8_t* data, uint8_t length, uint16_t mlremain)
{
//ESP_LOGW(TAGPOLL, "%03" PRIx32 " TYPE:%x PID:%02x Data:%02x %02x %02x %02x %02x %02x %02x %02x LENG:%02x REM:%02x", m_poll_moduleid_low, type, pid, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], length, mlremain);
// init / fill rx buffer:
if (m_poll_ml_frame == 0)
{
m_rxbuf.clear();
m_rxbuf.reserve(length + mlremain);
}

m_rxbuf.append((char*)data, length);

if (mlremain)
return;

ESP_LOGV(TAGPOLL, "IncomingPollReply: PID %02X: len=%d %s", pid, m_rxbuf.size(), hexencode(m_rxbuf).c_str());
//OvmsVehicleMitsubishi* trio = (OvmsVehicleMitsubishi*) MyVehicleFactory.ActiveVehicle();
switch (m_poll_moduleid_low)
{
// ****** BMU *****
case 0x762:
{
switch (m_poll_ml_frame) {
case 0:
{
OvmsMetricFloat* xmi_bat_soc_real = MyMetrics.InitFloat("xmi.b.soc.real", 10, 0, Percentage);
xmi_bat_soc_real->SetValue((data[0] * 0.5) - 5);

// displayed SOC
OvmsMetricFloat* xmi_bat_soc_display = MyMetrics.InitFloat("xmi.b.soc.display", 10, 0, Percentage);
xmi_bat_soc_display->SetValue((data[1] * 0.5) - 5);
break;
if(pid == 0x01)
{
OvmsMetricFloat* xmi_bat_soc_real = MyMetrics.InitFloat("xmi.b.soc.real", 10, 0, Percentage);
xmi_bat_soc_real->SetValue((RXB_BYTE(0) * 0.5) - 5);

// displayed SOC
OvmsMetricFloat* xmi_bat_soc_display = MyMetrics.InitFloat("xmi.b.soc.display", 10, 0, Percentage);
xmi_bat_soc_display->SetValue((RXB_BYTE(1) * 0.5) - 5);

// battery "max" capacity
StandardMetrics.ms_v_bat_cac->SetValue((RXB_UINT16(27) * 0.1f));

// battery remain capacity
ms_v_bat_cac_rem->SetValue((RXB_UINT16(29) * 0.1f));

//max charging kW
ms_v_bat_max_input->SetValue(RXB_BYTE(31)* 0.25);

//max output kW
ms_v_bat_max_output->SetValue(RXB_BYTE(32) * 0.25);
}

/*
Battery cell voltage
Miev: 88cell voltage, 24 bit blocks 16 bit voltage date,
*/

if(pid == 0x02 && !has_broadcast)
{
BmsRestartCellVoltages();

for (int i = 0; i < 16; i+=2) {
BmsSetCellVoltage(i/2, (RXB_UINT16(0+i) * 0.001f));
}

case 4:
{
// battery "max" capacity
StandardMetrics.ms_v_bat_cac->SetValue(((data[2] * 256.0 + data[3]) / 10.0));
int j = 0;
for (int i = 24; i < 40; i+=2) {
BmsSetCellVoltage(j+8, (RXB_UINT16(0+i) * 0.001f));
j++;
}

// battery remain capacity
ms_v_bat_cac_rem->SetValue(((data[4] * 256.0 + data[5]) * 0.1));
j = 0;
for (int i = 48; i < 64; i+=2) {
BmsSetCellVoltage(j+16, (RXB_UINT16(0+i) * 0.001f));
j++;
}

//max charging kW
ms_v_bat_max_input->SetValue(data[6] * 0.25);
break;
j = 0;
for (int i = 72; i < 88; i+=2) {
BmsSetCellVoltage(j+24, (RXB_UINT16(0+i) * 0.001f));
j++;
}

case 5:
{
//max output kW
ms_v_bat_max_output->SetValue(data[0] * 0.25);
break;
j = 0;
for (int i = 96; i < 112; i+=2) {
BmsSetCellVoltage(j+32, (RXB_UINT16(0+i) * 0.001f));
j++;
}

j = 0;
for (int i = 120; i < 128; i+=2) {
BmsSetCellVoltage(j+40, (RXB_UINT16(0+i) * 0.001f));
j++;
}

j = 0;
for (int i = 144; i < 160; i+=2) {
BmsSetCellVoltage(j+44, (RXB_UINT16(0+i) * 0.001f));
j++;
}

j = 0;
for (int i = 168; i < 184; i+=2) {
BmsSetCellVoltage(j+52, (RXB_UINT16(0+i) * 0.001f));
j++;
}

j = 0;
for (int i = 192; i < 208; i+=2) {
BmsSetCellVoltage(j+60, (RXB_UINT16(0+i) * 0.001f));
j++;
}

j = 0;
for (int i = 216; i < 232; i+=2) {
BmsSetCellVoltage(j+68, (RXB_UINT16(0+i) * 0.001f));
j++;
}

j = 0;
for (int i = 240; i < 256; i+=2) {
BmsSetCellVoltage(j+76, (RXB_UINT16(0+i) * 0.001f));
j++;
}
j = 0;
for (int i = 264; i < 272; i+=2) {
BmsSetCellVoltage(j+84, (RXB_UINT16(0+i) * 0.001f));
j++;
}
}

/*
Battery cell temperature
72 bit 66 cell temp after first 33 bit (cell temp) 3 fe bit
*/

if(pid == 0x03 && !has_broadcast)
{
BmsRestartCellTemperatures();
for (int i = 0; i < 33; i++) {
BmsSetCellTemperature(i, (RXB_BYTE(i) - 50.0));
ESP_LOGV(TAGPOLL, " %i cell temp: %0f",i, RXB_BYTE(i) - 50.0f);
}
for (int i = 36; i < 69; i++) {
BmsSetCellTemperature(33+i-36, (RXB_BYTE(i) - 50.0));
ESP_LOGV(TAGPOLL, " %i cell temp: %0f",33+i-36, RXB_BYTE(i) - 50.0f);
}
default:
break;
}
break;
}

// ****** OBC *****
case 0x766:
{
//ESP_LOGW(TAGPOLL, "%03" PRIx32 " TYPE:%x PID:%02x Data:%02x %02x %02x %02x %02x %02x %02x %02x LENG:%02x REM:%02x", m_poll_moduleid_low, type, pid, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], length, mlremain);
ESP_LOGV(TAGPOLL, "%03" PRIx32 " TYPE:%x PID:%02x Data:%02x %02x %02x %02x %02x %02x %02x %02x LENG:%02x REM:%02x", m_poll_moduleid_low, type, pid, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], length, mlremain);
break;
}

// ****** HVAC *****
case 0x772:
{
switch (m_poll_ml_frame) {
case 0:
{
StandardMetrics.ms_v_env_cabintemp->SetValue((data[0] * 0.25) - 16.0);
break;
}

case 1:
{
//StandardMetrics.ms_v_env_temp->SetValue((data[0] * 0.3) - 29.0);
break;
}
default:
break;
if(pid == 0x13)
{
StandardMetrics.ms_v_env_cabintemp->SetValue((RXB_BYTE(2) * 0.25) - 16.0);
StandardMetrics.ms_v_env_temp->SetValue((RXB_BYTE(4) * 0.3) - 29.0);
ESP_LOGI(TAGPOLL, "IntTempSen: %0f, AmbTempContr: %0f, AmbTempCan: %0f, AirTempSen: %0f, WaterTemp_HVAC: %0f", (RXB_BYTE(2) * 0.25) - 16.0, (RXB_BYTE(3) * 0.5) - 40.0, (RXB_BYTE(4) * 0.3) - 29.0, (RXB_BYTE(5) * 0.25) - 16.0,(RXB_BYTE(6) * 0.6) - 40.0);
}

break;
}

Expand All @@ -109,37 +200,14 @@ void OvmsVehicleMitsubishi::IncomingPollReply(canbus* bus, uint16_t type, uint16
{
if(pid == 0xCE)
{
switch (m_poll_ml_frame) {
case 0:
{
ms_v_trip_A->SetValue(((data[2] << 16 ) + (data[1] << 8) + data[0]) * 0.1, Kilometers);
tripb += data[3];
break;
}

case 1:
{
tripb += (data[1] << 16 ) + (data[0] << 8);
if((tripb * 0.1) > 0.1){
ms_v_trip_B->SetValue(tripb * 0.1, Kilometers);
has_trip = true;
}
else
{
has_trip = false;
}
tripb = 0.0;
break;
}
default:
break;
}
ms_v_trip_A->SetValue(RXB_UINT24b(0) * 0.1, Kilometers);
ms_v_trip_B->SetValue(RXB_UINT24b(3) * 0.1, Kilometers);
}
break;
}

default:
ESP_LOGW(TAGPOLL, "Unknown module: %03" PRIx32, m_poll_moduleid_low);
ESP_LOGV(TAGPOLL, "Unknown module: %03" PRIx32, m_poll_moduleid_low);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@
; - Fix charge metrics if crash during charge session
; 1.0.15
; - Add support for trip distance from speed
; 1.0.16
; - Add DC-DC current as 12v battery current (only on newer cars)
; 1.0.17
; - swap xmi.b.power.min/max
; 1.0.18
; - Add RX buffer for polling
; 1.0.19
; - Add Voltage/temp reading to newer cars that not broadcast it
; 1.0.20
; - Add environment temperature, and modify poll timers
;
; (C) 2011 Michael Stegen / Stegen Electronics
; (C) 2011-2018 Mark Webb-Johnson
Expand Down Expand Up @@ -106,7 +116,7 @@
#include "ovms_notify.h"
#include <sys/param.h>

#define VERSION "1.0.15"
#define VERSION "1.0.20"

static const char *TAG = "v-mitsubishi";

Expand All @@ -116,8 +126,10 @@ static const char *TAG = "v-mitsubishi";
static const OvmsVehicle::poll_pid_t vehicle_mitsubishi_polls[] =
{
{ 0x761, 0x762, VEHICLE_POLL_TYPE_OBDIIGROUP, 0x01, { 0, 10, 10 }, 0, ISOTP_STD }, // cac
{ 0x765, 0x766, VEHICLE_POLL_TYPE_OBDIIGROUP, 0x01, { 0, 10, 0 }, 0, ISOTP_STD }, // OBC
{ 0x771, 0x772, VEHICLE_POLL_TYPE_OBDIIGROUP, 0x13, { 0, 10, 10 }, 0, ISOTP_STD }, //external/internal temp
{ 0x761, 0x762, VEHICLE_POLL_TYPE_OBDIIGROUP, 0x02, { 0, 1, 1 }, 0, ISOTP_STD }, // cell voltage
{ 0x761, 0x762, VEHICLE_POLL_TYPE_OBDIIGROUP, 0x03, { 0, 1, 1 }, 0, ISOTP_STD }, // cell temp
{ 0x765, 0x766, VEHICLE_POLL_TYPE_OBDIIGROUP, 0x01, { 0, 1, 0 }, 0, ISOTP_STD }, // OBC
{ 0x771, 0x772, VEHICLE_POLL_TYPE_OBDIIGROUP, 0x13, { 0, 1, 1 }, 0, ISOTP_STD }, //external/internal temp
{ 0x782, 0x783, VEHICLE_POLL_TYPE_OBDIIGROUP, 0xCE, { 0, 5, 0 }, 0, ISOTP_STD }, //Trip A/B
POLL_LIST_END
};
Expand All @@ -137,7 +149,6 @@ OvmsVehicleMitsubishi::OvmsVehicleMitsubishi()
StandardMetrics.ms_v_charge_inprogress->SetAutoStale(30); //Set autostale to 30 second

set_odo = false;
has_trip = false;
mi_SC = false;

m_odo_trip = 0;
Expand Down Expand Up @@ -422,10 +433,10 @@ void OvmsVehicleMitsubishi::IncomingFrameCan1(CAN_frame_t* p_frame)
}

//min power
if (v_b_power_max->AsFloat() > StandardMetrics.ms_v_bat_power->AsFloat())
if (v_b_power_max->AsFloat() < StandardMetrics.ms_v_bat_power->AsFloat())
v_b_power_max->SetValue(StandardMetrics.ms_v_bat_power->AsFloat());
//max power
if (v_b_power_min->AsFloat() < StandardMetrics.ms_v_bat_power->AsFloat())
if (v_b_power_min->AsFloat() > StandardMetrics.ms_v_bat_power->AsFloat())
v_b_power_min->SetValue(StandardMetrics.ms_v_bat_power->AsFloat());

break;
Expand All @@ -439,6 +450,17 @@ void OvmsVehicleMitsubishi::IncomingFrameCan1(CAN_frame_t* p_frame)
break;
}

case 0x377://freq10 // DC-DC Converter
{
if(d[2] != 255 && d[3] != 255 )
{
StandardMetrics.ms_v_bat_12v_current->SetValue(((d[2] << 8) + d[3]) * 0.1);
}else{
StandardMetrics.ms_v_bat_12v_current->SetValue(0);
}
break;
}

case 0x384://freq10 //heating current
{
ms_v_env_heating_amp->SetValue(d[4] * 0.1);
Expand Down Expand Up @@ -701,6 +723,7 @@ void OvmsVehicleMitsubishi::IncomingFrameCan1(CAN_frame_t* p_frame)
case 0x6e3:
case 0x6e4:
{
has_broadcast = true;
//Pid index 0-3
int pid_index = (p_frame->MsgID) - 1761;
//cmu index 1-12: ignore high order nybble which appears to sometimes contain other status bits
Expand Down Expand Up @@ -919,7 +942,7 @@ void OvmsVehicleMitsubishi::vehicle_mitsubishi_car_on(bool isOn)
ms_v_trip_park_heating_kwh->SetValue(0);
ms_v_trip_park_ac_kwh->SetValue(0);
ms_v_trip_park_time_start->SetValue(StdMetrics.ms_m_timeutc->AsInt());
if(has_trip == true && StandardMetrics.ms_v_bat_soc->AsFloat() > 0.0)
if(StandardMetrics.ms_v_bat_soc->AsFloat() > 0.0)
{
ResetTripOdo();
//mi_park_trip_counter.Reset(ms_v_trip_B->AsFloat());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class OvmsVehicleMitsubishi : public OvmsVehicle
protected:

OvmsCommand *cmd_xmi;
std::string m_rxbuf;

public:
virtual vehicle_command_t CommandStat(int verbosity, OvmsWriter* writer);
Expand Down Expand Up @@ -161,7 +162,7 @@ class OvmsVehicleMitsubishi : public OvmsVehicle

bool has_odo;
bool set_odo;
bool has_trip;
bool has_broadcast = false;

// Trip length & SOC/energy consumption:
void ResetTripOdo();
Expand Down

0 comments on commit b6c10a5

Please sign in to comment.