Merge from main

This commit is contained in:
Jaakko Haakana 2025-07-02 19:09:01 +03:00
commit 2602316369
76 changed files with 128 additions and 107 deletions

View file

@ -109,9 +109,9 @@ void setup() {
return; return;
} }
setup_battery(); setup_battery();
setup_can_shunt(); setup_can_shunt();
// Init CAN only after any CAN receivers have had a chance to register.
if (!init_CAN()) { if (!init_CAN()) {
return; return;
} }
@ -155,6 +155,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
@ -223,6 +225,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*) {

View file

@ -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;
@ -131,6 +132,7 @@ const char* name_for_battery_type(BatteryType type) {
return nullptr; return nullptr;
} }
} }
#endif
#ifdef LFP_CHEMISTRY #ifdef LFP_CHEMISTRY
const battery_chemistry_enum battery_chemistry_default = battery_chemistry_enum::LFP; const battery_chemistry_enum battery_chemistry_default = battery_chemistry_enum::LFP;

View file

@ -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"

View file

@ -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; }

View file

@ -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;

View file

@ -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 **/

View file

@ -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; }

View file

@ -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; }

View file

@ -18,7 +18,7 @@ class CellPowerBms : 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 = "Cellpower BMS"; static constexpr const char* Name = "Cellpower BMS";
BatteryHtmlRenderer& get_status_renderer() { return renderer; } BatteryHtmlRenderer& get_status_renderer() { return renderer; }

View file

@ -714,7 +714,7 @@ void ChademoBattery::handle_chademo_sequence() {
* with timers to have higher confidence of certain conditions hitting * with timers to have higher confidence of certain conditions hitting
* a steady state * a steady state
*/ */
LOG_PRINTLN("CHADEMO plug is not inserted, cannot connect d2 relay to begin initialization."); DEBUG_PRINTLN("CHADEMO plug is not inserted, cannot connect d2 relay to begin initialization.");
CHADEMO_Status = CHADEMO_IDLE; CHADEMO_Status = CHADEMO_IDLE;
} }
break; break;
@ -723,7 +723,7 @@ void ChademoBattery::handle_chademo_sequence() {
* Used for triggers/error handling elsewhere; * Used for triggers/error handling elsewhere;
* State change to CHADEMO_NEGOTIATE occurs in handle_incoming_can_frame_battery(..) * State change to CHADEMO_NEGOTIATE occurs in handle_incoming_can_frame_battery(..)
*/ */
LOG_PRINTLN("Awaiting initial vehicle CAN to trigger negotiation"); DEBUG_PRINTLN("Awaiting initial vehicle CAN to trigger negotiation");
evse_init(); evse_init();
break; break;
case CHADEMO_NEGOTIATE: case CHADEMO_NEGOTIATE:

View file

@ -30,7 +30,7 @@ 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"; static constexpr const char* Name = "Chademo V2X mode";
private: private:
gpio_num_t pin2, pin10, pin4, pin7, pin_lock, precharge, positive_contactor; gpio_num_t pin2, pin10, pin4, pin7, pin_lock, precharge, positive_contactor;

View file

@ -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; }

View file

@ -1,10 +1,10 @@
#include "CanBattery.h" #include "CanBattery.h"
#include "../../src/include.h" #include "../../src/include.h"
CanBattery::CanBattery(bool low_speed) { 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, low_speed); register_can_receiver(this, can_interface, halfSpeed);
} }
void CanBattery::slow_down_can() { void CanBattery::slow_down_can() {

View file

@ -23,12 +23,12 @@ class CanBattery : public Battery, Transmitter, CanReceiver {
protected: protected:
CAN_Interface can_interface; CAN_Interface can_interface;
CanBattery(bool low_speed = false); CanBattery(bool halfSpeed = false);
CanBattery(CAN_Interface interface, bool low_speed = false) { 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, low_speed); register_can_receiver(this, can_interface, halfSpeed);
} }
void slow_down_can(); void slow_down_can();

View file

@ -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 */

View file

@ -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; }

View file

@ -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)

View file

@ -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; }

View file

@ -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

View file

@ -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

View file

@ -16,7 +16,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);

View file

@ -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; }

View file

@ -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

View file

@ -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; }

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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

View file

