mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-06 03:50:13 +02:00
Merge branch 'main' into feature/sofar-multiple-packs
This commit is contained in:
commit
05dd887d2f
73 changed files with 417 additions and 253 deletions
|
@ -89,10 +89,6 @@ void setup() {
|
||||||
&logging_loop_task, WIFI_CORE);
|
&logging_loop_task, WIFI_CORE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init_CAN();
|
|
||||||
|
|
||||||
init_contactors();
|
|
||||||
|
|
||||||
#ifdef PRECHARGE_CONTROL
|
#ifdef PRECHARGE_CONTROL
|
||||||
init_precharge_control();
|
init_precharge_control();
|
||||||
#endif // PRECHARGE_CONTROL
|
#endif // PRECHARGE_CONTROL
|
||||||
|
@ -100,6 +96,12 @@ void setup() {
|
||||||
setup_charger();
|
setup_charger();
|
||||||
setup_inverter();
|
setup_inverter();
|
||||||
setup_battery();
|
setup_battery();
|
||||||
|
setup_can_shunt();
|
||||||
|
|
||||||
|
// Init CAN only after any CAN receivers have had a chance to register.
|
||||||
|
init_CAN();
|
||||||
|
|
||||||
|
init_contactors();
|
||||||
|
|
||||||
init_rs485();
|
init_rs485();
|
||||||
|
|
||||||
|
@ -107,7 +109,6 @@ void setup() {
|
||||||
init_equipment_stop_button();
|
init_equipment_stop_button();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setup_can_shunt();
|
|
||||||
// BOOT button at runtime is used as an input for various things
|
// BOOT button at runtime is used as an input for various things
|
||||||
pinMode(0, INPUT_PULLUP);
|
pinMode(0, INPUT_PULLUP);
|
||||||
|
|
||||||
|
@ -139,6 +140,8 @@ void setup() {
|
||||||
set_event(EVENT_PERIODIC_BMS_RESET_AT_INIT_SUCCESS, 0);
|
set_event(EVENT_PERIODIC_BMS_RESET_AT_INIT_SUCCESS, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DEBUG_PRINTF("setup() complete\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop empty, all functionality runs in tasks
|
// Loop empty, all functionality runs in tasks
|
||||||
|
@ -207,6 +210,7 @@ static std::list<Transmitter*> transmitters;
|
||||||
|
|
||||||
void register_transmitter(Transmitter* transmitter) {
|
void register_transmitter(Transmitter* transmitter) {
|
||||||
transmitters.push_back(transmitter);
|
transmitters.push_back(transmitter);
|
||||||
|
DEBUG_PRINTF("transmitter registered, total: %d\n", transmitters.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_loop(void*) {
|
void core_loop(void*) {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
Battery* battery = nullptr;
|
Battery* battery = nullptr;
|
||||||
Battery* battery2 = nullptr;
|
Battery* battery2 = nullptr;
|
||||||
|
|
||||||
|
#ifdef COMMON_IMAGE
|
||||||
std::vector<BatteryType> supported_battery_types() {
|
std::vector<BatteryType> supported_battery_types() {
|
||||||
std::vector<BatteryType> types;
|
std::vector<BatteryType> types;
|
||||||
|
|
||||||
|
@ -101,6 +102,7 @@ extern const char* name_for_battery_type(BatteryType type) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef COMMON_IMAGE
|
#ifdef COMMON_IMAGE
|
||||||
#ifdef SELECTED_BATTERY_CLASS
|
#ifdef SELECTED_BATTERY_CLASS
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef BATTERIES_H
|
#ifndef BATTERIES_H
|
||||||
#define BATTERIES_H
|
#define BATTERIES_H
|
||||||
#include "../../USER_SETTINGS.h"
|
#include "../../USER_SETTINGS.h"
|
||||||
|
#include "Shunt.h"
|
||||||
|
|
||||||
class Battery;
|
class Battery;
|
||||||
|
|
||||||
|
@ -18,10 +19,8 @@ void setup_can_shunt();
|
||||||
#include "BOLT-AMPERA-BATTERY.h"
|
#include "BOLT-AMPERA-BATTERY.h"
|
||||||
#include "BYD-ATTO-3-BATTERY.h"
|
#include "BYD-ATTO-3-BATTERY.h"
|
||||||
#include "CELLPOWER-BMS.h"
|
#include "CELLPOWER-BMS.h"
|
||||||
|
|
||||||
#include "CHADEMO-BATTERY.h"
|
#include "CHADEMO-BATTERY.h"
|
||||||
#include "CHADEMO-SHUNTS.h"
|
#include "CHADEMO-SHUNTS.h"
|
||||||
|
|
||||||
#include "CMFA-EV-BATTERY.h"
|
#include "CMFA-EV-BATTERY.h"
|
||||||
#include "DALY-BMS.h"
|
#include "DALY-BMS.h"
|
||||||
#include "ECMP-BATTERY.h"
|
#include "ECMP-BATTERY.h"
|
||||||
|
|
|
@ -38,7 +38,7 @@ class BmwI3Battery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "BMW i3";
|
static constexpr const char* Name = "BMW i3";
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ class BmwIXBattery : public CanBattery {
|
||||||
void request_open_contactors() { datalayer_extended.bmwix.UserRequestContactorOpen = true; }
|
void request_open_contactors() { datalayer_extended.bmwix.UserRequestContactorOpen = true; }
|
||||||
void request_close_contactors() { datalayer_extended.bmwix.UserRequestContactorClose = true; }
|
void request_close_contactors() { datalayer_extended.bmwix.UserRequestContactorClose = true; }
|
||||||
|
|
||||||
static constexpr char* Name = "BMW iX and i4-7 platform";
|
static constexpr const char* Name = "BMW iX and i4-7 platform";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BmwIXHtmlRenderer renderer;
|
BmwIXHtmlRenderer renderer;
|
||||||
|
|
|
@ -13,7 +13,7 @@ class BmwSbox : public CanShunt {
|
||||||
void setup();
|
void setup();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void handle_incoming_can_frame(CAN_frame rx_frame);
|
void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "BMW SBOX";
|
static constexpr const char* Name = "BMW SBOX";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Minimum input voltage required to enable relay control **/
|
/** Minimum input voltage required to enable relay control **/
|
||||||
|
|
|
@ -17,7 +17,7 @@ class BoltAmperaBattery : public CanBattery {
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
|
|
||||||
static constexpr char* Name = "Chevrolet Bolt EV/Opel Ampera-e";
|
static constexpr const char* Name = "Chevrolet Bolt EV/Opel Ampera-e";
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class BydAttoBattery : public CanBattery {
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
|
|
||||||
static constexpr char* Name = "BYD Atto 3";
|
static constexpr const char* Name = "BYD Atto 3";
|
||||||
|
|
||||||
bool supports_charged_energy() { return true; }
|
bool supports_charged_energy() { return true; }
|
||||||
bool supports_reset_crash() { return true; }
|
bool supports_reset_crash() { return true; }
|
||||||
|
|
|
@ -79,6 +79,8 @@ class Battery {
|
||||||
virtual bool supports_real_BMS_status() { return false; }
|
virtual bool supports_real_BMS_status() { return false; }
|
||||||
virtual bool supports_toggle_SOC_method() { return false; }
|
virtual bool supports_toggle_SOC_method() { return false; }
|
||||||
virtual bool supports_factory_mode_method() { return false; }
|
virtual bool supports_factory_mode_method() { return false; }
|
||||||
|
virtual bool supports_chademo_restart() { return false; }
|
||||||
|
virtual bool supports_chademo_stop() { return false; }
|
||||||
|
|
||||||
virtual void clear_isolation() {}
|
virtual void clear_isolation() {}
|
||||||
virtual void reset_BMS() {}
|
virtual void reset_BMS() {}
|
||||||
|
@ -93,6 +95,8 @@ class Battery {
|
||||||
virtual void request_close_contactors() {}
|
virtual void request_close_contactors() {}
|
||||||
virtual void toggle_SOC_method() {}
|
virtual void toggle_SOC_method() {}
|
||||||
virtual void set_factory_mode() {}
|
virtual void set_factory_mode() {}
|
||||||
|
virtual void chademo_restart() {}
|
||||||
|
virtual void chademo_stop() {}
|
||||||
|
|
||||||
virtual void set_fake_voltage(float v) {}
|
virtual void set_fake_voltage(float v) {}
|
||||||
virtual float get_voltage();
|
virtual float get_voltage();
|
||||||
|
|
|
@ -11,12 +11,14 @@
|
||||||
|
|
||||||
class CellPowerBms : public CanBattery {
|
class CellPowerBms : public CanBattery {
|
||||||
public:
|
public:
|
||||||
|
CellPowerBms() : CanBattery(true) {}
|
||||||
|
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
|
|
||||||
static constexpr char* Name = "Cellpower BMS";
|
static constexpr const char* Name = "Cellpower BMS";
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
|
||||||
|
@ -132,7 +134,4 @@ class CellPowerBms : public CanBattery {
|
||||||
bool error_state = false;
|
bool error_state = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Do not modify any rows below*/
|
|
||||||
#define NATIVECAN_250KBPS
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
72
Software/src/battery/CHADEMO-BATTERY-HTML.h
Normal file
72
Software/src/battery/CHADEMO-BATTERY-HTML.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
#ifndef _CHADEMO_BATTERY_HTML_H
|
||||||
|
#define _CHADEMO_BATTERY_HTML_H
|
||||||
|
|
||||||
|
#include "../datalayer/datalayer.h"
|
||||||
|
#include "../datalayer/datalayer_extended.h"
|
||||||
|
#include "src/devboard/webserver/BatteryHtmlRenderer.h"
|
||||||
|
|
||||||
|
class ChademoBatteryHtmlRenderer : public BatteryHtmlRenderer {
|
||||||
|
public:
|
||||||
|
String get_status_html() {
|
||||||
|
String content;
|
||||||
|
content += "<h4>Chademo state: ";
|
||||||
|
switch (datalayer_extended.chademo.CHADEMO_Status) {
|
||||||
|
case 0:
|
||||||
|
content += String("FAULT</h4>");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
content += String("STOP</h4>");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
content += String("IDLE</h4>");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
content += String("CONNECTED</h4>");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
content += String("INIT</h4>");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
content += String("NEGOTIATE</h4>");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
content += String("EV ALLOWED</h4>");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
content += String("EVSE PREPARE</h4>");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
content += String("EVSE START</h4>");
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
content += String("EVSE CONTACTORS ENABLED</h4>");
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
content += String("POWERFLOW</h4>");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
content += String("Unknown</h4>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (datalayer_extended.chademo.FaultBatteryCurrentDeviation) {
|
||||||
|
content += "<h4>FAULT: Battery Current Deviation</h4>";
|
||||||
|
}
|
||||||
|
if (datalayer_extended.chademo.FaultBatteryOverVoltage) {
|
||||||
|
content += "<h4>FAULT: Battery Overvoltage</h4>";
|
||||||
|
}
|
||||||
|
if (datalayer_extended.chademo.FaultBatteryUnderVoltage) {
|
||||||
|
content += "<h4>FAULT: Battery Undervoltage</h4>";
|
||||||
|
}
|
||||||
|
if (datalayer_extended.chademo.FaultBatteryVoltageDeviation) {
|
||||||
|
content += "<h4>FAULT: Battery Voltage Deviation</h4>";
|
||||||
|
}
|
||||||
|
if (datalayer_extended.chademo.FaultHighBatteryTemperature) {
|
||||||
|
content += "<h4>FAULT: Battery Temperature</h4>";
|
||||||
|
}
|
||||||
|
content += "<h4>Protocol: " + String(datalayer_extended.chademo.ControlProtocolNumberEV) + "</h4>";
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -6,17 +6,24 @@
|
||||||
|
|
||||||
#ifdef CHADEMO_PIN_2 // Only support chademo for certain platforms
|
#ifdef CHADEMO_PIN_2 // Only support chademo for certain platforms
|
||||||
|
|
||||||
/* CHADEMO handling runs at 6.25 times the rate of most other code, so, rather than the
|
|
||||||
* default value of 12 (for 12 iterations of the 5s value update loop) * 5 for a 60s timeout,
|
|
||||||
* instead use 75 for 75*0.8s = 60s
|
|
||||||
*/
|
|
||||||
#undef CAN_STILL_ALIVE
|
|
||||||
#define CAN_STILL_ALIVE 75
|
|
||||||
//#define CH_CAN_DEBUG
|
|
||||||
|
|
||||||
//This function maps all the values fetched via CAN to the correct parameters used for the inverter
|
//This function maps all the values fetched via CAN to the correct parameters used for the inverter
|
||||||
void ChademoBattery::update_values() {
|
void ChademoBattery::update_values() {
|
||||||
|
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
//On this integration, we don't care if no CAN messages flow (normal before user plugs in)
|
||||||
|
//Always write the CAN as alive!
|
||||||
|
|
||||||
|
//Check if user is requesting an action, if so, have statemachine jump there
|
||||||
|
if (datalayer_extended.chademo.UserRequestStop) {
|
||||||
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
|
datalayer_extended.chademo.UserRequestStop = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (datalayer_extended.chademo.UserRequestRestart) {
|
||||||
|
CHADEMO_Status = CHADEMO_IDLE;
|
||||||
|
datalayer_extended.chademo.UserRequestRestart = false;
|
||||||
|
}
|
||||||
|
|
||||||
datalayer.battery.status.real_soc = x102_chg_session.StateOfCharge * 100; //Convert % to pptt
|
datalayer.battery.status.real_soc = x102_chg_session.StateOfCharge * 100; //Convert % to pptt
|
||||||
|
|
||||||
datalayer.battery.status.max_discharge_power_W =
|
datalayer.battery.status.max_discharge_power_W =
|
||||||
|
@ -49,6 +56,15 @@ void ChademoBattery::update_values() {
|
||||||
chargingrate = x102_chg_session.StateOfCharge / x100_chg_lim.ConstantOfChargingRateIndication * 100;
|
chargingrate = x102_chg_session.StateOfCharge / x100_chg_lim.ConstantOfChargingRateIndication * 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Update extended datalayer for easier visualization of what's going on
|
||||||
|
datalayer_extended.chademo.CHADEMO_Status = CHADEMO_Status;
|
||||||
|
datalayer_extended.chademo.ControlProtocolNumberEV = x102_chg_session.ControlProtocolNumberEV;
|
||||||
|
datalayer_extended.chademo.FaultBatteryVoltageDeviation = x102_chg_session.f.fault.FaultBatteryVoltageDeviation;
|
||||||
|
datalayer_extended.chademo.FaultHighBatteryTemperature = x102_chg_session.f.fault.FaultHighBatteryTemperature;
|
||||||
|
datalayer_extended.chademo.FaultBatteryCurrentDeviation = x102_chg_session.f.fault.FaultBatteryCurrentDeviation;
|
||||||
|
datalayer_extended.chademo.FaultBatteryUnderVoltage = x102_chg_session.f.fault.FaultBatteryUnderVoltage;
|
||||||
|
datalayer_extended.chademo.FaultBatteryOverVoltage = x102_chg_session.f.fault.FaultBatteryOverVoltage;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO simplified start/stop helper functions
|
//TODO simplified start/stop helper functions
|
||||||
|
@ -278,19 +294,6 @@ void ChademoBattery::process_vehicle_vendor_ID(CAN_frame rx_frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChademoBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
void ChademoBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
||||||
#ifdef CH_CAN_DEBUG
|
|
||||||
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
|
||||||
logging.print(" ");
|
|
||||||
logging.print(rx_frame.ID, HEX);
|
|
||||||
logging.print(" ");
|
|
||||||
logging.print(rx_frame.DLC);
|
|
||||||
logging.print(" ");
|
|
||||||
for (int i = 0; i < rx_frame.DLC; ++i) {
|
|
||||||
logging.print(rx_frame.data.u8[i], HEX);
|
|
||||||
logging.print(" ");
|
|
||||||
}
|
|
||||||
logging.println("");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// CHADEMO coexists with a CAN-based shunt. Only process CHADEMO-specific IDs
|
// CHADEMO coexists with a CAN-based shunt. Only process CHADEMO-specific IDs
|
||||||
// 202 is unknown
|
// 202 is unknown
|
||||||
|
@ -304,9 +307,6 @@ void ChademoBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
||||||
* has not yet been receied from a vehicle
|
* has not yet been receied from a vehicle
|
||||||
*/
|
*/
|
||||||
|
|
||||||
datalayer.battery.status.CAN_battery_still_alive =
|
|
||||||
CAN_STILL_ALIVE; //We are getting CAN messages from the vehicle, inform the watchdog
|
|
||||||
|
|
||||||
switch (rx_frame.ID) {
|
switch (rx_frame.ID) {
|
||||||
case 0x100:
|
case 0x100:
|
||||||
process_vehicle_charging_minimums(rx_frame);
|
process_vehicle_charging_minimums(rx_frame);
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#ifndef CHADEMO_BATTERY_H
|
#ifndef CHADEMO_BATTERY_H
|
||||||
#define CHADEMO_BATTERY_H
|
#define CHADEMO_BATTERY_H
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include "../datalayer/datalayer.h"
|
||||||
|
#include "../datalayer/datalayer_extended.h"
|
||||||
#include "../include.h"
|
#include "../include.h"
|
||||||
|
#include "CHADEMO-BATTERY-HTML.h"
|
||||||
#include "CanBattery.h"
|
#include "CanBattery.h"
|
||||||
|
|
||||||
#ifdef CHADEMO_BATTERY
|
#ifdef CHADEMO_BATTERY
|
||||||
|
@ -18,9 +21,18 @@ class ChademoBattery : public CanBattery {
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
|
|
||||||
static constexpr char* Name = "Chademo V2X mode";
|
bool supports_chademo_restart() { return true; }
|
||||||
|
bool supports_chademo_stop() { return true; }
|
||||||
|
|
||||||
|
void chademo_restart() { datalayer_extended.chademo.UserRequestRestart = true; }
|
||||||
|
void chademo_stop() { datalayer_extended.chademo.UserRequestStop = true; }
|
||||||
|
|
||||||
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
static constexpr const char* Name = "Chademo V2X mode";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ChademoBatteryHtmlRenderer renderer;
|
||||||
|
|
||||||
void process_vehicle_charging_minimums(CAN_frame rx_frame);
|
void process_vehicle_charging_minimums(CAN_frame rx_frame);
|
||||||
void process_vehicle_charging_maximums(CAN_frame rx_frame);
|
void process_vehicle_charging_maximums(CAN_frame rx_frame);
|
||||||
void process_vehicle_charging_session(CAN_frame rx_frame);
|
void process_vehicle_charging_session(CAN_frame rx_frame);
|
||||||
|
@ -39,19 +51,17 @@ class ChademoBattery : public CanBattery {
|
||||||
static const int MAX_EVSE_OUTPUT_VOLTAGE = 410;
|
static const int MAX_EVSE_OUTPUT_VOLTAGE = 410;
|
||||||
static const int MAX_EVSE_OUTPUT_CURRENT = 11;
|
static const int MAX_EVSE_OUTPUT_CURRENT = 11;
|
||||||
|
|
||||||
enum CHADEMO_STATE {
|
#define CHADEMO_FAULT 0
|
||||||
CHADEMO_FAULT,
|
#define CHADEMO_STOP 1
|
||||||
CHADEMO_STOP,
|
#define CHADEMO_IDLE 2
|
||||||
CHADEMO_IDLE,
|
#define CHADEMO_CONNECTED 3
|
||||||
CHADEMO_CONNECTED,
|
#define CHADEMO_INIT 4 // intermediate state indicating CAN from Vehicle not yet received after connection
|
||||||
CHADEMO_INIT, // intermediate state indicating CAN from Vehicle not yet received after connection
|
#define CHADEMO_NEGOTIATE 5
|
||||||
CHADEMO_NEGOTIATE,
|
#define CHADEMO_EV_ALLOWED 6
|
||||||
CHADEMO_EV_ALLOWED,
|
#define CHADEMO_EVSE_PREPARE 7
|
||||||
CHADEMO_EVSE_PREPARE,
|
#define CHADEMO_EVSE_START 8
|
||||||
CHADEMO_EVSE_START,
|
#define CHADEMO_EVSE_CONTACTORS_ENABLED 9
|
||||||
CHADEMO_EVSE_CONTACTORS_ENABLED,
|
#define CHADEMO_POWERFLOW 10
|
||||||
CHADEMO_POWERFLOW,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Mode { CHADEMO_CHARGE, CHADEMO_DISCHARGE, CHADEMO_BIDIRECTIONAL };
|
enum Mode { CHADEMO_CHARGE, CHADEMO_DISCHARGE, CHADEMO_BIDIRECTIONAL };
|
||||||
|
|
||||||
|
@ -290,7 +300,7 @@ should determine that the other is the EVSE or the vehicle of the model before t
|
||||||
// permissible rate of change is -20A/s to 20A/s relative to 102.3
|
// permissible rate of change is -20A/s to 20A/s relative to 102.3
|
||||||
|
|
||||||
Mode EVSE_mode = CHADEMO_DISCHARGE;
|
Mode EVSE_mode = CHADEMO_DISCHARGE;
|
||||||
CHADEMO_STATE CHADEMO_Status = CHADEMO_IDLE;
|
uint8_t CHADEMO_Status = CHADEMO_IDLE;
|
||||||
|
|
||||||
/* Charge/discharge sequence, indicating applicable V2H guideline
|
/* Charge/discharge sequence, indicating applicable V2H guideline
|
||||||
* If sequence number is not agreed upon via H201/H209 between EVSE and Vehicle,
|
* If sequence number is not agreed upon via H201/H209 between EVSE and Vehicle,
|
||||||
|
|
|
@ -32,7 +32,7 @@ class CmfaEvBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "CMFA platform, 27 kWh battery";
|
static constexpr const char* Name = "CMFA platform, 27 kWh battery";
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "CanBattery.h"
|
#include "CanBattery.h"
|
||||||
#include "../../src/include.h"
|
#include "../../src/include.h"
|
||||||
|
|
||||||
CanBattery::CanBattery() {
|
CanBattery::CanBattery(bool halfSpeed) {
|
||||||
can_interface = can_config.battery;
|
can_interface = can_config.battery;
|
||||||
register_transmitter(this);
|
register_transmitter(this);
|
||||||
register_can_receiver(this, can_interface);
|
register_can_receiver(this, can_interface, halfSpeed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ class CanBattery : public Battery, Transmitter, CanReceiver {
|
||||||
protected:
|
protected:
|
||||||
CAN_Interface can_interface;
|
CAN_Interface can_interface;
|
||||||
|
|
||||||
CanBattery();
|
CanBattery(bool halfSpeed = false);
|
||||||
|
|
||||||
CanBattery(CAN_Interface interface) {
|
CanBattery(CAN_Interface interface, bool halfSpeed = false) {
|
||||||
can_interface = interface;
|
can_interface = interface;
|
||||||
register_transmitter(this);
|
register_transmitter(this);
|
||||||
register_can_receiver(this, can_interface);
|
register_can_receiver(this, can_interface, halfSpeed);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ class DalyBms : public RS485Battery {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_rs485(unsigned long currentMillis);
|
void transmit_rs485(unsigned long currentMillis);
|
||||||
void receive();
|
void receive();
|
||||||
static constexpr char* Name = "DALY RS485";
|
static constexpr const char* Name = "DALY RS485";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Tweak these according to your battery build */
|
/* Tweak these according to your battery build */
|
||||||
|
|
|
@ -16,7 +16,7 @@ class EcmpBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Stellantis ECMP battery";
|
static constexpr const char* Name = "Stellantis ECMP battery";
|
||||||
|
|
||||||
bool supports_clear_isolation() { return true; }
|
bool supports_clear_isolation() { return true; }
|
||||||
void clear_isolation() { datalayer_extended.stellantisECMP.UserRequestIsolationReset = true; }
|
void clear_isolation() { datalayer_extended.stellantisECMP.UserRequestIsolationReset = true; }
|
||||||
|
|
|
@ -15,7 +15,7 @@ class FoxessBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "FoxESS HV2600/ECS4100 OEM battery";
|
static constexpr const char* Name = "FoxESS HV2600/ECS4100 OEM battery";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 4672; //467.2V for HS20.8 (used during startup, refined later)
|
static const int MAX_PACK_VOLTAGE_DV = 4672; //467.2V for HS20.8 (used during startup, refined later)
|
||||||
|
|
|
@ -16,7 +16,7 @@ class GeelyGeometryCBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Geely Geometry C";
|
static constexpr const char* Name = "Geely Geometry C";
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ImievCZeroIonBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "I-Miev / C-Zero / Ion Triplet";
|
static constexpr const char* Name = "I-Miev / C-Zero / Ion Triplet";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 3696; //5000 = 500.0V
|
static const int MAX_PACK_VOLTAGE_DV = 3696; //5000 = 500.0V
|
||||||
|
|
|
@ -13,7 +13,7 @@ class JaguarIpaceBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Jaguar I-PACE";
|
static constexpr const char* Name = "Jaguar I-PACE";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 4546; //5000 = 500.0V
|
static const int MAX_PACK_VOLTAGE_DV = 4546; //5000 = 500.0V
|
||||||
|
|
|
@ -19,7 +19,7 @@ class KiaEGmpBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Kia/Hyundai EGMP platform";
|
static constexpr const char* Name = "Kia/Hyundai EGMP platform";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps);
|
uint16_t estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps);
|
||||||
|
|
|
@ -35,7 +35,7 @@ class KiaHyundai64Battery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Kia/Hyundai 64/40kWh battery";
|
static constexpr const char* Name = "Kia/Hyundai 64/40kWh battery";
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class KiaHyundaiHybridBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Kia/Hyundai Hybrid";
|
static constexpr const char* Name = "Kia/Hyundai Hybrid";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 2550; //5000 = 500.0V
|
static const int MAX_PACK_VOLTAGE_DV = 2550; //5000 = 500.0V
|
||||||
|
|
|
@ -17,7 +17,7 @@ class MebBattery : public CanBattery {
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
bool supports_real_BMS_status() { return true; }
|
bool supports_real_BMS_status() { return true; }
|
||||||
bool supports_charged_energy() { return true; }
|
bool supports_charged_energy() { return true; }
|
||||||
static constexpr char* Name = "Volkswagen Group MEB platform via CAN-FD";
|
static constexpr const char* Name = "Volkswagen Group MEB platform via CAN-FD";
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Mg5Battery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "MG 5 battery";
|
static constexpr const char* Name = "MG 5 battery";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 4040; //5000 = 500.0V
|
static const int MAX_PACK_VOLTAGE_DV = 4040; //5000 = 500.0V
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "../datalayer/datalayer.h"
|
#include "../datalayer/datalayer.h"
|
||||||
#include "../datalayer/datalayer_extended.h" //For "More battery info" webpage
|
#include "../datalayer/datalayer_extended.h" //For "More battery info" webpage
|
||||||
#include "../devboard/utils/events.h"
|
#include "../devboard/utils/events.h"
|
||||||
|
#include "../devboard/utils/logging.h"
|
||||||
|
|
||||||
#include "../charger/CanCharger.h"
|
#include "../charger/CanCharger.h"
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class NissanLeafBattery : public CanBattery {
|
||||||
}
|
}
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
static constexpr char* Name = "Nissan LEAF battery";
|
static constexpr const char* Name = "Nissan LEAF battery";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 4040; //5000 = 500.0V
|
static const int MAX_PACK_VOLTAGE_DV = 4040; //5000 = 500.0V
|
||||||
|
|
|
@ -15,7 +15,7 @@ class OrionBms : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "DIY battery with Orion BMS (Victron setting)";
|
static constexpr const char* Name = "DIY battery with Orion BMS (Victron setting)";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Change the following to suit your battery */
|
/* Change the following to suit your battery */
|
||||||
|
|
|
@ -31,7 +31,7 @@ class PylonBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Pylon compatible battery";
|
static constexpr const char* Name = "Pylon compatible battery";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Change the following to suit your battery */
|
/* Change the following to suit your battery */
|
||||||
|
|
|
@ -15,7 +15,7 @@ class RangeRoverPhevBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Range Rover 13kWh PHEV battery (L494/L405)";
|
static constexpr const char* Name = "Range Rover 13kWh PHEV battery (L494/L405)";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Change the following to suit your battery */
|
/* Change the following to suit your battery */
|
||||||
|
|
|
@ -15,7 +15,7 @@ class RenaultKangooBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Renault Kangoo";
|
static constexpr const char* Name = "Renault Kangoo";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 4150; //5000 = 500.0V
|
static const int MAX_PACK_VOLTAGE_DV = 4150; //5000 = 500.0V
|
||||||
|
|
|
@ -13,7 +13,7 @@ class RenaultTwizyBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Renault Twizy";
|
static constexpr const char* Name = "Renault Twizy";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 579; // 57.9V at 100% SOC (with 70% SOH, new one might be higher)
|
static const int MAX_PACK_VOLTAGE_DV = 579; // 57.9V at 100% SOC (with 70% SOH, new one might be higher)
|
||||||
|
|
|
@ -166,7 +166,7 @@ void RenaultZoeGen1Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
||||||
switch (frame0) {
|
switch (frame0) {
|
||||||
case 0x10: //PID HEADER, datarow 0
|
case 0x10: //PID HEADER, datarow 0
|
||||||
requested_poll = rx_frame.data.u8[3];
|
requested_poll = rx_frame.data.u8[3];
|
||||||
transmit_can_frame(&ZOE_ACK_79B, can_config.battery);
|
transmit_can_frame(&ZOE_ACK_79B, can_interface);
|
||||||
|
|
||||||
if (requested_poll == GROUP1_CELLVOLTAGES_1_POLL) {
|
if (requested_poll == GROUP1_CELLVOLTAGES_1_POLL) {
|
||||||
cellvoltages[0] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
cellvoltages[0] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
|
@ -469,7 +469,7 @@ void RenaultZoeGen1Battery::transmit_can(unsigned long currentMillis) {
|
||||||
// Send 100ms CAN Message
|
// Send 100ms CAN Message
|
||||||
if (currentMillis - previousMillis100 >= INTERVAL_100_MS) {
|
if (currentMillis - previousMillis100 >= INTERVAL_100_MS) {
|
||||||
previousMillis100 = currentMillis;
|
previousMillis100 = currentMillis;
|
||||||
transmit_can_frame(&ZOE_423, can_config.battery);
|
transmit_can_frame(&ZOE_423, can_interface);
|
||||||
|
|
||||||
if ((counter_423 / 5) % 2 == 0) { // Alternate every 5 messages between these two
|
if ((counter_423 / 5) % 2 == 0) { // Alternate every 5 messages between these two
|
||||||
ZOE_423.data.u8[4] = 0xB2;
|
ZOE_423.data.u8[4] = 0xB2;
|
||||||
|
@ -508,7 +508,7 @@ void RenaultZoeGen1Battery::transmit_can(unsigned long currentMillis) {
|
||||||
|
|
||||||
ZOE_POLL_79B.data.u8[2] = current_poll;
|
ZOE_POLL_79B.data.u8[2] = current_poll;
|
||||||
|
|
||||||
transmit_can_frame(&ZOE_POLL_79B, can_config.battery);
|
transmit_can_frame(&ZOE_POLL_79B, can_interface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class RenaultZoeGen1Battery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Renault Zoe Gen1 22/40kWh";
|
static constexpr const char* Name = "Renault Zoe Gen1 22/40kWh";
|
||||||
|
|
||||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||||
|
|
||||||
|
|
|
@ -24,35 +24,35 @@ https://github.com/fesch/CanZE/tree/master/app/src/main/assets/ZOE_Ph2
|
||||||
|
|
||||||
void RenaultZoeGen2Battery::update_values() {
|
void RenaultZoeGen2Battery::update_values() {
|
||||||
|
|
||||||
datalayer.battery.status.soh_pptt = battery_soh;
|
datalayer_battery->status.soh_pptt = battery_soh;
|
||||||
|
|
||||||
if (battery_soc >= 300) {
|
if (battery_soc >= 300) {
|
||||||
datalayer.battery.status.real_soc = battery_soc - 300;
|
datalayer_battery->status.real_soc = battery_soc - 300;
|
||||||
} else {
|
} else {
|
||||||
datalayer.battery.status.real_soc = 0;
|
datalayer_battery->status.real_soc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
datalayer.battery.status.voltage_dV = battery_pack_voltage;
|
datalayer_battery->status.voltage_dV = battery_pack_voltage;
|
||||||
|
|
||||||
datalayer.battery.status.current_dA = ((battery_current - 32640) * 0.3125);
|
datalayer_battery->status.current_dA = ((battery_current - 32640) * 0.3125);
|
||||||
|
|
||||||
//Calculate the remaining Wh amount from SOC% and max Wh value.
|
//Calculate the remaining Wh amount from SOC% and max Wh value.
|
||||||
datalayer.battery.status.remaining_capacity_Wh = static_cast<uint32_t>(
|
datalayer_battery->status.remaining_capacity_Wh = static_cast<uint32_t>(
|
||||||
(static_cast<double>(datalayer.battery.status.real_soc) / 10000) * datalayer.battery.info.total_capacity_Wh);
|
(static_cast<double>(datalayer_battery->status.real_soc) / 10000) * datalayer_battery->info.total_capacity_Wh);
|
||||||
|
|
||||||
datalayer.battery.status.max_discharge_power_W = battery_max_available * 10;
|
datalayer_battery->status.max_discharge_power_W = battery_max_available * 10;
|
||||||
|
|
||||||
datalayer.battery.status.max_charge_power_W = battery_max_generated * 10;
|
datalayer_battery->status.max_charge_power_W = battery_max_generated * 10;
|
||||||
|
|
||||||
//Temperatures and voltages update at slow rate. Only publish new values once both have been sampled to avoid events
|
//Temperatures and voltages update at slow rate. Only publish new values once both have been sampled to avoid events
|
||||||
if ((battery_min_temp != 920) && (battery_max_temp != 920)) {
|
if ((battery_min_temp != 920) && (battery_max_temp != 920)) {
|
||||||
datalayer.battery.status.temperature_min_dC = ((battery_min_temp - 640) * 0.625);
|
datalayer_battery->status.temperature_min_dC = ((battery_min_temp - 640) * 0.625);
|
||||||
datalayer.battery.status.temperature_max_dC = ((battery_max_temp - 640) * 0.625);
|
datalayer_battery->status.temperature_max_dC = ((battery_max_temp - 640) * 0.625);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((battery_min_cell_voltage != 3700) && (battery_max_cell_voltage != 3700)) {
|
if ((battery_min_cell_voltage != 3700) && (battery_max_cell_voltage != 3700)) {
|
||||||
datalayer.battery.status.cell_min_voltage_mV = (battery_min_cell_voltage * 0.976563);
|
datalayer_battery->status.cell_min_voltage_mV = (battery_min_cell_voltage * 0.976563);
|
||||||
datalayer.battery.status.cell_max_voltage_mV = (battery_max_cell_voltage * 0.976563);
|
datalayer_battery->status.cell_max_voltage_mV = (battery_max_cell_voltage * 0.976563);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (battery_12v < 11000) { //11.000V
|
if (battery_12v < 11000) { //11.000V
|
||||||
|
@ -103,12 +103,12 @@ void RenaultZoeGen2Battery::update_values() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenaultZoeGen2Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
void RenaultZoeGen2Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
||||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
datalayer_battery->status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
switch (rx_frame.ID) {
|
switch (rx_frame.ID) {
|
||||||
case 0x18DAF1DB: // LBC Reply from active polling
|
case 0x18DAF1DB: // LBC Reply from active polling
|
||||||
|
|
||||||
if (rx_frame.data.u8[0] == 0x10) { //First frame of a group
|
if (rx_frame.data.u8[0] == 0x10) { //First frame of a group
|
||||||
transmit_can_frame(&ZOE_POLL_FLOW_CONTROL, can_config.battery);
|
transmit_can_frame(&ZOE_POLL_FLOW_CONTROL, can_interface);
|
||||||
//frame 2 & 3 contains which PID is sent
|
//frame 2 & 3 contains which PID is sent
|
||||||
reply_poll = (rx_frame.data.u8[3] << 8) | rx_frame.data.u8[4];
|
reply_poll = (rx_frame.data.u8[3] << 8) | rx_frame.data.u8[4];
|
||||||
}
|
}
|
||||||
|
@ -360,292 +360,292 @@ void RenaultZoeGen2Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
||||||
battery_soc_max = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
battery_soc_max = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_0:
|
case POLL_CELL_0:
|
||||||
datalayer.battery.status.cell_voltages_mV[0] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[0] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_1:
|
case POLL_CELL_1:
|
||||||
datalayer.battery.status.cell_voltages_mV[1] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[1] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_2:
|
case POLL_CELL_2:
|
||||||
datalayer.battery.status.cell_voltages_mV[2] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[2] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_3:
|
case POLL_CELL_3:
|
||||||
datalayer.battery.status.cell_voltages_mV[3] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[3] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_4:
|
case POLL_CELL_4:
|
||||||
datalayer.battery.status.cell_voltages_mV[4] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[4] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_5:
|
case POLL_CELL_5:
|
||||||
datalayer.battery.status.cell_voltages_mV[5] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[5] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_6:
|
case POLL_CELL_6:
|
||||||
datalayer.battery.status.cell_voltages_mV[6] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[6] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_7:
|
case POLL_CELL_7:
|
||||||
datalayer.battery.status.cell_voltages_mV[7] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[7] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_8:
|
case POLL_CELL_8:
|
||||||
datalayer.battery.status.cell_voltages_mV[8] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[8] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_9:
|
case POLL_CELL_9:
|
||||||
datalayer.battery.status.cell_voltages_mV[9] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[9] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_10:
|
case POLL_CELL_10:
|
||||||
datalayer.battery.status.cell_voltages_mV[10] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[10] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_11:
|
case POLL_CELL_11:
|
||||||
datalayer.battery.status.cell_voltages_mV[11] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[11] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_12:
|
case POLL_CELL_12:
|
||||||
datalayer.battery.status.cell_voltages_mV[12] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[12] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_13:
|
case POLL_CELL_13:
|
||||||
datalayer.battery.status.cell_voltages_mV[13] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[13] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_14:
|
case POLL_CELL_14:
|
||||||
datalayer.battery.status.cell_voltages_mV[14] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[14] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_15:
|
case POLL_CELL_15:
|
||||||
datalayer.battery.status.cell_voltages_mV[15] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[15] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_16:
|
case POLL_CELL_16:
|
||||||
datalayer.battery.status.cell_voltages_mV[16] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[16] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_17:
|
case POLL_CELL_17:
|
||||||
datalayer.battery.status.cell_voltages_mV[17] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[17] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_18:
|
case POLL_CELL_18:
|
||||||
datalayer.battery.status.cell_voltages_mV[18] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[18] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_19:
|
case POLL_CELL_19:
|
||||||
datalayer.battery.status.cell_voltages_mV[19] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[19] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_20:
|
case POLL_CELL_20:
|
||||||
datalayer.battery.status.cell_voltages_mV[20] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[20] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_21:
|
case POLL_CELL_21:
|
||||||
datalayer.battery.status.cell_voltages_mV[21] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[21] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_22:
|
case POLL_CELL_22:
|
||||||
datalayer.battery.status.cell_voltages_mV[22] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[22] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_23:
|
case POLL_CELL_23:
|
||||||
datalayer.battery.status.cell_voltages_mV[23] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[23] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_24:
|
case POLL_CELL_24:
|
||||||
datalayer.battery.status.cell_voltages_mV[24] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[24] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_25:
|
case POLL_CELL_25:
|
||||||
datalayer.battery.status.cell_voltages_mV[25] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[25] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_26:
|
case POLL_CELL_26:
|
||||||
datalayer.battery.status.cell_voltages_mV[26] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[26] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_27:
|
case POLL_CELL_27:
|
||||||
datalayer.battery.status.cell_voltages_mV[27] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[27] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_28:
|
case POLL_CELL_28:
|
||||||
datalayer.battery.status.cell_voltages_mV[28] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[28] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_29:
|
case POLL_CELL_29:
|
||||||
datalayer.battery.status.cell_voltages_mV[29] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[29] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_30:
|
case POLL_CELL_30:
|
||||||
datalayer.battery.status.cell_voltages_mV[30] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[30] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_31:
|
case POLL_CELL_31:
|
||||||
datalayer.battery.status.cell_voltages_mV[31] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[31] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_32:
|
case POLL_CELL_32:
|
||||||
datalayer.battery.status.cell_voltages_mV[32] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[32] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_33:
|
case POLL_CELL_33:
|
||||||
datalayer.battery.status.cell_voltages_mV[33] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[33] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_34:
|
case POLL_CELL_34:
|
||||||
datalayer.battery.status.cell_voltages_mV[34] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[34] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_35:
|
case POLL_CELL_35:
|
||||||
datalayer.battery.status.cell_voltages_mV[35] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[35] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_36:
|
case POLL_CELL_36:
|
||||||
datalayer.battery.status.cell_voltages_mV[36] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[36] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_37:
|
case POLL_CELL_37:
|
||||||
datalayer.battery.status.cell_voltages_mV[37] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[37] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_38:
|
case POLL_CELL_38:
|
||||||
datalayer.battery.status.cell_voltages_mV[38] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[38] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_39:
|
case POLL_CELL_39:
|
||||||
datalayer.battery.status.cell_voltages_mV[39] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[39] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_40:
|
case POLL_CELL_40:
|
||||||
datalayer.battery.status.cell_voltages_mV[40] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[40] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_41:
|
case POLL_CELL_41:
|
||||||
datalayer.battery.status.cell_voltages_mV[41] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[41] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_42:
|
case POLL_CELL_42:
|
||||||
datalayer.battery.status.cell_voltages_mV[42] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[42] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_43:
|
case POLL_CELL_43:
|
||||||
datalayer.battery.status.cell_voltages_mV[43] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[43] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_44:
|
case POLL_CELL_44:
|
||||||
datalayer.battery.status.cell_voltages_mV[44] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[44] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_45:
|
case POLL_CELL_45:
|
||||||
datalayer.battery.status.cell_voltages_mV[45] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[45] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_46:
|
case POLL_CELL_46:
|
||||||
datalayer.battery.status.cell_voltages_mV[46] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[46] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_47:
|
case POLL_CELL_47:
|
||||||
datalayer.battery.status.cell_voltages_mV[47] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[47] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_48:
|
case POLL_CELL_48:
|
||||||
datalayer.battery.status.cell_voltages_mV[48] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[48] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_49:
|
case POLL_CELL_49:
|
||||||
datalayer.battery.status.cell_voltages_mV[49] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[49] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_50:
|
case POLL_CELL_50:
|
||||||
datalayer.battery.status.cell_voltages_mV[50] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[50] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_51:
|
case POLL_CELL_51:
|
||||||
datalayer.battery.status.cell_voltages_mV[51] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[51] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_52:
|
case POLL_CELL_52:
|
||||||
datalayer.battery.status.cell_voltages_mV[52] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[52] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_53:
|
case POLL_CELL_53:
|
||||||
datalayer.battery.status.cell_voltages_mV[53] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[53] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_54:
|
case POLL_CELL_54:
|
||||||
datalayer.battery.status.cell_voltages_mV[54] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[54] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_55:
|
case POLL_CELL_55:
|
||||||
datalayer.battery.status.cell_voltages_mV[55] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[55] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_56:
|
case POLL_CELL_56:
|
||||||
datalayer.battery.status.cell_voltages_mV[56] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[56] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_57:
|
case POLL_CELL_57:
|
||||||
datalayer.battery.status.cell_voltages_mV[57] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[57] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_58:
|
case POLL_CELL_58:
|
||||||
datalayer.battery.status.cell_voltages_mV[58] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[58] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_59:
|
case POLL_CELL_59:
|
||||||
datalayer.battery.status.cell_voltages_mV[59] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[59] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_60:
|
case POLL_CELL_60:
|
||||||
datalayer.battery.status.cell_voltages_mV[60] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[60] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_61:
|
case POLL_CELL_61:
|
||||||
datalayer.battery.status.cell_voltages_mV[61] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[61] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_62:
|
case POLL_CELL_62:
|
||||||
datalayer.battery.status.cell_voltages_mV[62] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[62] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_63:
|
case POLL_CELL_63:
|
||||||
datalayer.battery.status.cell_voltages_mV[63] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[63] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_64:
|
case POLL_CELL_64:
|
||||||
datalayer.battery.status.cell_voltages_mV[64] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[64] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_65:
|
case POLL_CELL_65:
|
||||||
datalayer.battery.status.cell_voltages_mV[65] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[65] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_66:
|
case POLL_CELL_66:
|
||||||
datalayer.battery.status.cell_voltages_mV[66] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[66] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_67:
|
case POLL_CELL_67:
|
||||||
datalayer.battery.status.cell_voltages_mV[67] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[67] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_68:
|
case POLL_CELL_68:
|
||||||
datalayer.battery.status.cell_voltages_mV[68] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[68] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_69:
|
case POLL_CELL_69:
|
||||||
datalayer.battery.status.cell_voltages_mV[69] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[69] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_70:
|
case POLL_CELL_70:
|
||||||
datalayer.battery.status.cell_voltages_mV[70] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[70] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_71:
|
case POLL_CELL_71:
|
||||||
datalayer.battery.status.cell_voltages_mV[71] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[71] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_72:
|
case POLL_CELL_72:
|
||||||
datalayer.battery.status.cell_voltages_mV[72] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[72] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_73:
|
case POLL_CELL_73:
|
||||||
datalayer.battery.status.cell_voltages_mV[73] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[73] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_74:
|
case POLL_CELL_74:
|
||||||
datalayer.battery.status.cell_voltages_mV[74] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[74] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_75:
|
case POLL_CELL_75:
|
||||||
datalayer.battery.status.cell_voltages_mV[75] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[75] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_76:
|
case POLL_CELL_76:
|
||||||
datalayer.battery.status.cell_voltages_mV[76] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[76] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_77:
|
case POLL_CELL_77:
|
||||||
datalayer.battery.status.cell_voltages_mV[77] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[77] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_78:
|
case POLL_CELL_78:
|
||||||
datalayer.battery.status.cell_voltages_mV[78] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[78] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_79:
|
case POLL_CELL_79:
|
||||||
datalayer.battery.status.cell_voltages_mV[79] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[79] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_80:
|
case POLL_CELL_80:
|
||||||
datalayer.battery.status.cell_voltages_mV[80] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[80] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_81:
|
case POLL_CELL_81:
|
||||||
datalayer.battery.status.cell_voltages_mV[81] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[81] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_82:
|
case POLL_CELL_82:
|
||||||
datalayer.battery.status.cell_voltages_mV[82] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[82] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_83:
|
case POLL_CELL_83:
|
||||||
datalayer.battery.status.cell_voltages_mV[83] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[83] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_84:
|
case POLL_CELL_84:
|
||||||
datalayer.battery.status.cell_voltages_mV[84] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[84] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_85:
|
case POLL_CELL_85:
|
||||||
datalayer.battery.status.cell_voltages_mV[85] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[85] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_86:
|
case POLL_CELL_86:
|
||||||
datalayer.battery.status.cell_voltages_mV[86] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[86] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_87:
|
case POLL_CELL_87:
|
||||||
datalayer.battery.status.cell_voltages_mV[87] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[87] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_88:
|
case POLL_CELL_88:
|
||||||
datalayer.battery.status.cell_voltages_mV[88] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[88] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_89:
|
case POLL_CELL_89:
|
||||||
datalayer.battery.status.cell_voltages_mV[89] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[89] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_90:
|
case POLL_CELL_90:
|
||||||
datalayer.battery.status.cell_voltages_mV[90] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[90] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_91:
|
case POLL_CELL_91:
|
||||||
datalayer.battery.status.cell_voltages_mV[91] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[91] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_92:
|
case POLL_CELL_92:
|
||||||
datalayer.battery.status.cell_voltages_mV[92] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[92] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_93:
|
case POLL_CELL_93:
|
||||||
datalayer.battery.status.cell_voltages_mV[93] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[93] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_94:
|
case POLL_CELL_94:
|
||||||
datalayer.battery.status.cell_voltages_mV[94] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[94] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
case POLL_CELL_95:
|
case POLL_CELL_95:
|
||||||
datalayer.battery.status.cell_voltages_mV[95] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
datalayer_battery->status.cell_voltages_mV[95] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
break;
|
break;
|
||||||
default: // Unknown reply
|
default: // Unknown reply
|
||||||
break;
|
break;
|
||||||
|
@ -676,7 +676,7 @@ void RenaultZoeGen2Battery::transmit_can(unsigned long currentMillis) {
|
||||||
counter_373 = (counter_373 + 1) % 10;
|
counter_373 = (counter_373 + 1) % 10;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
transmit_can_frame(&ZOE_373, can_config.battery);
|
transmit_can_frame(&ZOE_373, can_interface);
|
||||||
transmit_can_frame_376();
|
transmit_can_frame_376();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,7 +691,7 @@ void RenaultZoeGen2Battery::transmit_can(unsigned long currentMillis) {
|
||||||
ZOE_POLL_18DADBF1.data.u8[2] = (uint8_t)((currentpoll & 0xFF00) >> 8);
|
ZOE_POLL_18DADBF1.data.u8[2] = (uint8_t)((currentpoll & 0xFF00) >> 8);
|
||||||
ZOE_POLL_18DADBF1.data.u8[3] = (uint8_t)(currentpoll & 0x00FF);
|
ZOE_POLL_18DADBF1.data.u8[3] = (uint8_t)(currentpoll & 0x00FF);
|
||||||
|
|
||||||
transmit_can_frame(&ZOE_POLL_18DADBF1, can_config.battery);
|
transmit_can_frame(&ZOE_POLL_18DADBF1, can_interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentMillis - previousMillis1000 >= INTERVAL_1_S) {
|
if (currentMillis - previousMillis1000 >= INTERVAL_1_S) {
|
||||||
|
@ -707,12 +707,12 @@ void RenaultZoeGen2Battery::setup(void) { // Performs one time setup at startup
|
||||||
strncpy(datalayer.system.info.battery_protocol, Name, 63);
|
strncpy(datalayer.system.info.battery_protocol, Name, 63);
|
||||||
datalayer.system.info.battery_protocol[63] = '\0';
|
datalayer.system.info.battery_protocol[63] = '\0';
|
||||||
datalayer.system.status.battery_allows_contactor_closing = true;
|
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||||
datalayer.battery.info.number_of_cells = 96;
|
datalayer_battery->info.number_of_cells = 96;
|
||||||
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
datalayer_battery->info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
||||||
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
datalayer_battery->info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
||||||
datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
datalayer_battery->info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
||||||
datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
datalayer_battery->info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||||
datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV;
|
datalayer_battery->info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenaultZoeGen2Battery::transmit_can_frame_376(void) {
|
void RenaultZoeGen2Battery::transmit_can_frame_376(void) {
|
||||||
|
@ -733,7 +733,7 @@ void RenaultZoeGen2Battery::transmit_can_frame_376(void) {
|
||||||
ZOE_376.data.u8[4] = hourSeg;
|
ZOE_376.data.u8[4] = hourSeg;
|
||||||
ZOE_376.data.u8[5] = minuteSeg;
|
ZOE_376.data.u8[5] = minuteSeg;
|
||||||
|
|
||||||
transmit_can_frame(&ZOE_376, can_config.battery);
|
transmit_can_frame(&ZOE_376, can_interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenaultZoeGen2Battery::transmit_reset_nvrol_frames(void) {
|
void RenaultZoeGen2Battery::transmit_reset_nvrol_frames(void) {
|
||||||
|
@ -742,14 +742,14 @@ void RenaultZoeGen2Battery::transmit_reset_nvrol_frames(void) {
|
||||||
startTimeNVROL = millis();
|
startTimeNVROL = millis();
|
||||||
// NVROL reset, part 1: send 0x021003AAAAAAAAAA
|
// NVROL reset, part 1: send 0x021003AAAAAAAAAA
|
||||||
ZOE_POLL_18DADBF1.data = {0x02, 0x10, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
|
ZOE_POLL_18DADBF1.data = {0x02, 0x10, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
|
||||||
transmit_can_frame(&ZOE_POLL_18DADBF1, can_config.battery);
|
transmit_can_frame(&ZOE_POLL_18DADBF1, can_interface);
|
||||||
NVROLstateMachine = 1;
|
NVROLstateMachine = 1;
|
||||||
break;
|
break;
|
||||||
case 1: // wait 100 ms
|
case 1: // wait 100 ms
|
||||||
if ((millis() - startTimeNVROL) > INTERVAL_100_MS) {
|
if ((millis() - startTimeNVROL) > INTERVAL_100_MS) {
|
||||||
// NVROL reset, part 2: send 0x043101B00900AAAA
|
// NVROL reset, part 2: send 0x043101B00900AAAA
|
||||||
ZOE_POLL_18DADBF1.data = {0x04, 0x31, 0x01, 0xB0, 0x09, 0x00, 0xAA, 0xAA};
|
ZOE_POLL_18DADBF1.data = {0x04, 0x31, 0x01, 0xB0, 0x09, 0x00, 0xAA, 0xAA};
|
||||||
transmit_can_frame(&ZOE_POLL_18DADBF1, can_config.battery);
|
transmit_can_frame(&ZOE_POLL_18DADBF1, can_interface);
|
||||||
startTimeNVROL = millis(); //Reset time start, so we can check time for next step
|
startTimeNVROL = millis(); //Reset time start, so we can check time for next step
|
||||||
NVROLstateMachine = 2;
|
NVROLstateMachine = 2;
|
||||||
}
|
}
|
||||||
|
@ -758,7 +758,7 @@ void RenaultZoeGen2Battery::transmit_reset_nvrol_frames(void) {
|
||||||
if ((millis() - startTimeNVROL) > INTERVAL_1_S) {
|
if ((millis() - startTimeNVROL) > INTERVAL_1_S) {
|
||||||
// Enable temporisation before sleep, part 1: send 0x021003AAAAAAAAAA
|
// Enable temporisation before sleep, part 1: send 0x021003AAAAAAAAAA
|
||||||
ZOE_POLL_18DADBF1.data = {0x02, 0x10, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
|
ZOE_POLL_18DADBF1.data = {0x02, 0x10, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
|
||||||
transmit_can_frame(&ZOE_POLL_18DADBF1, can_config.battery);
|
transmit_can_frame(&ZOE_POLL_18DADBF1, can_interface);
|
||||||
startTimeNVROL = millis(); //Reset time start, so we can check time for next step
|
startTimeNVROL = millis(); //Reset time start, so we can check time for next step
|
||||||
NVROLstateMachine = 3;
|
NVROLstateMachine = 3;
|
||||||
}
|
}
|
||||||
|
@ -767,7 +767,7 @@ void RenaultZoeGen2Battery::transmit_reset_nvrol_frames(void) {
|
||||||
if ((millis() - startTimeNVROL) > INTERVAL_100_MS) {
|
if ((millis() - startTimeNVROL) > INTERVAL_100_MS) {
|
||||||
// Enable temporisation before sleep, part 2: send 0x042E928101AAAAAA
|
// Enable temporisation before sleep, part 2: send 0x042E928101AAAAAA
|
||||||
ZOE_POLL_18DADBF1.data = {0x04, 0x2E, 0x92, 0x81, 0x01, 0xAA, 0xAA, 0xAA};
|
ZOE_POLL_18DADBF1.data = {0x04, 0x2E, 0x92, 0x81, 0x01, 0xAA, 0xAA, 0xAA};
|
||||||
transmit_can_frame(&ZOE_POLL_18DADBF1, can_config.battery);
|
transmit_can_frame(&ZOE_POLL_18DADBF1, can_interface);
|
||||||
// Set data back to init values, we are done with the ZOE_POLL_18DADBF1 frame
|
// Set data back to init values, we are done with the ZOE_POLL_18DADBF1 frame
|
||||||
ZOE_POLL_18DADBF1.data = {0x03, 0x22, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00};
|
ZOE_POLL_18DADBF1.data = {0x03, 0x22, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
poll_index = 0;
|
poll_index = 0;
|
||||||
|
|
|
@ -11,11 +11,28 @@
|
||||||
|
|
||||||
class RenaultZoeGen2Battery : public CanBattery {
|
class RenaultZoeGen2Battery : public CanBattery {
|
||||||
public:
|
public:
|
||||||
|
// Use this constructor for the second battery.
|
||||||
|
RenaultZoeGen2Battery(DATALAYER_BATTERY_TYPE* datalayer_ptr, DATALAYER_INFO_ZOE_PH2* extended,
|
||||||
|
CAN_Interface targetCan)
|
||||||
|
: CanBattery(targetCan) {
|
||||||
|
datalayer_battery = datalayer_ptr;
|
||||||
|
allows_contactor_closing = nullptr;
|
||||||
|
datalayer_zoePH2 = extended;
|
||||||
|
|
||||||
|
battery_pack_voltage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the default constructor to create the first or single battery.
|
||||||
|
RenaultZoeGen2Battery() {
|
||||||
|
datalayer_battery = &datalayer.battery;
|
||||||
|
allows_contactor_closing = &datalayer.system.status.battery_allows_contactor_closing;
|
||||||
|
datalayer_zoePH2 = &datalayer_extended.zoePH2;
|
||||||
|
}
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Renault Zoe Gen2 50kWh";
|
static constexpr const char* Name = "Renault Zoe Gen2 50kWh";
|
||||||
|
|
||||||
bool supports_reset_NVROL() { return true; }
|
bool supports_reset_NVROL() { return true; }
|
||||||
|
|
||||||
|
@ -25,6 +42,13 @@ class RenaultZoeGen2Battery : public CanBattery {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RenaultZoeGen2HtmlRenderer renderer;
|
RenaultZoeGen2HtmlRenderer renderer;
|
||||||
|
|
||||||
|
DATALAYER_BATTERY_TYPE* datalayer_battery;
|
||||||
|
DATALAYER_INFO_ZOE_PH2* datalayer_zoePH2;
|
||||||
|
|
||||||
|
// If not null, this battery decides when the contactor can be closed and writes the value here.
|
||||||
|
bool* allows_contactor_closing;
|
||||||
|
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 4100; //5000 = 500.0V
|
static const int MAX_PACK_VOLTAGE_DV = 4100; //5000 = 500.0V
|
||||||
static const int MIN_PACK_VOLTAGE_DV = 3000;
|
static const int MIN_PACK_VOLTAGE_DV = 3000;
|
||||||
static const int MAX_CELL_DEVIATION_MV = 150;
|
static const int MAX_CELL_DEVIATION_MV = 150;
|
||||||
|
@ -174,7 +198,7 @@ class RenaultZoeGen2Battery : public CanBattery {
|
||||||
uint16_t battery_soc = 0;
|
uint16_t battery_soc = 0;
|
||||||
uint16_t battery_usable_soc = 5000;
|
uint16_t battery_usable_soc = 5000;
|
||||||
uint16_t battery_soh = 10000;
|
uint16_t battery_soh = 10000;
|
||||||
uint16_t battery_pack_voltage = 370;
|
uint16_t battery_pack_voltage = 3700;
|
||||||
uint16_t battery_max_cell_voltage = 3700;
|
uint16_t battery_max_cell_voltage = 3700;
|
||||||
uint16_t battery_min_cell_voltage = 3700;
|
uint16_t battery_min_cell_voltage = 3700;
|
||||||
uint16_t battery_12v = 12000;
|
uint16_t battery_12v = 12000;
|
||||||
|
|
|
@ -11,11 +11,13 @@
|
||||||
|
|
||||||
class RjxzsBms : public CanBattery {
|
class RjxzsBms : public CanBattery {
|
||||||
public:
|
public:
|
||||||
|
RjxzsBms() : CanBattery(true) {}
|
||||||
|
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "RJXZS BMS, DIY battery";
|
static constexpr const char* Name = "RJXZS BMS, DIY battery";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Tweak these according to your battery build */
|
/* Tweak these according to your battery build */
|
||||||
|
@ -103,7 +105,4 @@ class RjxzsBms : public CanBattery {
|
||||||
bool discharging_active = false;
|
bool discharging_active = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Do not modify any rows below*/
|
|
||||||
#define NATIVECAN_250KBPS
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,7 +27,7 @@ class SantaFePhevBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Santa Fe PHEV";
|
static constexpr const char* Name = "Santa Fe PHEV";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DATALAYER_BATTERY_TYPE* datalayer_battery;
|
DATALAYER_BATTERY_TYPE* datalayer_battery;
|
||||||
|
|
|
@ -15,7 +15,7 @@ class SimpBmsBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "SIMPBMS battery";
|
static constexpr const char* Name = "SIMPBMS battery";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* DEFAULT VALUES BMS will send configured */
|
/* DEFAULT VALUES BMS will send configured */
|
||||||
|
|
|
@ -15,7 +15,7 @@ class SonoBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Sono Motors Sion 64kWh LFP ";
|
static constexpr const char* Name = "Sono Motors Sion 64kWh LFP ";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_PACK_VOLTAGE_DV = 5000; //5000 = 500.0V
|
static const int MAX_PACK_VOLTAGE_DV = 5000; //5000 = 500.0V
|
||||||
|
|
|
@ -513,14 +513,14 @@ class TeslaModel3YBattery : public TeslaBattery {
|
||||||
operate_contactors = true;
|
operate_contactors = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static constexpr char* Name = "Tesla Model 3/Y";
|
static constexpr const char* Name = "Tesla Model 3/Y";
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class TeslaModelSXBattery : public TeslaBattery {
|
class TeslaModelSXBattery : public TeslaBattery {
|
||||||
public:
|
public:
|
||||||
TeslaModelSXBattery() { operate_contactors = true; }
|
TeslaModelSXBattery() { operate_contactors = true; }
|
||||||
static constexpr char* Name = "Tesla Model S/X";
|
static constexpr const char* Name = "Tesla Model S/X";
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ class TestFakeBattery : public CanBattery {
|
||||||
allows_contactor_closing = &datalayer.system.status.battery_allows_contactor_closing;
|
allows_contactor_closing = &datalayer.system.status.battery_allows_contactor_closing;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr char* Name = "Fake battery for testing purposes";
|
static constexpr const char* Name = "Fake battery for testing purposes";
|
||||||
|
|
||||||
virtual void setup();
|
virtual void setup();
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
|
|
|
@ -102,8 +102,6 @@ void VolvoSpaBattery::
|
||||||
logging.println(MAX_U);
|
logging.println(MAX_U);
|
||||||
logging.print("Battery minimum voltage limit: ");
|
logging.print("Battery minimum voltage limit: ");
|
||||||
logging.println(MIN_U);
|
logging.println(MIN_U);
|
||||||
logging.print("Remaining Energy: ");
|
|
||||||
logging.println(remaining_capacity);
|
|
||||||
logging.print("Discharge limit: ");
|
logging.print("Discharge limit: ");
|
||||||
logging.println(HvBattPwrLimDchaSoft);
|
logging.println(HvBattPwrLimDchaSoft);
|
||||||
logging.print("Battery Error Indication: ");
|
logging.print("Battery Error Indication: ");
|
||||||
|
|
|
@ -16,7 +16,7 @@ class VolvoSpaBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Volvo / Polestar 69/78kWh SPA battery";
|
static constexpr const char* Name = "Volvo / Polestar 69/78kWh SPA battery";
|
||||||
|
|
||||||
bool supports_reset_DTC() { return true; }
|
bool supports_reset_DTC() { return true; }
|
||||||
void reset_DTC() { datalayer_extended.VolvoPolestar.UserRequestDTCreset = true; }
|
void reset_DTC() { datalayer_extended.VolvoPolestar.UserRequestDTCreset = true; }
|
||||||
|
|
|
@ -16,7 +16,7 @@ class VolvoSpaHybridBattery : public CanBattery {
|
||||||
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
|
||||||
virtual void update_values();
|
virtual void update_values();
|
||||||
virtual void transmit_can(unsigned long currentMillis);
|
virtual void transmit_can(unsigned long currentMillis);
|
||||||
static constexpr char* Name = "Volvo PHEV battery";
|
static constexpr const char* Name = "Volvo PHEV battery";
|
||||||
|
|
||||||
bool supports_reset_DTC() { return true; }
|
bool supports_reset_DTC() { return true; }
|
||||||
void reset_DTC() { datalayer_extended.VolvoHybrid.UserRequestDTCreset = true; }
|
void reset_DTC() { datalayer_extended.VolvoHybrid.UserRequestDTCreset = true; }
|
||||||
|
|
|
@ -14,7 +14,7 @@ class ChevyVoltCharger : public CanCharger {
|
||||||
ChevyVoltCharger() : CanCharger(ChargerType::ChevyVolt) {}
|
ChevyVoltCharger() : CanCharger(ChargerType::ChevyVolt) {}
|
||||||
|
|
||||||
const char* name() { return Name; }
|
const char* name() { return Name; }
|
||||||
static constexpr char* Name = "Chevy Volt Gen1 Charger";
|
static constexpr const char* Name = "Chevy Volt Gen1 Charger";
|
||||||
|
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
|
|
|
@ -14,7 +14,7 @@ class NissanLeafCharger : public CanCharger {
|
||||||
NissanLeafCharger() : CanCharger(ChargerType::NissanLeaf) {}
|
NissanLeafCharger() : CanCharger(ChargerType::NissanLeaf) {}
|
||||||
|
|
||||||
const char* name() { return Name; }
|
const char* name() { return Name; }
|
||||||
static constexpr char* Name = "Nissan LEAF 2013-2024 PDM charger";
|
static constexpr const char* Name = "Nissan LEAF 2013-2024 PDM charger";
|
||||||
|
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
|
|
|
@ -9,6 +9,6 @@ class CanReceiver {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Register a receiver object for a given CAN interface
|
// Register a receiver object for a given CAN interface
|
||||||
void register_can_receiver(CanReceiver* receiver, CAN_Interface interface);
|
void register_can_receiver(CanReceiver* receiver, CAN_Interface interface, bool halfSpeed = false);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,6 +2,24 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "../../include.h"
|
#include "../../include.h"
|
||||||
#include "src/devboard/sdcard/sdcard.h"
|
#include "src/devboard/sdcard/sdcard.h"
|
||||||
|
#include "src/devboard/utils/logging.h"
|
||||||
|
|
||||||
|
struct CanReceiverRegistration {
|
||||||
|
CanReceiver* receiver;
|
||||||
|
bool halfSpeed;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::multimap<CAN_Interface, CanReceiverRegistration> can_receivers;
|
||||||
|
|
||||||
|
bool hasHalfSpeedReceivers(const CAN_Interface& iface) {
|
||||||
|
auto range = can_receivers.equal_range(iface);
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
if (it->second.halfSpeed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Parameters
|
// Parameters
|
||||||
CAN_device_t CAN_cfg; // CAN Config
|
CAN_device_t CAN_cfg; // CAN Config
|
||||||
|
@ -27,21 +45,25 @@ ACAN2517FD canfd(MCP2517_CS, SPI2517, MCP2517_INT);
|
||||||
// Initialization functions
|
// Initialization functions
|
||||||
|
|
||||||
void init_CAN() {
|
void init_CAN() {
|
||||||
|
DEBUG_PRINTF("init_CAN called\n");
|
||||||
// CAN pins
|
// CAN pins
|
||||||
#ifdef CAN_SE_PIN
|
#ifdef CAN_SE_PIN
|
||||||
pinMode(CAN_SE_PIN, OUTPUT);
|
pinMode(CAN_SE_PIN, OUTPUT);
|
||||||
digitalWrite(CAN_SE_PIN, LOW);
|
digitalWrite(CAN_SE_PIN, LOW);
|
||||||
#endif // CAN_SE_PIN
|
#endif // CAN_SE_PIN
|
||||||
CAN_cfg.speed = CAN_SPEED_500KBPS;
|
|
||||||
#ifdef NATIVECAN_250KBPS // Some component is requesting lower CAN speed
|
// Half-speed currently only supported for CAN_NATIVE
|
||||||
CAN_cfg.speed = CAN_SPEED_250KBPS;
|
auto anyHalfSpeedNative = hasHalfSpeedReceivers(CAN_Interface::CAN_NATIVE);
|
||||||
#endif // NATIVECAN_250KBPS
|
|
||||||
|
CAN_cfg.speed = anyHalfSpeedNative ? CAN_SPEED_250KBPS : CAN_SPEED_500KBPS;
|
||||||
CAN_cfg.tx_pin_id = CAN_TX_PIN;
|
CAN_cfg.tx_pin_id = CAN_TX_PIN;
|
||||||
CAN_cfg.rx_pin_id = CAN_RX_PIN;
|
CAN_cfg.rx_pin_id = CAN_RX_PIN;
|
||||||
CAN_cfg.rx_queue = xQueueCreate(rx_queue_size, sizeof(CAN_frame_t));
|
CAN_cfg.rx_queue = xQueueCreate(rx_queue_size, sizeof(CAN_frame_t));
|
||||||
// Init CAN Module
|
// Init CAN Module
|
||||||
ESP32Can.CANInit();
|
ESP32Can.CANInit();
|
||||||
|
|
||||||
|
DEBUG_PRINTF("init_CAN performed\n");
|
||||||
|
|
||||||
#ifdef CAN_ADDON
|
#ifdef CAN_ADDON
|
||||||
#ifdef DEBUG_LOG
|
#ifdef DEBUG_LOG
|
||||||
logging.println("Dual CAN Bus (ESP32+MCP2515) selected");
|
logging.println("Dual CAN Bus (ESP32+MCP2515) selected");
|
||||||
|
@ -119,6 +141,7 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface) {
|
||||||
|
|
||||||
switch (interface) {
|
switch (interface) {
|
||||||
case CAN_NATIVE:
|
case CAN_NATIVE:
|
||||||
|
|
||||||
CAN_frame_t frame;
|
CAN_frame_t frame;
|
||||||
frame.MsgID = tx_frame->ID;
|
frame.MsgID = tx_frame->ID;
|
||||||
frame.FIR.B.FF = tx_frame->ext_ID ? CAN_frame_ext : CAN_frame_std;
|
frame.FIR.B.FF = tx_frame->ext_ID ? CAN_frame_ext : CAN_frame_std;
|
||||||
|
@ -276,10 +299,9 @@ void print_can_frame(CAN_frame frame, frameDirection msgDir) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::multimap<CAN_Interface, CanReceiver*> can_receivers;
|
void register_can_receiver(CanReceiver* receiver, CAN_Interface interface, bool halfSpeed) {
|
||||||
|
can_receivers.insert({interface, {receiver, halfSpeed}});
|
||||||
void register_can_receiver(CanReceiver* receiver, CAN_Interface interface) {
|
DEBUG_PRINTF("CAN receiver registered, total: %d\n", can_receivers.size());
|
||||||
can_receivers.insert({interface, receiver});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void map_can_frame_to_variable(CAN_frame* rx_frame, CAN_Interface interface) {
|
void map_can_frame_to_variable(CAN_frame* rx_frame, CAN_Interface interface) {
|
||||||
|
@ -302,7 +324,7 @@ void map_can_frame_to_variable(CAN_frame* rx_frame, CAN_Interface interface) {
|
||||||
|
|
||||||
for (auto it = receivers.first; it != receivers.second; ++it) {
|
for (auto it = receivers.first; it != receivers.second; ++it) {
|
||||||
auto& receiver = it->second;
|
auto& receiver = it->second;
|
||||||
receiver->receive_can_frame(rx_frame);
|
receiver.receiver->receive_can_frame(rx_frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,19 @@ typedef struct {
|
||||||
bool warning_Charger_not_responding = false;
|
bool warning_Charger_not_responding = false;
|
||||||
} DATALAYER_INFO_CELLPOWER;
|
} DATALAYER_INFO_CELLPOWER;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool UserRequestRestart = false;
|
||||||
|
bool UserRequestStop = false;
|
||||||
|
bool FaultBatteryVoltageDeviation = false;
|
||||||
|
bool FaultHighBatteryTemperature = false;
|
||||||
|
bool FaultBatteryCurrentDeviation = false;
|
||||||
|
bool FaultBatteryUnderVoltage = false;
|
||||||
|
bool FaultBatteryOverVoltage = false;
|
||||||
|
uint8_t CHADEMO_Status = 0;
|
||||||
|
uint8_t ControlProtocolNumberEV = 0;
|
||||||
|
|
||||||
|
} DATALAYER_INFO_CHADEMO;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t soc_z = 0;
|
uint16_t soc_z = 0;
|
||||||
uint16_t soc_u = 0;
|
uint16_t soc_u = 0;
|
||||||
|
@ -885,6 +898,7 @@ class DataLayerExtended {
|
||||||
DATALAYER_INFO_BMWI3 bmwi3;
|
DATALAYER_INFO_BMWI3 bmwi3;
|
||||||
DATALAYER_INFO_BYDATTO3 bydAtto3;
|
DATALAYER_INFO_BYDATTO3 bydAtto3;
|
||||||
DATALAYER_INFO_CELLPOWER cellpower;
|
DATALAYER_INFO_CELLPOWER cellpower;
|
||||||
|
DATALAYER_INFO_CHADEMO chademo;
|
||||||
DATALAYER_INFO_CMFAEV CMFAEV;
|
DATALAYER_INFO_CMFAEV CMFAEV;
|
||||||
DATALAYER_INFO_ECMP stellantisECMP;
|
DATALAYER_INFO_ECMP stellantisECMP;
|
||||||
DATALAYER_INFO_GEELY_GEOMETRY_C geometryC;
|
DATALAYER_INFO_GEELY_GEOMETRY_C geometryC;
|
||||||
|
|
|
@ -17,4 +17,11 @@ class Logging : public Print {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Logging logging;
|
extern Logging logging;
|
||||||
|
|
||||||
|
#ifdef DEBUG_LOG
|
||||||
|
#define DEBUG_PRINTF(fmt, ...) logging.printf(fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_PRINTF(fmt, ...) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // __LOGGING_H__
|
#endif // __LOGGING_H__
|
||||||
|
|
|
@ -12,6 +12,15 @@ std::vector<BatteryCommand> battery_commands = {
|
||||||
[](Battery* b) {
|
[](Battery* b) {
|
||||||
b->clear_isolation();
|
b->clear_isolation();
|
||||||
}},
|
}},
|
||||||
|
{"chademoRestart", "Restart", "restart the V2X session?",
|
||||||
|
[](Battery* b) { return b && b->supports_chademo_restart(); },
|
||||||
|
[](Battery* b) {
|
||||||
|
b->chademo_restart();
|
||||||
|
}},
|
||||||
|
{"chademoStop", "Stop", "stop V2X?", [](Battery* b) { return b && b->supports_chademo_restart(); },
|
||||||
|
[](Battery* b) {
|
||||||
|
b->chademo_restart();
|
||||||
|
}},
|
||||||
{"resetBMS", "BMS reset", "reset the BMS?", [](Battery* b) { return b && b->supports_reset_BMS(); },
|
{"resetBMS", "BMS reset", "reset the BMS?", [](Battery* b) { return b && b->supports_reset_BMS(); },
|
||||||
[](Battery* b) {
|
[](Battery* b) {
|
||||||
b->reset_BMS();
|
b->reset_BMS();
|
||||||
|
|
|
@ -1258,7 +1258,7 @@ String processor(const String& var) {
|
||||||
|
|
||||||
if (contactor_control_enabled) {
|
if (contactor_control_enabled) {
|
||||||
content += "<h4>Contactors controlled by emulator, state: ";
|
content += "<h4>Contactors controlled by emulator, state: ";
|
||||||
if (datalayer.system.status.contactors_battery2_engaged) {
|
if (datalayer.system.status.contactors_engaged) {
|
||||||
content += "<span style='color: green;'>ON</span>";
|
content += "<span style='color: green;'>ON</span>";
|
||||||
} else {
|
} else {
|
||||||
content += "<span style='color: red;'>OFF</span>";
|
content += "<span style='color: red;'>OFF</span>";
|
||||||
|
|
|
@ -14,7 +14,7 @@ class AforeCanInverter : public CanInverterProtocol {
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
void update_values();
|
void update_values();
|
||||||
static constexpr char* Name = "Afore battery over CAN";
|
static constexpr const char* Name = "Afore battery over CAN";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* The code is following the Afore 2.3 CAN standard, little-endian, 500kbps, from 2023.08.07 */
|
/* The code is following the Afore 2.3 CAN standard, little-endian, 500kbps, from 2023.08.07 */
|
||||||
|
|
|
@ -14,7 +14,7 @@ class BydCanInverter : public CanInverterProtocol {
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
void update_values();
|
void update_values();
|
||||||
static constexpr char* Name = "BYD Battery-Box Premium HVS over CAN Bus";
|
static constexpr const char* Name = "BYD Battery-Box Premium HVS over CAN Bus";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void send_initial_data();
|
void send_initial_data();
|
||||||
|
|
|
@ -12,7 +12,7 @@ class BydModbusInverter : public ModbusInverterProtocol {
|
||||||
public:
|
public:
|
||||||
void setup();
|
void setup();
|
||||||
void update_values();
|
void update_values();
|
||||||
static constexpr char* Name = "BYD 11kWh HVM battery over Modbus RTU";
|
static constexpr const char* Name = "BYD 11kWh HVM battery over Modbus RTU";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handle_static_data();
|
void handle_static_data();
|
||||||
|
|
|
@ -15,7 +15,7 @@ class FerroampCanInverter : public CanInverterProtocol {
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
|
|
||||||
static constexpr char* Name = "Ferroamp Pylon battery over CAN bus";
|
static constexpr const char* Name = "Ferroamp Pylon battery over CAN bus";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void send_system_data();
|
void send_system_data();
|
||||||
|
|
|
@ -14,7 +14,7 @@ class FoxessCanInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "FoxESS compatible HV2600/ECS4100 battery";
|
static constexpr const char* Name = "FoxESS compatible HV2600/ECS4100 battery";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int16_t temperature_average = 0;
|
int16_t temperature_average = 0;
|
||||||
|
|
|
@ -14,7 +14,7 @@ class GrowattHvInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "Growatt High Voltage protocol via CAN";
|
static constexpr const char* Name = "Growatt High Voltage protocol via CAN";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//Total number of Cells (1-512)
|
//Total number of Cells (1-512)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class GrowattLvInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "Growatt Low Voltage (48V) protocol via CAN";
|
static constexpr const char* Name = "Growatt Low Voltage (48V) protocol via CAN";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//Actual content messages
|
//Actual content messages
|
||||||
|
|
|
@ -22,7 +22,7 @@ class KostalInverterProtocol : public Rs485InverterProtocol {
|
||||||
void setup();
|
void setup();
|
||||||
void receive();
|
void receive();
|
||||||
void update_values();
|
void update_values();
|
||||||
static constexpr char* Name = "BYD battery via Kostal RS485";
|
static constexpr const char* Name = "BYD battery via Kostal RS485";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int baud_rate() { return 57600; }
|
int baud_rate() { return 57600; }
|
||||||
|
|
|
@ -14,7 +14,7 @@ class PylonInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "Pylontech battery over CAN bus";
|
static constexpr const char* Name = "Pylontech battery over CAN bus";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void send_system_data();
|
void send_system_data();
|
||||||
|
|
|
@ -14,7 +14,7 @@ class PylonLvInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "Pylontech LV battery over CAN bus";
|
static constexpr const char* Name = "Pylontech LV battery over CAN bus";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void send_system_data();
|
void send_system_data();
|
||||||
|
|
|
@ -14,7 +14,7 @@ class SchneiderInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "Schneider V2 SE BMS CAN";
|
static constexpr const char* Name = "Schneider V2 SE BMS CAN";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int STATE_OFFLINE = 0;
|
static const int STATE_OFFLINE = 0;
|
||||||
|
|
|
@ -15,7 +15,7 @@ class SmaBydHInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "BYD over SMA CAN";
|
static constexpr const char* Name = "BYD over SMA CAN";
|
||||||
|
|
||||||
virtual bool controls_contactor() { return true; }
|
virtual bool controls_contactor() { return true; }
|
||||||
virtual bool allows_contactor_closing() { return digitalRead(INVERTER_CONTACTOR_ENABLE_PIN) == 1; }
|
virtual bool allows_contactor_closing() { return digitalRead(INVERTER_CONTACTOR_ENABLE_PIN) == 1; }
|
||||||
|
|
|
@ -15,7 +15,7 @@ class SmaBydHvsInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "BYD Battery-Box HVS over SMA CAN";
|
static constexpr const char* Name = "BYD Battery-Box HVS over SMA CAN";
|
||||||
|
|
||||||
virtual bool controls_contactor() { return true; }
|
virtual bool controls_contactor() { return true; }
|
||||||
virtual bool allows_contactor_closing() { return digitalRead(INVERTER_CONTACTOR_ENABLE_PIN) == 1; }
|
virtual bool allows_contactor_closing() { return digitalRead(INVERTER_CONTACTOR_ENABLE_PIN) == 1; }
|
||||||
|
|
|
@ -14,7 +14,7 @@ class SmaLvInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "SMA Low Voltage (48V) protocol via CAN";
|
static constexpr const char* Name = "SMA Low Voltage (48V) protocol via CAN";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int READY_STATE = 0x03;
|
static const int READY_STATE = 0x03;
|
||||||
|
|
|
@ -15,7 +15,7 @@ class SmaTripowerInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "SMA Tripower CAN";
|
static constexpr const char* Name = "SMA Tripower CAN";
|
||||||
|
|
||||||
virtual bool controls_contactor() { return true; }
|
virtual bool controls_contactor() { return true; }
|
||||||
virtual bool allows_contactor_closing() { return digitalRead(INVERTER_CONTACTOR_ENABLE_PIN) == 1; }
|
virtual bool allows_contactor_closing() { return digitalRead(INVERTER_CONTACTOR_ENABLE_PIN) == 1; }
|
||||||
|
|
|
@ -14,7 +14,7 @@ class SofarInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "Sofar BMS (Extended Frame) over CAN bus";
|
static constexpr const char* Name = "Sofar BMS (Extended Frame) over CAN bus";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send
|
unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send
|
||||||
|
|
|
@ -14,7 +14,7 @@ class SolaxInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "SolaX Triple Power LFP over CAN bus";
|
static constexpr const char* Name = "SolaX Triple Power LFP over CAN bus";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Timeout in milliseconds
|
// Timeout in milliseconds
|
||||||
|
|
|
@ -14,7 +14,7 @@ class SungrowInverter : public CanInverterProtocol {
|
||||||
void update_values();
|
void update_values();
|
||||||
void transmit_can(unsigned long currentMillis);
|
void transmit_can(unsigned long currentMillis);
|
||||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||||
static constexpr char* Name = "Sungrow SBR064 battery over CAN bus";
|
static constexpr const char* Name = "Sungrow SBR064 battery over CAN bus";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned long previousMillis500ms = 0;
|
unsigned long previousMillis500ms = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue