diff --git a/Software/Software.ino b/Software/Software.ino index 5b847925..0f0f8203 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -224,10 +224,9 @@ void core_loop(void*) { #endif // Input, Runs as fast as possible - receive_can(); // Receive CAN messages -#if defined(RS485_INVERTER_SELECTED) || defined(RS485_BATTERY_SELECTED) - receive_RS485(); // Process serial2 RS485 interface -#endif // RS485_INVERTER_SELECTED + receive_can(); // Receive CAN messages + receive_rs485(); // Process serial2 RS485 interface + END_TIME_MEASUREMENT_MAX(comm, datalayer.system.status.time_comm_us); #ifdef WEBSERVER START_TIME_MEASUREMENT(ota); diff --git a/Software/src/battery/BATTERIES.cpp b/Software/src/battery/BATTERIES.cpp index 77e5868f..bf6b3580 100644 --- a/Software/src/battery/BATTERIES.cpp +++ b/Software/src/battery/BATTERIES.cpp @@ -41,21 +41,4 @@ void setup_battery() { #endif } -// transmit_can_battery is called once and we need to -// call both batteries. - -void handle_incoming_can_frame_battery(CAN_frame rx_frame) { - ((CanBattery*)battery)->handle_incoming_can_frame(rx_frame); -} - -void handle_incoming_can_frame_battery2(CAN_frame rx_frame) { - ((CanBattery*)battery2)->handle_incoming_can_frame(rx_frame); -} - -#ifdef RS485_BATTERY_SELECTED -void receive_RS485() { - ((RS485Battery*)battery)->receive_RS485(); -} -#endif - #endif diff --git a/Software/src/battery/BATTERIES.h b/Software/src/battery/BATTERIES.h index 4e6b0ccb..a1e38da3 100644 --- a/Software/src/battery/BATTERIES.h +++ b/Software/src/battery/BATTERIES.h @@ -13,7 +13,6 @@ void setup_can_shunt(); #ifdef BMW_SBOX #include "BMW-SBOX.h" -void handle_incoming_can_frame_shunt(CAN_frame rx_frame); #endif #ifdef BMW_I3_BATTERY @@ -160,14 +159,4 @@ void handle_incoming_can_frame_shunt(CAN_frame rx_frame); void setup_battery(void); -#ifdef RS485_BATTERY_SELECTED -void transmit_rs485(unsigned long currentMillis); -void receive_RS485(); -#else -void handle_incoming_can_frame_battery(CAN_frame rx_frame); -void transmit_can_battery(unsigned long currentMillis); -#endif - -void handle_incoming_can_frame_battery2(CAN_frame rx_frame); - #endif diff --git a/Software/src/battery/CHADEMO-BATTERY.cpp b/Software/src/battery/CHADEMO-BATTERY.cpp index 8f893686..ff08d86e 100644 --- a/Software/src/battery/CHADEMO-BATTERY.cpp +++ b/Software/src/battery/CHADEMO-BATTERY.cpp @@ -341,6 +341,8 @@ void ChademoBattery::handle_incoming_can_frame(CAN_frame rx_frame) { } handle_chademo_sequence(); + + ISA_handleFrame(&rx_frame); } /* (re)initialize evse structures to pre-charge/discharge states */ diff --git a/Software/src/battery/CanBattery.h b/Software/src/battery/CanBattery.h index 181301d3..936c2a74 100644 --- a/Software/src/battery/CanBattery.h +++ b/Software/src/battery/CanBattery.h @@ -4,10 +4,11 @@ #include "Battery.h" #include "src/communication/Transmitter.h" +#include "src/communication/can/CanReceiver.h" #include "src/devboard/utils/types.h" // Abstract base class for batteries using the CAN bus -class CanBattery : public Battery, Transmitter { +class CanBattery : public Battery, Transmitter, CanReceiver { public: virtual void handle_incoming_can_frame(CAN_frame rx_frame) = 0; virtual void transmit_can(unsigned long currentMillis) = 0; @@ -16,17 +17,21 @@ class CanBattery : public Battery, Transmitter { void transmit(unsigned long currentMillis) { transmit_can(currentMillis); } + void receive_can_frame(CAN_frame* frame) { handle_incoming_can_frame(*frame); } + protected: CAN_Interface can_interface; CanBattery() { can_interface = can_config.battery; register_transmitter(this); + register_can_receiver(this, can_interface); } CanBattery(CAN_Interface interface) { can_interface = interface; register_transmitter(this); + register_can_receiver(this, can_interface); } }; diff --git a/Software/src/battery/DALY-BMS.cpp b/Software/src/battery/DALY-BMS.cpp index 8f57f18e..0b96fcd5 100644 --- a/Software/src/battery/DALY-BMS.cpp +++ b/Software/src/battery/DALY-BMS.cpp @@ -178,7 +178,7 @@ void DalyBms::transmit_rs485(unsigned long currentMillis) { } } -void DalyBms::receive_RS485() { +void DalyBms::receive() { static uint8_t recv_buff[13] = {0}; static uint8_t recv_len = 0; diff --git a/Software/src/battery/DALY-BMS.h b/Software/src/battery/DALY-BMS.h index b84a267e..a8902f85 100644 --- a/Software/src/battery/DALY-BMS.h +++ b/Software/src/battery/DALY-BMS.h @@ -23,7 +23,7 @@ class DalyBms : public RS485Battery { void setup(); void update_values(); void transmit_rs485(unsigned long currentMillis); - void receive_RS485(); + void receive(); private: int baud_rate() { return 9600; } diff --git a/Software/src/battery/RS485Battery.h b/Software/src/battery/RS485Battery.h index 53477f35..7d93753a 100644 --- a/Software/src/battery/RS485Battery.h +++ b/Software/src/battery/RS485Battery.h @@ -6,17 +6,21 @@ #include "src/communication/Transmitter.h" #include "src/devboard/utils/types.h" +#include "src/communication/rs485/comm_rs485.h" + // Abstract base class for batteries using the RS485 interface -class RS485Battery : public Battery, Transmitter { +class RS485Battery : public Battery, Transmitter, Rs485Receiver { public: - virtual void receive_RS485() = 0; virtual void transmit_rs485(unsigned long currentMillis) = 0; String interface_name() { return "RS485"; } void transmit(unsigned long currentMillis) { transmit_rs485(currentMillis); } - RS485Battery() { register_transmitter(this); } + RS485Battery() { + register_transmitter(this); + register_receiver(this); + } }; #endif diff --git a/Software/src/battery/Shunt.h b/Software/src/battery/Shunt.h index c39a7ed5..6672d998 100644 --- a/Software/src/battery/Shunt.h +++ b/Software/src/battery/Shunt.h @@ -1,11 +1,11 @@ #ifndef _SHUNT_H #define _SHUNT_H -#include "../communication/can/comm_can.h" #include "src/communication/Transmitter.h" +#include "src/communication/can/CanReceiver.h" #include "src/devboard/utils/types.h" -class CanShunt : public Transmitter { +class CanShunt : public Transmitter, CanReceiver { public: virtual void setup() = 0; virtual void transmit_can(unsigned long currentMillis) = 0; @@ -17,12 +17,15 @@ class CanShunt : public Transmitter { } } + void receive_can_frame(CAN_frame* frame) { handle_incoming_can_frame(*frame); } + protected: CAN_Interface can_interface; CanShunt() { can_interface = can_config.battery; register_transmitter(this); + register_can_receiver(this, can_interface); } }; diff --git a/Software/src/battery/Shunts.cpp b/Software/src/battery/Shunts.cpp index a04120a8..a95ca82e 100644 --- a/Software/src/battery/Shunts.cpp +++ b/Software/src/battery/Shunts.cpp @@ -4,13 +4,7 @@ CanShunt* shunt = nullptr; void setup_can_shunt() { -#if defined(CAN_SHUNT_SELECTED) && defined(SELECTED_SHUNT_CLASS) +#if defined(SELECTED_SHUNT_CLASS) shunt = new SELECTED_SHUNT_CLASS(); #endif } - -void handle_incoming_can_frame_shunt(CAN_frame rx_frame) { - if (shunt) { - shunt->handle_incoming_can_frame(rx_frame); - } -} diff --git a/Software/src/charger/CanCharger.h b/Software/src/charger/CanCharger.h index 8d7631dc..7e75391f 100644 --- a/Software/src/charger/CanCharger.h +++ b/Software/src/charger/CanCharger.h @@ -5,6 +5,7 @@ #include "../datalayer/datalayer.h" #include "src/communication/Transmitter.h" +#include "src/communication/can/CanReceiver.h" enum class ChargerType { NissanLeaf, ChevyVolt }; @@ -37,7 +38,7 @@ class Charger { }; // Base class for chargers on a CAN bus -class CanCharger : public Charger, Transmitter { +class CanCharger : public Charger, Transmitter, CanReceiver { public: virtual void map_can_frame_to_variable(CAN_frame rx_frame) = 0; virtual void transmit_can(unsigned long currentMillis) = 0; @@ -48,8 +49,13 @@ class CanCharger : public Charger, Transmitter { } } + void receive_can_frame(CAN_frame* frame) { map_can_frame_to_variable(*frame); } + protected: - CanCharger(ChargerType type) : Charger(type) { register_transmitter(this); } + CanCharger(ChargerType type) : Charger(type) { + register_transmitter(this); + register_can_receiver(this, can_config.charger); + } }; #endif diff --git a/Software/src/communication/can/CanReceiver.h b/Software/src/communication/can/CanReceiver.h new file mode 100644 index 00000000..22a9ba58 --- /dev/null +++ b/Software/src/communication/can/CanReceiver.h @@ -0,0 +1,15 @@ +#ifndef _CANRECEIVER_H +#define _CANRECEIVER_H + +#include "src/devboard/utils/types.h" +#include "src/include.h" + +class CanReceiver { + public: + virtual void receive_can_frame(CAN_frame* rx_frame) = 0; +}; + +// Register a receiver object for a given CAN interface +void register_can_receiver(CanReceiver* receiver, CAN_Interface interface); + +#endif diff --git a/Software/src/communication/can/comm_can.cpp b/Software/src/communication/can/comm_can.cpp index afb3fd0c..9030387d 100644 --- a/Software/src/communication/can/comm_can.cpp +++ b/Software/src/communication/can/comm_can.cpp @@ -1,4 +1,5 @@ #include "comm_can.h" +#include #include "../../include.h" #include "src/devboard/sdcard/sdcard.h" @@ -10,6 +11,8 @@ volatile bool send_ok_2515 = 0; volatile bool send_ok_2518 = 0; static unsigned long previousMillis10 = 0; +void map_can_frame_to_variable(CAN_frame* rx_frame, CAN_Interface interface); + #ifdef CAN_ADDON static const uint32_t QUARTZ_FREQUENCY = CRYSTAL_FREQUENCY_MHZ * 1000000UL; //MHZ configured in USER_SETTINGS.h SPIClass SPI2515; @@ -273,7 +276,13 @@ void print_can_frame(CAN_frame frame, frameDirection msgDir) { } } -void map_can_frame_to_variable(CAN_frame* rx_frame, int interface) { +static std::multimap can_receivers; + +void register_can_receiver(CanReceiver* receiver, CAN_Interface interface) { + can_receivers.insert({interface, receiver}); +} + +void map_can_frame_to_variable(CAN_frame* rx_frame, CAN_Interface interface) { if (interface != CANFD_NATIVE) { //Avoid printing twice due to receive_frame_canfd_addon sending to both FD interfaces //TODO: This check can be removed later when refactored to use inline functions for logging @@ -288,31 +297,15 @@ void map_can_frame_to_variable(CAN_frame* rx_frame, int interface) { } #endif - if (interface == can_config.battery) { -#ifndef RS485_BATTERY_SELECTED - handle_incoming_can_frame_battery(*rx_frame); -#endif -#ifdef CHADEMO_BATTERY - ISA_handleFrame(rx_frame); -#endif - } - if (interface == can_config.inverter) { -#ifdef CAN_INVERTER_SELECTED - map_can_frame_to_variable_inverter(*rx_frame); -#endif - } - if (interface == can_config.battery_double && battery2) { - handle_incoming_can_frame_battery2(*rx_frame); - } - if (interface == can_config.charger && charger) { - charger->map_can_frame_to_variable(*rx_frame); - } - if (interface == can_config.shunt) { -#ifdef CAN_SHUNT_SELECTED - handle_incoming_can_frame_shunt(*rx_frame); -#endif + // Send the frame to all the receivers registered for this interface. + auto receivers = can_receivers.equal_range(interface); + + for (auto it = receivers.first; it != receivers.second; ++it) { + auto& receiver = it->second; + receiver->receive_can_frame(rx_frame); } } + void dump_can_frame(CAN_frame& frame, frameDirection msgDir) { char* message_string = datalayer.system.info.logged_can_messages; int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer diff --git a/Software/src/communication/can/comm_can.h b/Software/src/communication/can/comm_can.h index b51be935..dcd5b4f5 100644 --- a/Software/src/communication/can/comm_can.h +++ b/Software/src/communication/can/comm_can.h @@ -27,16 +27,6 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface); */ void init_CAN(); -/** - * @brief Transmit one CAN frame - * - * @param[in] CAN_frame* tx_frame - * @param[in] int interface - * - * @return void - */ -void transmit_can_frame(); - /** * @brief Receive CAN messages from all interfaces * @@ -82,14 +72,4 @@ void receive_frame_canfd_addon(); */ void print_can_frame(CAN_frame frame, frameDirection msgDir); -/** - * @brief Map CAN frame from specified interface to variable - * - * @param[in] CAN_frame* rx_frame - * @param[in] int interface - * - * @return void - */ -void map_can_frame_to_variable(CAN_frame* rx_frame, int interface); - #endif diff --git a/Software/src/communication/rs485/comm_rs485.cpp b/Software/src/communication/rs485/comm_rs485.cpp index 7aac54d0..ba3048b4 100644 --- a/Software/src/communication/rs485/comm_rs485.cpp +++ b/Software/src/communication/rs485/comm_rs485.cpp @@ -1,6 +1,8 @@ #include "comm_rs485.h" #include "../../include.h" +#include + void init_rs485() { #ifdef RS485_EN_PIN pinMode(RS485_EN_PIN, OUTPUT); @@ -18,3 +20,15 @@ void init_rs485() { // Inverters and batteries are expected to initialize their serial port in their setup-function // for RS485 or Modbus comms. } + +static std::list receivers; + +void receive_rs485() { + for (auto& receiver : receivers) { + receiver->receive(); + } +} + +void register_receiver(Rs485Receiver* receiver) { + receivers.push_back(receiver); +} diff --git a/Software/src/communication/rs485/comm_rs485.h b/Software/src/communication/rs485/comm_rs485.h index b4077dd4..85a649fc 100644 --- a/Software/src/communication/rs485/comm_rs485.h +++ b/Software/src/communication/rs485/comm_rs485.h @@ -1,12 +1,6 @@ #ifndef _COMM_RS485_H_ #define _COMM_RS485_H_ -#include "../../include.h" - -#include "../../lib/eModbus-eModbus/Logging.h" -#include "../../lib/eModbus-eModbus/ModbusServerRTU.h" -#include "../../lib/eModbus-eModbus/scripts/mbServerFCs.h" - /** * @brief Initialization of RS485 * @@ -16,4 +10,17 @@ */ void init_rs485(); +// Defines an interface for any object that needs to receive a signal to handle RS485 comm. +// Can be extended later for more complex operation. +class Rs485Receiver { + public: + virtual void receive() = 0; +}; + +// Forwards the call to all registered RS485 receivers +void receive_rs485(); + +// Registers the given object as a receiver. +void register_receiver(Rs485Receiver* receiver); + #endif diff --git a/Software/src/devboard/safety/safety.cpp b/Software/src/devboard/safety/safety.cpp index d29c6bce..af2a0317 100644 --- a/Software/src/devboard/safety/safety.cpp +++ b/Software/src/devboard/safety/safety.cpp @@ -212,17 +212,18 @@ void update_machineryprotection() { clear_event(EVENT_CAN_CORRUPTED_WARNING); } -#ifdef CAN_INVERTER_SELECTED - // Check if the inverter is still sending CAN messages. If we go 60s without messages we raise a warning - if (!datalayer.system.status.CAN_inverter_still_alive) { - set_event(EVENT_CAN_INVERTER_MISSING, can_config.inverter); - } else { - datalayer.system.status.CAN_inverter_still_alive--; - clear_event(EVENT_CAN_INVERTER_MISSING); + if (inverter && inverter->interface_type() == InverterInterfaceType::Can) { + // Check if the inverter is still sending CAN messages. If we go 60s without messages we raise a warning + if (!datalayer.system.status.CAN_inverter_still_alive) { + set_event(EVENT_CAN_INVERTER_MISSING, can_config.inverter); + } else { + datalayer.system.status.CAN_inverter_still_alive--; + clear_event(EVENT_CAN_INVERTER_MISSING); + } } -#endif //CAN_INVERTER_SELECTED if (charger) { + // Assuming chargers are all CAN here. // Check if the charger is still sending CAN messages. If we go 60s without messages we raise a warning if (!datalayer.charger.CAN_charger_still_alive) { set_event(EVENT_CAN_CHARGER_MISSING, can_config.charger); diff --git a/Software/src/inverter/AFORE-CAN.h b/Software/src/inverter/AFORE-CAN.h index 43068af3..9f5cdd9d 100644 --- a/Software/src/inverter/AFORE-CAN.h +++ b/Software/src/inverter/AFORE-CAN.h @@ -3,7 +3,6 @@ #include "../include.h" #ifdef AFORE_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS AforeCanInverter #endif diff --git a/Software/src/inverter/BYD-CAN.h b/Software/src/inverter/BYD-CAN.h index 27f82400..fa1c3aa4 100644 --- a/Software/src/inverter/BYD-CAN.h +++ b/Software/src/inverter/BYD-CAN.h @@ -3,7 +3,6 @@ #include "../include.h" #ifdef BYD_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS BydCanInverter #endif diff --git a/Software/src/inverter/BYD-MODBUS.h b/Software/src/inverter/BYD-MODBUS.h index 0f5faa7b..fc1bb454 100644 --- a/Software/src/inverter/BYD-MODBUS.h +++ b/Software/src/inverter/BYD-MODBUS.h @@ -3,7 +3,6 @@ #include "../include.h" #ifdef BYD_MODBUS -#define MODBUS_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS BydModbusInverter #endif diff --git a/Software/src/inverter/CanInverterProtocol.h b/Software/src/inverter/CanInverterProtocol.h index c4f63235..2bce2a60 100644 --- a/Software/src/inverter/CanInverterProtocol.h +++ b/Software/src/inverter/CanInverterProtocol.h @@ -3,11 +3,14 @@ #include "InverterProtocol.h" +#include "src/communication/can/CanReceiver.h" #include "src/devboard/utils/types.h" -class CanInverterProtocol : public InverterProtocol, Transmitter { +class CanInverterProtocol : public InverterProtocol, Transmitter, CanReceiver { public: virtual const char* interface_name() { return getCANInterfaceName(can_config.inverter); } + InverterInterfaceType interface_type() { return InverterInterfaceType::Can; } + virtual void transmit_can(unsigned long currentMillis) = 0; virtual void map_can_frame_to_variable(CAN_frame rx_frame) = 0; @@ -17,8 +20,13 @@ class CanInverterProtocol : public InverterProtocol, Transmitter { } } + void receive_can_frame(CAN_frame* frame) { map_can_frame_to_variable(*frame); } + protected: - CanInverterProtocol() { register_transmitter(this); } + CanInverterProtocol() { + register_transmitter(this); + register_can_receiver(this, can_config.inverter); + } }; #endif diff --git a/Software/src/inverter/FERROAMP-CAN.h b/Software/src/inverter/FERROAMP-CAN.h index 711549ff..c05f3270 100644 --- a/Software/src/inverter/FERROAMP-CAN.h +++ b/Software/src/inverter/FERROAMP-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef FERROAMP_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS FerroampCanInverter #endif diff --git a/Software/src/inverter/FOXESS-CAN.h b/Software/src/inverter/FOXESS-CAN.h index 78a90c04..454f79bb 100644 --- a/Software/src/inverter/FOXESS-CAN.h +++ b/Software/src/inverter/FOXESS-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef FOXESS_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS FoxessCanInverter #endif diff --git a/Software/src/inverter/GROWATT-HV-CAN.h b/Software/src/inverter/GROWATT-HV-CAN.h index aa8e71e2..16658119 100644 --- a/Software/src/inverter/GROWATT-HV-CAN.h +++ b/Software/src/inverter/GROWATT-HV-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef GROWATT_HV_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS GrowattHvInverter #endif diff --git a/Software/src/inverter/GROWATT-LV-CAN.h b/Software/src/inverter/GROWATT-LV-CAN.h index 8fa5a914..a3d52f5a 100644 --- a/Software/src/inverter/GROWATT-LV-CAN.h +++ b/Software/src/inverter/GROWATT-LV-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef GROWATT_LV_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS GrowattLvInverter #endif diff --git a/Software/src/inverter/INVERTERS.cpp b/Software/src/inverter/INVERTERS.cpp index 77d858fb..301638ef 100644 --- a/Software/src/inverter/INVERTERS.cpp +++ b/Software/src/inverter/INVERTERS.cpp @@ -1,47 +1,16 @@ #include "../include.h" -// These functions adapt the old C-style global functions inverter-API to the -// object-oriented inverter protocol API. - InverterProtocol* inverter = nullptr; -#ifdef CAN_INVERTER_SELECTED -CanInverterProtocol* can_inverter; -#endif - -#ifdef MODBUS_INVERTER_SELECTED -ModbusInverterProtocol* modbus_inverter; -#endif - void setup_inverter() { -#ifdef MODBUS_INVERTER_SELECTED - modbus_inverter = new SELECTED_INVERTER_CLASS(); - inverter = modbus_inverter; -#endif + if (inverter) { + // The inverter is setup only once. + return; + } -#ifdef CAN_INVERTER_SELECTED - can_inverter = new SELECTED_INVERTER_CLASS(); - inverter = can_inverter; -#endif - -#ifdef RS485_INVERTER_SELECTED inverter = new SELECTED_INVERTER_CLASS(); -#endif if (inverter) { inverter->setup(); } } - -#ifdef CAN_INVERTER_SELECTED - -void map_can_frame_to_variable_inverter(CAN_frame rx_frame) { - can_inverter->map_can_frame_to_variable(rx_frame); -} -#endif - -#ifdef RS485_INVERTER_SELECTED -void receive_RS485() { - ((Rs485InverterProtocol*)inverter)->receive_RS485(); -} -#endif diff --git a/Software/src/inverter/INVERTERS.h b/Software/src/inverter/INVERTERS.h index 98e6c5a6..123e212f 100644 --- a/Software/src/inverter/INVERTERS.h +++ b/Software/src/inverter/INVERTERS.h @@ -33,13 +33,4 @@ extern InverterProtocol* inverter; // Call to initialize the build-time selected inverter. Safe to call even though inverter was not selected. void setup_inverter(); -#ifdef CAN_INVERTER_SELECTED -void map_can_frame_to_variable_inverter(CAN_frame rx_frame); -void transmit_can_inverter(unsigned long currentMillis); -#endif - -#ifdef RS485_INVERTER_SELECTED -void receive_RS485(); -#endif - #endif diff --git a/Software/src/inverter/InverterProtocol.h b/Software/src/inverter/InverterProtocol.h index 65e2b2e9..8e78a9fc 100644 --- a/Software/src/inverter/InverterProtocol.h +++ b/Software/src/inverter/InverterProtocol.h @@ -1,11 +1,14 @@ #ifndef INVERTER_PROTOCOL_H #define INVERTER_PROTOCOL_H +enum class InverterInterfaceType { Can, Rs485, Modbus }; + // The abstract base class for all inverter protocols class InverterProtocol { public: virtual void setup() = 0; virtual const char* interface_name() = 0; + virtual InverterInterfaceType interface_type() = 0; // This function maps all the values fetched from battery to the correct battery emulator data structures virtual void update_values() = 0; diff --git a/Software/src/inverter/KOSTAL-RS485.cpp b/Software/src/inverter/KOSTAL-RS485.cpp index d97eea02..37ef14b6 100644 --- a/Software/src/inverter/KOSTAL-RS485.cpp +++ b/Software/src/inverter/KOSTAL-RS485.cpp @@ -203,7 +203,7 @@ void KostalInverterProtocol::update_values() { } } -void KostalInverterProtocol::receive_RS485() // Runs as fast as possible to handle the serial stream +void KostalInverterProtocol::receive() // Runs as fast as possible to handle the serial stream { currentMillis = millis(); diff --git a/Software/src/inverter/KOSTAL-RS485.h b/Software/src/inverter/KOSTAL-RS485.h index e472a00a..fdf748cb 100644 --- a/Software/src/inverter/KOSTAL-RS485.h +++ b/Software/src/inverter/KOSTAL-RS485.h @@ -20,7 +20,7 @@ class KostalInverterProtocol : public Rs485InverterProtocol { public: void setup(); - void receive_RS485(); + void receive(); void update_values(); private: diff --git a/Software/src/inverter/ModbusInverterProtocol.h b/Software/src/inverter/ModbusInverterProtocol.h index 5b83b3a6..c3a32fe2 100644 --- a/Software/src/inverter/ModbusInverterProtocol.h +++ b/Software/src/inverter/ModbusInverterProtocol.h @@ -10,7 +10,8 @@ extern uint16_t mbPV[]; // The abstract base class for all Modbus inverter protocols class ModbusInverterProtocol : public InverterProtocol { - virtual const char* interface_name() { return "RS485 / Modbus"; } + const char* interface_name() { return "RS485 / Modbus"; } + InverterInterfaceType interface_type() { return InverterInterfaceType::Modbus; } protected: // Create a ModbusRTU server instance with 2000ms timeout diff --git a/Software/src/inverter/PYLON-CAN.h b/Software/src/inverter/PYLON-CAN.h index 4820b490..c744ab82 100644 --- a/Software/src/inverter/PYLON-CAN.h +++ b/Software/src/inverter/PYLON-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef PYLON_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS PylonInverter #endif diff --git a/Software/src/inverter/PYLON-LV-CAN.h b/Software/src/inverter/PYLON-LV-CAN.h index d28f9cfe..b22c6b07 100644 --- a/Software/src/inverter/PYLON-LV-CAN.h +++ b/Software/src/inverter/PYLON-LV-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef PYLON_LV_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS PylonLvInverter #endif diff --git a/Software/src/inverter/Rs485InverterProtocol.h b/Software/src/inverter/Rs485InverterProtocol.h index 19a6d30e..069007f2 100644 --- a/Software/src/inverter/Rs485InverterProtocol.h +++ b/Software/src/inverter/Rs485InverterProtocol.h @@ -1,12 +1,14 @@ -#ifndef RS485CANINVERTER_PROTOCOL_H -#define RS485INVERTER_PROTOCOL_H +#ifndef _RS485INVERTER_PROTOCOL_H +#define _RS485INVERTER_PROTOCOL_H #include "InverterProtocol.h" -class Rs485InverterProtocol : public InverterProtocol { +#include "src/communication/rs485/comm_rs485.h" + +class Rs485InverterProtocol : public InverterProtocol, Rs485Receiver { public: virtual const char* interface_name() { return "RS485"; } - virtual void receive_RS485() = 0; + InverterInterfaceType interface_type() { return InverterInterfaceType::Rs485; } virtual int baud_rate() = 0; }; diff --git a/Software/src/inverter/SCHNEIDER-CAN.h b/Software/src/inverter/SCHNEIDER-CAN.h index b154ada3..ace28795 100644 --- a/Software/src/inverter/SCHNEIDER-CAN.h +++ b/Software/src/inverter/SCHNEIDER-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef SCHNEIDER_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS SchneiderInverter #endif diff --git a/Software/src/inverter/SMA-BYD-H-CAN.h b/Software/src/inverter/SMA-BYD-H-CAN.h index fc1e7fb2..d6c84ba2 100644 --- a/Software/src/inverter/SMA-BYD-H-CAN.h +++ b/Software/src/inverter/SMA-BYD-H-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef SMA_BYD_H_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS SmaBydHInverter #endif diff --git a/Software/src/inverter/SMA-BYD-HVS-CAN.h b/Software/src/inverter/SMA-BYD-HVS-CAN.h index 2604b1ad..cdc113da 100644 --- a/Software/src/inverter/SMA-BYD-HVS-CAN.h +++ b/Software/src/inverter/SMA-BYD-HVS-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef SMA_BYD_HVS_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS SmaBydHvsInverter #endif diff --git a/Software/src/inverter/SMA-LV-CAN.h b/Software/src/inverter/SMA-LV-CAN.h index 57154120..c8ff13ed 100644 --- a/Software/src/inverter/SMA-LV-CAN.h +++ b/Software/src/inverter/SMA-LV-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef SMA_LV_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS SmaLvInverter #endif diff --git a/Software/src/inverter/SMA-TRIPOWER-CAN.h b/Software/src/inverter/SMA-TRIPOWER-CAN.h index 4e6bb80c..916691a2 100644 --- a/Software/src/inverter/SMA-TRIPOWER-CAN.h +++ b/Software/src/inverter/SMA-TRIPOWER-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef SMA_TRIPOWER_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS SmaTripowerInverter #endif diff --git a/Software/src/inverter/SOFAR-CAN.h b/Software/src/inverter/SOFAR-CAN.h index d9ec0a43..13ee83b4 100644 --- a/Software/src/inverter/SOFAR-CAN.h +++ b/Software/src/inverter/SOFAR-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef SOFAR_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS SofarInverter #endif diff --git a/Software/src/inverter/SOLAX-CAN.h b/Software/src/inverter/SOLAX-CAN.h index eae63f39..169ca9c8 100644 --- a/Software/src/inverter/SOLAX-CAN.h +++ b/Software/src/inverter/SOLAX-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef SOLAX_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS SolaxInverter #endif diff --git a/Software/src/inverter/SUNGROW-CAN.h b/Software/src/inverter/SUNGROW-CAN.h index 73734975..5947b9d3 100644 --- a/Software/src/inverter/SUNGROW-CAN.h +++ b/Software/src/inverter/SUNGROW-CAN.h @@ -5,7 +5,6 @@ #include "CanInverterProtocol.h" #ifdef SUNGROW_CAN -#define CAN_INVERTER_SELECTED #define SELECTED_INVERTER_CLASS SungrowInverter #endif