mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-05 02:39:57 +02:00
Can receivers can register with half speed
This commit is contained in:
parent
e57f2ce324
commit
d3f6577ebc
13 changed files with 66 additions and 31 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"
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
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();
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
@ -205,6 +206,8 @@ void NissanLeafBattery::
|
||||||
}
|
}
|
||||||
|
|
||||||
void NissanLeafBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
void NissanLeafBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
||||||
|
DEBUG_PRINTF("Leaf frame %x", rx_frame.ID);
|
||||||
|
|
||||||
switch (rx_frame.ID) {
|
switch (rx_frame.ID) {
|
||||||
case 0x1DB:
|
case 0x1DB:
|
||||||
if (is_message_corrupt(rx_frame)) {
|
if (is_message_corrupt(rx_frame)) {
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
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();
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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: ");
|
||||||
|
|
|
@ -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");
|
||||||
|
@ -108,6 +130,7 @@ void init_CAN() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void transmit_can_frame(CAN_frame* tx_frame, int interface) {
|
void transmit_can_frame(CAN_frame* tx_frame, int interface) {
|
||||||
|
DEBUG_PRINTF("transmit can %d", interface);
|
||||||
if (!allowed_to_send_CAN) {
|
if (!allowed_to_send_CAN) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -119,6 +142,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,13 +300,13 @@ 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) {
|
||||||
|
DEBUG_PRINTF("map_can_frame_to_variable %d\n", interface);
|
||||||
if (interface !=
|
if (interface !=
|
||||||
CANFD_NATIVE) { //Avoid printing twice due to receive_frame_canfd_addon sending to both FD interfaces
|
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
|
//TODO: This check can be removed later when refactored to use inline functions for logging
|
||||||
|
@ -302,7 +326,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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>";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue