From 4cd5289929f005b2a24e24f586fffa26360d2866 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 1 Feb 2024 17:23:41 +0200 Subject: [PATCH 01/10] Initial version of PDM support --- Software/Software.ino | 7 + Software/USER_SETTINGS.cpp | 2 +- Software/USER_SETTINGS.h | 7 +- Software/src/battery/TEST-FAKE-BATTERY.cpp | 2 +- Software/src/charger/CHARGERS.h | 4 + Software/src/charger/nissanleaf.cpp | 256 ++++++++++++++++++ Software/src/charger/nissanleaf.h | 15 + Software/src/devboard/webserver/webserver.cpp | 78 +++++- 8 files changed, 357 insertions(+), 14 deletions(-) create mode 100644 Software/src/charger/nissanleaf.cpp create mode 100644 Software/src/charger/nissanleaf.h diff --git a/Software/Software.ino b/Software/Software.ino index f23676bb..52183af0 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -377,8 +377,12 @@ void receive_can() { // This section checks if we have a complete CAN message i #ifdef SMA_CAN receive_can_sma(rx_frame); #endif + // Charger #ifdef CHEVYVOLT_CHARGER receive_can_chevyvolt_charger(rx_frame); +#endif +#ifdef NISSANLEAF_CHARGER + receive_can_nissanleaf_charger(rx_frame); #endif } else { //printf("New extended frame"); @@ -441,6 +445,9 @@ void send_can() { #ifdef CHEVYVOLT_CHARGER send_can_chevyvolt_charger(); #endif +#ifdef NISSANLEAF_CHARGER + send_can_nissanleaf_charger(); +#endif } #ifdef DUAL_CAN diff --git a/Software/USER_SETTINGS.cpp b/Software/USER_SETTINGS.cpp index 78bcc435..9851c556 100644 --- a/Software/USER_SETTINGS.cpp +++ b/Software/USER_SETTINGS.cpp @@ -15,7 +15,7 @@ volatile uint16_t MAXCHARGEAMP = volatile uint16_t MAXDISCHARGEAMP = 300; //30.0A , BYD CAN specific setting, Max discharge speed in Amp (Some inverters needs to be artificially limited) -/* Charger settings */ +/* Charger settings (Optional, when generator charging) */ volatile float CHARGER_SET_HV = 384; // Reasonably appropriate 4.0v per cell charging of a 96s pack volatile float CHARGER_MAX_HV = 420; // Max permissible output (VDC) of charger volatile float CHARGER_MIN_HV = 200; // Min permissible output (VDC) of charger diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 9ed9e043..d34aa303 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -17,7 +17,7 @@ //#define RENAULT_ZOE_BATTERY //#define SANTA_FE_PHEV_BATTERY //#define TESLA_MODEL_3_BATTERY -//#define TEST_FAKE_BATTERY +#define TEST_FAKE_BATTERY /* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */ //#define BYD_CAN //Enable this line to emulate a "BYD Battery-Box Premium HVS" over CAN Bus @@ -36,10 +36,11 @@ //#define DUAL_CAN //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 controller (Needed for FoxESS inverters) //#define SERIAL_LINK_RECEIVER //Enable this line to receive battery data over RS485 pins from another Lilygo (This LilyGo interfaces with inverter) //#define SERIAL_LINK_TRANSMITTER //Enable this line to send battery data over RS485 pins to another Lilygo (This LilyGo interfaces with battery) -//#define WEBSERVER //Enable this line to enable WiFi, and to run the webserver. See USER_SETTINGS.cpp for the Wifi settings. +#define WEBSERVER //Enable this line to enable WiFi, and to run the webserver. See USER_SETTINGS.cpp for the Wifi settings. /* Select charger used (Optional) */ //#define CHEVYVOLT_CHARGER //Enable this line to control a Chevrolet Volt charger connected to battery - for example, when generator charging or using an inverter without a charging function. +#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging /* Battery limits: These are set in the USER_SETTINGS.cpp file, or later on via the Webserver */ extern volatile uint16_t BATTERY_WH_MAX; @@ -49,7 +50,7 @@ extern volatile uint16_t MAXCHARGEAMP; extern volatile uint16_t MAXDISCHARGEAMP; extern volatile uint8_t AccessPointEnabled; -/* Charger limits: Set in the USER_SETTINGS.cpp or later in the webserver */ +/* Charger limits (Optional): Set in the USER_SETTINGS.cpp or later in the webserver */ extern volatile float charger_setpoint_HV_VDC; extern volatile float charger_setpoint_HV_IDC; extern volatile float charger_setpoint_HV_IDC_END; diff --git a/Software/src/battery/TEST-FAKE-BATTERY.cpp b/Software/src/battery/TEST-FAKE-BATTERY.cpp index d825bd34..f24b8f8a 100644 --- a/Software/src/battery/TEST-FAKE-BATTERY.cpp +++ b/Software/src/battery/TEST-FAKE-BATTERY.cpp @@ -25,7 +25,7 @@ void update_values_test_battery() { /* This function puts fake values onto the p StateOfHealth = 9900; // 99.00% - battery_voltage = 3700; // 370.0V + //battery_voltage = 3700; // 370.0V , value set in startup in .ino file, editable via webUI battery_current = 0; // 0 A diff --git a/Software/src/charger/CHARGERS.h b/Software/src/charger/CHARGERS.h index 73bae3a1..bbf54b35 100644 --- a/Software/src/charger/CHARGERS.h +++ b/Software/src/charger/CHARGERS.h @@ -5,4 +5,8 @@ #include "chevyvolt.h" #endif +#ifdef NISSANLEAF_CHARGER +#include "nissanleaf.h" +#endif + #endif diff --git a/Software/src/charger/nissanleaf.cpp b/Software/src/charger/nissanleaf.cpp new file mode 100644 index 00000000..145fe91e --- /dev/null +++ b/Software/src/charger/nissanleaf.cpp @@ -0,0 +1,256 @@ +#include "nissanleaf.h" +#include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h" +#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" + +/* This implements Nissan LEAF PDM charger support. 2013-2024 Gen2/3 PDMs are supported + * + * This code is intended to facilitate standalone battery charging, + * for instance for troubleshooting purposes or emergency generator usage + * + * Credits go to: + * Damien Maguire (evmbw.org, https://github.com/damienmaguire/Stm32-vcu) + * + * The code functions a bit differently incase a Nissan LEAF battery is used. Almost + * all CAN messages are already sent from the battery in that case, so the charger + * implementation can focus on only controlling the charger, spoofing battery messages + * is not needed. + * + * Incase another battery type is used, the code ofcourse emulates a complete Nissan LEAF + * battery onto the CAN bus. +*/ + +/* CAN cycles and timers */ +static const uint8_t interval10ms = 10; +static const uint8_t interval100ms = 100; +static unsigned long previousMillis10ms = 0; +static unsigned long previousMillis100ms = 0; + +/* LEAF charger/battery parameters */ +enum OBC_MODES : uint8_t { IDLE_OR_QC = 1, FINISHED = 2, CHARGING_OR_INTERRUPTED = 4, IDLE1 = 8, IDLE2 = 9, PLUGGED_IN_WAITING_ON_TIMER }; +static uint8_t mprun100 = 0; //counter 0-3 +static uint8_t mprun10 = 0; //counter 0-3 +static uint8_t OBC_Charge_Status = IDLE_OR_QC; +static uint8_t OBCpowerSetpoint = 0; +static uint8_t OBCpower = 0; +static bool PPStatus = false; +static bool OBCwakeup = false; + +/* Voltage and current settings. Validation performed to set ceiling of 3300w vol*cur */ +extern volatile float charger_setpoint_HV_VDC; +extern volatile float charger_setpoint_HV_IDC; +extern volatile float charger_setpoint_HV_IDC_END; +extern bool charger_HV_enabled; +extern bool charger_aux12V_enabled; + +extern float charger_stat_HVcur; +extern float charger_stat_HVvol; +extern float charger_stat_ACcur; +extern float charger_stat_ACvol; +extern float charger_stat_LVcur; +extern float charger_stat_LVvol; + +//Actual content messages +static CAN_frame_t LEAF_1DB = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x1DB, + .data = {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00}}; +static CAN_frame_t LEAF_1DC = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x1DC, + .data = {0x6E, 0x0A, 0x05, 0xD5, 0x00, 0x00, 0x00, 0x00}}; +static CAN_frame_t LEAF_1F2 = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x1F2, + .data = {0x30, 0x00, 0x20, 0xAC, 0x00, 0x3C, 0x00, 0x8F}}; +static CAN_frame_t LEAF_50B = {.FIR = {.B = + { + .DLC = 7, + .FF = CAN_frame_std, + }}, + .MsgID = 0x50B, + .data = {0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x00}}; +static CAN_frame_t LEAF_55B = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x55B, + .data = {0xA4, 0x40, 0xAA, 0x00, 0xDF, 0xC0, 0x10, 0x00}}; +static CAN_frame_t LEAF_5BC = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x5BC, + .data = {0x3D, 0x80, 0xF0, 0x64, 0xB0, 0x01, 0x00, 0x32}}; + +static CAN_frame_t LEAF_59E = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x59E, + .data = {0x00, 0x00, 0x0C, 0x76, 0x18, 0x00, 0x00, 0x00}}; + +static uint8_t crctable[256] = { + 0, 133, 143, 10, 155, 30, 20, 145, 179, 54, 60, 185, 40, 173, 167, 34, 227, 102, 108, 233, 120, 253, + 247, 114, 80, 213, 223, 90, 203, 78, 68, 193, 67, 198, 204, 73, 216, 93, 87, 210, 240, 117, 127, 250, + 107, 238, 228, 97, 160, 37, 47, 170, 59, 190, 180, 49, 19, 150, 156, 25, 136, 13, 7, 130, 134, 3, + 9, 140, 29, 152, 146, 23, 53, 176, 186, 63, 174, 43, 33, 164, 101, 224, 234, 111, 254, 123, 113, 244, + 214, 83, 89, 220, 77, 200, 194, 71, 197, 64, 74, 207, 94, 219, 209, 84, 118, 243, 249, 124, 237, 104, + 98, 231, 38, 163, 169, 44, 189, 56, 50, 183, 149, 16, 26, 159, 14, 139, 129, 4, 137, 12, 6, 131, + 18, 151, 157, 24, 58, 191, 181, 48, 161, 36, 46, 171, 106, 239, 229, 96, 241, 116, 126, 251, 217, 92, + 86, 211, 66, 199, 205, 72, 202, 79, 69, 192, 81, 212, 222, 91, 121, 252, 246, 115, 226, 103, 109, 232, + 41, 172, 166, 35, 178, 55, 61, 184, 154, 31, 21, 144, 1, 132, 142, 11, 15, 138, 128, 5, 148, 17, + 27, 158, 188, 57, 51, 182, 39, 162, 168, 45, 236, 105, 99, 230, 119, 242, 248, 125, 95, 218, 208, 85, + 196, 65, 75, 206, 76, 201, 195, 70, 215, 82, 88, 221, 255, 122, 112, 245, 100, 225, 235, 110, 175, 42, + 32, 165, 52, 177, 187, 62, 28, 153, 147, 22, 135, 2, 8, 141}; + + +void receive_can_nissanleaf_charger(CAN_frame_t rx_frame) { + + switch (rx_frame.MsgID) { + case 0x679: // This message fires once when charging cable is plugged in + OBCwakeup = true; + charger_aux12V_enabled = true; //Not possible to turn off 12V charging + // Startout with default values, so that charging can begin when user plugs in cable + charger_HV_enabled = true; + charger_setpoint_HV_IDC = 16; // Ampere + charger_setpoint_HV_VDC = 400; // Target voltage + break; + case 0x390: + OBC_Charge_Status = ((rx_frame.data.u8[5] & 0x7E) >> 1); + if(OBC_Charge_Status == PLUGGED_IN_WAITING_ON_TIMER || CHARGING_OR_INTERRUPTED) { + PPStatus = true; //plug inserted + } + else { + PPStatus = false; //plug not inserted + } + break; + default: + break; + } +} + +void send_can_nissanleaf_charger() { + unsigned long currentMillis = millis(); + + /* Send keepalive with mode every 10ms */ + if (currentMillis - previousMillis10ms >= interval10ms) { + previousMillis10ms = currentMillis; + + mprun10++; + if (mprun10 >= 4) + mprun10 = 0; + + /* 1DB is the main control message. If LEAF battery is used, the battery controls almost everything */ + // Only send these messages if Nissan LEAF battery is not used + #ifndef NISSAN_LEAF_BATTERY + + // VCM message, containing info if battery should sleep or stay awake + ESP32Can.CANWriteFrame(&LEAF_50B); // HCM_WakeUpSleepCommand == 11b == WakeUp, and CANMASK = 1 + + LEAF_1DB.data.u8[7] = calculate_CRC_Nissan(&LEAF_1DB); + ESP32Can.CANWriteFrame(&LEAF_1DB); + + LEAF_1DC.data.u8[7] = calculate_CRC_Nissan(&LEAF_1DC); + ESP32Can.CANWriteFrame(&LEAF_1DC); + #endif + + OBCpowerSetpoint = ((charger_setpoint_HV_IDC * 4) + 0x64); + + // convert power setpoint to PDM format: + // 0xA0 = 15A (60x) + // 0x70 = 3 amps ish (12x) + // 0x6a = 1.4A (6x) + // 0x66 = 0.5A (2x) + // 0x65 = 0.3A (1x) + // 0x64 = no chg + // so 0x64=100. 0xA0=160. so 60 decimal steps. 1 step=100W??? + + // This line controls if power should flow or not + if (PPStatus && charger_HV_enabled) { //Charging starts when cable plugged in and User has requested charging to start via WebUI + // clamp min and max values + if (OBCpowerSetpoint > 0xA0) { //15A TODO, raise once cofirmed how to map bits into frame0 and frame1 + OBCpowerSetpoint = 0xA0; + } + else if(OBCpowerSetpoint <= 0x64) { + OBCpowerSetpoint = 0x64; // 100W? stuck at 100 in drive mode (no charging) + } + + // if actual battery_voltage is less than setpoint got to max power set from web ui + if (battery_voltage < (CHARGER_SET_HV * 10)) { //battery_voltage = V+1, 0-500.0 (0-5000) + OBCpower = OBCpowerSetpoint; + } + + // decrement charger power if volt setpoint is reached + if (battery_voltage >= (CHARGER_SET_HV * 10)) { + OBCpower--; + } + } + else + { + // set power to 0 if charge control is set to off or not in charge mode + OBCpower = 0x64; + } + + LEAF_1F2.data.u8[1] = OBCpower; + LEAF_1F2.data.u8[6] = mprun10; + LEAF_1F2.data.u8[7] = calculate_checksum_nibble(&LEAF_1F2); + + // TODO + ESP32Can.CANWriteFrame(&LEAF_1F2); // Logic needed to hijack so that the LEAF code does not send the static locked variant when charger is used! This is the only collision message + + } + + /* Send messages every 100ms here */ + if (currentMillis - previousMillis100ms >= interval100ms) { + previousMillis100ms = currentMillis; + + mprun100++; + if (mprun100 > 3) { + mprun100 = 0; + } + + // Only send these messages if Nissan LEAF battery is not used + #ifndef NISSAN_LEAF_BATTERY + + LEAF_55B.data.u8[6] = ((0x1 << 4) | (mprun100)); + + LEAF_55B.data.u8[7] = calculate_CRC_Nissan(&LEAF_55B); + ESP32Can.CANWriteFrame(&LEAF_55B); + + ESP32Can.CANWriteFrame(&LEAF_59E); + + ESP32Can.CANWriteFrame(&LEAF_5BC); + #endif + } + +} + +uint8_t calculate_CRC_Nissan(CAN_frame_t* frame) { + uint8_t crc = 0; + for (uint8_t j = 0; j < 7; j++) { + crc = crctable[(crc ^ static_cast(frame->data.u8[j])) % 256]; + } + return crc; +} + +uint8_t calculate_checksum_nibble(CAN_frame_t *frame){ + uint8_t sum = 0; + for(uint8_t i = 0; i < 7; i++){ + sum += frame->data.u8[i] >> 4; + sum += frame->data.u8[i] & 0xF; + } + sum = (sum + 2) & 0xF; + return sum; +} \ No newline at end of file diff --git a/Software/src/charger/nissanleaf.h b/Software/src/charger/nissanleaf.h new file mode 100644 index 00000000..7d725adf --- /dev/null +++ b/Software/src/charger/nissanleaf.h @@ -0,0 +1,15 @@ +#ifndef NISSANLEAF_H +#define NISSANLEAF_H +#include +#include "../../USER_SETTINGS.h" +#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" + +extern uint16_t battery_voltage; //V+1, 0-500.0 (0-5000) + +void update_values_can_nissanleaf_charger(); +void send_can_nissanleaf_charger(); +void receive_can_nissanleaf_charger(CAN_frame_t rx_frame); +uint8_t calculate_CRC_Nissan(CAN_frame_t* frame); +uint8_t calculate_checksum_nibble(CAN_frame_t *frame); + +#endif diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index e739c22a..ef93b801 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -115,7 +115,23 @@ void init_webserver() { } }); -#ifdef CHEVYVOLT_CHARGER +#ifdef TEST_FAKE_BATTERY + // Route for editing FakeBatteryVoltage + server.on("/updateFakeBatteryVoltage", HTTP_GET, [](AsyncWebServerRequest* request) { + if (!request->hasParam("value")) { + request->send(400, "text/plain", "Bad Request"); + } + + String value = request->getParam("value")->value(); + float val = value.toFloat(); + + battery_voltage = val*10; + + request->send(200, "text/plain", "Updated successfully"); + }); +#endif + +#if defined CHEVYVOLT_CHARGER || defined NISSANLEAF_CHARGER // Route for editing ChargerTargetV server.on("/updateChargeSetpointV", HTTP_GET, [](AsyncWebServerRequest* request) { if (!request->hasParam("value")) { @@ -378,10 +394,13 @@ String processor(const String& var) { #endif content += ""; -#ifdef CHEVYVOLT_CHARGER +#if defined CHEVYVOLT_CHARGER || defined NISSANLEAF_CHARGER content += "

Charger protocol: "; #ifdef CHEVYVOLT_CHARGER content += "Chevy Volt Gen1 Charger"; +#endif +#ifdef NISSANLEAF_CHARGER + content += "Nissan LEAF 2013-2024 PDM charger"; #endif content += "

"; #endif @@ -479,7 +498,13 @@ String processor(const String& var) { content += ""; } -#ifdef CHEVYVOLT_CHARGER + // Close the block + content += ""; + +#if defined CHEVYVOLT_CHARGER || defined NISSANLEAF_CHARGER + // Start a new block with orange background color + content += "
"; + content += "

Charger HV Enabled: "; if (charger_HV_enabled) { content += ""; @@ -513,10 +538,12 @@ String processor(const String& var) { content += "

Charger LVDC Output V: " + String(LVvol, 2) + "

"; content += "

Charger AC Input V: " + String(ACvol, 2) + "VAC

"; content += "

Charger AC Input I: " + String(ACvol, 2) + "VAC

"; -#endif // Close the block content += "
"; +#endif + + content += ""; content += " "; @@ -569,7 +596,25 @@ String settings_processor(const String& var) { " A "; content += "

Max discharge speed: " + String(MAXDISCHARGEAMP / 10.0, 1) + " A

"; -#ifdef CHEVYVOLT_CHARGER + // Close the block + content += ""; + +#ifdef TEST_FAKE_BATTERY + // Start a new block with blue background color + content += "
"; + float voltageFloat = static_cast(battery_voltage) / 10.0; // Convert to float and divide by 10 + content += "

Fake battery voltage: " + String(voltageFloat, 1) + + " V

"; + + // Close the block + content += "
"; +#endif + +#if defined CHEVYVOLT_CHARGER || defined NISSANLEAF_CHARGER + + // Start a new block with orange background color + content += "
"; + content += "

Charger HVDC Enabled: "; if (charger_HV_enabled) { content += ""; @@ -590,6 +635,9 @@ String settings_processor(const String& var) { " V

"; content += "

Charger Current Setpoint: " + String(charger_setpoint_HV_IDC, 1) + " A

"; + + // Close the block + content += "
"; #endif content += ""; - // Close the block - content += ""; - content += ""; content += ""; + return content; + } + return String(); +} + + + + + void onOTAStart() { // Log when OTA has started Serial.println("OTA update started!"); diff --git a/Software/src/devboard/webserver/webserver.h b/Software/src/devboard/webserver/webserver.h index e296c086..63fe2da8 100644 --- a/Software/src/devboard/webserver/webserver.h +++ b/Software/src/devboard/webserver/webserver.h @@ -25,6 +25,7 @@ extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 funct extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350 +extern uint16_t cellvoltages[120]; //mV 0-5000 per cell extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false @@ -98,6 +99,15 @@ String processor(const String& var); */ String settings_processor(const String& var); +/** + * @brief Replaces placeholder with content section in web page + * + * @param[in] var + * + * @return String + */ +String cellmonitor_processor(const String& var); + /** * @brief Executes on OTA start * From 055c933ee080ab9f16f8b2c14385a62e661896e9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 1 Feb 2024 21:58:06 +0200 Subject: [PATCH 03/10] Final tweaks, and 1F2 sending --- Software/USER_SETTINGS.h | 6 ++-- Software/src/battery/NISSAN-LEAF-BATTERY.cpp | 3 ++ Software/src/charger/nissanleaf.cpp | 29 +++++++++++++++---- Software/src/devboard/webserver/webserver.cpp | 24 +++++++++++---- Software/src/devboard/webserver/webserver.h | 3 ++ 5 files changed, 51 insertions(+), 14 deletions(-) diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index d34aa303..8620e53f 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -17,7 +17,7 @@ //#define RENAULT_ZOE_BATTERY //#define SANTA_FE_PHEV_BATTERY //#define TESLA_MODEL_3_BATTERY -#define TEST_FAKE_BATTERY +//#define TEST_FAKE_BATTERY /* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */ //#define BYD_CAN //Enable this line to emulate a "BYD Battery-Box Premium HVS" over CAN Bus @@ -36,11 +36,11 @@ //#define DUAL_CAN //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 controller (Needed for FoxESS inverters) //#define SERIAL_LINK_RECEIVER //Enable this line to receive battery data over RS485 pins from another Lilygo (This LilyGo interfaces with inverter) //#define SERIAL_LINK_TRANSMITTER //Enable this line to send battery data over RS485 pins to another Lilygo (This LilyGo interfaces with battery) -#define WEBSERVER //Enable this line to enable WiFi, and to run the webserver. See USER_SETTINGS.cpp for the Wifi settings. +//#define WEBSERVER //Enable this line to enable WiFi, and to run the webserver. See USER_SETTINGS.cpp for the Wifi settings. /* Select charger used (Optional) */ //#define CHEVYVOLT_CHARGER //Enable this line to control a Chevrolet Volt charger connected to battery - for example, when generator charging or using an inverter without a charging function. -#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging +//#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging /* Battery limits: These are set in the USER_SETTINGS.cpp file, or later on via the Webserver */ extern volatile uint16_t BATTERY_WH_MAX; diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp index 673b57d2..957178ef 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp @@ -844,7 +844,10 @@ void send_can_leaf_battery() { break; } + //Only send this message when NISSANLEAF_CHARGER is not defined (otherwise it will collide!) + #ifndef NISSANLEAF_CHARGER ESP32Can.CANWriteFrame(&LEAF_1F2); //Contains (CHG_STA_RQ == 1 == Normal Charge) + #endif mprun10r++; if (mprun10r > 19) { // 0x1F2 patter repeats after 20 messages, diff --git a/Software/src/charger/nissanleaf.cpp b/Software/src/charger/nissanleaf.cpp index 145fe91e..85a76d44 100644 --- a/Software/src/charger/nissanleaf.cpp +++ b/Software/src/charger/nissanleaf.cpp @@ -27,9 +27,12 @@ static unsigned long previousMillis100ms = 0; /* LEAF charger/battery parameters */ enum OBC_MODES : uint8_t { IDLE_OR_QC = 1, FINISHED = 2, CHARGING_OR_INTERRUPTED = 4, IDLE1 = 8, IDLE2 = 9, PLUGGED_IN_WAITING_ON_TIMER }; -static uint8_t mprun100 = 0; //counter 0-3 -static uint8_t mprun10 = 0; //counter 0-3 +enum OBC_VOLTAGES : uint8_t { NO_SIGNAL = 0, AC110 = 1, AC230 = 2, ABNORMAL_WAVE = 3 }; +static uint16_t OBC_Charge_Power = 0; // Actual charger output +static uint8_t mprun100 = 0; // Counter 0-3 +static uint8_t mprun10 = 0; // Counter 0-3 static uint8_t OBC_Charge_Status = IDLE_OR_QC; +static uint8_t OBC_Status_AC_Voltage = 0; //1=110V, 2=230V static uint8_t OBCpowerSetpoint = 0; static uint8_t OBCpower = 0; static bool PPStatus = false; @@ -122,7 +125,7 @@ void receive_can_nissanleaf_charger(CAN_frame_t rx_frame) { case 0x679: // This message fires once when charging cable is plugged in OBCwakeup = true; charger_aux12V_enabled = true; //Not possible to turn off 12V charging - // Startout with default values, so that charging can begin when user plugs in cable + // Startout with default values, so that charging can begin right when user plugs in cable charger_HV_enabled = true; charger_setpoint_HV_IDC = 16; // Ampere charger_setpoint_HV_VDC = 400; // Target voltage @@ -135,6 +138,19 @@ void receive_can_nissanleaf_charger(CAN_frame_t rx_frame) { else { PPStatus = false; //plug not inserted } + OBC_Status_AC_Voltage = ((rx_frame.data.u8[3] & 0x18) >> 3); + if(OBC_Status_AC_Voltage == AC110){ + charger_stat_ACvol = 110; + } + if(OBC_Status_AC_Voltage == AC230){ + charger_stat_ACvol = 230; + } + if(OBC_Status_AC_Voltage == ABNORMAL_WAVE){ + charger_stat_ACvol = 1; + } + + OBC_Charge_Power = ((rx_frame.data.u8[0] & 0x01) << 8) | (rx_frame.data.u8[1]); + charger_stat_HVcur = OBC_Charge_Power; break; default: break; @@ -194,7 +210,9 @@ void send_can_nissanleaf_charger() { // decrement charger power if volt setpoint is reached if (battery_voltage >= (CHARGER_SET_HV * 10)) { - OBCpower--; + if (OBCpower > 0x64){ + OBCpower--; + } } } else @@ -207,8 +225,7 @@ void send_can_nissanleaf_charger() { LEAF_1F2.data.u8[6] = mprun10; LEAF_1F2.data.u8[7] = calculate_checksum_nibble(&LEAF_1F2); - // TODO - ESP32Can.CANWriteFrame(&LEAF_1F2); // Logic needed to hijack so that the LEAF code does not send the static locked variant when charger is used! This is the only collision message + ESP32Can.CANWriteFrame(&LEAF_1F2); // Sending of 1F2 message is halted in LEAF-BATTERY function incase charger is used! } diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 5ebe4812..15569a9d 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -524,6 +524,7 @@ String processor(const String& var) { content += ""; } content += ""; + #ifdef CHEVYVOLT_CHARGER float chgPwrDC = static_cast(charger_stat_HVcur * charger_stat_HVvol); float chgPwrAC = static_cast(charger_stat_ACcur * charger_stat_ACvol); float chgEff = chgPwrDC / chgPwrAC * 100; @@ -536,13 +537,26 @@ String processor(const String& var) { content += formatPowerValue("Charger Output Power", chgPwrDC, "", 1); content += "

Charger Efficiency: " + String(chgEff) + "%

"; - content += "

Charger HVDC Output V: " + String(HVvol, 2) + "

"; - content += "

Charger HVDC Output I: " + String(HVcur, 2) + "

"; + content += "

Charger HVDC Output V: " + String(HVvol, 2) + " V

"; + content += "

Charger HVDC Output I: " + String(HVcur, 2) + " A

"; content += "

Charger LVDC Output I: " + String(LVcur, 2) + "

"; content += "

Charger LVDC Output V: " + String(LVvol, 2) + "

"; - content += "

Charger AC Input V: " + String(ACvol, 2) + "VAC

"; - content += "

Charger AC Input I: " + String(ACvol, 2) + "VAC

"; + content += "

Charger AC Input V: " + String(ACvol, 2) + " VAC

"; + content += "

Charger AC Input I: " + String(ACcur, 2) + " A

"; + #endif + #ifdef NISSANLEAF_CHARGER + float chgPwrDC = static_cast(charger_stat_HVcur*100); + charger_stat_HVcur = chgPwrDC/(battery_voltage/10); // P/U=I + charger_stat_HVvol = static_cast(battery_voltage/10); + float ACvol = charger_stat_ACvol; + float HVvol = charger_stat_HVvol; + float HVcur = charger_stat_HVcur; + content += formatPowerValue("Charger Output Power", chgPwrDC, "", 1); + content += "

Charger HVDC Output V: " + String(HVvol, 2) + " V

"; + content += "

Charger HVDC Output I: " + String(HVcur, 2) + " A

"; + content += "

Charger AC Input V: " + String(ACvol, 2) + " VAC

"; + #endif // Close the block content += ""; #endif @@ -920,4 +934,4 @@ String formatPowerValue(String label, T value, String unit, int precision) { result += unit + ""; return result; -} +} \ No newline at end of file diff --git a/Software/src/devboard/webserver/webserver.h b/Software/src/devboard/webserver/webserver.h index 63fe2da8..a3b9bc91 100644 --- a/Software/src/devboard/webserver/webserver.h +++ b/Software/src/devboard/webserver/webserver.h @@ -44,6 +44,9 @@ extern float charger_stat_ACvol; extern float charger_stat_LVcur; extern float charger_stat_LVvol; +//LEAF charger +extern uint16_t OBC_Charge_Power; + /** * @brief Initialization function for the webserver. * From 30d37480bee26cb4f7a1da0c4faca438481a91ed Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 1 Feb 2024 21:59:06 +0200 Subject: [PATCH 04/10] Pre-commit fix --- Software/Software.ino | 2 +- Software/src/battery/NISSAN-LEAF-BATTERY.cpp | 6 +- Software/src/battery/NISSAN-LEAF-BATTERY.h | 12 +- Software/src/battery/TEST-FAKE-BATTERY.cpp | 4 +- Software/src/battery/TEST-FAKE-BATTERY.h | 10 +- Software/src/charger/nissanleaf.cpp | 176 +++++++++--------- Software/src/charger/nissanleaf.h | 4 +- Software/src/devboard/webserver/webserver.cpp | 33 ++-- Software/src/devboard/webserver/webserver.h | 12 +- 9 files changed, 128 insertions(+), 131 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index 550172b4..b52e4bc3 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -67,7 +67,7 @@ uint8_t bms_status = ACTIVE; // ACTIVE - [0..5]<>[STANDBY,INACTIVE,DA uint16_t stat_batt_power = 0; // Power going in/out of battery uint16_t cell_max_voltage = 3700; // Stores the highest cell voltage value in the system uint16_t cell_min_voltage = 3700; // Stores the minimum cell voltage value in the system -uint16_t cellvoltages[120]; // Stores all cell voltages +uint16_t cellvoltages[120]; // Stores all cell voltages bool LFP_Chemistry = false; // Common charger parameters diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp index 957178ef..47415e57 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp @@ -844,10 +844,10 @@ void send_can_leaf_battery() { break; } - //Only send this message when NISSANLEAF_CHARGER is not defined (otherwise it will collide!) - #ifndef NISSANLEAF_CHARGER +//Only send this message when NISSANLEAF_CHARGER is not defined (otherwise it will collide!) +#ifndef NISSANLEAF_CHARGER ESP32Can.CANWriteFrame(&LEAF_1F2); //Contains (CHG_STA_RQ == 1 == Normal Charge) - #endif +#endif mprun10r++; if (mprun10r > 19) { // 0x1F2 patter repeats after 20 messages, diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.h b/Software/src/battery/NISSAN-LEAF-BATTERY.h index 1ae3a0b3..68e749e9 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.h +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.h @@ -21,12 +21,12 @@ extern uint16_t max_target_charge_power; //W, 0-60000 extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) -extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) -extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) -extern uint16_t cell_max_voltage; //mV, 0-4350 -extern uint16_t cell_min_voltage; //mV, 0-4350 -extern uint8_t LEDcolor; //Enum, 0-10 -extern uint16_t cellvoltages[120]; //mV 0-5000 per cell +extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) +extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) +extern uint16_t cell_max_voltage; //mV, 0-4350 +extern uint16_t cell_min_voltage; //mV, 0-4350 +extern uint8_t LEDcolor; //Enum, 0-10 +extern uint16_t cellvoltages[120]; //mV 0-5000 per cell extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false void update_values_leaf_battery(); diff --git a/Software/src/battery/TEST-FAKE-BATTERY.cpp b/Software/src/battery/TEST-FAKE-BATTERY.cpp index 82d9aad5..8deac988 100644 --- a/Software/src/battery/TEST-FAKE-BATTERY.cpp +++ b/Software/src/battery/TEST-FAKE-BATTERY.cpp @@ -46,9 +46,9 @@ void update_values_test_battery() { /* This function puts fake values onto the p max_target_discharge_power = 5000; // 5kW max_target_charge_power = 5000; // 5kW - + for (int i = 0; i < 97; ++i) { - cellvoltages[i] = 3500+i; + cellvoltages[i] = 3500 + i; } /*Finally print out values to serial if configured to do so*/ diff --git a/Software/src/battery/TEST-FAKE-BATTERY.h b/Software/src/battery/TEST-FAKE-BATTERY.h index 986afd78..22f0a9c2 100644 --- a/Software/src/battery/TEST-FAKE-BATTERY.h +++ b/Software/src/battery/TEST-FAKE-BATTERY.h @@ -21,11 +21,11 @@ extern uint16_t max_target_charge_power; //W, 0-60000 extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) -extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) -extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) -extern uint16_t cell_max_voltage; //mV, 0-4350 -extern uint16_t cell_min_voltage; //mV, 0-4350 -extern uint16_t cellvoltages[120]; //mV 0-5000 per cell +extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) +extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) +extern uint16_t cell_max_voltage; //mV, 0-4350 +extern uint16_t cell_min_voltage; //mV, 0-4350 +extern uint16_t cellvoltages[120]; //mV 0-5000 per cell extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false extern uint8_t LEDcolor; //Enum, 0-10 diff --git a/Software/src/charger/nissanleaf.cpp b/Software/src/charger/nissanleaf.cpp index 85a76d44..89998fd5 100644 --- a/Software/src/charger/nissanleaf.cpp +++ b/Software/src/charger/nissanleaf.cpp @@ -26,13 +26,20 @@ static unsigned long previousMillis10ms = 0; static unsigned long previousMillis100ms = 0; /* LEAF charger/battery parameters */ -enum OBC_MODES : uint8_t { IDLE_OR_QC = 1, FINISHED = 2, CHARGING_OR_INTERRUPTED = 4, IDLE1 = 8, IDLE2 = 9, PLUGGED_IN_WAITING_ON_TIMER }; +enum OBC_MODES : uint8_t { + IDLE_OR_QC = 1, + FINISHED = 2, + CHARGING_OR_INTERRUPTED = 4, + IDLE1 = 8, + IDLE2 = 9, + PLUGGED_IN_WAITING_ON_TIMER +}; enum OBC_VOLTAGES : uint8_t { NO_SIGNAL = 0, AC110 = 1, AC230 = 2, ABNORMAL_WAVE = 3 }; -static uint16_t OBC_Charge_Power = 0; // Actual charger output -static uint8_t mprun100 = 0; // Counter 0-3 -static uint8_t mprun10 = 0; // Counter 0-3 +static uint16_t OBC_Charge_Power = 0; // Actual charger output +static uint8_t mprun100 = 0; // Counter 0-3 +static uint8_t mprun10 = 0; // Counter 0-3 static uint8_t OBC_Charge_Status = IDLE_OR_QC; -static uint8_t OBC_Status_AC_Voltage = 0; //1=110V, 2=230V +static uint8_t OBC_Status_AC_Voltage = 0; //1=110V, 2=230V static uint8_t OBCpowerSetpoint = 0; static uint8_t OBCpower = 0; static bool PPStatus = false; @@ -54,55 +61,55 @@ extern float charger_stat_LVvol; //Actual content messages static CAN_frame_t LEAF_1DB = {.FIR = {.B = - { - .DLC = 8, - .FF = CAN_frame_std, - }}, - .MsgID = 0x1DB, - .data = {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00}}; + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x1DB, + .data = {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00}}; static CAN_frame_t LEAF_1DC = {.FIR = {.B = - { - .DLC = 8, - .FF = CAN_frame_std, - }}, - .MsgID = 0x1DC, - .data = {0x6E, 0x0A, 0x05, 0xD5, 0x00, 0x00, 0x00, 0x00}}; + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x1DC, + .data = {0x6E, 0x0A, 0x05, 0xD5, 0x00, 0x00, 0x00, 0x00}}; static CAN_frame_t LEAF_1F2 = {.FIR = {.B = - { - .DLC = 8, - .FF = CAN_frame_std, - }}, - .MsgID = 0x1F2, - .data = {0x30, 0x00, 0x20, 0xAC, 0x00, 0x3C, 0x00, 0x8F}}; + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x1F2, + .data = {0x30, 0x00, 0x20, 0xAC, 0x00, 0x3C, 0x00, 0x8F}}; static CAN_frame_t LEAF_50B = {.FIR = {.B = - { - .DLC = 7, - .FF = CAN_frame_std, - }}, - .MsgID = 0x50B, - .data = {0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x00}}; + { + .DLC = 7, + .FF = CAN_frame_std, + }}, + .MsgID = 0x50B, + .data = {0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x00}}; static CAN_frame_t LEAF_55B = {.FIR = {.B = - { - .DLC = 8, - .FF = CAN_frame_std, - }}, - .MsgID = 0x55B, - .data = {0xA4, 0x40, 0xAA, 0x00, 0xDF, 0xC0, 0x10, 0x00}}; + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x55B, + .data = {0xA4, 0x40, 0xAA, 0x00, 0xDF, 0xC0, 0x10, 0x00}}; static CAN_frame_t LEAF_5BC = {.FIR = {.B = - { - .DLC = 8, - .FF = CAN_frame_std, - }}, - .MsgID = 0x5BC, - .data = {0x3D, 0x80, 0xF0, 0x64, 0xB0, 0x01, 0x00, 0x32}}; + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x5BC, + .data = {0x3D, 0x80, 0xF0, 0x64, 0xB0, 0x01, 0x00, 0x32}}; static CAN_frame_t LEAF_59E = {.FIR = {.B = - { - .DLC = 8, - .FF = CAN_frame_std, - }}, - .MsgID = 0x59E, - .data = {0x00, 0x00, 0x0C, 0x76, 0x18, 0x00, 0x00, 0x00}}; + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x59E, + .data = {0x00, 0x00, 0x0C, 0x76, 0x18, 0x00, 0x00, 0x00}}; static uint8_t crctable[256] = { 0, 133, 143, 10, 155, 30, 20, 145, 179, 54, 60, 185, 40, 173, 167, 34, 227, 102, 108, 233, 120, 253, @@ -118,34 +125,32 @@ static uint8_t crctable[256] = { 196, 65, 75, 206, 76, 201, 195, 70, 215, 82, 88, 221, 255, 122, 112, 245, 100, 225, 235, 110, 175, 42, 32, 165, 52, 177, 187, 62, 28, 153, 147, 22, 135, 2, 8, 141}; - void receive_can_nissanleaf_charger(CAN_frame_t rx_frame) { switch (rx_frame.MsgID) { - case 0x679: // This message fires once when charging cable is plugged in + case 0x679: // This message fires once when charging cable is plugged in OBCwakeup = true; - charger_aux12V_enabled = true; //Not possible to turn off 12V charging + charger_aux12V_enabled = true; //Not possible to turn off 12V charging // Startout with default values, so that charging can begin right when user plugs in cable charger_HV_enabled = true; - charger_setpoint_HV_IDC = 16; // Ampere - charger_setpoint_HV_VDC = 400; // Target voltage + charger_setpoint_HV_IDC = 16; // Ampere + charger_setpoint_HV_VDC = 400; // Target voltage break; case 0x390: OBC_Charge_Status = ((rx_frame.data.u8[5] & 0x7E) >> 1); - if(OBC_Charge_Status == PLUGGED_IN_WAITING_ON_TIMER || CHARGING_OR_INTERRUPTED) { - PPStatus = true; //plug inserted - } - else { - PPStatus = false; //plug not inserted + if (OBC_Charge_Status == PLUGGED_IN_WAITING_ON_TIMER || CHARGING_OR_INTERRUPTED) { + PPStatus = true; //plug inserted + } else { + PPStatus = false; //plug not inserted } OBC_Status_AC_Voltage = ((rx_frame.data.u8[3] & 0x18) >> 3); - if(OBC_Status_AC_Voltage == AC110){ + if (OBC_Status_AC_Voltage == AC110) { charger_stat_ACvol = 110; } - if(OBC_Status_AC_Voltage == AC230){ + if (OBC_Status_AC_Voltage == AC230) { charger_stat_ACvol = 230; } - if(OBC_Status_AC_Voltage == ABNORMAL_WAVE){ + if (OBC_Status_AC_Voltage == ABNORMAL_WAVE) { charger_stat_ACvol = 1; } @@ -166,11 +171,11 @@ void send_can_nissanleaf_charger() { mprun10++; if (mprun10 >= 4) - mprun10 = 0; + mprun10 = 0; - /* 1DB is the main control message. If LEAF battery is used, the battery controls almost everything */ - // Only send these messages if Nissan LEAF battery is not used - #ifndef NISSAN_LEAF_BATTERY +/* 1DB is the main control message. If LEAF battery is used, the battery controls almost everything */ +// Only send these messages if Nissan LEAF battery is not used +#ifndef NISSAN_LEAF_BATTERY // VCM message, containing info if battery should sleep or stay awake ESP32Can.CANWriteFrame(&LEAF_50B); // HCM_WakeUpSleepCommand == 11b == WakeUp, and CANMASK = 1 @@ -180,7 +185,7 @@ void send_can_nissanleaf_charger() { LEAF_1DC.data.u8[7] = calculate_CRC_Nissan(&LEAF_1DC); ESP32Can.CANWriteFrame(&LEAF_1DC); - #endif +#endif OBCpowerSetpoint = ((charger_setpoint_HV_IDC * 4) + 0x64); @@ -194,39 +199,37 @@ void send_can_nissanleaf_charger() { // so 0x64=100. 0xA0=160. so 60 decimal steps. 1 step=100W??? // This line controls if power should flow or not - if (PPStatus && charger_HV_enabled) { //Charging starts when cable plugged in and User has requested charging to start via WebUI + if (PPStatus && + charger_HV_enabled) { //Charging starts when cable plugged in and User has requested charging to start via WebUI // clamp min and max values - if (OBCpowerSetpoint > 0xA0) { //15A TODO, raise once cofirmed how to map bits into frame0 and frame1 + if (OBCpowerSetpoint > 0xA0) { //15A TODO, raise once cofirmed how to map bits into frame0 and frame1 OBCpowerSetpoint = 0xA0; + } else if (OBCpowerSetpoint <= 0x64) { + OBCpowerSetpoint = 0x64; // 100W? stuck at 100 in drive mode (no charging) } - else if(OBCpowerSetpoint <= 0x64) { - OBCpowerSetpoint = 0x64; // 100W? stuck at 100 in drive mode (no charging) - } - + // if actual battery_voltage is less than setpoint got to max power set from web ui - if (battery_voltage < (CHARGER_SET_HV * 10)) { //battery_voltage = V+1, 0-500.0 (0-5000) + if (battery_voltage < (CHARGER_SET_HV * 10)) { //battery_voltage = V+1, 0-500.0 (0-5000) OBCpower = OBCpowerSetpoint; } // decrement charger power if volt setpoint is reached if (battery_voltage >= (CHARGER_SET_HV * 10)) { - if (OBCpower > 0x64){ + if (OBCpower > 0x64) { OBCpower--; } } - } - else - { + } else { // set power to 0 if charge control is set to off or not in charge mode OBCpower = 0x64; - } + } LEAF_1F2.data.u8[1] = OBCpower; LEAF_1F2.data.u8[6] = mprun10; LEAF_1F2.data.u8[7] = calculate_checksum_nibble(&LEAF_1F2); - ESP32Can.CANWriteFrame(&LEAF_1F2); // Sending of 1F2 message is halted in LEAF-BATTERY function incase charger is used! - + ESP32Can.CANWriteFrame( + &LEAF_1F2); // Sending of 1F2 message is halted in LEAF-BATTERY function incase charger is used! } /* Send messages every 100ms here */ @@ -238,20 +241,19 @@ void send_can_nissanleaf_charger() { mprun100 = 0; } - // Only send these messages if Nissan LEAF battery is not used - #ifndef NISSAN_LEAF_BATTERY +// Only send these messages if Nissan LEAF battery is not used +#ifndef NISSAN_LEAF_BATTERY LEAF_55B.data.u8[6] = ((0x1 << 4) | (mprun100)); - + LEAF_55B.data.u8[7] = calculate_CRC_Nissan(&LEAF_55B); ESP32Can.CANWriteFrame(&LEAF_55B); ESP32Can.CANWriteFrame(&LEAF_59E); ESP32Can.CANWriteFrame(&LEAF_5BC); - #endif +#endif } - } uint8_t calculate_CRC_Nissan(CAN_frame_t* frame) { @@ -262,12 +264,12 @@ uint8_t calculate_CRC_Nissan(CAN_frame_t* frame) { return crc; } -uint8_t calculate_checksum_nibble(CAN_frame_t *frame){ +uint8_t calculate_checksum_nibble(CAN_frame_t* frame) { uint8_t sum = 0; - for(uint8_t i = 0; i < 7; i++){ + for (uint8_t i = 0; i < 7; i++) { sum += frame->data.u8[i] >> 4; sum += frame->data.u8[i] & 0xF; } sum = (sum + 2) & 0xF; return sum; -} \ No newline at end of file +} diff --git a/Software/src/charger/nissanleaf.h b/Software/src/charger/nissanleaf.h index 7d725adf..beb76aab 100644 --- a/Software/src/charger/nissanleaf.h +++ b/Software/src/charger/nissanleaf.h @@ -4,12 +4,12 @@ #include "../../USER_SETTINGS.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" -extern uint16_t battery_voltage; //V+1, 0-500.0 (0-5000) +extern uint16_t battery_voltage; //V+1, 0-500.0 (0-5000) void update_values_can_nissanleaf_charger(); void send_can_nissanleaf_charger(); void receive_can_nissanleaf_charger(CAN_frame_t rx_frame); uint8_t calculate_CRC_Nissan(CAN_frame_t* frame); -uint8_t calculate_checksum_nibble(CAN_frame_t *frame); +uint8_t calculate_checksum_nibble(CAN_frame_t* frame); #endif diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 15569a9d..9d108077 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -61,8 +61,9 @@ void init_webserver() { [](AsyncWebServerRequest* request) { request->send_P(200, "text/html", index_html, settings_processor); }); // Route for going to cellmonitor web page - server.on("/cellmonitor", HTTP_GET, - [](AsyncWebServerRequest* request) { request->send_P(200, "text/html", index_html, cellmonitor_processor); }); + server.on("/cellmonitor", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send_P(200, "text/html", index_html, cellmonitor_processor); + }); // Route for editing Wh server.on("/updateBatterySize", HTTP_GET, [](AsyncWebServerRequest* request) { @@ -129,7 +130,7 @@ void init_webserver() { String value = request->getParam("value")->value(); float val = value.toFloat(); - battery_voltage = val*10; + battery_voltage = val * 10; request->send(200, "text/plain", "Updated successfully"); }); @@ -524,7 +525,7 @@ String processor(const String& var) { content += ""; } content += ""; - #ifdef CHEVYVOLT_CHARGER +#ifdef CHEVYVOLT_CHARGER float chgPwrDC = static_cast(charger_stat_HVcur * charger_stat_HVvol); float chgPwrAC = static_cast(charger_stat_ACcur * charger_stat_ACvol); float chgEff = chgPwrDC / chgPwrAC * 100; @@ -543,11 +544,11 @@ String processor(const String& var) { content += "

Charger LVDC Output V: " + String(LVvol, 2) + "

"; content += "

Charger AC Input V: " + String(ACvol, 2) + " VAC

"; content += "

Charger AC Input I: " + String(ACcur, 2) + " A

"; - #endif - #ifdef NISSANLEAF_CHARGER - float chgPwrDC = static_cast(charger_stat_HVcur*100); - charger_stat_HVcur = chgPwrDC/(battery_voltage/10); // P/U=I - charger_stat_HVvol = static_cast(battery_voltage/10); +#endif +#ifdef NISSANLEAF_CHARGER + float chgPwrDC = static_cast(charger_stat_HVcur * 100); + charger_stat_HVcur = chgPwrDC / (battery_voltage / 10); // P/U=I + charger_stat_HVvol = static_cast(battery_voltage / 10); float ACvol = charger_stat_ACvol; float HVvol = charger_stat_HVvol; float HVcur = charger_stat_HVcur; @@ -556,13 +557,11 @@ String processor(const String& var) { content += "

Charger HVDC Output V: " + String(HVvol, 2) + " V

"; content += "

Charger HVDC Output I: " + String(HVcur, 2) + " A

"; content += "

Charger AC Input V: " + String(ACvol, 2) + " VAC

"; - #endif +#endif // Close the block content += ""; #endif - - content += ""; content += " "; content += ""; @@ -839,8 +838,8 @@ String cellmonitor_processor(const String& var) { content += "body { background-color: black; color: white; }"; content += ".container { display: flex; flex-wrap: wrap; justify-content: space-around; }"; content += ".cell { width: 48%; margin: 1%; padding: 10px; border: 1px solid white; text-align: center; }"; - content += ".low-voltage { color: red; }"; // Style for low voltage text - content += ".voltage-values { margin-bottom: 10px; }"; // Style for voltage values section + content += ".low-voltage { color: red; }"; // Style for low voltage text + content += ".voltage-values { margin-bottom: 10px; }"; // Style for voltage values section content += ""; // Start a new block with a specific background color @@ -885,10 +884,6 @@ String cellmonitor_processor(const String& var) { return String(); } - - - - void onOTAStart() { // Log when OTA has started Serial.println("OTA update started!"); @@ -934,4 +929,4 @@ String formatPowerValue(String label, T value, String unit, int precision) { result += unit + ""; return result; -} \ No newline at end of file +} diff --git a/Software/src/devboard/webserver/webserver.h b/Software/src/devboard/webserver/webserver.h index a3b9bc91..cb807312 100644 --- a/Software/src/devboard/webserver/webserver.h +++ b/Software/src/devboard/webserver/webserver.h @@ -21,12 +21,12 @@ extern uint16_t max_target_charge_power; //W, 0-60000 extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) -extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) -extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) -extern uint16_t cell_max_voltage; //mV, 0-4350 -extern uint16_t cell_min_voltage; //mV, 0-4350 -extern uint16_t cellvoltages[120]; //mV 0-5000 per cell -extern uint8_t LEDcolor; //Enum, 0-10 +extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) +extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) +extern uint16_t cell_max_voltage; //mV, 0-4350 +extern uint16_t cell_min_voltage; //mV, 0-4350 +extern uint16_t cellvoltages[120]; //mV 0-5000 per cell +extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false From 31178526b87af42b5478da1b91843d9a944ad4fe Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 1 Feb 2024 22:08:33 +0200 Subject: [PATCH 05/10] Fix bug, LEAF has 96S not 97S --- Software/src/battery/NISSAN-LEAF-BATTERY.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp index 47415e57..cfebe41e 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp @@ -240,7 +240,7 @@ void update_values_leaf_battery() { /* This function maps all the values fetched } //Map all cell voltages to the global array - for (int i = 0; i < 97; ++i) { + for (int i = 0; i < 96; ++i) { cellvoltages[i] = cell_voltages[i]; } From c04d4af3df96500844af9cce641abb6d3f141da3 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 2 Feb 2024 21:54:08 +0200 Subject: [PATCH 06/10] Add all cellvoltages to monitoring --- Software/src/battery/TESLA-MODEL-3-BATTERY.cpp | 16 ++++++++++++++++ Software/src/battery/TESLA-MODEL-3-BATTERY.h | 11 ++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp b/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp index 2e742863..3cd038e1 100644 --- a/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp +++ b/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp @@ -451,6 +451,22 @@ void receive_can_tesla_model_3_battery(CAN_frame_t rx_frame) { min_temp = (rx_frame.data.u8[3] * 5) - 400; //Multiply by 5 and remove offset to get C+1 (0x61*5=485-400=8.5*C) } break; + case 0x401: // Cell stats + mux = (rx_frame.data.u8[0]); + + static uint16_t volts; + + if (rx_frame.data.u8[1] == 0x2A) // status byte must be 0x2A to read cellvoltages + { + // Example, frame3=0x89,frame2=0x1D = 35101 / 10 = 3510mV + volts = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]) / 10; + cellvoltages[1 + mux * 3] = volts; + volts = ((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[4]) / 10; + cellvoltages[2 + mux * 3] = volts; + volts = ((rx_frame.data.u8[7] << 8) | rx_frame.data.u8[6]) / 10; + cellvoltages[3 + mux * 3] = volts; + } + break; case 0x2d2: //Min / max limits min_voltage = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * 0.01 * 2; //Example 24148mv * 0.01 = 241.48 V diff --git a/Software/src/battery/TESLA-MODEL-3-BATTERY.h b/Software/src/battery/TESLA-MODEL-3-BATTERY.h index e958efd5..13225497 100644 --- a/Software/src/battery/TESLA-MODEL-3-BATTERY.h +++ b/Software/src/battery/TESLA-MODEL-3-BATTERY.h @@ -24,11 +24,12 @@ extern uint16_t max_target_charge_power; //W, 0-60000 extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) -extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) -extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) -extern uint16_t cell_max_voltage; //mV, 0-4350 -extern uint16_t cell_min_voltage; //mV, 0-4350 -extern uint8_t LEDcolor; //Enum, 0-10 +extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) +extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) +extern uint16_t cell_max_voltage; //mV, 0-4350 +extern uint16_t cell_min_voltage; //mV, 0-4350 +extern uint16_t cellvoltages[120]; //mV 0-5000 per cell +extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false extern bool LFP_Chemistry; From 19c99974e7a8d73572537937582936f2f274fb32 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 3 Feb 2024 12:02:20 +0200 Subject: [PATCH 07/10] Fix cellvoltages to start from 0 --- Software/src/battery/TESLA-MODEL-3-BATTERY.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp b/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp index 3cd038e1..aded7618 100644 --- a/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp +++ b/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp @@ -460,11 +460,11 @@ void receive_can_tesla_model_3_battery(CAN_frame_t rx_frame) { { // Example, frame3=0x89,frame2=0x1D = 35101 / 10 = 3510mV volts = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]) / 10; - cellvoltages[1 + mux * 3] = volts; + cellvoltages[mux * 3] = volts; volts = ((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[4]) / 10; - cellvoltages[2 + mux * 3] = volts; + cellvoltages[1 + mux * 3] = volts; volts = ((rx_frame.data.u8[7] << 8) | rx_frame.data.u8[6]) / 10; - cellvoltages[3 + mux * 3] = volts; + cellvoltages[2 + mux * 3] = volts; } break; case 0x2d2: From 6d7fe8719217b9dd41a4718f096aed737c1ec805 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 3 Feb 2024 12:39:15 +0200 Subject: [PATCH 08/10] Rename files to match guidelines --- Software/src/charger/CHARGERS.h | 4 ++-- .../src/charger/{chevyvolt.cpp => CHEVY-VOLT-CHARGER.cpp} | 2 +- Software/src/charger/{chevyvolt.h => CHEVY-VOLT-CHARGER.h} | 4 ++-- .../src/charger/{nissanleaf.cpp => NISSAN-LEAF-CHARGER.cpp} | 2 +- Software/src/charger/{nissanleaf.h => NISSAN-LEAF-CHARGER.h} | 5 ++--- 5 files changed, 8 insertions(+), 9 deletions(-) rename Software/src/charger/{chevyvolt.cpp => CHEVY-VOLT-CHARGER.cpp} (99%) rename Software/src/charger/{chevyvolt.h => CHEVY-VOLT-CHARGER.h} (90%) rename Software/src/charger/{nissanleaf.cpp => NISSAN-LEAF-CHARGER.cpp} (99%) rename Software/src/charger/{nissanleaf.h => NISSAN-LEAF-CHARGER.h} (81%) diff --git a/Software/src/charger/CHARGERS.h b/Software/src/charger/CHARGERS.h index bbf54b35..2b5793f3 100644 --- a/Software/src/charger/CHARGERS.h +++ b/Software/src/charger/CHARGERS.h @@ -2,11 +2,11 @@ #define CHARGERS_H #ifdef CHEVYVOLT_CHARGER -#include "chevyvolt.h" +#include "CHEVY-VOLT-CHARGER.h" #endif #ifdef NISSANLEAF_CHARGER -#include "nissanleaf.h" +#include "NISSAN-LEAF-CHARGER.h" #endif #endif diff --git a/Software/src/charger/chevyvolt.cpp b/Software/src/charger/CHEVY-VOLT-CHARGER.cpp similarity index 99% rename from Software/src/charger/chevyvolt.cpp rename to Software/src/charger/CHEVY-VOLT-CHARGER.cpp index a44e59b2..817c606b 100644 --- a/Software/src/charger/chevyvolt.cpp +++ b/Software/src/charger/CHEVY-VOLT-CHARGER.cpp @@ -1,4 +1,4 @@ -#include "chevyvolt.h" +#include "CHEVY-VOLT-CHARGER.h" #include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" diff --git a/Software/src/charger/chevyvolt.h b/Software/src/charger/CHEVY-VOLT-CHARGER.h similarity index 90% rename from Software/src/charger/chevyvolt.h rename to Software/src/charger/CHEVY-VOLT-CHARGER.h index 522397e6..8f80797a 100644 --- a/Software/src/charger/chevyvolt.h +++ b/Software/src/charger/CHEVY-VOLT-CHARGER.h @@ -1,5 +1,5 @@ -#ifndef CHEVYVOLT_H -#define CHEVYVOLT_H +#ifndef CHEVYVOLT_CHARGER_H +#define CHEVYVOLT_CHARGER_H #include #include "../../USER_SETTINGS.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" diff --git a/Software/src/charger/nissanleaf.cpp b/Software/src/charger/NISSAN-LEAF-CHARGER.cpp similarity index 99% rename from Software/src/charger/nissanleaf.cpp rename to Software/src/charger/NISSAN-LEAF-CHARGER.cpp index 89998fd5..69a43978 100644 --- a/Software/src/charger/nissanleaf.cpp +++ b/Software/src/charger/NISSAN-LEAF-CHARGER.cpp @@ -1,4 +1,4 @@ -#include "nissanleaf.h" +#include "NISSAN-LEAF-CHARGER.h" #include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" diff --git a/Software/src/charger/nissanleaf.h b/Software/src/charger/NISSAN-LEAF-CHARGER.h similarity index 81% rename from Software/src/charger/nissanleaf.h rename to Software/src/charger/NISSAN-LEAF-CHARGER.h index beb76aab..b004e8bc 100644 --- a/Software/src/charger/nissanleaf.h +++ b/Software/src/charger/NISSAN-LEAF-CHARGER.h @@ -1,12 +1,11 @@ -#ifndef NISSANLEAF_H -#define NISSANLEAF_H +#ifndef NISSANLEAF_CHARGER_H +#define NISSANLEAF_CHARGER_H #include #include "../../USER_SETTINGS.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" extern uint16_t battery_voltage; //V+1, 0-500.0 (0-5000) -void update_values_can_nissanleaf_charger(); void send_can_nissanleaf_charger(); void receive_can_nissanleaf_charger(CAN_frame_t rx_frame); uint8_t calculate_CRC_Nissan(CAN_frame_t* frame); From 0befc4b71309fbb80fc505f09a42af20231bfa6c Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 3 Feb 2024 12:49:12 +0200 Subject: [PATCH 09/10] Update comment on cellvoltagearray --- Software/src/battery/NISSAN-LEAF-BATTERY.h | 2 +- Software/src/battery/TESLA-MODEL-3-BATTERY.h | 2 +- Software/src/devboard/webserver/webserver.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.h b/Software/src/battery/NISSAN-LEAF-BATTERY.h index 68e749e9..046bd3ca 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.h +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.h @@ -26,7 +26,7 @@ extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 func extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350 extern uint8_t LEDcolor; //Enum, 0-10 -extern uint16_t cellvoltages[120]; //mV 0-5000 per cell +extern uint16_t cellvoltages[120]; //mV 0-4350 per cell extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false void update_values_leaf_battery(); diff --git a/Software/src/battery/TESLA-MODEL-3-BATTERY.h b/Software/src/battery/TESLA-MODEL-3-BATTERY.h index 13225497..4de5457e 100644 --- a/Software/src/battery/TESLA-MODEL-3-BATTERY.h +++ b/Software/src/battery/TESLA-MODEL-3-BATTERY.h @@ -28,7 +28,7 @@ extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 func extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350 -extern uint16_t cellvoltages[120]; //mV 0-5000 per cell +extern uint16_t cellvoltages[120]; //mV 0-4350 per cell extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false diff --git a/Software/src/devboard/webserver/webserver.h b/Software/src/devboard/webserver/webserver.h index e1739f9a..69e7324a 100644 --- a/Software/src/devboard/webserver/webserver.h +++ b/Software/src/devboard/webserver/webserver.h @@ -25,7 +25,7 @@ extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 func extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350 -extern uint16_t cellvoltages[120]; //mV 0-5000 per cell +extern uint16_t cellvoltages[120]; //mV 0-4350 per cell extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false From 05b9e79c728d73a23052376e6f27296e626b2514 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 3 Feb 2024 12:54:11 +0200 Subject: [PATCH 10/10] Make functions static --- Software/src/charger/NISSAN-LEAF-CHARGER.cpp | 36 ++++++++++---------- Software/src/charger/NISSAN-LEAF-CHARGER.h | 2 -- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Software/src/charger/NISSAN-LEAF-CHARGER.cpp b/Software/src/charger/NISSAN-LEAF-CHARGER.cpp index 69a43978..50e7a263 100644 --- a/Software/src/charger/NISSAN-LEAF-CHARGER.cpp +++ b/Software/src/charger/NISSAN-LEAF-CHARGER.cpp @@ -125,6 +125,24 @@ static uint8_t crctable[256] = { 196, 65, 75, 206, 76, 201, 195, 70, 215, 82, 88, 221, 255, 122, 112, 245, 100, 225, 235, 110, 175, 42, 32, 165, 52, 177, 187, 62, 28, 153, 147, 22, 135, 2, 8, 141}; +static uint8_t calculate_CRC_Nissan(CAN_frame_t* frame) { + uint8_t crc = 0; + for (uint8_t j = 0; j < 7; j++) { + crc = crctable[(crc ^ static_cast(frame->data.u8[j])) % 256]; + } + return crc; +} + +static uint8_t calculate_checksum_nibble(CAN_frame_t* frame) { + uint8_t sum = 0; + for (uint8_t i = 0; i < 7; i++) { + sum += frame->data.u8[i] >> 4; + sum += frame->data.u8[i] & 0xF; + } + sum = (sum + 2) & 0xF; + return sum; +} + void receive_can_nissanleaf_charger(CAN_frame_t rx_frame) { switch (rx_frame.MsgID) { @@ -255,21 +273,3 @@ void send_can_nissanleaf_charger() { #endif } } - -uint8_t calculate_CRC_Nissan(CAN_frame_t* frame) { - uint8_t crc = 0; - for (uint8_t j = 0; j < 7; j++) { - crc = crctable[(crc ^ static_cast(frame->data.u8[j])) % 256]; - } - return crc; -} - -uint8_t calculate_checksum_nibble(CAN_frame_t* frame) { - uint8_t sum = 0; - for (uint8_t i = 0; i < 7; i++) { - sum += frame->data.u8[i] >> 4; - sum += frame->data.u8[i] & 0xF; - } - sum = (sum + 2) & 0xF; - return sum; -} diff --git a/Software/src/charger/NISSAN-LEAF-CHARGER.h b/Software/src/charger/NISSAN-LEAF-CHARGER.h index b004e8bc..691a7535 100644 --- a/Software/src/charger/NISSAN-LEAF-CHARGER.h +++ b/Software/src/charger/NISSAN-LEAF-CHARGER.h @@ -8,7 +8,5 @@ extern uint16_t battery_voltage; //V+1, 0-500.0 (0-5000) void send_can_nissanleaf_charger(); void receive_can_nissanleaf_charger(CAN_frame_t rx_frame); -uint8_t calculate_CRC_Nissan(CAN_frame_t* frame); -uint8_t calculate_checksum_nibble(CAN_frame_t* frame); #endif