@ -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)

View file

@ -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);
} }
} }

View file

@ -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; }

View file

@ -15,7 +15,7 @@ class RenaultZoeGen2Battery : 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 Gen2 50kWh"; static constexpr const char* Name = "Renault Zoe Gen2 50kWh";
bool supports_reset_NVROL() { return true; } bool supports_reset_NVROL() { return true; }

View file

@ -17,7 +17,7 @@ class RjxzsBms : 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 = "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 */

View file

@ -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;

View file

@ -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 */

View file

@ -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

View file

@ -3,6 +3,7 @@
#include "src/communication/Transmitter.h" #include "src/communication/Transmitter.h"
#include "src/communication/can/CanReceiver.h" #include "src/communication/can/CanReceiver.h"
#include "src/communication/can/comm_can.h"
#include "src/devboard/utils/types.h" #include "src/devboard/utils/types.h"
class CanShunt : public Transmitter, CanReceiver { class CanShunt : public Transmitter, CanReceiver {

View file

@ -514,14 +514,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);
}; };

View file

@ -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);

View file

@ -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; }

View file

@ -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; }

View file

@ -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);

View file

@ -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);

View file

@ -6,6 +6,14 @@
#include "../../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h" #include "../../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h"
#include "../../lib/pierremolinaro-acan2515/ACAN2515.h" #include "../../lib/pierremolinaro-acan2515/ACAN2515.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;
// Parameters // Parameters
CAN_device_t CAN_cfg; // CAN Config CAN_device_t CAN_cfg; // CAN Config
@ -22,17 +30,11 @@ const bool use_canfd_as_can_default = false;
#endif #endif
bool use_canfd_as_can = use_canfd_as_can_default; bool use_canfd_as_can = use_canfd_as_can_default;
struct CanInterfaceRegistration {
CanReceiver* receiver;
bool lowSpeed;
};
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);
static std::multimap<CAN_Interface, CanInterfaceRegistration> 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, bool low_speed) { DEBUG_PRINTF("CAN receiver registered, total: %d\n", can_receivers.size());
can_receivers.insert({interface, {receiver, low_speed}});
} }
static const uint32_t QUARTZ_FREQUENCY = CRYSTAL_FREQUENCY_MHZ * 1000000UL; //MHZ configured in USER_SETTINGS.h static const uint32_t QUARTZ_FREQUENCY = CRYSTAL_FREQUENCY_MHZ * 1000000UL; //MHZ configured in USER_SETTINGS.h
@ -65,7 +67,7 @@ bool init_CAN() {
digitalWrite(se_pin, LOW); digitalWrite(se_pin, LOW);
} }
if (nativeIt->second.lowSpeed) { if (nativeIt->second.halfSpeed) {
CAN_cfg.speed = CAN_SPEED_250KBPS; CAN_cfg.speed = CAN_SPEED_250KBPS;
} else { } else {
CAN_cfg.speed = CAN_SPEED_500KBPS; CAN_cfg.speed = CAN_SPEED_500KBPS;
@ -104,7 +106,7 @@ bool init_CAN() {
SPI2515.begin(sck_pin, miso_pin, mosi_pin); SPI2515.begin(sck_pin, miso_pin, mosi_pin);
// CAN bit rate 250 or 500 kb/s // CAN bit rate 250 or 500 kb/s
auto bitRate = addonIt->second.lowSpeed ? 250UL * 1000UL : 500UL * 1000UL; auto bitRate = addonIt->second.halfSpeed ? 250UL * 1000UL : 500UL * 1000UL;
settings2515 = new ACAN2515Settings(QUARTZ_FREQUENCY, bitRate); settings2515 = new ACAN2515Settings(QUARTZ_FREQUENCY, bitRate);
settings2515->mRequestedMode = ACAN2515Settings::NormalMode; settings2515->mRequestedMode = ACAN2515Settings::NormalMode;
@ -128,8 +130,8 @@ bool init_CAN() {
if (fdNativeIt != can_receivers.end() || fdAddonIt != can_receivers.end()) { if (fdNativeIt != can_receivers.end() || fdAddonIt != can_receivers.end()) {
auto slow = (fdNativeIt != can_receivers.end() && fdNativeIt->second.lowSpeed) || auto slow = (fdNativeIt != can_receivers.end() && fdNativeIt->second.halfSpeed) ||
(fdAddonIt != can_receivers.end() && fdAddonIt->second.lowSpeed); (fdAddonIt != can_receivers.end() && fdAddonIt->second.halfSpeed);
auto cs_pin = esp32hal->MCP2517_CS(); auto cs_pin = esp32hal->MCP2517_CS();
auto int_pin = esp32hal->MCP2517_INT(); auto int_pin = esp32hal->MCP2517_INT();
@ -201,6 +203,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;

View file

@ -12,8 +12,8 @@ class CanReceiver;
// Register a receiver object for a given CAN interface. // Register a receiver object for a given CAN interface.
// By default receivers expect the CAN interface to be operated at "fast" speed. // By default receivers expect the CAN interface to be operated at "fast" speed.
// If low_speed is true, half speed is used. // If halfSpeed is true, half speed is used.
void register_can_receiver(CanReceiver* receiver, CAN_Interface interface, bool low_speed = false); void register_can_receiver(CanReceiver* receiver, CAN_Interface interface, bool halfSpeed = false);
/** /**
* @brief Initializes all CAN interfaces requested earlier by other modules (see register_can_receiver) * @brief Initializes all CAN interfaces requested earlier by other modules (see register_can_receiver)

View file

@ -16,6 +16,7 @@ void init_stored_settings() {
// Always get the equipment stop status // Always get the equipment stop status
datalayer.system.settings.equipment_stop_active = settings.getBool("EQUIPMENT_STOP", false); datalayer.system.settings.equipment_stop_active = settings.getBool("EQUIPMENT_STOP", false);
if (datalayer.system.settings.equipment_stop_active) { if (datalayer.system.settings.equipment_stop_active) {
DEBUG_PRINTF("Equipment stop status set in boot.");
set_event(EVENT_EQUIPMENT_STOP, 1); set_event(EVENT_EQUIPMENT_STOP, 1);
} }

View file

@ -30,6 +30,8 @@ bool init_rs485() {
// Inverters and batteries are expected to initialize their serial port in their setup-function // Inverters and batteries are expected to initialize their serial port in their setup-function
// for RS485 or Modbus comms. // for RS485 or Modbus comms.
return true;
} }
static std::list<Rs485Receiver*> receivers; static std::list<Rs485Receiver*> receivers;

View file

@ -31,13 +31,16 @@ class Esp32Hal {
for (gpio_num_t pin : requested_pins) { for (gpio_num_t pin : requested_pins) {
if (pin < 0) { if (pin < 0) {
set_event(EVENT_GPIO_NOT_DEFINED, (int)pin); set_event(EVENT_GPIO_NOT_DEFINED, (int)pin);
LOG_PRINT("%s attempted to allocate pin %d that wasn't defined for the selected HW.\n", name, (int)pin); allocator_name = name;
DEBUG_PRINTF("%s attempted to allocate pin %d that wasn't defined for the selected HW.\n", name, (int)pin);
return false; return false;
} }
auto it = allocated_pins.find(pin); auto it = allocated_pins.find(pin);
if (it != allocated_pins.end()) { if (it != allocated_pins.end()) {
LOG_PRINT("GPIO conflict for pin %d between %s and %s.\n", (int)pin, name, it->second.c_str()); allocator_name = name;
allocated_name = it->second.c_str();
DEBUG_PRINTF("GPIO conflict for pin %d between %s and %s.\n", (int)pin, name, it->second.c_str());
set_event(EVENT_GPIO_CONFLICT, (int)pin); set_event(EVENT_GPIO_CONFLICT, (int)pin);
return false; return false;
} }
@ -143,8 +146,16 @@ class Esp32Hal {
// Returns the available comm interfaces on this HW // Returns the available comm interfaces on this HW
virtual std::vector<comm_interface> available_interfaces() = 0; virtual std::vector<comm_interface> available_interfaces() = 0;
String failed_allocator() { return allocator_name; }
String conflicting_allocator() { return allocated_name; }
private: private:
std::unordered_map<gpio_num_t, std::string> allocated_pins; std::unordered_map<gpio_num_t, std::string> allocated_pins;
// For event logging, store the name of the allocator/allocated
// for failed gpio allocations.
String allocator_name;
String allocated_name;
}; };
extern Esp32Hal* esp32hal; extern Esp32Hal* esp32hal;

View file

@ -415,7 +415,7 @@ bool publish_events() {
doc["severity"] = String(get_event_level_string(event_handle)); doc["severity"] = String(get_event_level_string(event_handle));
doc["count"] = String(event_pointer->occurences); doc["count"] = String(event_pointer->occurences);
doc["data"] = String(event_pointer->data); doc["data"] = String(event_pointer->data);
doc["message"] = String(get_event_message_string(event_handle)); doc["message"] = get_event_message_string(event_handle);
doc["millis"] = String(event_pointer->timestamp); doc["millis"] = String(event_pointer->timestamp);
serializeJson(doc, mqtt_msg); serializeJson(doc, mqtt_msg);

View file

@ -330,6 +330,7 @@ void update_machineryprotection() {
//battery pause status begin //battery pause status begin
void setBatteryPause(bool pause_battery, bool pause_CAN, bool equipment_stop, bool store_settings) { void setBatteryPause(bool pause_battery, bool pause_CAN, bool equipment_stop, bool store_settings) {
DEBUG_PRINTF("Battery pause begin %d %d %d %d\n", pause_battery, pause_CAN, equipment_stop, store_settings);
// First handle equipment stop / resume // First handle equipment stop / resume
if (equipment_stop && !datalayer.system.settings.equipment_stop_active) { if (equipment_stop && !datalayer.system.settings.equipment_stop_active) {
@ -396,12 +397,12 @@ void update_pause_state() {
allowed_to_send_CAN = (!emulator_pause_CAN_send_ON || emulator_pause_status == NORMAL); allowed_to_send_CAN = (!emulator_pause_CAN_send_ON || emulator_pause_status == NORMAL);
if (previous_allowed_to_send_CAN && !allowed_to_send_CAN) { if (previous_allowed_to_send_CAN && !allowed_to_send_CAN) {
LOG_PRINT("Safety: Pausing CAN sending\n"); DEBUG_PRINTF("Safety: Pausing CAN sending\n");
//completely force stop the CAN communication //completely force stop the CAN communication
stop_can(); stop_can();
} else if (!previous_allowed_to_send_CAN && allowed_to_send_CAN) { } else if (!previous_allowed_to_send_CAN && allowed_to_send_CAN) {
//resume CAN communication //resume CAN communication
LOG_PRINT("Safety: Resuming CAN sending\n"); DEBUG_PRINTF("Safety: Resuming CAN sending\n");
restart_can(); restart_can();
} }
} }

View file

@ -174,7 +174,7 @@ void set_event_MQTTpublished(EVENTS_ENUM_TYPE event) {
events.entries[event].MQTTpublished = true; events.entries[event].MQTTpublished = true;
} }
const char* get_event_message_string(EVENTS_ENUM_TYPE event) { String get_event_message_string(EVENTS_ENUM_TYPE event) {
switch (event) { switch (event) {
case EVENT_CANMCP2517FD_INIT_FAILURE: case EVENT_CANMCP2517FD_INIT_FAILURE:
return "CAN-FD initialization failed. Check hardware or bitrate settings"; return "CAN-FD initialization failed. Check hardware or bitrate settings";
@ -378,9 +378,10 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
return "Failed to syncronise with the NTP Server. BMS will reset every 24 hours from when the emulator was " return "Failed to syncronise with the NTP Server. BMS will reset every 24 hours from when the emulator was "
"powered on"; "powered on";
case EVENT_GPIO_CONFLICT: case EVENT_GPIO_CONFLICT:
return "There is a GPIO pin conflict between SW components."; return "There is a GPIO pin conflict between SW components: " + esp32hal->failed_allocator() + " / " +
esp32hal->conflicting_allocator();
case EVENT_GPIO_NOT_DEFINED: case EVENT_GPIO_NOT_DEFINED:
return "SW module requires GPIO that is not defined for this hardware."; return "SW module requires GPIO that is not defined for this hardware: " + esp32hal->failed_allocator();
default: default:
return ""; return "";
} }
@ -417,10 +418,8 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
(events.entries[event].state != EVENT_STATE_ACTIVE_LATCHED)) { (events.entries[event].state != EVENT_STATE_ACTIVE_LATCHED)) {
events.entries[event].occurences++; events.entries[event].occurences++;
events.entries[event].MQTTpublished = false; events.entries[event].MQTTpublished = false;
#ifdef DEBUG_LOG
logging.print("Event: "); DEBUG_PRINTF("Event: %s\n", get_event_message_string(event).c_str());
logging.println(get_event_message_string(event));
#endif
} }
// We should set the event, update event info // We should set the event, update event info

View file

@ -1,6 +1,8 @@
#ifndef __EVENTS_H__ #ifndef __EVENTS_H__
#define __EVENTS_H__ #define __EVENTS_H__
#include <WString.h>
#include <src/devboard/utils/types.h>
#include <stdint.h> #include <stdint.h>
#define GENERATE_ENUM(ENUM) ENUM, #define GENERATE_ENUM(ENUM) ENUM,
@ -146,7 +148,7 @@ struct EventData {
}; };
const char* get_event_enum_string(EVENTS_ENUM_TYPE event); const char* get_event_enum_string(EVENTS_ENUM_TYPE event);
const char* get_event_message_string(EVENTS_ENUM_TYPE event); String get_event_message_string(EVENTS_ENUM_TYPE event);
const char* get_event_level_string(EVENTS_ENUM_TYPE event); const char* get_event_level_string(EVENTS_ENUM_TYPE event);
EVENTS_LEVEL_TYPE get_event_level(void); EVENTS_LEVEL_TYPE get_event_level(void);

View file

@ -19,15 +19,11 @@ class Logging : public Print {
extern Logging logging; extern Logging logging;
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
#define LOG_PRINT(fmt, ...) logging.printf(fmt, ##__VA_ARGS__) #define DEBUG_PRINTF(fmt, ...) logging.printf(fmt, ##__VA_ARGS__)
#define LOG_PRINTLN(str) logging.println(str) #define DEBUG_PRINTLN(str) logging.println(str)
#else #else
#define LOG_PRINT(fmt, ...) \ #define DEBUG_PRINTF(fmt, ...) ((void)0)
do { \ #define DEBUG_PRINTLN(fmt, ...) ((void)0)
} while (0)
#define LOG_PRINTLN(str) \
do { \
} while (0)
#endif #endif
#endif // __LOGGING_H__ #endif // __LOGGING_H__

View file

@ -54,7 +54,7 @@ String events_processor(const String& var) {
String(timestamp_now - event_pointer->timestamp) + "</div>"); String(timestamp_now - event_pointer->timestamp) + "</div>");
content.concat("<div>" + String(event_pointer->occurences) + "</div>"); content.concat("<div>" + String(event_pointer->occurences) + "</div>");
content.concat("<div>" + String(event_pointer->data) + "</div>"); content.concat("<div>" + String(event_pointer->data) + "</div>");
content.concat("<div>" + String(get_event_message_string(event_handle)) + "</div>"); content.concat("<div>" + get_event_message_string(event_handle) + "</div>");
content.concat("</div>"); // End of event row content.concat("</div>"); // End of event row
} }

View file

@ -1257,7 +1257,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>";

View file

@ -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 */

View file

@ -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();

View file

@ -13,7 +13,7 @@ class BydModbusInverter : public ModbusInverterProtocol {
const char* name() override { return Name; } const char* name() override { return Name; }
bool setup() override; bool setup() override;
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();

View file

@ -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();

View file

@ -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;

View file

@ -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)

View file

@ -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

View file

@ -23,7 +23,7 @@ class KostalInverterProtocol : public Rs485InverterProtocol {
bool setup() override; bool setup() override;
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; }

View file

@ -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();

View file

@ -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();

View file

@ -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;

View file

@ -15,7 +15,7 @@ class SmaBydHInverter : public SmaInverterBase {
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; }

View file

@ -15,7 +15,7 @@ class SmaBydHvsInverter : public SmaInverterBase {
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; }

View file

@ -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;

View file

@ -15,7 +15,7 @@ class SmaTripowerInverter : public SmaInverterBase {
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; }

View file

@ -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

View file

@ -15,7 +15,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

View file

@ -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;