Skip to content

Commit

Permalink
Merge pull request #984 from Dimitrie78/SmartED
Browse files Browse the repository at this point in the history
SmartED 451
  • Loading branch information
dexterbg committed Mar 29, 2024
2 parents b4c70ce + f17a69e commit a28765a
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 43 deletions.
104 changes: 70 additions & 34 deletions vehicle/OVMS.V3/components/vehicle_smarted/src/ed_can_poll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,18 @@ static const char *TAG = "v-smarted";

static const OvmsPoller::poll_pid_t smarted_polls[] =
{
// Note: poller ticker cycles at 3600 seconds = max period
// { tx, rx, type, pid, {OFF,AWAKE,ON,CHARGING}, bus, protocol }
{ 0x61A, 0x483, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0xF111, { 0,300,600,600 }, 0, ISOTP_STD }, // rqChargerPN_HW
{ 0x61A, 0x483, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0226, { 0,300,0,3 }, 0, ISOTP_STD }, // rqChargerVoltages
{ 0x61A, 0x483, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0225, { 0,300,0,3 }, 0, ISOTP_STD }, // rqChargerAmps
{ 0x61A, 0x483, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x022A, { 0,300,0,60 }, 0, ISOTP_STD }, // rqChargerSelCurrent
{ 0x61A, 0x483, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0223, { 0,300,0,60 }, 0, ISOTP_STD }, // rqChargerTemperatures
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0xF190, { 0,300,600,600 }, 0, ISOTP_STD }, // rqBattVIN
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0208, { 0,300,600,60 }, 0, ISOTP_STD }, // rqBattVolts
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0310, { 0,300,600,60 }, 0, ISOTP_STD }, // rqBattCapacity
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0203, { 0,300,600,600 }, 0, ISOTP_STD }, // rqBattAmps
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0207, { 0,300,600,600 }, 0, ISOTP_STD }, // rqBattADCref
// { 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0208, { 0,60,60,60 }, 0, ISOTP_STD }, // rqBattVolts
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0310, { 0,60,60,60 }, 0, ISOTP_STD }, // rqBattCapacity
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0203, { 0,60,60,60 }, 0, ISOTP_STD }, // rqBattAmps
// { 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0207, { 0,60,60,60 }, 0, ISOTP_STD }, // rqBattADCref
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0304, { 0,300,600,600 }, 0, ISOTP_STD }, // rqBattDate
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0xF18C, { 0,300,600,600 }, 0, ISOTP_STD }, // rqBattProdDate
//getBatteryRevision
Expand Down Expand Up @@ -133,7 +135,6 @@ static const OvmsPoller::poll_pid_t smarted_polls[] =
{ 0x7E5, 0x7ED, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x2041, { 0,3600,3600,120 }, 0, ISOTP_STD }, // rqVacuumPumpPress1
{ 0x7E5, 0x7ED, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x2043, { 0,3600,3600,120 }, 0, ISOTP_STD }, // rqVacuumPumpPress2
{ 0x7E5, 0x7ED, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x6308, { 0,3600,3600,300 }, 0, ISOTP_STD }, // DT_Batterie_Alterszustand
POLL_LIST_END
};

void OvmsVehicleSmartED::ObdInitPoll() {
Expand Down Expand Up @@ -236,12 +237,6 @@ void OvmsVehicleSmartED::ObdInitPoll() {
BmsSetCellDefaultThresholdsVoltage(0.030, 0.050);
BmsSetCellDefaultThresholdsTemperature(4.0, 5.0);

// init poller:
PollSetPidList(m_can1, smarted_polls);
PollSetState(0);
PollSetThrottling(5);
PollSetResponseSeparationTime(10);

// init commands:
OvmsCommand* cmd;
OvmsCommand* obd;
Expand All @@ -253,6 +248,35 @@ void OvmsVehicleSmartED::ObdInitPoll() {
cmd->RegisterCommand("getvolts", "Send OBD2 request to get Cell Volts", shell_obd_request);
}

void OvmsVehicleSmartED::ObdModifyPoll() {
OvmsRecMutexLock lock(&m_poll_mutex);

PollSetPidList(m_can1, NULL);
PollSetState(0);
PollSetThrottling(5);
PollSetResponseSeparationTime(10);

// modify Poller..
m_poll_vector.clear();
// Add PIDs to poll list:
m_poll_vector.insert(m_poll_vector.end(), smarted_polls, endof_array(smarted_polls));
m_poll_vector.insert(m_poll_vector.end(), {
{ 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0207, { 0,60,60,60 }, 0, ISOTP_STD },
});

OvmsPoller::poll_pid_t p = { 0x7E7, 0x7EF, VEHICLE_POLL_TYPE_OBDIIEXTENDED, 0x0208, { 0,0,0,0 }, 0, ISOTP_STD };
p.polltime[1] = m_cfg_cell_interval_awk;
p.polltime[2] = m_cfg_cell_interval_drv;
p.polltime[3] = m_cfg_cell_interval_chg;
m_poll_vector.push_back(p);

// Terminate poll list:
m_poll_vector.push_back(POLL_LIST_END);
ESP_LOGI(TAG, "Poll vector: size=%d cap=%d", m_poll_vector.size(), m_poll_vector.capacity());

PollSetPidList(m_can1, m_poll_vector.data());
}

/**
* Incoming poll reply messages
*/
Expand Down Expand Up @@ -477,7 +501,7 @@ int OvmsVehicleSmartED::ObdRequest(uint16_t txid, uint16_t rxid, string request,

// restore default polling:
smarted_obd_rxwait.Give();
PollSetPidList(m_can1, smarted_polls);
PollSetPidList(m_can1, m_poll_vector.data());

return (rxok == pdFALSE) ? -1 : (int)smarted_obd_rxerr;
}
Expand Down Expand Up @@ -512,12 +536,6 @@ void OvmsVehicleSmartED::PollReply_BMS_BattADCref(const char* reply_data, uint16
mt_myBMS_ADCCvolts_mean->SetValue(reply_data[4] * 256 + reply_data[5]);
mt_myBMS_ADCCvolts_min->SetValue(reply_data[2] * 256 + reply_data[3] + 1500);
mt_myBMS_ADCCvolts_max->SetValue(reply_data[0] * 256 + reply_data[1] + 1500);

if (RAW_VOLTAGES) {
mt_myBMS_ADCvoltsOffset->SetValue(0);
} else {
mt_myBMS_ADCvoltsOffset->SetValue(StdMetrics.ms_v_bat_pack_vavg->AsFloat()*1000 - mt_myBMS_ADCCvolts_mean->AsInt());
}
}

void OvmsVehicleSmartED::PollReply_BMS_BattDate(const char* reply_data, uint16_t reply_len) {
Expand Down Expand Up @@ -581,24 +599,42 @@ void OvmsVehicleSmartED::PollReply_BMS_ModuleTemp(const char* reply_data, uint16
}

void OvmsVehicleSmartED::PollReply_BMS_BattVolts(const char* reply_data, uint16_t reply_len) {
double sum=0, avg;
for(uint16_t n = 0; n < (CELLCOUNT * 2); n = n + 2){
float Cells = (reply_data[n] * 256 + reply_data[n + 1]);
BmsSetCellVoltage(n/2, Cells/1000);
m_bms_raw_voltages[n/2] = Cells/1000;
//BmsSetCellVoltage(n/2, Cells/1000);
sum += Cells/1000;
}
avg = sum / CELLCOUNT;
m_bms_bat_pack_avg = ROUNDPREC(avg, 5);

if (RAW_VOLTAGES) {
mt_myBMS_ADCvoltsOffset->SetValue(0);
} else if (mt_myBMS_ADCCvolts_mean->AsInt() > 0) {
mt_myBMS_ADCvoltsOffset->SetValue(m_bms_bat_pack_avg*1000 - mt_myBMS_ADCCvolts_mean->AsInt());
}
float min=0, max=0;
int cmin=0, cmax=0;
for(int i = 0; i < StdMetrics.ms_v_bat_cell_voltage->GetSize(); i++) {
if (min==0 || StdMetrics.ms_v_bat_cell_voltage->GetElemValue(i)<min) {
min = StdMetrics.ms_v_bat_cell_voltage->GetElemValue(i);
cmin = i+1;

if (mt_myBMS_ADCCvolts_mean->AsInt() > 0) {
float min=0, max=0;
int cmin=0, cmax=0;

for(int i = 0; i < CELLCOUNT; i++) {
BmsSetCellVoltage(i, m_bms_raw_voltages[i] - (mt_myBMS_ADCvoltsOffset->AsFloat()/1000));
}
if (max==0 || StdMetrics.ms_v_bat_cell_voltage->GetElemValue(i)>max) {
max = StdMetrics.ms_v_bat_cell_voltage->GetElemValue(i);
cmax = i+1;
for(int i = 0; i < StdMetrics.ms_v_bat_cell_voltage->GetSize(); i++) {
if (min==0 || StdMetrics.ms_v_bat_cell_voltage->GetElemValue(i)<min) {
min = StdMetrics.ms_v_bat_cell_voltage->GetElemValue(i);
cmin = i+1;
}
if (max==0 || StdMetrics.ms_v_bat_cell_voltage->GetElemValue(i)>max) {
max = StdMetrics.ms_v_bat_cell_voltage->GetElemValue(i);
cmax = i+1;
}
}
mt_v_bat_pack_cmin_cell_volt->SetValue(cmin);
mt_v_bat_pack_cmax_cell_volt->SetValue(cmax);
}
mt_v_bat_pack_cmin_cell_volt->SetValue(cmin);
mt_v_bat_pack_cmax_cell_volt->SetValue(cmax);
}

void OvmsVehicleSmartED::PollReply_BMS_BattCapacity(const char* reply_data, uint16_t reply_len) {
Expand Down Expand Up @@ -1057,16 +1093,16 @@ void OvmsVehicleSmartED::BmsDiag(int verbosity, OvmsWriter* writer) {

writer->puts(" # ;mV ;As/10");
for(int16_t n = 0; n < CELLCOUNT; n++){
writer->printf("%3d; %4.0f; %5.0f\n", n+1, m_bms_voltages[n]*1000 - mt_myBMS_ADCvoltsOffset->AsInt(), m_bms_capacitys[n]);
writer->printf("%3d; %4.0f; %5.0f\n", n+1, m_bms_voltages[n]*1000, m_bms_capacitys[n]);
}
writer->puts("-------------------------------------------");
writer->puts("Individual Cell Statistics:");
writer->puts("-------------------------------------------");
writer->printf("CV mean : %4.0f mV", StdMetrics.ms_v_bat_pack_vavg->AsFloat()*1000 - mt_myBMS_ADCvoltsOffset->AsInt());
writer->printf("CV mean : %4.0f mV", StdMetrics.ms_v_bat_pack_vavg->AsFloat()*1000);
writer->printf(", dV= %.0f mV", StdMetrics.ms_v_bat_pack_vmax->AsFloat()*1000 - StdMetrics.ms_v_bat_pack_vmin->AsFloat()*1000);
writer->printf(", s= %.2f mV\n", StdMetrics.ms_v_bat_pack_vstddev->AsFloat()*1000);
writer->printf("CV min : %4.0f mV, # %d\n", StdMetrics.ms_v_bat_pack_vmin->AsFloat()*1000 - mt_myBMS_ADCvoltsOffset->AsInt(), mt_v_bat_pack_cmin_cell_volt->AsInt());
writer->printf("CV max : %4.0f mV, # %d\n", StdMetrics.ms_v_bat_pack_vmax->AsFloat()*1000 - mt_myBMS_ADCvoltsOffset->AsInt(), mt_v_bat_pack_cmax_cell_volt->AsInt());
writer->printf("CV min : %4.0f mV, # %d\n", StdMetrics.ms_v_bat_pack_vmin->AsFloat()*1000, mt_v_bat_pack_cmin_cell_volt->AsInt());
writer->printf("CV max : %4.0f mV, # %d\n", StdMetrics.ms_v_bat_pack_vmax->AsFloat()*1000, mt_v_bat_pack_cmax_cell_volt->AsInt());
writer->puts("-------------------------------------------");
writer->printf("CAP mean: %5.0f As/10, %2.1f Ah\n", mt_v_bat_pack_cavg->AsFloat(), mt_v_bat_pack_cavg->AsFloat() / 360.0);
writer->printf("CAP min : %5.0f As/10, %2.1f Ah, # %d \n", mt_v_bat_pack_cmin->AsFloat(), mt_v_bat_pack_cmin->AsFloat() / 360.0, mt_v_bat_pack_cmin_cell->AsInt());
Expand Down
40 changes: 32 additions & 8 deletions vehicle/OVMS.V3/components/vehicle_smarted/src/ed_web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,15 @@ void OvmsVehicleSmartED::WebCfgBattery(PageEntry_t& p, PageContext_t& c)
std::string error;
// suffsoc Sufficient SOC [%] (Default: 0=disabled)
// suffrange Sufficient range [km] (Default: 0=disabled)
std::string suffrange, suffsoc;
std::string suffrange, suffsoc, cell_interval_drv, cell_interval_chg, cell_interval_awk;

if (c.method == "POST") {
// process form submission:
suffrange = c.getvar("suffrange");
suffsoc = c.getvar("suffsoc");
cell_interval_drv = c.getvar("cell_interval_drv");
cell_interval_chg = c.getvar("cell_interval_chg");
cell_interval_awk = c.getvar("cell_interval_awk");

// check:
if (!suffrange.empty()) {
Expand All @@ -306,6 +309,9 @@ void OvmsVehicleSmartED::WebCfgBattery(PageEntry_t& p, PageContext_t& c)
// store:
MyConfig.SetParamValue("xse", "suffrange", suffrange);
MyConfig.SetParamValue("xse", "suffsoc", suffsoc);
MyConfig.SetParamValue("xse", "cell_interval_drv", cell_interval_drv);
MyConfig.SetParamValue("xse", "cell_interval_chg", cell_interval_chg);
MyConfig.SetParamValue("xse", "cell_interval_awk", cell_interval_awk);

c.head(200);
c.alert("success", "<p class=\"lead\">SmartED3 battery setup saved.</p>");
Expand All @@ -322,7 +328,10 @@ void OvmsVehicleSmartED::WebCfgBattery(PageEntry_t& p, PageContext_t& c)
else {
// read configuration:
suffrange = MyConfig.GetParamValue("xse", "suffrange", "0");
suffsoc = MyConfig.GetParamValue("xse", "suffsoc", "0");
suffsoc = MyConfig.GetParamValue("xse", "suffsoc", "0");
cell_interval_drv = MyConfig.GetParamValue("xse", "cell_interval_drv", "60");
cell_interval_chg = MyConfig.GetParamValue("xse", "cell_interval_chg", "60");
cell_interval_awk = MyConfig.GetParamValue("xse", "cell_interval_awk", "60");

c.head(200);
}
Expand All @@ -343,6 +352,22 @@ void OvmsVehicleSmartED::WebCfgBattery(PageEntry_t& p, PageContext_t& c)
"<p>Default 0=off. Notify/stop charge when reaching this level.</p>");

c.fieldset_end();

c.fieldset_start("BMS Cell Monitoring");
c.input_slider("Update interval driving", "cell_interval_drv", 3, "s",
atof(cell_interval_drv.c_str()) > 0, atof(cell_interval_drv.c_str()),
60, 0, 300, 1,
"<p>Default 60 seconds, 0=off.</p>");
c.input_slider("Update interval charging", "cell_interval_chg", 3, "s",
atof(cell_interval_chg.c_str()) > 0, atof(cell_interval_chg.c_str()),
60, 0, 300, 1,
"<p>Default 60 seconds, 0=off.</p>");
c.input_slider("Update interval awake", "cell_interval_awk", 3, "s",
atof(cell_interval_awk.c_str()) > 0, atof(cell_interval_awk.c_str()),
60, 0, 300, 1,
"<p>Default 60 seconds, 0=off. Note: an interval below 30 seconds may keep the car awake indefinitely.</p>");

c.fieldset_end();

c.print("<hr>");
c.input_button("default", "Save");
Expand Down Expand Up @@ -778,17 +803,16 @@ void OvmsVehicleSmartED::WebCfgBmsCellMonitor(PageEntry_t& p, PageContext_t& c)
"var cnt = metrics[\"v.b.c.voltage\"] ? metrics[\"v.b.c.voltage\"].length : 0;\n"
"if (cnt == 0)\n"
"return data;\n"
"var i, act, min, max, devmax, dalert, dlow, dhigh, voffset;\n"
"voffset = metrics[\"xse.mybms.adc.volts.offset\"]/1000;\n"
"data.voltmean = metrics[\"v.b.p.voltage.avg\"]-voffset || 0;\n"
"var i, act, min, max, devmax, dalert, dlow, dhigh;\n"
"data.voltmean = metrics[\"v.b.p.voltage.avg\"] || 0;\n"
"data.sdlo = data.voltmean - (metrics[\"v.b.p.voltage.stddev\"] || 0);\n"
"data.sdhi = data.voltmean + (metrics[\"v.b.p.voltage.stddev\"] || 0);\n"
"data.sdmaxlo = data.voltmean - (metrics[\"v.b.p.voltage.stddev.max\"] || 0);\n"
"data.sdmaxhi = data.voltmean + (metrics[\"v.b.p.voltage.stddev.max\"] || 0);\n"
"for (i=0; i<cnt; i++) {\n"
"act = metrics[\"v.b.c.voltage\"][i]-voffset;\n"
"min = metrics[\"v.b.c.voltage.min\"][i]-voffset || act;\n"
"max = metrics[\"v.b.c.voltage.max\"][i]-voffset || act;\n"
"act = metrics[\"v.b.c.voltage\"][i];\n"
"min = metrics[\"v.b.c.voltage.min\"][i] || act;\n"
"max = metrics[\"v.b.c.voltage.max\"][i] || act;\n"
"devmax = metrics[\"v.b.c.voltage.dev.max\"][i] || 0;\n"
"dalert = metrics[\"v.b.c.voltage.alert\"][i] || 0;\n"
"if (devmax > 0) {\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,15 @@ OvmsVehicleSmartED::OvmsVehicleSmartED() : smarted_obd_rxwait(1,1) {
cmd_xse->RegisterCommand("rptdata", "Show BMS RPTdata", xse_RPTdata);

MyConfig.RegisterParam("xse", "Smart ED", true, true);
ConfigChanged(NULL);

RegisterCanBus(1, CAN_MODE_ACTIVE, CAN_SPEED_500KBPS);
RegisterCanBus(2, CAN_MODE_ACTIVE, CAN_SPEED_500KBPS);

// init OBD2 poller:
ObdInitPoll();

ConfigChanged(NULL);

#ifdef CONFIG_OVMS_COMP_WEBSERVER
WebInit();
#endif
Expand Down Expand Up @@ -165,6 +166,23 @@ void OvmsVehicleSmartED::ConfigChanged(OvmsConfigParam* param) {
StandardMetrics.ms_v_charge_limit_soc->SetValue((float) MyConfig.GetParamValueInt("xse", "suffsoc", 0), Percentage );
StandardMetrics.ms_v_charge_limit_range->SetValue((float) MyConfig.GetParamValueInt("xse", "suffrange", 0), Kilometers );

int cell_interval_drv = MyConfig.GetParamValueInt("xse", "cell_interval_drv", 60);
int cell_interval_chg = MyConfig.GetParamValueInt("xse", "cell_interval_chg", 60);
int cell_interval_awk = MyConfig.GetParamValueInt("xse", "cell_interval_awk", 60);

bool do_modify_poll = (
(cell_interval_drv != m_cfg_cell_interval_drv) ||
(cell_interval_chg != m_cfg_cell_interval_chg) ||
(cell_interval_awk != m_cfg_cell_interval_awk));

m_cfg_cell_interval_drv = cell_interval_drv;
m_cfg_cell_interval_chg = cell_interval_chg;
m_cfg_cell_interval_awk = cell_interval_awk;

if (do_modify_poll) {
ObdModifyPoll();
}

if (!m_enable_write) PollSetState(0);

#ifdef CONFIG_OVMS_COMP_MAX7317
Expand Down
13 changes: 13 additions & 0 deletions vehicle/OVMS.V3/components/vehicle_smarted/src/vehicle_smarted.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@

using namespace std;

typedef std::vector<OvmsPoller::poll_pid_t, ExtRamAllocator<OvmsPoller::poll_pid_t>> poll_vector_t;
typedef std::initializer_list<const OvmsPoller::poll_pid_t> poll_list_t;

class OvmsVehicleSmartED : public OvmsVehicle
{
public:
Expand All @@ -72,6 +75,7 @@ class OvmsVehicleSmartED : public OvmsVehicle
void WebDeInit();
#endif
void ObdInitPoll();
void ObdModifyPoll();
#ifdef CONFIG_OVMS_COMP_WEBSERVER
static void WebCfgFeatures(PageEntry_t& p, PageContext_t& c);
static void WebCfgBattery(PageEntry_t& p, PageContext_t& c);
Expand Down Expand Up @@ -286,6 +290,8 @@ class OvmsVehicleSmartED : public OvmsVehicle

// BMS helpers
protected:
float m_bms_raw_voltages[93]; // BMS raw voltages (current value)
float m_bms_bat_pack_avg; // BMS avg raw voltages
float* m_bms_capacitys; // BMS Capacity (current value)
float* m_bms_cmins; // BMS minimum Capacity seen (since reset)
float* m_bms_cmaxs; // BMS maximum Capacity seen (since reset)
Expand Down Expand Up @@ -362,6 +368,13 @@ class OvmsVehicleSmartED : public OvmsVehicle
protected:
void HandleCharging12v();
unsigned int m_charging_timer;

protected:
poll_vector_t m_poll_vector; // List of PIDs to poll

int m_cfg_cell_interval_drv; // Cell poll interval while driving, default 15 sec.
int m_cfg_cell_interval_chg; // … while charging, default 60 sec.
int m_cfg_cell_interval_awk; // … while awake, default 60 sec.
};

#endif //#ifndef __VEHICLE_SMARTED_H__

0 comments on commit a28765a

Please sign in to comment.