mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Merge branch 'dalathegreat:main' into improvement/tesla-advanced-battery
This commit is contained in:
commit
d07443f8be
50 changed files with 2091 additions and 820 deletions
4
.github/workflows/compile-all-batteries.yml
vendored
4
.github/workflows/compile-all-batteries.yml
vendored
|
@ -86,6 +86,10 @@ jobs:
|
||||||
# First we clone the repo using the `checkout` action.
|
# First we clone the repo using the `checkout` action.
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h
|
||||||
|
- name: Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h
|
||||||
|
run: cp ./Software/USER_SECRETS.TEMPLATE.h ./Software/USER_SECRETS.h
|
||||||
|
|
||||||
# We use the `arduino/setup-arduino-cli` action to install and
|
# We use the `arduino/setup-arduino-cli` action to install and
|
||||||
# configure the Arduino CLI on the system.
|
# configure the Arduino CLI on the system.
|
||||||
|
|
|
@ -92,6 +92,10 @@ jobs:
|
||||||
# First we clone the repo using the `checkout` action.
|
# First we clone the repo using the `checkout` action.
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h
|
||||||
|
- name: Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h
|
||||||
|
run: cp ./Software/USER_SECRETS.TEMPLATE.h ./Software/USER_SECRETS.h
|
||||||
|
|
||||||
# We use the `arduino/setup-arduino-cli` action to install and
|
# We use the `arduino/setup-arduino-cli` action to install and
|
||||||
# configure the Arduino CLI on the system.
|
# configure the Arduino CLI on the system.
|
||||||
|
|
|
@ -93,6 +93,10 @@ jobs:
|
||||||
# First we clone the repo using the `checkout` action.
|
# First we clone the repo using the `checkout` action.
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h
|
||||||
|
- name: Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h
|
||||||
|
run: cp ./Software/USER_SECRETS.TEMPLATE.h ./Software/USER_SECRETS.h
|
||||||
|
|
||||||
# We use the `arduino/setup-arduino-cli` action to install and
|
# We use the `arduino/setup-arduino-cli` action to install and
|
||||||
# configure the Arduino CLI on the system.
|
# configure the Arduino CLI on the system.
|
||||||
|
|
4
.github/workflows/compile-all-inverters.yml
vendored
4
.github/workflows/compile-all-inverters.yml
vendored
|
@ -78,6 +78,10 @@ jobs:
|
||||||
# First we clone the repo using the `checkout` action.
|
# First we clone the repo using the `checkout` action.
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h
|
||||||
|
- name: Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h
|
||||||
|
run: cp ./Software/USER_SECRETS.TEMPLATE.h ./Software/USER_SECRETS.h
|
||||||
|
|
||||||
# We use the `arduino/setup-arduino-cli` action to install and
|
# We use the `arduino/setup-arduino-cli` action to install and
|
||||||
# configure the Arduino CLI on the system.
|
# configure the Arduino CLI on the system.
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -22,3 +22,6 @@ compile.bat
|
||||||
|
|
||||||
# Ignore binary files
|
# Ignore binary files
|
||||||
*.bin
|
*.bin
|
||||||
|
|
||||||
|
# Ignore secret file
|
||||||
|
USER_SECRETS.h
|
10
README.md
10
README.md
|
@ -44,17 +44,19 @@ For more examples showing wiring, see each battery types own Wiki page. For inst
|
||||||
3. Click `File` menu -> `Preferences` -> `Additional Development` -> `Additional Board Manager URLs` -> Enter the URL in the input box: `https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json` and click OK.
|
3. Click `File` menu -> `Preferences` -> `Additional Development` -> `Additional Board Manager URLs` -> Enter the URL in the input box: `https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json` and click OK.
|
||||||
4. Click `Tools` menu -> `Board: "...."` -> `Boards Manager...`, install the `esp32` package by `Espressif Systems` (not `Arduino ESP32 Boards`), then press `Close`.
|
4. Click `Tools` menu -> `Board: "...."` -> `Boards Manager...`, install the `esp32` package by `Espressif Systems` (not `Arduino ESP32 Boards`), then press `Close`.
|
||||||
|
|
||||||
**NOTE: The version depends on which release of Battery-Emulator you are running!**
|
**NOTE: The ESP32 version depends on which release of Battery-Emulator you are running!**
|
||||||
|
|
||||||
- ⚠️ Make sure to use a 2.x.x version if you are on a release **older** than 6.0.0 (For instance ESP32 v2.0.11 when using Battery-Emulator v5.4.0)
|
- ⚠️ Make sure to use a 2.x.x version if you are on a release **older** than 6.0.0 (For instance ESP32 v2.0.11 when using Battery-Emulator v5.4.0)
|
||||||
- ⚠️ Make sure to use a 3.x.x version if you are on a release **newer** than 6.0.0 (For instance ESP32 v3.0.0 when using Battery-Emulator v6.0.0)
|
- ⚠️ Make sure to use a 3.0.x version if you are on a release **newer** than 6.0.0 (For instance ESP32 v3.0.0 when using Battery-Emulator v6.0.0)
|
||||||
|
- ⚠️ Make sure to use a 3.1.x version if you are on a release **newer** than 8.0.0 (For instance ESP32 v3.1.0 when using Battery-Emulator v8.0.0)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
5. The Arduino board should be set to `ESP32 Dev Module` (under `Tools` -> `Board` -> `ESP32 Arduino`) with the following settings:
|
5. The Arduino board should be set to `ESP32 Dev Module` (under `Tools` -> `Board` -> `ESP32 Arduino`) with the following settings:
|
||||||

|

|
||||||
6. Select which battery type you will use, along with other optional settings. This is done in the `USER_SETTINGS.h` file.
|
6. Select which battery type you will use, along with other optional settings. This is done in the `USER_SETTINGS.h` file.
|
||||||
7. Press `Verify` and `Upload` to send the sketch to the board.
|
7. Copy the `USER_SECRETS.TEMPLATE.h` file to `USER_SECRETS.h` and update connectivity settings inside this file.
|
||||||
|
8. Press `Verify` and `Upload` to send the sketch to the board.
|
||||||
NOTE: In some cases, the LilyGo must be powered through the main power connector instead of USB-C
|
NOTE: In some cases, the LilyGo must be powered through the main power connector instead of USB-C
|
||||||
when performing the initial firmware upload.
|
when performing the initial firmware upload.
|
||||||
NOTE: On Mac, the following USB driver may need to be installed: https://github.com/WCHSoftGroup/ch34xser_macos
|
NOTE: On Mac, the following USB driver may need to be installed: https://github.com/WCHSoftGroup/ch34xser_macos
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "src/datalayer/datalayer.h"
|
#include "src/datalayer/datalayer.h"
|
||||||
#include "src/devboard/utils/events.h"
|
#include "src/devboard/utils/events.h"
|
||||||
#include "src/devboard/utils/led_handler.h"
|
#include "src/devboard/utils/led_handler.h"
|
||||||
|
#include "src/devboard/utils/logging.h"
|
||||||
#include "src/devboard/utils/value_mapping.h"
|
#include "src/devboard/utils/value_mapping.h"
|
||||||
#include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h"
|
#include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h"
|
||||||
#include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h"
|
#include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h"
|
||||||
|
@ -84,6 +85,8 @@ MyTimer check_pause_2s(INTERVAL_2_S);
|
||||||
TaskHandle_t main_loop_task;
|
TaskHandle_t main_loop_task;
|
||||||
TaskHandle_t connectivity_loop_task;
|
TaskHandle_t connectivity_loop_task;
|
||||||
|
|
||||||
|
Logging logging;
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
void setup() {
|
void setup() {
|
||||||
init_serial();
|
init_serial();
|
||||||
|
|
13
Software/USER_SECRETS.TEMPLATE.h
Normal file
13
Software/USER_SECRETS.TEMPLATE.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID" // Maximum of 63 characters
|
||||||
|
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD" // Minimum of 8 characters
|
||||||
|
#define AP_PASSWORD "123456789" // Minimum of 8 characters; set to blank if you want the access point to be open
|
||||||
|
|
||||||
|
#define WEBSERVER_AUTH_REQUIRED \
|
||||||
|
false //Set this line to true to activate webserver authentication (this line must not be commented).
|
||||||
|
#define HTTP_USERNAME "admin" // username to webserver authentication;
|
||||||
|
#define HTTP_PASSWORD "admin" // password to webserver authentication;
|
||||||
|
|
||||||
|
#define MQTT_SERVER "192.168.xxx.yyy" // mqtt server address
|
||||||
|
#define MQTT_PORT 1883 // mqtt server port
|
||||||
|
#define MQTT_USER NULL // mqtt username, leave blank for no authentication
|
||||||
|
#define MQTT_PASSWORD NULL // mqtt password, leave blank for no authentication
|
|
@ -1,5 +1,6 @@
|
||||||
#include "USER_SETTINGS.h"
|
#include "USER_SETTINGS.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "USER_SECRETS.h"
|
||||||
#include "src/devboard/hal/hal.h"
|
#include "src/devboard/hal/hal.h"
|
||||||
|
|
||||||
/* This file contains all the battery settings and limits */
|
/* This file contains all the battery settings and limits */
|
||||||
|
@ -21,12 +22,12 @@ volatile CAN_Configuration can_config = {
|
||||||
|
|
||||||
#ifdef WIFI
|
#ifdef WIFI
|
||||||
|
|
||||||
volatile uint8_t AccessPointEnabled = true; //Set to either true/false to enable direct wifi access point
|
volatile uint8_t AccessPointEnabled = true; //Set to either true/false to enable direct wifi access point
|
||||||
std::string ssid = "REPLACE_WITH_YOUR_SSID"; // Maximum of 63 characters
|
std::string ssid = WIFI_SSID; // Set in USER_SECRETS.h
|
||||||
std::string password = "REPLACE_WITH_YOUR_PASSWORD"; // Minimum of 8 characters
|
std::string password = WIFI_PASSWORD; // Set in USER_SECRETS.h
|
||||||
const char* ssidAP = "Battery Emulator"; // Maximum of 63 characters, also used for device name on web interface
|
const char* ssidAP = "Battery Emulator"; // Maximum of 63 characters, also used for device name on web interface
|
||||||
const char* passwordAP = "123456789"; // Minimum of 8 characters; set to NULL if you want the access point to be open
|
const char* passwordAP = AP_PASSWORD; // Set in USER_SECRETS.h
|
||||||
const uint8_t wifi_channel = 0; // Set to 0 for automatic channel selection
|
const uint8_t wifi_channel = 0; // Set to 0 for automatic channel selection
|
||||||
|
|
||||||
#ifdef WIFICONFIG
|
#ifdef WIFICONFIG
|
||||||
// Set your Static IP address
|
// Set your Static IP address
|
||||||
|
@ -37,14 +38,14 @@ IPAddress gateway(192, 168, 10, 1);
|
||||||
IPAddress subnet(255, 255, 255, 0);
|
IPAddress subnet(255, 255, 255, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef WEBSERVER
|
#ifdef WEBSERVER
|
||||||
const char* http_username = "admin"; // username to webserver authentication;
|
const char* http_username = HTTP_USERNAME; // Set in USER_SECRETS.h
|
||||||
const char* http_password = "admin"; // password to webserver authentication;
|
const char* http_password = HTTP_PASSWORD; // Set in USER_SECRETS.h
|
||||||
|
|
||||||
#endif // WEBSERVER
|
#endif // WEBSERVER
|
||||||
// MQTT
|
// MQTT
|
||||||
#ifdef MQTT
|
#ifdef MQTT
|
||||||
const char* mqtt_user = "REDACTED"; // Set NULL for no username
|
const char* mqtt_user = MQTT_USER; // Set in USER_SECRETS.h
|
||||||
const char* mqtt_password = "REDACTED"; // Set NULL for no password
|
const char* mqtt_password = MQTT_PASSWORD; // Set in USER_SECRETS.h
|
||||||
#ifdef MQTT_MANUAL_TOPIC_OBJECT_NAME
|
#ifdef MQTT_MANUAL_TOPIC_OBJECT_NAME
|
||||||
const char* mqtt_topic_name =
|
const char* mqtt_topic_name =
|
||||||
"BE"; // Custom MQTT topic name. Previously, the name was automatically set to "battery-emulator_esp32-XXXXXX"
|
"BE"; // Custom MQTT topic name. Previously, the name was automatically set to "battery-emulator_esp32-XXXXXX"
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
/* Select battery used */
|
/* Select battery used */
|
||||||
//#define BMW_I3_BATTERY
|
//#define BMW_I3_BATTERY
|
||||||
//#define BMW_IX_BATTERY
|
//#define BMW_IX_BATTERY
|
||||||
|
//#define BOLT_AMPERA_BATTERY
|
||||||
//#define BYD_ATTO_3_BATTERY
|
//#define BYD_ATTO_3_BATTERY
|
||||||
//#define CELLPOWER_BMS
|
//#define CELLPOWER_BMS
|
||||||
//#define CHADEMO_BATTERY //NOTE: inherently enables CONTACTOR_CONTROL below
|
//#define CHADEMO_BATTERY //NOTE: inherently enables CONTACTOR_CONTROL below
|
||||||
|
@ -66,6 +67,11 @@
|
||||||
|
|
||||||
/* Other options */
|
/* Other options */
|
||||||
//#define DEBUG_VIA_USB //Enable this line to have the USB port output serial diagnostic data while program runs (WARNING, raises CPU load, do not use for production)
|
//#define DEBUG_VIA_USB //Enable this line to have the USB port output serial diagnostic data while program runs (WARNING, raises CPU load, do not use for production)
|
||||||
|
//#define DEBUG_VIA_WEB //Enable this line to log diagnostic data while program runs, which can be viewed via webpage (WARNING, slightly raises CPU load, do not use for production)
|
||||||
|
#if defined(DEBUG_VIA_USB) || defined(DEBUG_VIA_WEB)
|
||||||
|
#define DEBUG_LOG
|
||||||
|
#endif
|
||||||
|
|
||||||
//#define DEBUG_CAN_DATA //Enable this line to print incoming/outgoing CAN & CAN-FD messages to USB serial (WARNING, raises CPU load, do not use for production)
|
//#define DEBUG_CAN_DATA //Enable this line to print incoming/outgoing CAN & CAN-FD messages to USB serial (WARNING, raises CPU load, do not use for production)
|
||||||
//#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting
|
//#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting
|
||||||
//#define CAN_ADDON //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery)
|
//#define CAN_ADDON //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery)
|
||||||
|
@ -82,8 +88,6 @@
|
||||||
#define WIFI
|
#define WIFI
|
||||||
//#define WIFICONFIG //Enable this line to set a static IP address / gateway /subnet mask for the device. see USER_SETTINGS.cpp for the settings
|
//#define WIFICONFIG //Enable this line to set a static IP address / gateway /subnet mask for the device. see USER_SETTINGS.cpp for the settings
|
||||||
#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.
|
||||||
#define WEBSERVER_AUTH_REQUIRED \
|
|
||||||
false //Set this line to true to activate webserver authentication (this line must not be commented). Refer to USER_SETTINGS.cpp for setting the credentials.
|
|
||||||
#define WIFIAP //Disable this line to permanently disable WIFI AP mode (make sure to hardcode ssid and password of you home wifi network). When enabled WIFI AP can still be disabled by a setting in the future.
|
#define WIFIAP //Disable this line to permanently disable WIFI AP mode (make sure to hardcode ssid and password of you home wifi network). When enabled WIFI AP can still be disabled by a setting in the future.
|
||||||
#define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled.
|
#define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled.
|
||||||
#define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot (overrides Wifi/battery settings set below)
|
#define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot (overrides Wifi/battery settings set below)
|
||||||
|
@ -92,8 +96,6 @@
|
||||||
|
|
||||||
/* MQTT options */
|
/* MQTT options */
|
||||||
// #define MQTT // Enable this line to enable MQTT
|
// #define MQTT // Enable this line to enable MQTT
|
||||||
#define MQTT_SERVER "192.168.xxx.yyy"
|
|
||||||
#define MQTT_PORT 1883
|
|
||||||
#define MQTT_MANUAL_TOPIC_OBJECT_NAME // Enable this to use custom MQTT topic, object ID prefix, and device name. \
|
#define MQTT_MANUAL_TOPIC_OBJECT_NAME // Enable this to use custom MQTT topic, object ID prefix, and device name. \
|
||||||
// WARNING: If this is not defined, the previous default naming format \
|
// WARNING: If this is not defined, the previous default naming format \
|
||||||
// 'battery-emulator_esp32-XXXXXX' (based on hardware ID) will be used. \
|
// 'battery-emulator_esp32-XXXXXX' (based on hardware ID) will be used. \
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
#include "BMW-IX-BATTERY.h"
|
#include "BMW-IX-BATTERY.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOLT_AMPERA_BATTERY
|
||||||
|
#include "BOLT-AMPERA-BATTERY.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BYD_ATTO_3_BATTERY
|
#ifdef BYD_ATTO_3_BATTERY
|
||||||
#include "BYD-ATTO-3-BATTERY.h"
|
#include "BYD-ATTO-3-BATTERY.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -670,8 +670,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
|
|
||||||
if ((rx_frame.data.u8[6] << 8 | rx_frame.data.u8[7]) == 10000 ||
|
if ((rx_frame.data.u8[6] << 8 | rx_frame.data.u8[7]) == 10000 ||
|
||||||
(rx_frame.data.u8[8] << 8 | rx_frame.data.u8[9]) == 10000) { //Qualifier Invalid Mode - Request Reboot
|
(rx_frame.data.u8[8] << 8 | rx_frame.data.u8[9]) == 10000) { //Qualifier Invalid Mode - Request Reboot
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Cell MinMax Qualifier Invalid - Requesting BMS Reset");
|
logging.println("Cell MinMax Qualifier Invalid - Requesting BMS Reset");
|
||||||
#endif
|
#endif
|
||||||
//set_event(EVENT_BATTERY_VALUE_UNAVAILABLE, (millis())); //Eventually need new Info level event type
|
//set_event(EVENT_BATTERY_VALUE_UNAVAILABLE, (millis())); //Eventually need new Info level event type
|
||||||
transmit_can(&BMWiX_6F4_REQUEST_HARD_RESET, can_config.battery);
|
transmit_can(&BMWiX_6F4_REQUEST_HARD_RESET, can_config.battery);
|
||||||
|
|
789
Software/src/battery/BOLT-AMPERA-BATTERY.cpp
Normal file
789
Software/src/battery/BOLT-AMPERA-BATTERY.cpp
Normal file
|
@ -0,0 +1,789 @@
|
||||||
|
#include "../include.h"
|
||||||
|
#ifdef BOLT_AMPERA_BATTERY
|
||||||
|
#include "../datalayer/datalayer.h"
|
||||||
|
#include "../datalayer/datalayer_extended.h"
|
||||||
|
#include "../devboard/utils/events.h"
|
||||||
|
#include "BOLT-AMPERA-BATTERY.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODOs left for this implementation
|
||||||
|
- The battery has 3 CAN ports. One of them is responsible for the 7E4 polls, the other for the 7E7 polls
|
||||||
|
- Current implementation only seems to get the 7E7 polls working.
|
||||||
|
- Could on of the CAN channels be GMLAN?
|
||||||
|
|
||||||
|
- The values missing for a working implementation is:
|
||||||
|
- SOC% missing! This is absolutely mandatory to fix before starting to use this!
|
||||||
|
- Capacity (kWh) (can be estimated)
|
||||||
|
- Charge max power (can be estimated)
|
||||||
|
- Discharge max power (can be estimated)
|
||||||
|
- SOH% (low prio))
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Do not change code below unless you are sure what you are doing */
|
||||||
|
static unsigned long previousMillis20ms = 0; // will store last time a 20ms CAN Message was send
|
||||||
|
static unsigned long previousMillis100ms = 0; // will store last time a 100ms CAN Message was send
|
||||||
|
static unsigned long previousMillis120ms = 0; // will store last time a 120ms CAN Message was send
|
||||||
|
|
||||||
|
CAN_frame BOLT_778 = {.FD = false, // Unsure of what this message is, added only as example
|
||||||
|
.ext_ID = false,
|
||||||
|
.DLC = 7,
|
||||||
|
.ID = 0x778,
|
||||||
|
.data = {0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
CAN_frame BOLT_POLL_7E4 = {.FD = false,
|
||||||
|
.ext_ID = false,
|
||||||
|
.DLC = 8,
|
||||||
|
.ID = 0x7E4,
|
||||||
|
.data = {0x03, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
CAN_frame BOLT_ACK_7E4 = {.FD = false,
|
||||||
|
.ext_ID = false,
|
||||||
|
.DLC = 8,
|
||||||
|
.ID = 0x7E4,
|
||||||
|
.data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
CAN_frame BOLT_POLL_7E7 = {.FD = false,
|
||||||
|
.ext_ID = false,
|
||||||
|
.DLC = 8,
|
||||||
|
.ID = 0x7E7,
|
||||||
|
.data = {0x03, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
CAN_frame BOLT_ACK_7E7 = {.FD = false,
|
||||||
|
.ext_ID = false,
|
||||||
|
.DLC = 8,
|
||||||
|
.ID = 0x7E7,
|
||||||
|
.data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
|
||||||
|
// 7E4 Battery , reply 000007EC
|
||||||
|
// 7E7 Battery (Cell voltages), reply 000007EF
|
||||||
|
|
||||||
|
static uint16_t battery_cell_voltages[96]; //array with all the cellvoltages
|
||||||
|
static uint16_t battery_capacity_my17_18 = 0;
|
||||||
|
static uint16_t battery_capacity_my19plus = 0;
|
||||||
|
static uint16_t battery_SOC_display = 0;
|
||||||
|
static uint16_t battery_SOC_raw_highprec = 0;
|
||||||
|
static uint16_t battery_max_temperature = 0;
|
||||||
|
static uint16_t battery_min_temperature = 0;
|
||||||
|
static uint16_t battery_min_cell_voltage = 0;
|
||||||
|
static uint16_t battery_max_cell_voltage = 0;
|
||||||
|
static uint16_t battery_internal_resistance = 0;
|
||||||
|
static uint16_t battery_lowest_cell = 0;
|
||||||
|
static uint16_t battery_highest_cell = 0;
|
||||||
|
static uint16_t battery_voltage_polled = 0;
|
||||||
|
static uint16_t battery_voltage_periodic = 0;
|
||||||
|
static uint16_t battery_vehicle_isolation = 0;
|
||||||
|
static uint16_t battery_isolation_kohm = 0;
|
||||||
|
static uint16_t battery_HV_locked = 0;
|
||||||
|
static uint16_t battery_crash_event = 0;
|
||||||
|
static uint16_t battery_HVIL = 0;
|
||||||
|
static uint16_t battery_HVIL_status = 0;
|
||||||
|
static uint16_t battery_5V_ref = 0;
|
||||||
|
static int16_t battery_current_7E4 = 0;
|
||||||
|
static int16_t battery_module_temp_1 = 0;
|
||||||
|
static int16_t battery_module_temp_2 = 0;
|
||||||
|
static int16_t battery_module_temp_3 = 0;
|
||||||
|
static int16_t battery_module_temp_4 = 0;
|
||||||
|
static int16_t battery_module_temp_5 = 0;
|
||||||
|
static int16_t battery_module_temp_6 = 0;
|
||||||
|
static uint16_t battery_cell_average_voltage = 0;
|
||||||
|
static uint16_t battery_cell_average_voltage_2 = 0;
|
||||||
|
static uint16_t battery_terminal_voltage = 0;
|
||||||
|
static uint16_t battery_ignition_power_mode = 0;
|
||||||
|
static int16_t battery_current_7E7 = 0;
|
||||||
|
static int16_t temperature_1 = 0;
|
||||||
|
static int16_t temperature_2 = 0;
|
||||||
|
static int16_t temperature_3 = 0;
|
||||||
|
static int16_t temperature_4 = 0;
|
||||||
|
static int16_t temperature_5 = 0;
|
||||||
|
static int16_t temperature_6 = 0;
|
||||||
|
static int16_t temperature_highest = 0;
|
||||||
|
static int16_t temperature_lowest = 0;
|
||||||
|
static uint8_t mux = 0;
|
||||||
|
static uint8_t poll_index_7E4 = 0;
|
||||||
|
static uint16_t currentpoll_7E4 = POLL_7E4_CAPACITY_EST_GEN1;
|
||||||
|
static uint16_t reply_poll_7E4 = 0;
|
||||||
|
static uint8_t poll_index_7E7 = 0;
|
||||||
|
static uint16_t currentpoll_7E7 = POLL_7E7_CURRENT;
|
||||||
|
static uint16_t reply_poll_7E7 = 0;
|
||||||
|
|
||||||
|
const uint16_t poll_commands_7E4[19] = {POLL_7E4_CAPACITY_EST_GEN1,
|
||||||
|
POLL_7E4_CAPACITY_EST_GEN2,
|
||||||
|
POLL_7E4_SOC_DISPLAY,
|
||||||
|
POLL_7E4_SOC_RAW_HIGHPREC,
|
||||||
|
POLL_7E4_MAX_TEMPERATURE,
|
||||||
|
POLL_7E4_MIN_TEMPERATURE,
|
||||||
|
POLL_7E4_MIN_CELL_V,
|
||||||
|
POLL_7E4_MAX_CELL_V,
|
||||||
|
POLL_7E4_INTERNAL_RES,
|
||||||
|
POLL_7E4_LOWEST_CELL_NUMBER,
|
||||||
|
POLL_7E4_HIGHEST_CELL_NUMBER,
|
||||||
|
POLL_7E4_VOLTAGE,
|
||||||
|
POLL_7E4_VEHICLE_ISOLATION,
|
||||||
|
POLL_7E4_ISOLATION_TEST_KOHM,
|
||||||
|
POLL_7E4_HV_LOCKED_OUT,
|
||||||
|
POLL_7E4_CRASH_EVENT,
|
||||||
|
POLL_7E4_HVIL,
|
||||||
|
POLL_7E4_HVIL_STATUS,
|
||||||
|
POLL_7E4_CURRENT};
|
||||||
|
|
||||||
|
const uint16_t poll_commands_7E7[108] = {POLL_7E7_CURRENT, POLL_7E7_5V_REF,
|
||||||
|
POLL_7E7_MODULE_TEMP_1, POLL_7E7_MODULE_TEMP_2,
|
||||||
|
POLL_7E7_MODULE_TEMP_3, POLL_7E7_MODULE_TEMP_4,
|
||||||
|
POLL_7E7_MODULE_TEMP_5, POLL_7E7_MODULE_TEMP_6,
|
||||||
|
POLL_7E7_CELL_AVG_VOLTAGE, POLL_7E7_CELL_AVG_VOLTAGE_2,
|
||||||
|
POLL_7E7_TERMINAL_VOLTAGE, POLL_7E7_IGNITION_POWER_MODE,
|
||||||
|
POLL_7E7_CELL_01, POLL_7E7_CELL_02,
|
||||||
|
POLL_7E7_CELL_03, POLL_7E7_CELL_04,
|
||||||
|
POLL_7E7_CELL_05, POLL_7E7_CELL_06,
|
||||||
|
POLL_7E7_CELL_07, POLL_7E7_CELL_08,
|
||||||
|
POLL_7E7_CELL_09, POLL_7E7_CELL_10,
|
||||||
|
POLL_7E7_CELL_11, POLL_7E7_CELL_12,
|
||||||
|
POLL_7E7_CELL_13, POLL_7E7_CELL_14,
|
||||||
|
POLL_7E7_CELL_15, POLL_7E7_CELL_16,
|
||||||
|
POLL_7E7_CELL_17, POLL_7E7_CELL_18,
|
||||||
|
POLL_7E7_CELL_19, POLL_7E7_CELL_20,
|
||||||
|
POLL_7E7_CELL_21, POLL_7E7_CELL_22,
|
||||||
|
POLL_7E7_CELL_23, POLL_7E7_CELL_24,
|
||||||
|
POLL_7E7_CELL_25, POLL_7E7_CELL_26,
|
||||||
|
POLL_7E7_CELL_27, POLL_7E7_CELL_28,
|
||||||
|
POLL_7E7_CELL_29, POLL_7E7_CELL_30,
|
||||||
|
POLL_7E7_CELL_31, POLL_7E7_CELL_32,
|
||||||
|
POLL_7E7_CELL_33, POLL_7E7_CELL_34,
|
||||||
|
POLL_7E7_CELL_35, POLL_7E7_CELL_36,
|
||||||
|
POLL_7E7_CELL_37, POLL_7E7_CELL_38,
|
||||||
|
POLL_7E7_CELL_39, POLL_7E7_CELL_40,
|
||||||
|
POLL_7E7_CELL_41, POLL_7E7_CELL_42,
|
||||||
|
POLL_7E7_CELL_43, POLL_7E7_CELL_44,
|
||||||
|
POLL_7E7_CELL_45, POLL_7E7_CELL_46,
|
||||||
|
POLL_7E7_CELL_47, POLL_7E7_CELL_48,
|
||||||
|
POLL_7E7_CELL_49, POLL_7E7_CELL_50,
|
||||||
|
POLL_7E7_CELL_51, POLL_7E7_CELL_52,
|
||||||
|
POLL_7E7_CELL_53, POLL_7E7_CELL_54,
|
||||||
|
POLL_7E7_CELL_55, POLL_7E7_CELL_56,
|
||||||
|
POLL_7E7_CELL_57, POLL_7E7_CELL_58,
|
||||||
|
POLL_7E7_CELL_59, POLL_7E7_CELL_60,
|
||||||
|
POLL_7E7_CELL_61, POLL_7E7_CELL_62,
|
||||||
|
POLL_7E7_CELL_63, POLL_7E7_CELL_64,
|
||||||
|
POLL_7E7_CELL_65, POLL_7E7_CELL_66,
|
||||||
|
POLL_7E7_CELL_67, POLL_7E7_CELL_68,
|
||||||
|
POLL_7E7_CELL_69, POLL_7E7_CELL_70,
|
||||||
|
POLL_7E7_CELL_71, POLL_7E7_CELL_72,
|
||||||
|
POLL_7E7_CELL_73, POLL_7E7_CELL_74,
|
||||||
|
POLL_7E7_CELL_75, POLL_7E7_CELL_76,
|
||||||
|
POLL_7E7_CELL_77, POLL_7E7_CELL_78,
|
||||||
|
POLL_7E7_CELL_79, POLL_7E7_CELL_80,
|
||||||
|
POLL_7E7_CELL_81, POLL_7E7_CELL_82,
|
||||||
|
POLL_7E7_CELL_83, POLL_7E7_CELL_84,
|
||||||
|
POLL_7E7_CELL_85, POLL_7E7_CELL_86,
|
||||||
|
POLL_7E7_CELL_87, POLL_7E7_CELL_88,
|
||||||
|
POLL_7E7_CELL_89, POLL_7E7_CELL_90,
|
||||||
|
POLL_7E7_CELL_91, POLL_7E7_CELL_92,
|
||||||
|
POLL_7E7_CELL_93, POLL_7E7_CELL_94,
|
||||||
|
POLL_7E7_CELL_95, POLL_7E7_CELL_96};
|
||||||
|
|
||||||
|
void update_values_battery() { //This function maps all the values fetched via CAN to the battery datalayer
|
||||||
|
|
||||||
|
datalayer.battery.status.real_soc = battery_SOC_display;
|
||||||
|
|
||||||
|
//datalayer.battery.status.voltage_dV = battery_voltage * 0.52;
|
||||||
|
datalayer.battery.status.voltage_dV = (battery_voltage_periodic / 8) * 10;
|
||||||
|
|
||||||
|
datalayer.battery.status.current_dA = battery_current_7E7;
|
||||||
|
|
||||||
|
datalayer.battery.info.total_capacity_Wh;
|
||||||
|
|
||||||
|
datalayer.battery.status.remaining_capacity_Wh;
|
||||||
|
|
||||||
|
datalayer.battery.status.soh_pptt;
|
||||||
|
|
||||||
|
datalayer.battery.status.max_discharge_power_W;
|
||||||
|
|
||||||
|
datalayer.battery.status.max_charge_power_W;
|
||||||
|
|
||||||
|
// Store temperatures in an array
|
||||||
|
int16_t temperatures[] = {temperature_1, temperature_2, temperature_3, temperature_4, temperature_5, temperature_6};
|
||||||
|
|
||||||
|
// Initialize highest and lowest to the first element
|
||||||
|
temperature_highest = temperatures[0];
|
||||||
|
temperature_lowest = temperatures[0];
|
||||||
|
|
||||||
|
// Iterate through the array to find the highest and lowest values
|
||||||
|
for (uint8_t i = 1; i < 6; ++i) {
|
||||||
|
if (temperatures[i] > temperature_highest) {
|
||||||
|
temperature_highest = temperatures[i];
|
||||||
|
}
|
||||||
|
if (temperatures[i] < temperature_lowest) {
|
||||||
|
temperature_lowest = temperatures[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
datalayer.battery.status.temperature_min_dC = temperature_lowest * 10;
|
||||||
|
|
||||||
|
datalayer.battery.status.temperature_max_dC = temperature_highest * 10;
|
||||||
|
|
||||||
|
//Map all cell voltages to the global array
|
||||||
|
memcpy(datalayer.battery.status.cell_voltages_mV, battery_cell_voltages, 96 * sizeof(uint16_t));
|
||||||
|
|
||||||
|
// Update webserver datalayer
|
||||||
|
datalayer_extended.boltampera.battery_5V_ref = battery_5V_ref;
|
||||||
|
datalayer_extended.boltampera.battery_module_temp_1 = battery_module_temp_1;
|
||||||
|
datalayer_extended.boltampera.battery_module_temp_2 = battery_module_temp_2;
|
||||||
|
datalayer_extended.boltampera.battery_module_temp_3 = battery_module_temp_3;
|
||||||
|
datalayer_extended.boltampera.battery_module_temp_4 = battery_module_temp_4;
|
||||||
|
datalayer_extended.boltampera.battery_module_temp_5 = battery_module_temp_5;
|
||||||
|
datalayer_extended.boltampera.battery_module_temp_6 = battery_module_temp_6;
|
||||||
|
datalayer_extended.boltampera.battery_cell_average_voltage = battery_cell_average_voltage;
|
||||||
|
datalayer_extended.boltampera.battery_cell_average_voltage_2 = battery_cell_average_voltage_2;
|
||||||
|
datalayer_extended.boltampera.battery_terminal_voltage = battery_terminal_voltage;
|
||||||
|
datalayer_extended.boltampera.battery_ignition_power_mode = battery_ignition_power_mode;
|
||||||
|
datalayer_extended.boltampera.battery_current_7E7 = battery_current_7E7;
|
||||||
|
datalayer_extended.boltampera.battery_capacity_my17_18 = battery_capacity_my17_18;
|
||||||
|
datalayer_extended.boltampera.battery_capacity_my19plus = battery_capacity_my19plus;
|
||||||
|
datalayer_extended.boltampera.battery_SOC_display = battery_SOC_display;
|
||||||
|
datalayer_extended.boltampera.battery_SOC_raw_highprec = battery_SOC_raw_highprec;
|
||||||
|
datalayer_extended.boltampera.battery_max_temperature = battery_max_temperature;
|
||||||
|
datalayer_extended.boltampera.battery_min_temperature = battery_min_temperature;
|
||||||
|
datalayer_extended.boltampera.battery_min_cell_voltage = battery_min_cell_voltage;
|
||||||
|
datalayer_extended.boltampera.battery_max_cell_voltage = battery_max_cell_voltage;
|
||||||
|
datalayer_extended.boltampera.battery_lowest_cell = battery_lowest_cell;
|
||||||
|
datalayer_extended.boltampera.battery_highest_cell = battery_highest_cell;
|
||||||
|
datalayer_extended.boltampera.battery_internal_resistance = battery_internal_resistance;
|
||||||
|
datalayer_extended.boltampera.battery_voltage_polled = battery_voltage_polled;
|
||||||
|
datalayer_extended.boltampera.battery_vehicle_isolation = battery_vehicle_isolation;
|
||||||
|
datalayer_extended.boltampera.battery_isolation_kohm = battery_isolation_kohm;
|
||||||
|
datalayer_extended.boltampera.battery_HV_locked = battery_HV_locked;
|
||||||
|
datalayer_extended.boltampera.battery_crash_event = battery_crash_event;
|
||||||
|
datalayer_extended.boltampera.battery_HVIL = battery_HVIL;
|
||||||
|
datalayer_extended.boltampera.battery_HVIL_status = battery_HVIL_status;
|
||||||
|
datalayer_extended.boltampera.battery_current_7E4 = battery_current_7E4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void receive_can_battery(CAN_frame rx_frame) {
|
||||||
|
switch (rx_frame.ID) {
|
||||||
|
case 0x200:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7
|
||||||
|
break;
|
||||||
|
case 0x202:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7
|
||||||
|
break;
|
||||||
|
case 0x204:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7
|
||||||
|
break;
|
||||||
|
case 0x206:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7
|
||||||
|
break;
|
||||||
|
case 0x208:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7
|
||||||
|
break;
|
||||||
|
case 0x20C:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x216:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x2C7:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
battery_voltage_periodic = (rx_frame.data.u8[3] << 4) | (rx_frame.data.u8[4] >> 4);
|
||||||
|
break;
|
||||||
|
case 0x260:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x270:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x272:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x274:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x302:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
temperature_1 = ((rx_frame.data.u8[1] / 2) - 40); //Module 1 Temperature
|
||||||
|
temperature_2 = ((rx_frame.data.u8[2] / 2) - 40); //Module 2 Temperature
|
||||||
|
temperature_3 = ((rx_frame.data.u8[3] / 2) - 40); //Module 3 Temperature
|
||||||
|
temperature_4 = ((rx_frame.data.u8[4] / 2) - 40); //Module 4 Temperature
|
||||||
|
temperature_5 = ((rx_frame.data.u8[5] / 2) - 40); //Module 5 Temperature
|
||||||
|
temperature_6 = ((rx_frame.data.u8[6] / 2) - 40); //Module 6 Temperature
|
||||||
|
break;
|
||||||
|
case 0x3E3:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x460:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x5EF:
|
||||||
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x7EC: //When polling 7E4 BMS replies with 7EC ??
|
||||||
|
|
||||||
|
if (rx_frame.data.u8[0] == 0x10) { //"PID Header"
|
||||||
|
transmit_can(&BOLT_ACK_7E4, can_config.battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Frame 2 & 3 contains reply
|
||||||
|
reply_poll_7E4 = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3];
|
||||||
|
|
||||||
|
switch (reply_poll_7E4) {
|
||||||
|
case POLL_7E4_CAPACITY_EST_GEN1:
|
||||||
|
battery_capacity_my17_18 = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_CAPACITY_EST_GEN2:
|
||||||
|
battery_capacity_my19plus = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_SOC_DISPLAY:
|
||||||
|
battery_SOC_display = ((rx_frame.data.u8[4] * 100) / 255);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_SOC_RAW_HIGHPREC:
|
||||||
|
battery_SOC_raw_highprec = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 100) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_MAX_TEMPERATURE:
|
||||||
|
battery_max_temperature = (rx_frame.data.u8[4] - 40);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_MIN_TEMPERATURE:
|
||||||
|
battery_min_temperature = (rx_frame.data.u8[4] - 40);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_MIN_CELL_V:
|
||||||
|
battery_min_cell_voltage = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / 1666;
|
||||||
|
break;
|
||||||
|
case POLL_7E4_MAX_CELL_V:
|
||||||
|
battery_max_cell_voltage = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / 1666;
|
||||||
|
break;
|
||||||
|
case POLL_7E4_INTERNAL_RES:
|
||||||
|
battery_internal_resistance = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / 2;
|
||||||
|
break;
|
||||||
|
case POLL_7E4_LOWEST_CELL_NUMBER:
|
||||||
|
battery_lowest_cell = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case POLL_7E4_HIGHEST_CELL_NUMBER:
|
||||||
|
battery_highest_cell = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case POLL_7E4_VOLTAGE:
|
||||||
|
battery_voltage_polled = (((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 0.52);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_VEHICLE_ISOLATION:
|
||||||
|
battery_vehicle_isolation = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_ISOLATION_TEST_KOHM:
|
||||||
|
battery_isolation_kohm = (rx_frame.data.u8[4] * 25);
|
||||||
|
break;
|
||||||
|
case POLL_7E4_HV_LOCKED_OUT:
|
||||||
|
battery_HV_locked = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case POLL_7E4_CRASH_EVENT:
|
||||||
|
battery_crash_event = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case POLL_7E4_HVIL:
|
||||||
|
battery_HVIL = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case POLL_7E4_HVIL_STATUS:
|
||||||
|
battery_HVIL_status = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case POLL_7E4_CURRENT:
|
||||||
|
battery_current_7E4 = (((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / (-6.675));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0x7EF: //When polling 7E7 BMS replies with 7EF
|
||||||
|
|
||||||
|
if (rx_frame.data.u8[0] == 0x10) { //"PID Header"
|
||||||
|
transmit_can(&BOLT_ACK_7E7, can_config.battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Frame 2 & 3 contains reply
|
||||||
|
reply_poll_7E7 = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3];
|
||||||
|
|
||||||
|
switch (reply_poll_7E7) {
|
||||||
|
case POLL_7E7_CURRENT:
|
||||||
|
battery_current_7E7 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5];
|
||||||
|
break;
|
||||||
|
case POLL_7E7_5V_REF:
|
||||||
|
battery_5V_ref = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_MODULE_TEMP_1:
|
||||||
|
battery_module_temp_1 = (rx_frame.data.u8[4] - 40);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_MODULE_TEMP_2:
|
||||||
|
battery_module_temp_2 = (rx_frame.data.u8[4] - 40);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_MODULE_TEMP_3:
|
||||||
|
battery_module_temp_3 = (rx_frame.data.u8[4] - 40);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_MODULE_TEMP_4:
|
||||||
|
battery_module_temp_4 = (rx_frame.data.u8[4] - 40);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_MODULE_TEMP_5:
|
||||||
|
battery_module_temp_5 = (rx_frame.data.u8[4] - 40);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_MODULE_TEMP_6:
|
||||||
|
battery_module_temp_6 = (rx_frame.data.u8[4] - 40);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_AVG_VOLTAGE:
|
||||||
|
battery_cell_average_voltage = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_AVG_VOLTAGE_2:
|
||||||
|
battery_cell_average_voltage_2 = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / 8000) * 1000);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_TERMINAL_VOLTAGE:
|
||||||
|
battery_terminal_voltage = rx_frame.data.u8[4] * 2;
|
||||||
|
break;
|
||||||
|
case POLL_7E7_IGNITION_POWER_MODE:
|
||||||
|
battery_ignition_power_mode = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_01:
|
||||||
|
battery_cell_voltages[0] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_02:
|
||||||
|
battery_cell_voltages[1] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_03:
|
||||||
|
battery_cell_voltages[2] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_04:
|
||||||
|
battery_cell_voltages[3] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_05:
|
||||||
|
battery_cell_voltages[4] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_06:
|
||||||
|
battery_cell_voltages[5] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_07:
|
||||||
|
battery_cell_voltages[6] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_08:
|
||||||
|
battery_cell_voltages[7] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_09:
|
||||||
|
battery_cell_voltages[8] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_10:
|
||||||
|
battery_cell_voltages[9] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_11:
|
||||||
|
battery_cell_voltages[10] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_12:
|
||||||
|
battery_cell_voltages[11] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_13:
|
||||||
|
battery_cell_voltages[12] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_14:
|
||||||
|
battery_cell_voltages[13] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_15:
|
||||||
|
battery_cell_voltages[14] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_16:
|
||||||
|
battery_cell_voltages[15] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_17:
|
||||||
|
battery_cell_voltages[16] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_18:
|
||||||
|
battery_cell_voltages[17] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_19:
|
||||||
|
battery_cell_voltages[18] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_20:
|
||||||
|
battery_cell_voltages[19] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_21:
|
||||||
|
battery_cell_voltages[20] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_22:
|
||||||
|
battery_cell_voltages[21] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_23:
|
||||||
|
battery_cell_voltages[22] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_24:
|
||||||
|
battery_cell_voltages[23] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_25:
|
||||||
|
battery_cell_voltages[24] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_26:
|
||||||
|
battery_cell_voltages[25] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_27:
|
||||||
|
battery_cell_voltages[26] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_28:
|
||||||
|
battery_cell_voltages[27] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_29:
|
||||||
|
battery_cell_voltages[28] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_30:
|
||||||
|
battery_cell_voltages[29] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_31:
|
||||||
|
battery_cell_voltages[30] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_32:
|
||||||
|
battery_cell_voltages[31] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_33:
|
||||||
|
battery_cell_voltages[32] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_34:
|
||||||
|
battery_cell_voltages[33] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_35:
|
||||||
|
battery_cell_voltages[34] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_36:
|
||||||
|
battery_cell_voltages[35] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_37:
|
||||||
|
battery_cell_voltages[36] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_38:
|
||||||
|
battery_cell_voltages[37] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_39:
|
||||||
|
battery_cell_voltages[38] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_40:
|
||||||
|
battery_cell_voltages[39] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_41:
|
||||||
|
battery_cell_voltages[40] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_42:
|
||||||
|
battery_cell_voltages[41] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_43:
|
||||||
|
battery_cell_voltages[42] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_44:
|
||||||
|
battery_cell_voltages[43] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_45:
|
||||||
|
battery_cell_voltages[44] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_46:
|
||||||
|
battery_cell_voltages[45] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_47:
|
||||||
|
battery_cell_voltages[46] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_48:
|
||||||
|
battery_cell_voltages[47] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_49:
|
||||||
|
battery_cell_voltages[48] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_50:
|
||||||
|
battery_cell_voltages[49] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_51:
|
||||||
|
battery_cell_voltages[50] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_52:
|
||||||
|
battery_cell_voltages[51] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_53:
|
||||||
|
battery_cell_voltages[52] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_54:
|
||||||
|
battery_cell_voltages[53] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_55:
|
||||||
|
battery_cell_voltages[54] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_56:
|
||||||
|
battery_cell_voltages[55] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_57:
|
||||||
|
battery_cell_voltages[56] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_58:
|
||||||
|
battery_cell_voltages[57] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_59:
|
||||||
|
battery_cell_voltages[58] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_60:
|
||||||
|
battery_cell_voltages[59] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_61:
|
||||||
|
battery_cell_voltages[60] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_62:
|
||||||
|
battery_cell_voltages[61] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_63:
|
||||||
|
battery_cell_voltages[62] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_64:
|
||||||
|
battery_cell_voltages[63] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_65:
|
||||||
|
battery_cell_voltages[64] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_66:
|
||||||
|
battery_cell_voltages[65] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_67:
|
||||||
|
battery_cell_voltages[66] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_68:
|
||||||
|
battery_cell_voltages[67] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_69:
|
||||||
|
battery_cell_voltages[68] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_70:
|
||||||
|
battery_cell_voltages[69] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_71:
|
||||||
|
battery_cell_voltages[70] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_72:
|
||||||
|
battery_cell_voltages[71] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_73:
|
||||||
|
battery_cell_voltages[72] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_74:
|
||||||
|
battery_cell_voltages[73] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_75:
|
||||||
|
battery_cell_voltages[74] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_76:
|
||||||
|
battery_cell_voltages[75] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_77:
|
||||||
|
battery_cell_voltages[76] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_78:
|
||||||
|
battery_cell_voltages[77] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_79:
|
||||||
|
battery_cell_voltages[78] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_80:
|
||||||
|
battery_cell_voltages[79] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_81:
|
||||||
|
battery_cell_voltages[80] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_82:
|
||||||
|
battery_cell_voltages[81] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_83:
|
||||||
|
battery_cell_voltages[82] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_84:
|
||||||
|
battery_cell_voltages[83] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_85:
|
||||||
|
battery_cell_voltages[84] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_86:
|
||||||
|
battery_cell_voltages[85] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_87:
|
||||||
|
battery_cell_voltages[86] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_88:
|
||||||
|
battery_cell_voltages[87] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_89:
|
||||||
|
battery_cell_voltages[88] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_90:
|
||||||
|
battery_cell_voltages[89] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_91:
|
||||||
|
battery_cell_voltages[90] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_92:
|
||||||
|
battery_cell_voltages[91] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_93:
|
||||||
|
battery_cell_voltages[92] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_94:
|
||||||
|
battery_cell_voltages[93] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_95:
|
||||||
|
battery_cell_voltages[94] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
case POLL_7E7_CELL_96:
|
||||||
|
battery_cell_voltages[95] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_can_battery() {
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
|
||||||
|
//Send 20ms message
|
||||||
|
if (currentMillis - previousMillis20ms >= INTERVAL_20_MS) {
|
||||||
|
// Check if sending of CAN messages has been delayed too much.
|
||||||
|
if ((currentMillis - previousMillis20ms >= INTERVAL_20_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) {
|
||||||
|
set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis20ms));
|
||||||
|
} else {
|
||||||
|
clear_event(EVENT_CAN_OVERRUN);
|
||||||
|
}
|
||||||
|
previousMillis20ms = currentMillis;
|
||||||
|
transmit_can(&BOLT_778, can_config.battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send 100ms message
|
||||||
|
if (currentMillis - previousMillis100ms >= INTERVAL_100_MS) {
|
||||||
|
previousMillis100ms = currentMillis;
|
||||||
|
|
||||||
|
// Update current poll from the 7E7 array
|
||||||
|
currentpoll_7E7 = poll_commands_7E7[poll_index_7E7];
|
||||||
|
poll_index_7E7 = (poll_index_7E7 + 1) % 108;
|
||||||
|
|
||||||
|
BOLT_POLL_7E7.data.u8[2] = (uint8_t)((currentpoll_7E7 & 0xFF00) >> 8);
|
||||||
|
BOLT_POLL_7E7.data.u8[3] = (uint8_t)(currentpoll_7E7 & 0x00FF);
|
||||||
|
|
||||||
|
transmit_can(&BOLT_POLL_7E7, can_config.battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send 120ms message
|
||||||
|
if (currentMillis - previousMillis120ms >= 120) {
|
||||||
|
previousMillis120ms = currentMillis;
|
||||||
|
|
||||||
|
// Update current poll from the 7E4 array
|
||||||
|
currentpoll_7E4 = poll_commands_7E4[poll_index_7E4];
|
||||||
|
poll_index_7E4 = (poll_index_7E4 + 1) % 19;
|
||||||
|
|
||||||
|
BOLT_POLL_7E4.data.u8[2] = (uint8_t)((currentpoll_7E4 & 0xFF00) >> 8);
|
||||||
|
BOLT_POLL_7E4.data.u8[3] = (uint8_t)(currentpoll_7E4 & 0x00FF);
|
||||||
|
|
||||||
|
transmit_can(&BOLT_POLL_7E4, can_config.battery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_battery(void) { // Performs one time setup at startup
|
||||||
|
strncpy(datalayer.system.info.battery_protocol, "Chevrolet Bolt EV/Opel Ampera-e", 63);
|
||||||
|
datalayer.system.info.battery_protocol[63] = '\0';
|
||||||
|
datalayer.battery.info.number_of_cells = 96;
|
||||||
|
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
||||||
|
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
||||||
|
datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
||||||
|
datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||||
|
datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV;
|
||||||
|
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
146
Software/src/battery/BOLT-AMPERA-BATTERY.h
Normal file
146
Software/src/battery/BOLT-AMPERA-BATTERY.h
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
#ifndef BOLT_AMPERA_BATTERY_H
|
||||||
|
#define BOLT_AMPERA_BATTERY_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "../include.h"
|
||||||
|
|
||||||
|
#define BATTERY_SELECTED
|
||||||
|
|
||||||
|
#define MAX_PACK_VOLTAGE_DV 4150 //5000 = 500.0V
|
||||||
|
#define MIN_PACK_VOLTAGE_DV 2500
|
||||||
|
#define MAX_CELL_DEVIATION_MV 500
|
||||||
|
#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value
|
||||||
|
#define MIN_CELL_VOLTAGE_MV 2700 //Battery is put into emergency stop if one cell goes below this value
|
||||||
|
|
||||||
|
#define POLL_7E4_CAPACITY_EST_GEN1 0x41A3
|
||||||
|
#define POLL_7E4_CAPACITY_EST_GEN2 0x45F9
|
||||||
|
#define POLL_7E4_SOC_DISPLAY 0x8334
|
||||||
|
#define POLL_7E4_SOC_RAW_HIGHPREC 0x43AF
|
||||||
|
#define POLL_7E4_MAX_TEMPERATURE 0x4349
|
||||||
|
#define POLL_7E4_MIN_TEMPERATURE 0x434A
|
||||||
|
#define POLL_7E4_MIN_CELL_V 0x4329
|
||||||
|
#define POLL_7E4_MAX_CELL_V 0x432B
|
||||||
|
#define POLL_7E4_INTERNAL_RES 0x40E9
|
||||||
|
#define POLL_7E4_LOWEST_CELL_NUMBER 0x433B
|
||||||
|
#define POLL_7E4_HIGHEST_CELL_NUMBER 0x433C
|
||||||
|
#define POLL_7E4_VOLTAGE 0x432D
|
||||||
|
#define POLL_7E4_VEHICLE_ISOLATION 0x41EC
|
||||||
|
#define POLL_7E4_ISOLATION_TEST_KOHM 0x43A6
|
||||||
|
#define POLL_7E4_HV_LOCKED_OUT 0x44F8
|
||||||
|
#define POLL_7E4_CRASH_EVENT 0x4522
|
||||||
|
#define POLL_7E4_HVIL 0x4310
|
||||||
|
#define POLL_7E4_HVIL_STATUS 0x4311
|
||||||
|
#define POLL_7E4_CURRENT 0x4356
|
||||||
|
|
||||||
|
#define POLL_7E7_CURRENT 0x40D4
|
||||||
|
#define POLL_7E7_5V_REF 0x40D3
|
||||||
|
#define POLL_7E7_MODULE_TEMP_1 0x40D7
|
||||||
|
#define POLL_7E7_MODULE_TEMP_2 0x40D9
|
||||||
|
#define POLL_7E7_MODULE_TEMP_3 0x40DB
|
||||||
|
#define POLL_7E7_MODULE_TEMP_4 0x40DD
|
||||||
|
#define POLL_7E7_MODULE_TEMP_5 0x40DF
|
||||||
|
#define POLL_7E7_MODULE_TEMP_6 0x40E1
|
||||||
|
#define POLL_7E7_CELL_AVG_VOLTAGE 0xC218
|
||||||
|
#define POLL_7E7_CELL_AVG_VOLTAGE_2 0x44B9
|
||||||
|
#define POLL_7E7_TERMINAL_VOLTAGE 0x82A3
|
||||||
|
#define POLL_7E7_IGNITION_POWER_MODE 0x8002
|
||||||
|
#define POLL_7E7_CELL_01 0x4181
|
||||||
|
#define POLL_7E7_CELL_02 0x4182
|
||||||
|
#define POLL_7E7_CELL_03 0x4183
|
||||||
|
#define POLL_7E7_CELL_04 0x4184
|
||||||
|
#define POLL_7E7_CELL_05 0x4185
|
||||||
|
#define POLL_7E7_CELL_06 0x4186
|
||||||
|
#define POLL_7E7_CELL_07 0x4187
|
||||||
|
#define POLL_7E7_CELL_08 0x4188
|
||||||
|
#define POLL_7E7_CELL_09 0x4189
|
||||||
|
#define POLL_7E7_CELL_10 0x418A
|
||||||
|
#define POLL_7E7_CELL_11 0x418B
|
||||||
|
#define POLL_7E7_CELL_12 0x418C
|
||||||
|
#define POLL_7E7_CELL_13 0x418D
|
||||||
|
#define POLL_7E7_CELL_14 0x418E
|
||||||
|
#define POLL_7E7_CELL_15 0x418F
|
||||||
|
#define POLL_7E7_CELL_16 0x4190
|
||||||
|
#define POLL_7E7_CELL_17 0x4191
|
||||||
|
#define POLL_7E7_CELL_18 0x4192
|
||||||
|
#define POLL_7E7_CELL_19 0x4193
|
||||||
|
#define POLL_7E7_CELL_20 0x4194
|
||||||
|
#define POLL_7E7_CELL_21 0x4195
|
||||||
|
#define POLL_7E7_CELL_22 0x4196
|
||||||
|
#define POLL_7E7_CELL_23 0x4197
|
||||||
|
#define POLL_7E7_CELL_24 0x4198
|
||||||
|
#define POLL_7E7_CELL_25 0x4199
|
||||||
|
#define POLL_7E7_CELL_26 0x419A
|
||||||
|
#define POLL_7E7_CELL_27 0x419B
|
||||||
|
#define POLL_7E7_CELL_28 0x419C
|
||||||
|
#define POLL_7E7_CELL_29 0x419D
|
||||||
|
#define POLL_7E7_CELL_30 0x419E
|
||||||
|
#define POLL_7E7_CELL_31 0x419F
|
||||||
|
#define POLL_7E7_CELL_32 0x4200
|
||||||
|
#define POLL_7E7_CELL_33 0x4201
|
||||||
|
#define POLL_7E7_CELL_34 0x4202
|
||||||
|
#define POLL_7E7_CELL_35 0x4203
|
||||||
|
#define POLL_7E7_CELL_36 0x4204
|
||||||
|
#define POLL_7E7_CELL_37 0x4205
|
||||||
|
#define POLL_7E7_CELL_38 0x4206
|
||||||
|
#define POLL_7E7_CELL_39 0x4207
|
||||||
|
#define POLL_7E7_CELL_40 0x4208
|
||||||
|
#define POLL_7E7_CELL_41 0x4209
|
||||||
|
#define POLL_7E7_CELL_42 0x420A
|
||||||
|
#define POLL_7E7_CELL_43 0x420B
|
||||||
|
#define POLL_7E7_CELL_44 0x420C
|
||||||
|
#define POLL_7E7_CELL_45 0x420D
|
||||||
|
#define POLL_7E7_CELL_46 0x420E
|
||||||
|
#define POLL_7E7_CELL_47 0x420F
|
||||||
|
#define POLL_7E7_CELL_48 0x4210
|
||||||
|
#define POLL_7E7_CELL_49 0x4211
|
||||||
|
#define POLL_7E7_CELL_50 0x4212
|
||||||
|
#define POLL_7E7_CELL_51 0x4213
|
||||||
|
#define POLL_7E7_CELL_52 0x4214
|
||||||
|
#define POLL_7E7_CELL_53 0x4215
|
||||||
|
#define POLL_7E7_CELL_54 0x4216
|
||||||
|
#define POLL_7E7_CELL_55 0x4217
|
||||||
|
#define POLL_7E7_CELL_56 0x4218
|
||||||
|
#define POLL_7E7_CELL_57 0x4219
|
||||||
|
#define POLL_7E7_CELL_58 0x421A
|
||||||
|
#define POLL_7E7_CELL_59 0x421B
|
||||||
|
#define POLL_7E7_CELL_60 0x421C
|
||||||
|
#define POLL_7E7_CELL_61 0x421D
|
||||||
|
#define POLL_7E7_CELL_62 0x421E
|
||||||
|
#define POLL_7E7_CELL_63 0x421F
|
||||||
|
#define POLL_7E7_CELL_64 0x4220
|
||||||
|
#define POLL_7E7_CELL_65 0x4221
|
||||||
|
#define POLL_7E7_CELL_66 0x4222
|
||||||
|
#define POLL_7E7_CELL_67 0x4223
|
||||||
|
#define POLL_7E7_CELL_68 0x4224
|
||||||
|
#define POLL_7E7_CELL_69 0x4225
|
||||||
|
#define POLL_7E7_CELL_70 0x4226
|
||||||
|
#define POLL_7E7_CELL_71 0x4227
|
||||||
|
#define POLL_7E7_CELL_72 0x4228
|
||||||
|
#define POLL_7E7_CELL_73 0x4229
|
||||||
|
#define POLL_7E7_CELL_74 0x422A
|
||||||
|
#define POLL_7E7_CELL_75 0x422B
|
||||||
|
#define POLL_7E7_CELL_76 0x422C
|
||||||
|
#define POLL_7E7_CELL_77 0x422D
|
||||||
|
#define POLL_7E7_CELL_78 0x422E
|
||||||
|
#define POLL_7E7_CELL_79 0x422F
|
||||||
|
#define POLL_7E7_CELL_80 0x4230
|
||||||
|
#define POLL_7E7_CELL_81 0x4231
|
||||||
|
#define POLL_7E7_CELL_82 0x4232
|
||||||
|
#define POLL_7E7_CELL_83 0x4233
|
||||||
|
#define POLL_7E7_CELL_84 0x4234
|
||||||
|
#define POLL_7E7_CELL_85 0x4235
|
||||||
|
#define POLL_7E7_CELL_86 0x4236
|
||||||
|
#define POLL_7E7_CELL_87 0x4237
|
||||||
|
#define POLL_7E7_CELL_88 0x4238
|
||||||
|
#define POLL_7E7_CELL_89 0x4239
|
||||||
|
#define POLL_7E7_CELL_90 0x423A
|
||||||
|
#define POLL_7E7_CELL_91 0x423B
|
||||||
|
#define POLL_7E7_CELL_92 0x423C
|
||||||
|
#define POLL_7E7_CELL_93 0x423D
|
||||||
|
#define POLL_7E7_CELL_94 0x423E
|
||||||
|
#define POLL_7E7_CELL_95 0x423F
|
||||||
|
#define POLL_7E7_CELL_96 0x4240
|
||||||
|
|
||||||
|
void setup_battery(void);
|
||||||
|
void transmit_can(CAN_frame* tx_frame, int interface);
|
||||||
|
|
||||||
|
#endif
|
|
@ -197,13 +197,13 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
|
||||||
x102_chg_session.ChargingCurrentRequest = newChargingCurrentRequest;
|
x102_chg_session.ChargingCurrentRequest = newChargingCurrentRequest;
|
||||||
x102_chg_session.TargetBatteryVoltage = newTargetBatteryVoltage;
|
x102_chg_session.TargetBatteryVoltage = newTargetBatteryVoltage;
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
//Note on p131
|
//Note on p131
|
||||||
uint8_t chargingrate = 0;
|
uint8_t chargingrate = 0;
|
||||||
if (x100_chg_lim.ConstantOfChargingRateIndication > 0) {
|
if (x100_chg_lim.ConstantOfChargingRateIndication > 0) {
|
||||||
chargingrate = x102_chg_session.StateOfCharge / x100_chg_lim.ConstantOfChargingRateIndication * 100;
|
chargingrate = x102_chg_session.StateOfCharge / x100_chg_lim.ConstantOfChargingRateIndication * 100;
|
||||||
Serial.print("Charge Rate (kW): ");
|
logging.print("Charge Rate (kW): ");
|
||||||
Serial.println(chargingrate);
|
logging.println(chargingrate);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -217,40 +217,40 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
|
||||||
*/
|
*/
|
||||||
if ((CHADEMO_Status == CHADEMO_INIT && vehicle_permission) ||
|
if ((CHADEMO_Status == CHADEMO_INIT && vehicle_permission) ||
|
||||||
(x102_chg_session.s.status.StatusVehicleChargingEnabled && !vehicle_permission)) {
|
(x102_chg_session.s.status.StatusVehicleChargingEnabled && !vehicle_permission)) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Inconsistent charge/discharge state.");
|
logging.println("Inconsistent charge/discharge state.");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_FAULT;
|
CHADEMO_Status = CHADEMO_FAULT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x102_chg_session.f.fault.FaultBatteryOverVoltage) {
|
if (x102_chg_session.f.fault.FaultBatteryOverVoltage) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Vehicle indicates fault, battery over voltage.");
|
logging.println("Vehicle indicates fault, battery over voltage.");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x102_chg_session.f.fault.FaultBatteryUnderVoltage) {
|
if (x102_chg_session.f.fault.FaultBatteryUnderVoltage) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Vehicle indicates fault, battery under voltage.");
|
logging.println("Vehicle indicates fault, battery under voltage.");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x102_chg_session.f.fault.FaultBatteryCurrentDeviation) {
|
if (x102_chg_session.f.fault.FaultBatteryCurrentDeviation) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Vehicle indicates fault, battery current deviation. Possible EVSE issue?");
|
logging.println("Vehicle indicates fault, battery current deviation. Possible EVSE issue?");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x102_chg_session.f.fault.FaultBatteryVoltageDeviation) {
|
if (x102_chg_session.f.fault.FaultBatteryVoltageDeviation) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Vehicle indicates fault, battery voltage deviation. Possible EVSE issue?");
|
logging.println("Vehicle indicates fault, battery voltage deviation. Possible EVSE issue?");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
return;
|
return;
|
||||||
|
@ -264,8 +264,8 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
|
||||||
|
|
||||||
//FIXME condition nesting or more stanzas needed here for clear determination of cessation reason
|
//FIXME condition nesting or more stanzas needed here for clear determination of cessation reason
|
||||||
if (CHADEMO_Status == CHADEMO_POWERFLOW && EVSE_mode == CHADEMO_CHARGE && !vehicle_permission) {
|
if (CHADEMO_Status == CHADEMO_POWERFLOW && EVSE_mode == CHADEMO_CHARGE && !vehicle_permission) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("State of charge ceiling reached or charging interrupted, stop charging");
|
logging.println("State of charge ceiling reached or charging interrupted, stop charging");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
return;
|
return;
|
||||||
|
@ -273,8 +273,8 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
|
||||||
|
|
||||||
if (vehicle_permission && CHADEMO_Status == CHADEMO_NEGOTIATE) {
|
if (vehicle_permission && CHADEMO_Status == CHADEMO_NEGOTIATE) {
|
||||||
CHADEMO_Status = CHADEMO_EV_ALLOWED;
|
CHADEMO_Status = CHADEMO_EV_ALLOWED;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("STATE shift to CHADEMO_EV_ALLOWED in process_vehicle_charging_session()");
|
logging.println("STATE shift to CHADEMO_EV_ALLOWED in process_vehicle_charging_session()");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -284,22 +284,22 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) {
|
||||||
// consider relocating
|
// consider relocating
|
||||||
if (vehicle_permission && CHADEMO_Status == CHADEMO_EVSE_PREPARE && priorTargetBatteryVoltage == 0 &&
|
if (vehicle_permission && CHADEMO_Status == CHADEMO_EVSE_PREPARE && priorTargetBatteryVoltage == 0 &&
|
||||||
newTargetBatteryVoltage > 0 && x102_chg_session.s.status.StatusVehicleChargingEnabled) {
|
newTargetBatteryVoltage > 0 && x102_chg_session.s.status.StatusVehicleChargingEnabled) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("STATE SHIFT to EVSE_START reached in process_vehicle_charging_session()");
|
logging.println("STATE SHIFT to EVSE_START reached in process_vehicle_charging_session()");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_EVSE_START;
|
CHADEMO_Status = CHADEMO_EVSE_START;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vehicle_permission && evse_permission && CHADEMO_Status == CHADEMO_POWERFLOW) {
|
if (vehicle_permission && evse_permission && CHADEMO_Status == CHADEMO_POWERFLOW) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("updating vehicle request in process_vehicle_charging_session()");
|
logging.println("updating vehicle request in process_vehicle_charging_session()");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("UNHANDLED STATE IN process_vehicle_charging_session()");
|
logging.println("UNHANDLED STATE IN process_vehicle_charging_session()");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -312,20 +312,20 @@ inline void process_vehicle_charging_limits(CAN_frame rx_frame) {
|
||||||
x200_discharge_limits.MinimumBatteryDischargeLevel = rx_frame.data.u8[6];
|
x200_discharge_limits.MinimumBatteryDischargeLevel = rx_frame.data.u8[6];
|
||||||
x200_discharge_limits.MaxRemainingCapacityForCharging = rx_frame.data.u8[7];
|
x200_discharge_limits.MaxRemainingCapacityForCharging = rx_frame.data.u8[7];
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
/* unsigned long currentMillis = millis();
|
/* unsigned long currentMillis = millis();
|
||||||
if (currentMillis - previousMillis5000 >= INTERVAL_5_S) {
|
if (currentMillis - previousMillis5000 >= INTERVAL_5_S) {
|
||||||
previousMillis5000 = currentMillis;
|
previousMillis5000 = currentMillis;
|
||||||
Serial.println("x200 Max remaining capacity for charging/discharging:");
|
logging.println("x200 Max remaining capacity for charging/discharging:");
|
||||||
// initially this is set to 0, which is represented as 0xFF
|
// initially this is set to 0, which is represented as 0xFF
|
||||||
Serial.println(0xFF - x200_discharge_limits.MaxRemainingCapacityForCharging);
|
logging.println(0xFF - x200_discharge_limits.MaxRemainingCapacityForCharging);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (get_measured_voltage() <= x200_discharge_limits.MinimumDischargeVoltage && CHADEMO_Status > CHADEMO_NEGOTIATE) {
|
if (get_measured_voltage() <= x200_discharge_limits.MinimumDischargeVoltage && CHADEMO_Status > CHADEMO_NEGOTIATE) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("x200 minimum discharge voltage met or exceeded, stopping.");
|
logging.println("x200 minimum discharge voltage met or exceeded, stopping.");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
}
|
}
|
||||||
|
@ -341,13 +341,13 @@ inline void process_vehicle_discharge_estimate(CAN_frame rx_frame) {
|
||||||
x201_discharge_estimate.ApproxDischargeCompletionTime = ((rx_frame.data.u8[2] << 8) | rx_frame.data.u8[1]);
|
x201_discharge_estimate.ApproxDischargeCompletionTime = ((rx_frame.data.u8[2] << 8) | rx_frame.data.u8[1]);
|
||||||
x201_discharge_estimate.AvailableVehicleEnergy = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[3]);
|
x201_discharge_estimate.AvailableVehicleEnergy = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[3]);
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
if (currentMillis - previousMillis5000 >= INTERVAL_5_S) {
|
if (currentMillis - previousMillis5000 >= INTERVAL_5_S) {
|
||||||
previousMillis5000 = currentMillis;
|
previousMillis5000 = currentMillis;
|
||||||
Serial.print("x201 availabile vehicle energy, completion time: ");
|
logging.print("x201 availabile vehicle energy, completion time: ");
|
||||||
Serial.println(x201_discharge_estimate.AvailableVehicleEnergy);
|
logging.println(x201_discharge_estimate.AvailableVehicleEnergy);
|
||||||
Serial.print("x201 approx vehicle completion time: ");
|
logging.print("x201 approx vehicle completion time: ");
|
||||||
Serial.println(x201_discharge_estimate.ApproxDischargeCompletionTime);
|
logging.println(x201_discharge_estimate.ApproxDischargeCompletionTime);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -369,17 +369,17 @@ inline void process_vehicle_vendor_ID(CAN_frame rx_frame) {
|
||||||
|
|
||||||
void receive_can_battery(CAN_frame rx_frame) {
|
void receive_can_battery(CAN_frame rx_frame) {
|
||||||
#ifdef CH_CAN_DEBUG
|
#ifdef CH_CAN_DEBUG
|
||||||
Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
Serial.print(rx_frame.ID, HEX);
|
logging.print(rx_frame.ID, HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
Serial.print(rx_frame.DLC);
|
logging.print(rx_frame.DLC);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
for (int i = 0; i < rx_frame.DLC; ++i) {
|
for (int i = 0; i < rx_frame.DLC; ++i) {
|
||||||
Serial.print(rx_frame.data.u8[i], HEX);
|
logging.print(rx_frame.data.u8[i], HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
}
|
}
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// CHADEMO coexists with a CAN-based shunt. Only process CHADEMO-specific IDs
|
// CHADEMO coexists with a CAN-based shunt. Only process CHADEMO-specific IDs
|
||||||
|
@ -713,9 +713,9 @@ void send_can_battery() {
|
||||||
// TODO need an update_evse_dynamic_control(..) function above before we send 118
|
// TODO need an update_evse_dynamic_control(..) function above before we send 118
|
||||||
// 110.0.0
|
// 110.0.0
|
||||||
if (x102_chg_session.ControlProtocolNumberEV >= 0x03) { //Only send the following on Chademo 2.0 vehicles?
|
if (x102_chg_session.ControlProtocolNumberEV >= 0x03) { //Only send the following on Chademo 2.0 vehicles?
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
//FIXME REMOVE
|
//FIXME REMOVE
|
||||||
Serial.println("REMOVE: proto 2.0");
|
logging.println("REMOVE: proto 2.0");
|
||||||
#endif
|
#endif
|
||||||
transmit_can(&CHADEMO_118, can_config.battery);
|
transmit_can(&CHADEMO_118, can_config.battery);
|
||||||
}
|
}
|
||||||
|
@ -753,15 +753,15 @@ void handle_chademo_sequence() {
|
||||||
/* ------------------- State override conditions checks ------------------- */
|
/* ------------------- State override conditions checks ------------------- */
|
||||||
/* ------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------ */
|
||||||
if (CHADEMO_Status >= CHADEMO_EV_ALLOWED && x102_chg_session.s.status.StatusVehicleShifterPosition) {
|
if (CHADEMO_Status >= CHADEMO_EV_ALLOWED && x102_chg_session.s.status.StatusVehicleShifterPosition) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Vehicle is not parked, abort.");
|
logging.println("Vehicle is not parked, abort.");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHADEMO_Status >= CHADEMO_EV_ALLOWED && !vehicle_permission) {
|
if (CHADEMO_Status >= CHADEMO_EV_ALLOWED && !vehicle_permission) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Vehicle charge/discharge permission ended, stop.");
|
logging.println("Vehicle charge/discharge permission ended, stop.");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
}
|
}
|
||||||
|
@ -775,24 +775,24 @@ void handle_chademo_sequence() {
|
||||||
plug_inserted = digitalRead(CHADEMO_PIN_7);
|
plug_inserted = digitalRead(CHADEMO_PIN_7);
|
||||||
|
|
||||||
if (!plug_inserted) {
|
if (!plug_inserted) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
// Serial.println("CHADEMO plug is not inserted.");
|
// logging.println("CHADEMO plug is not inserted.");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHADEMO_Status = CHADEMO_CONNECTED;
|
CHADEMO_Status = CHADEMO_CONNECTED;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("CHADEMO plug is inserted. Provide EVSE power to vehicle to trigger initialization.");
|
logging.println("CHADEMO plug is inserted. Provide EVSE power to vehicle to trigger initialization.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CHADEMO_CONNECTED:
|
case CHADEMO_CONNECTED:
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
//Serial.println("CHADEMO_CONNECTED State");
|
//logging.println("CHADEMO_CONNECTED State");
|
||||||
#endif
|
#endif
|
||||||
/* plug_inserted is .. essentially a volatile of sorts, so verify */
|
/* plug_inserted is .. essentially a volatile of sorts, so verify */
|
||||||
if (plug_inserted) {
|
if (plug_inserted) {
|
||||||
|
@ -810,8 +810,8 @@ void handle_chademo_sequence() {
|
||||||
* with timers to have higher confidence of certain conditions hitting
|
* with timers to have higher confidence of certain conditions hitting
|
||||||
* a steady state
|
* a steady state
|
||||||
*/
|
*/
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("CHADEMO plug is not inserted, cannot connect d2 relay to begin initialization.");
|
logging.println("CHADEMO plug is not inserted, cannot connect d2 relay to begin initialization.");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_IDLE;
|
CHADEMO_Status = CHADEMO_IDLE;
|
||||||
}
|
}
|
||||||
|
@ -821,8 +821,8 @@ void handle_chademo_sequence() {
|
||||||
* Used for triggers/error handling elsewhere;
|
* Used for triggers/error handling elsewhere;
|
||||||
* State change to CHADEMO_NEGOTIATE occurs in receive_can_battery(..)
|
* State change to CHADEMO_NEGOTIATE occurs in receive_can_battery(..)
|
||||||
*/
|
*/
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Serial.println("Awaiting initial vehicle CAN to trigger negotiation");
|
// logging.println("Awaiting initial vehicle CAN to trigger negotiation");
|
||||||
#endif
|
#endif
|
||||||
evse_init();
|
evse_init();
|
||||||
break;
|
break;
|
||||||
|
@ -830,16 +830,16 @@ void handle_chademo_sequence() {
|
||||||
/* Vehicle and EVSE dance */
|
/* Vehicle and EVSE dance */
|
||||||
//TODO if pin 4 / j goes high,
|
//TODO if pin 4 / j goes high,
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
// Serial.println("CHADEMO_NEGOTIATE State");
|
// logging.println("CHADEMO_NEGOTIATE State");
|
||||||
#endif
|
#endif
|
||||||
x109_evse_state.s.status.ChgDischStopControl = 1;
|
x109_evse_state.s.status.ChgDischStopControl = 1;
|
||||||
break;
|
break;
|
||||||
case CHADEMO_EV_ALLOWED:
|
case CHADEMO_EV_ALLOWED:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
Serial.println("CHADEMO_EV_ALLOWED State");
|
logging.println("CHADEMO_EV_ALLOWED State");
|
||||||
#endif
|
#endif
|
||||||
// If we are in this state, vehicle_permission was already set to true...but re-verify
|
// If we are in this state, vehicle_permission was already set to true...but re-verify
|
||||||
// that pin 4 (j) reads high
|
// that pin 4 (j) reads high
|
||||||
|
@ -855,9 +855,9 @@ void handle_chademo_sequence() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHADEMO_EVSE_PREPARE:
|
case CHADEMO_EVSE_PREPARE:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
Serial.println("CHADEMO_EVSE_PREPARE State");
|
logging.println("CHADEMO_EVSE_PREPARE State");
|
||||||
#endif
|
#endif
|
||||||
/* TODO voltage check of output < 20v
|
/* TODO voltage check of output < 20v
|
||||||
* insulation test hypothetically happens here before triggering PIN 10 high
|
* insulation test hypothetically happens here before triggering PIN 10 high
|
||||||
|
@ -878,7 +878,7 @@ void handle_chademo_sequence() {
|
||||||
digitalWrite(CHADEMO_PIN_10, HIGH);
|
digitalWrite(CHADEMO_PIN_10, HIGH);
|
||||||
evse_permission = true;
|
evse_permission = true;
|
||||||
} else {
|
} else {
|
||||||
Serial.println("Insulation check measures > 20v ");
|
logging.println("Insulation check measures > 20v ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// likely unnecessary but just to be sure. consider removal
|
// likely unnecessary but just to be sure. consider removal
|
||||||
|
@ -891,9 +891,9 @@ void handle_chademo_sequence() {
|
||||||
//state changes to CHADEMO_EVSE_START only upon receipt of charging session request
|
//state changes to CHADEMO_EVSE_START only upon receipt of charging session request
|
||||||
break;
|
break;
|
||||||
case CHADEMO_EVSE_START:
|
case CHADEMO_EVSE_START:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
Serial.println("CHADEMO_EVSE_START State");
|
logging.println("CHADEMO_EVSE_START State");
|
||||||
#endif
|
#endif
|
||||||
datalayer.system.status.battery_allows_contactor_closing = true;
|
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||||
x109_evse_state.s.status.ChgDischStopControl = 1;
|
x109_evse_state.s.status.ChgDischStopControl = 1;
|
||||||
|
@ -901,8 +901,8 @@ void handle_chademo_sequence() {
|
||||||
|
|
||||||
CHADEMO_Status = CHADEMO_EVSE_CONTACTORS_ENABLED;
|
CHADEMO_Status = CHADEMO_EVSE_CONTACTORS_ENABLED;
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Initiating contactors");
|
logging.println("Initiating contactors");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* break rather than fall through because contactors are not instantaneous;
|
/* break rather than fall through because contactors are not instantaneous;
|
||||||
|
@ -911,17 +911,17 @@ void handle_chademo_sequence() {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CHADEMO_EVSE_CONTACTORS_ENABLED:
|
case CHADEMO_EVSE_CONTACTORS_ENABLED:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
Serial.println("CHADEMO_EVSE_CONTACTORS State");
|
logging.println("CHADEMO_EVSE_CONTACTORS State");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* check whether contactors ready, because externally dependent upon inverter allow during discharge */
|
/* check whether contactors ready, because externally dependent upon inverter allow during discharge */
|
||||||
if (contactors_ready) {
|
if (contactors_ready) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Contactors ready");
|
logging.println("Contactors ready");
|
||||||
Serial.print("Voltage: ");
|
logging.print("Voltage: ");
|
||||||
Serial.println(get_measured_voltage());
|
logging.println(get_measured_voltage());
|
||||||
#endif
|
#endif
|
||||||
/* transition to POWERFLOW state if discharge compatible on both sides */
|
/* transition to POWERFLOW state if discharge compatible on both sides */
|
||||||
if (x109_evse_state.discharge_compatible && x102_chg_session.s.status.StatusVehicleDischargeCompatible &&
|
if (x109_evse_state.discharge_compatible && x102_chg_session.s.status.StatusVehicleDischargeCompatible &&
|
||||||
|
@ -941,9 +941,9 @@ void handle_chademo_sequence() {
|
||||||
/* break or fall through ? TODO */
|
/* break or fall through ? TODO */
|
||||||
break;
|
break;
|
||||||
case CHADEMO_POWERFLOW:
|
case CHADEMO_POWERFLOW:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
Serial.println("CHADEMO_POWERFLOW State");
|
logging.println("CHADEMO_POWERFLOW State");
|
||||||
#endif
|
#endif
|
||||||
/* POWERFLOW for charging, discharging, and bidirectional */
|
/* POWERFLOW for charging, discharging, and bidirectional */
|
||||||
/* Interpretation */
|
/* Interpretation */
|
||||||
|
@ -961,8 +961,8 @@ void handle_chademo_sequence() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_measured_voltage() <= x200_discharge_limits.MinimumDischargeVoltage) {
|
if (get_measured_voltage() <= x200_discharge_limits.MinimumDischargeVoltage) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("x200 minimum discharge voltage met or exceeded, stopping.");
|
logging.println("x200 minimum discharge voltage met or exceeded, stopping.");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_STOP;
|
CHADEMO_Status = CHADEMO_STOP;
|
||||||
}
|
}
|
||||||
|
@ -972,9 +972,9 @@ void handle_chademo_sequence() {
|
||||||
x109_evse_state.s.status.EVSE_status = 1;
|
x109_evse_state.s.status.EVSE_status = 1;
|
||||||
break;
|
break;
|
||||||
case CHADEMO_STOP:
|
case CHADEMO_STOP:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
Serial.println("CHADEMO_STOP State");
|
logging.println("CHADEMO_STOP State");
|
||||||
#endif
|
#endif
|
||||||
/* back to CHADEMO_IDLE after teardown */
|
/* back to CHADEMO_IDLE after teardown */
|
||||||
x109_evse_state.s.status.ChgDischStopControl = 1;
|
x109_evse_state.s.status.ChgDischStopControl = 1;
|
||||||
|
@ -1000,16 +1000,16 @@ void handle_chademo_sequence() {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CHADEMO_FAULT:
|
case CHADEMO_FAULT:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
// Commented unless needed for debug
|
// Commented unless needed for debug
|
||||||
Serial.println("CHADEMO_FAULT State");
|
logging.println("CHADEMO_FAULT State");
|
||||||
#endif
|
#endif
|
||||||
/* Once faulted, never departs CHADEMO_FAULT state unless device is power cycled as a safety measure */
|
/* Once faulted, never departs CHADEMO_FAULT state unless device is power cycled as a safety measure */
|
||||||
x109_evse_state.s.status.EVSE_error = 1;
|
x109_evse_state.s.status.EVSE_error = 1;
|
||||||
x109_evse_state.s.status.ChgDischError = 1;
|
x109_evse_state.s.status.ChgDischError = 1;
|
||||||
x109_evse_state.s.status.ChgDischStopControl = 1;
|
x109_evse_state.s.status.ChgDischStopControl = 1;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("CHADEMO fault encountered, tearing down to make safe");
|
logging.println("CHADEMO fault encountered, tearing down to make safe");
|
||||||
#endif
|
#endif
|
||||||
digitalWrite(CHADEMO_PIN_10, LOW);
|
digitalWrite(CHADEMO_PIN_10, LOW);
|
||||||
digitalWrite(CHADEMO_PIN_2, LOW);
|
digitalWrite(CHADEMO_PIN_2, LOW);
|
||||||
|
@ -1020,8 +1020,8 @@ void handle_chademo_sequence() {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("UNHANDLED CHADEMO_STATE, setting FAULT");
|
logging.println("UNHANDLED CHADEMO_STATE, setting FAULT");
|
||||||
#endif
|
#endif
|
||||||
CHADEMO_Status = CHADEMO_FAULT;
|
CHADEMO_Status = CHADEMO_FAULT;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -91,17 +91,17 @@ void ISA_handleFrame(CAN_frame* frame) {
|
||||||
|
|
||||||
case 0x510:
|
case 0x510:
|
||||||
case 0x511:
|
case 0x511:
|
||||||
Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
Serial.print(frame->ID, HEX);
|
logging.print(frame->ID, HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
Serial.print(frame->DLC);
|
logging.print(frame->DLC);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
for (int i = 0; i < frame->DLC; ++i) {
|
for (int i = 0; i < frame->DLC; ++i) {
|
||||||
Serial.print(frame->data.u8[i], HEX);
|
logging.print(frame->data.u8[i], HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
}
|
}
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x521:
|
case 0x521:
|
||||||
|
@ -245,8 +245,8 @@ void ISA_initialize() {
|
||||||
ISA_STOP();
|
ISA_STOP();
|
||||||
delay(500);
|
delay(500);
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
Serial.print("ISA Initialization ");
|
logging.print("ISA Initialization ");
|
||||||
Serial.println(i);
|
logging.println(i);
|
||||||
|
|
||||||
outframe.data.u8[0] = (0x20 + i);
|
outframe.data.u8[0] = (0x20 + i);
|
||||||
outframe.data.u8[1] = 0x02;
|
outframe.data.u8[1] = 0x02;
|
||||||
|
@ -271,7 +271,7 @@ void ISA_initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISA_STOP() {
|
void ISA_STOP() {
|
||||||
Serial.println("ISA STOP");
|
logging.println("ISA STOP");
|
||||||
|
|
||||||
outframe.data.u8[0] = 0x34;
|
outframe.data.u8[0] = 0x34;
|
||||||
outframe.data.u8[1] = 0x00;
|
outframe.data.u8[1] = 0x00;
|
||||||
|
@ -286,7 +286,7 @@ void ISA_STOP() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISA_sendSTORE() {
|
void ISA_sendSTORE() {
|
||||||
Serial.println("ISA send STORE");
|
logging.println("ISA send STORE");
|
||||||
|
|
||||||
outframe.data.u8[0] = 0x32;
|
outframe.data.u8[0] = 0x32;
|
||||||
outframe.data.u8[1] = 0x00;
|
outframe.data.u8[1] = 0x00;
|
||||||
|
@ -301,7 +301,7 @@ void ISA_sendSTORE() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISA_START() {
|
void ISA_START() {
|
||||||
Serial.println("ISA START");
|
logging.println("ISA START");
|
||||||
|
|
||||||
outframe.data.u8[0] = 0x34;
|
outframe.data.u8[0] = 0x34;
|
||||||
outframe.data.u8[1] = 0x01;
|
outframe.data.u8[1] = 0x01;
|
||||||
|
@ -317,7 +317,7 @@ void ISA_START() {
|
||||||
|
|
||||||
void ISA_RESTART() {
|
void ISA_RESTART() {
|
||||||
//Has the effect of zeroing AH and KWH
|
//Has the effect of zeroing AH and KWH
|
||||||
Serial.println("ISA RESTART");
|
logging.println("ISA RESTART");
|
||||||
|
|
||||||
outframe.data.u8[0] = 0x3F;
|
outframe.data.u8[0] = 0x3F;
|
||||||
outframe.data.u8[1] = 0x00;
|
outframe.data.u8[1] = 0x00;
|
||||||
|
@ -336,7 +336,7 @@ void ISA_deFAULT() {
|
||||||
ISA_STOP();
|
ISA_STOP();
|
||||||
delay(500);
|
delay(500);
|
||||||
|
|
||||||
Serial.println("ISA RESTART to default");
|
logging.println("ISA RESTART to default");
|
||||||
|
|
||||||
outframe.data.u8[0] = 0x3D;
|
outframe.data.u8[0] = 0x3D;
|
||||||
outframe.data.u8[1] = 0x00;
|
outframe.data.u8[1] = 0x00;
|
||||||
|
@ -358,7 +358,7 @@ void ISA_initCurrent() {
|
||||||
ISA_STOP();
|
ISA_STOP();
|
||||||
delay(500);
|
delay(500);
|
||||||
|
|
||||||
Serial.println("ISA Initialization Current");
|
logging.println("ISA Initialization Current");
|
||||||
|
|
||||||
outframe.data.u8[0] = 0x21;
|
outframe.data.u8[0] = 0x21;
|
||||||
outframe.data.u8[1] = 0x02;
|
outframe.data.u8[1] = 0x02;
|
||||||
|
@ -382,8 +382,8 @@ void ISA_initCurrent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISA_getCONFIG(uint8_t i) {
|
void ISA_getCONFIG(uint8_t i) {
|
||||||
Serial.print("ISA Get Config ");
|
logging.print("ISA Get Config ");
|
||||||
Serial.println(i);
|
logging.println(i);
|
||||||
|
|
||||||
outframe.data.u8[0] = (0x60 + i);
|
outframe.data.u8[0] = (0x60 + i);
|
||||||
outframe.data.u8[1] = 0x00;
|
outframe.data.u8[1] = 0x00;
|
||||||
|
@ -398,8 +398,8 @@ void ISA_getCONFIG(uint8_t i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISA_getCAN_ID(uint8_t i) {
|
void ISA_getCAN_ID(uint8_t i) {
|
||||||
Serial.print("ISA Get CAN ID ");
|
logging.print("ISA Get CAN ID ");
|
||||||
Serial.println(i);
|
logging.println(i);
|
||||||
|
|
||||||
outframe.data.u8[0] = (0x50 + i);
|
outframe.data.u8[0] = (0x50 + i);
|
||||||
if (i == 8)
|
if (i == 8)
|
||||||
|
@ -418,8 +418,8 @@ void ISA_getCAN_ID(uint8_t i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISA_getINFO(uint8_t i) {
|
void ISA_getINFO(uint8_t i) {
|
||||||
Serial.print("ISA Get INFO ");
|
logging.print("ISA Get INFO ");
|
||||||
Serial.println(i, HEX);
|
logging.println(i, HEX);
|
||||||
|
|
||||||
outframe.data.u8[0] = (0x70 + i);
|
outframe.data.u8[0] = (0x70 + i);
|
||||||
outframe.data.u8[1] = 0x00;
|
outframe.data.u8[1] = 0x00;
|
||||||
|
|
|
@ -103,29 +103,29 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BMU_Detected) {
|
if (!BMU_Detected) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("BMU not detected, check wiring!");
|
logging.println("BMU not detected, check wiring!");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Battery Values");
|
logging.println("Battery Values");
|
||||||
Serial.print("BMU SOC: ");
|
logging.print("BMU SOC: ");
|
||||||
Serial.print(BMU_SOC);
|
logging.print(BMU_SOC);
|
||||||
Serial.print(" BMU Current: ");
|
logging.print(" BMU Current: ");
|
||||||
Serial.print(BMU_Current);
|
logging.print(BMU_Current);
|
||||||
Serial.print(" BMU Battery Voltage: ");
|
logging.print(" BMU Battery Voltage: ");
|
||||||
Serial.print(BMU_PackVoltage);
|
logging.print(BMU_PackVoltage);
|
||||||
Serial.print(" BMU_Power: ");
|
logging.print(" BMU_Power: ");
|
||||||
Serial.print(BMU_Power);
|
logging.print(BMU_Power);
|
||||||
Serial.print(" Cell max voltage: ");
|
logging.print(" Cell max voltage: ");
|
||||||
Serial.print(max_volt_cel);
|
logging.print(max_volt_cel);
|
||||||
Serial.print(" Cell min voltage: ");
|
logging.print(" Cell min voltage: ");
|
||||||
Serial.print(min_volt_cel);
|
logging.print(min_volt_cel);
|
||||||
Serial.print(" Cell max temp: ");
|
logging.print(" Cell max temp: ");
|
||||||
Serial.print(max_temp_cel);
|
logging.print(max_temp_cel);
|
||||||
Serial.print(" Cell min temp: ");
|
logging.print(" Cell min temp: ");
|
||||||
Serial.println(min_temp_cel);
|
logging.println(min_temp_cel);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,9 +57,9 @@ CAN_frame ipace_keep_alive = {.FD = false,
|
||||||
.data = {0x9E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};*/
|
.data = {0x9E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};*/
|
||||||
|
|
||||||
void print_units(char* header, int value, char* units) {
|
void print_units(char* header, int value, char* units) {
|
||||||
Serial.print(header);
|
logging.print(header);
|
||||||
Serial.print(value);
|
logging.print(value);
|
||||||
Serial.print(units);
|
logging.print(units);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_values_battery() {
|
void update_values_battery() {
|
||||||
|
@ -104,8 +104,8 @@ void update_values_battery() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Finally print out values to serial if configured to do so*/
|
/*Finally print out values to serial if configured to do so*/
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Values going to inverter");
|
logging.println("Values going to inverter");
|
||||||
print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% ");
|
print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% ");
|
||||||
print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% ");
|
print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% ");
|
||||||
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
|
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
|
||||||
|
@ -115,7 +115,7 @@ void update_values_battery() {
|
||||||
print_units(", Min temp: ", (datalayer.battery.status.temperature_min_dC * 0.1), "°C ");
|
print_units(", Min temp: ", (datalayer.battery.status.temperature_min_dC * 0.1), "°C ");
|
||||||
print_units(", Max cell voltage: ", datalayer.battery.status.cell_max_voltage_mV, "mV ");
|
print_units(", Max cell voltage: ", datalayer.battery.status.cell_max_voltage_mV, "mV ");
|
||||||
print_units(", Min cell voltage: ", datalayer.battery.status.cell_min_voltage_mV, "mV ");
|
print_units(", Min cell voltage: ", datalayer.battery.status.cell_min_voltage_mV, "mV ");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,17 +229,17 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// All CAN messages recieved will be logged via serial
|
// All CAN messages recieved will be logged via serial
|
||||||
Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
Serial.print(rx_frame.ID, HEX);
|
logging.print(rx_frame.ID, HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
Serial.print(rx_frame.DLC);
|
logging.print(rx_frame.DLC);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
for (int i = 0; i < rx_frame.DLC; ++i) {
|
for (int i = 0; i < rx_frame.DLC; ++i) {
|
||||||
Serial.print(rx_frame.data.u8[i], HEX);
|
logging.print(rx_frame.data.u8[i], HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
}
|
}
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_can_battery() {
|
void send_can_battery() {
|
||||||
|
|
|
@ -690,63 +690,63 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
|
|
||||||
/* Safeties verified. Perform USB serial printout if configured to do so */
|
/* Safeties verified. Perform USB serial printout if configured to do so */
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println(); //sepatator
|
logging.println(); //sepatator
|
||||||
Serial.println("Values from battery: ");
|
logging.println("Values from battery: ");
|
||||||
Serial.print("SOC BMS: ");
|
logging.print("SOC BMS: ");
|
||||||
Serial.print((uint16_t)SOC_BMS / 10.0, 1);
|
logging.print((uint16_t)SOC_BMS / 10.0, 1);
|
||||||
Serial.print("% | SOC Display: ");
|
logging.print("% | SOC Display: ");
|
||||||
Serial.print((uint16_t)SOC_Display / 10.0, 1);
|
logging.print((uint16_t)SOC_Display / 10.0, 1);
|
||||||
Serial.print("% | SOH ");
|
logging.print("% | SOH ");
|
||||||
Serial.print((uint16_t)batterySOH / 10.0, 1);
|
logging.print((uint16_t)batterySOH / 10.0, 1);
|
||||||
Serial.println("%");
|
logging.println("%");
|
||||||
Serial.print((int16_t)batteryAmps / 10.0, 1);
|
logging.print((int16_t)batteryAmps / 10.0, 1);
|
||||||
Serial.print(" Amps | ");
|
logging.print(" Amps | ");
|
||||||
Serial.print((uint16_t)batteryVoltage / 10.0, 1);
|
logging.print((uint16_t)batteryVoltage / 10.0, 1);
|
||||||
Serial.print(" Volts | ");
|
logging.print(" Volts | ");
|
||||||
Serial.print((int16_t)datalayer.battery.status.active_power_W);
|
logging.print((int16_t)datalayer.battery.status.active_power_W);
|
||||||
Serial.println(" Watts");
|
logging.println(" Watts");
|
||||||
Serial.print("Allowed Charge ");
|
logging.print("Allowed Charge ");
|
||||||
Serial.print((uint16_t)allowedChargePower * 10);
|
logging.print((uint16_t)allowedChargePower * 10);
|
||||||
Serial.print(" W | Allowed Discharge ");
|
logging.print(" W | Allowed Discharge ");
|
||||||
Serial.print((uint16_t)allowedDischargePower * 10);
|
logging.print((uint16_t)allowedDischargePower * 10);
|
||||||
Serial.println(" W");
|
logging.println(" W");
|
||||||
Serial.print("MaxCellVolt ");
|
logging.print("MaxCellVolt ");
|
||||||
Serial.print(CellVoltMax_mV);
|
logging.print(CellVoltMax_mV);
|
||||||
Serial.print(" mV No ");
|
logging.print(" mV No ");
|
||||||
Serial.print(CellVmaxNo);
|
logging.print(CellVmaxNo);
|
||||||
Serial.print(" | MinCellVolt ");
|
logging.print(" | MinCellVolt ");
|
||||||
Serial.print(CellVoltMin_mV);
|
logging.print(CellVoltMin_mV);
|
||||||
Serial.print(" mV No ");
|
logging.print(" mV No ");
|
||||||
Serial.println(CellVminNo);
|
logging.println(CellVminNo);
|
||||||
Serial.print("TempHi ");
|
logging.print("TempHi ");
|
||||||
Serial.print((int16_t)temperatureMax);
|
logging.print((int16_t)temperatureMax);
|
||||||
Serial.print("°C TempLo ");
|
logging.print("°C TempLo ");
|
||||||
Serial.print((int16_t)temperatureMin);
|
logging.print((int16_t)temperatureMin);
|
||||||
Serial.print("°C WaterInlet ");
|
logging.print("°C WaterInlet ");
|
||||||
Serial.print((int8_t)temperature_water_inlet);
|
logging.print((int8_t)temperature_water_inlet);
|
||||||
Serial.print("°C PowerRelay ");
|
logging.print("°C PowerRelay ");
|
||||||
Serial.print((int8_t)powerRelayTemperature * 2);
|
logging.print((int8_t)powerRelayTemperature * 2);
|
||||||
Serial.println("°C");
|
logging.println("°C");
|
||||||
Serial.print("Aux12volt: ");
|
logging.print("Aux12volt: ");
|
||||||
Serial.print((int16_t)leadAcidBatteryVoltage / 10.0, 1);
|
logging.print((int16_t)leadAcidBatteryVoltage / 10.0, 1);
|
||||||
Serial.println("V | ");
|
logging.println("V | ");
|
||||||
Serial.print("BmsManagementMode ");
|
logging.print("BmsManagementMode ");
|
||||||
Serial.print((uint8_t)batteryManagementMode, BIN);
|
logging.print((uint8_t)batteryManagementMode, BIN);
|
||||||
if (bitRead((uint8_t)BMS_ign, 2) == 1) {
|
if (bitRead((uint8_t)BMS_ign, 2) == 1) {
|
||||||
Serial.print(" | BmsIgnition ON");
|
logging.print(" | BmsIgnition ON");
|
||||||
} else {
|
} else {
|
||||||
Serial.print(" | BmsIgnition OFF");
|
logging.print(" | BmsIgnition OFF");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitRead((uint8_t)batteryRelay, 0) == 1) {
|
if (bitRead((uint8_t)batteryRelay, 0) == 1) {
|
||||||
Serial.print(" | PowerRelay ON");
|
logging.print(" | PowerRelay ON");
|
||||||
} else {
|
} else {
|
||||||
Serial.print(" | PowerRelay OFF");
|
logging.print(" | PowerRelay OFF");
|
||||||
}
|
}
|
||||||
Serial.print(" | Inverter ");
|
logging.print(" | Inverter ");
|
||||||
Serial.print(inverterVoltage);
|
logging.print(inverterVoltage);
|
||||||
Serial.println(" Volts");
|
logging.println(" Volts");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,7 +808,7 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
// print_canfd_frame(frame);
|
// print_canfd_frame(frame);
|
||||||
switch (rx_frame.data.u8[0]) {
|
switch (rx_frame.data.u8[0]) {
|
||||||
case 0x10: //"PID Header"
|
case 0x10: //"PID Header"
|
||||||
// Serial.println ("Send ack");
|
// logging.println ("Send ack");
|
||||||
poll_data_pid = rx_frame.data.u8[4];
|
poll_data_pid = rx_frame.data.u8[4];
|
||||||
// if (rx_frame.data.u8[4] == poll_data_pid) {
|
// if (rx_frame.data.u8[4] == poll_data_pid) {
|
||||||
transmit_can(&EGMP_7E4_ack, can_config.battery); //Send ack to BMS if the same frame is sent as polled
|
transmit_can(&EGMP_7E4_ack, can_config.battery); //Send ack to BMS if the same frame is sent as polled
|
||||||
|
|
|
@ -142,63 +142,63 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
|
|
||||||
/* Safeties verified. Perform USB serial printout if configured to do so */
|
/* Safeties verified. Perform USB serial printout if configured to do so */
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println(); //sepatator
|
logging.println(); //sepatator
|
||||||
Serial.println("Values from battery: ");
|
logging.println("Values from battery: ");
|
||||||
Serial.print("SOC BMS: ");
|
logging.print("SOC BMS: ");
|
||||||
Serial.print((uint16_t)SOC_BMS / 10.0, 1);
|
logging.print((uint16_t)SOC_BMS / 10.0, 1);
|
||||||
Serial.print("% | SOC Display: ");
|
logging.print("% | SOC Display: ");
|
||||||
Serial.print((uint16_t)SOC_Display / 10.0, 1);
|
logging.print((uint16_t)SOC_Display / 10.0, 1);
|
||||||
Serial.print("% | SOH ");
|
logging.print("% | SOH ");
|
||||||
Serial.print((uint16_t)batterySOH / 10.0, 1);
|
logging.print((uint16_t)batterySOH / 10.0, 1);
|
||||||
Serial.println("%");
|
logging.println("%");
|
||||||
Serial.print((int16_t)batteryAmps / 10.0, 1);
|
logging.print((int16_t)batteryAmps / 10.0, 1);
|
||||||
Serial.print(" Amps | ");
|
logging.print(" Amps | ");
|
||||||
Serial.print((uint16_t)batteryVoltage / 10.0, 1);
|
logging.print((uint16_t)batteryVoltage / 10.0, 1);
|
||||||
Serial.print(" Volts | ");
|
logging.print(" Volts | ");
|
||||||
Serial.print((int16_t)datalayer.battery.status.active_power_W);
|
logging.print((int16_t)datalayer.battery.status.active_power_W);
|
||||||
Serial.println(" Watts");
|
logging.println(" Watts");
|
||||||
Serial.print("Allowed Charge ");
|
logging.print("Allowed Charge ");
|
||||||
Serial.print((uint16_t)allowedChargePower * 10);
|
logging.print((uint16_t)allowedChargePower * 10);
|
||||||
Serial.print(" W | Allowed Discharge ");
|
logging.print(" W | Allowed Discharge ");
|
||||||
Serial.print((uint16_t)allowedDischargePower * 10);
|
logging.print((uint16_t)allowedDischargePower * 10);
|
||||||
Serial.println(" W");
|
logging.println(" W");
|
||||||
Serial.print("MaxCellVolt ");
|
logging.print("MaxCellVolt ");
|
||||||
Serial.print(CellVoltMax_mV);
|
logging.print(CellVoltMax_mV);
|
||||||
Serial.print(" mV No ");
|
logging.print(" mV No ");
|
||||||
Serial.print(CellVmaxNo);
|
logging.print(CellVmaxNo);
|
||||||
Serial.print(" | MinCellVolt ");
|
logging.print(" | MinCellVolt ");
|
||||||
Serial.print(CellVoltMin_mV);
|
logging.print(CellVoltMin_mV);
|
||||||
Serial.print(" mV No ");
|
logging.print(" mV No ");
|
||||||
Serial.println(CellVminNo);
|
logging.println(CellVminNo);
|
||||||
Serial.print("TempHi ");
|
logging.print("TempHi ");
|
||||||
Serial.print((int16_t)temperatureMax);
|
logging.print((int16_t)temperatureMax);
|
||||||
Serial.print("°C TempLo ");
|
logging.print("°C TempLo ");
|
||||||
Serial.print((int16_t)temperatureMin);
|
logging.print((int16_t)temperatureMin);
|
||||||
Serial.print("°C WaterInlet ");
|
logging.print("°C WaterInlet ");
|
||||||
Serial.print((int8_t)temperature_water_inlet);
|
logging.print((int8_t)temperature_water_inlet);
|
||||||
Serial.print("°C PowerRelay ");
|
logging.print("°C PowerRelay ");
|
||||||
Serial.print((int8_t)powerRelayTemperature * 2);
|
logging.print((int8_t)powerRelayTemperature * 2);
|
||||||
Serial.println("°C");
|
logging.println("°C");
|
||||||
Serial.print("Aux12volt: ");
|
logging.print("Aux12volt: ");
|
||||||
Serial.print((int16_t)leadAcidBatteryVoltage / 10.0, 1);
|
logging.print((int16_t)leadAcidBatteryVoltage / 10.0, 1);
|
||||||
Serial.println("V | ");
|
logging.println("V | ");
|
||||||
Serial.print("BmsManagementMode ");
|
logging.print("BmsManagementMode ");
|
||||||
Serial.print((uint8_t)batteryManagementMode, BIN);
|
logging.print((uint8_t)batteryManagementMode, BIN);
|
||||||
if (bitRead((uint8_t)BMS_ign, 2) == 1) {
|
if (bitRead((uint8_t)BMS_ign, 2) == 1) {
|
||||||
Serial.print(" | BmsIgnition ON");
|
logging.print(" | BmsIgnition ON");
|
||||||
} else {
|
} else {
|
||||||
Serial.print(" | BmsIgnition OFF");
|
logging.print(" | BmsIgnition OFF");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitRead((uint8_t)batteryRelay, 0) == 1) {
|
if (bitRead((uint8_t)batteryRelay, 0) == 1) {
|
||||||
Serial.print(" | PowerRelay ON");
|
logging.print(" | PowerRelay ON");
|
||||||
} else {
|
} else {
|
||||||
Serial.print(" | PowerRelay OFF");
|
logging.print(" | PowerRelay OFF");
|
||||||
}
|
}
|
||||||
Serial.print(" | Inverter ");
|
logging.print(" | Inverter ");
|
||||||
Serial.print(inverterVoltage);
|
logging.print(inverterVoltage);
|
||||||
Serial.println(" Volts");
|
logging.println(" Volts");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,6 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
datalayer.battery.status.temperature_min_dC;
|
datalayer.battery.status.temperature_min_dC;
|
||||||
|
|
||||||
datalayer.battery.status.temperature_max_dC;
|
datalayer.battery.status.temperature_max_dC;
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void receive_can_battery(CAN_frame rx_frame) {
|
void receive_can_battery(CAN_frame rx_frame) {
|
||||||
|
|
|
@ -103,36 +103,36 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
|
|
||||||
datalayer.battery.status.cell_max_voltage_mV = LB_Cell_Max_Voltage;
|
datalayer.battery.status.cell_max_voltage_mV = LB_Cell_Max_Voltage;
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Values going to inverter:");
|
logging.println("Values going to inverter:");
|
||||||
Serial.print("SOH%: ");
|
logging.print("SOH%: ");
|
||||||
Serial.print(datalayer.battery.status.soh_pptt);
|
logging.print(datalayer.battery.status.soh_pptt);
|
||||||
Serial.print(", SOC% scaled: ");
|
logging.print(", SOC% scaled: ");
|
||||||
Serial.print(datalayer.battery.status.reported_soc);
|
logging.print(datalayer.battery.status.reported_soc);
|
||||||
Serial.print(", Voltage: ");
|
logging.print(", Voltage: ");
|
||||||
Serial.print(datalayer.battery.status.voltage_dV);
|
logging.print(datalayer.battery.status.voltage_dV);
|
||||||
Serial.print(", Max discharge power: ");
|
logging.print(", Max discharge power: ");
|
||||||
Serial.print(datalayer.battery.status.max_discharge_power_W);
|
logging.print(datalayer.battery.status.max_discharge_power_W);
|
||||||
Serial.print(", Max charge power: ");
|
logging.print(", Max charge power: ");
|
||||||
Serial.print(datalayer.battery.status.max_charge_power_W);
|
logging.print(datalayer.battery.status.max_charge_power_W);
|
||||||
Serial.print(", Max temp: ");
|
logging.print(", Max temp: ");
|
||||||
Serial.print(datalayer.battery.status.temperature_max_dC);
|
logging.print(datalayer.battery.status.temperature_max_dC);
|
||||||
Serial.print(", Min temp: ");
|
logging.print(", Min temp: ");
|
||||||
Serial.print(datalayer.battery.status.temperature_min_dC);
|
logging.print(datalayer.battery.status.temperature_min_dC);
|
||||||
Serial.print(", BMS Status (3=OK): ");
|
logging.print(", BMS Status (3=OK): ");
|
||||||
Serial.print(datalayer.battery.status.bms_status);
|
logging.print(datalayer.battery.status.bms_status);
|
||||||
|
|
||||||
Serial.println("Battery values: ");
|
logging.println("Battery values: ");
|
||||||
Serial.print("Real SOC: ");
|
logging.print("Real SOC: ");
|
||||||
Serial.print(LB_SOC);
|
logging.print(LB_SOC);
|
||||||
Serial.print(", Current: ");
|
logging.print(", Current: ");
|
||||||
Serial.print(LB_Current);
|
logging.print(LB_Current);
|
||||||
Serial.print(", kWh remain: ");
|
logging.print(", kWh remain: ");
|
||||||
Serial.print(LB_kWh_Remaining);
|
logging.print(LB_kWh_Remaining);
|
||||||
Serial.print(", max mV: ");
|
logging.print(", max mV: ");
|
||||||
Serial.print(LB_Cell_Max_Voltage);
|
logging.print(LB_Cell_Max_Voltage);
|
||||||
Serial.print(", min mV: ");
|
logging.print(", min mV: ");
|
||||||
Serial.print(LB_Cell_Min_Voltage);
|
logging.print(LB_Cell_Min_Voltage);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
|
|
||||||
datalayer.battery.status.max_discharge_power_W = LB_Discharge_allowed_W;
|
datalayer.battery.status.max_discharge_power_W = LB_Discharge_allowed_W;
|
||||||
|
|
||||||
datalayer.battery.status.max_charge_power_W = LB_Charging_Power_W;
|
datalayer.battery.status.max_charge_power_W = LB_Regen_allowed_W;
|
||||||
|
|
||||||
int16_t temperatures[] = {cell_1_temperature_polled, cell_2_temperature_polled, cell_3_temperature_polled,
|
int16_t temperatures[] = {cell_1_temperature_polled, cell_2_temperature_polled, cell_3_temperature_polled,
|
||||||
cell_4_temperature_polled, cell_5_temperature_polled, cell_6_temperature_polled,
|
cell_4_temperature_polled, cell_5_temperature_polled, cell_6_temperature_polled,
|
||||||
|
|
|
@ -216,10 +216,6 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
datalayer_extended.zoePH2.battery_pack_time = battery_pack_time;
|
datalayer_extended.zoePH2.battery_pack_time = battery_pack_time;
|
||||||
datalayer_extended.zoePH2.battery_soc_min = battery_soc_min;
|
datalayer_extended.zoePH2.battery_soc_min = battery_soc_min;
|
||||||
datalayer_extended.zoePH2.battery_soc_max = battery_soc_max;
|
datalayer_extended.zoePH2.battery_soc_max = battery_soc_max;
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void receive_can_battery(CAN_frame rx_frame) {
|
void receive_can_battery(CAN_frame rx_frame) {
|
||||||
|
|
|
@ -162,17 +162,17 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// All CAN messages recieved will be logged via serial
|
// All CAN messages recieved will be logged via serial
|
||||||
Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
Serial.print(rx_frame.ID, HEX);
|
logging.print(rx_frame.ID, HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
Serial.print(rx_frame.DLC);
|
logging.print(rx_frame.DLC);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
for (int i = 0; i < rx_frame.DLC; ++i) {
|
for (int i = 0; i < rx_frame.DLC; ++i) {
|
||||||
Serial.print(rx_frame.data.u8[i], HEX);
|
logging.print(rx_frame.data.u8[i], HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
}
|
}
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
*/
|
*/
|
||||||
switch (rx_frame.ID) {
|
switch (rx_frame.ID) {
|
||||||
case 0xF5: // This is the only message is sent from BMS
|
case 0xF5: // This is the only message is sent from BMS
|
||||||
|
|
|
@ -94,8 +94,8 @@ void manageSerialLinkReceiver() {
|
||||||
bool readError = dataLinkReceive.checkReadError(true); // check for error & clear error flag
|
bool readError = dataLinkReceive.checkReadError(true); // check for error & clear error flag
|
||||||
|
|
||||||
if (readError) {
|
if (readError) {
|
||||||
Serial.print(currentTime);
|
logging.print(currentTime);
|
||||||
Serial.println(" - ERROR: SerialDataLink - Read Error");
|
logging.println(" - ERROR: SerialDataLink - Read Error");
|
||||||
lasterror = true;
|
lasterror = true;
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
|
@ -112,8 +112,8 @@ void manageSerialLinkReceiver() {
|
||||||
//bms_status = ACTIVE; // just testing
|
//bms_status = ACTIVE; // just testing
|
||||||
if (lasterror) {
|
if (lasterror) {
|
||||||
lasterror = false;
|
lasterror = false;
|
||||||
Serial.print(currentTime);
|
logging.print(currentTime);
|
||||||
Serial.println(" - RECOVERY: SerialDataLink - Read GOOD");
|
logging.println(" - RECOVERY: SerialDataLink - Read GOOD");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,34 +134,34 @@ void manageSerialLinkReceiver() {
|
||||||
// report Lost data & Max charge / Discharge reductions
|
// report Lost data & Max charge / Discharge reductions
|
||||||
if (minutesLost != last_minutesLost) {
|
if (minutesLost != last_minutesLost) {
|
||||||
last_minutesLost = minutesLost;
|
last_minutesLost = minutesLost;
|
||||||
Serial.print(currentTime);
|
logging.print(currentTime);
|
||||||
if (batteryFault) {
|
if (batteryFault) {
|
||||||
Serial.print("Battery Fault (minutes) : ");
|
logging.print("Battery Fault (minutes) : ");
|
||||||
} else {
|
} else {
|
||||||
Serial.print(" - Minutes without data : ");
|
logging.print(" - Minutes without data : ");
|
||||||
}
|
}
|
||||||
Serial.print(minutesLost);
|
logging.print(minutesLost);
|
||||||
Serial.print(", max Charge = ");
|
logging.print(", max Charge = ");
|
||||||
Serial.print(datalayer.battery.status.max_charge_power_W);
|
logging.print(datalayer.battery.status.max_charge_power_W);
|
||||||
Serial.print(", max Discharge = ");
|
logging.print(", max Discharge = ");
|
||||||
Serial.println(datalayer.battery.status.max_discharge_power_W);
|
logging.println(datalayer.battery.status.max_discharge_power_W);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTime - reportTime > 59999) {
|
if (currentTime - reportTime > 59999) {
|
||||||
reportTime = currentTime;
|
reportTime = currentTime;
|
||||||
Serial.print(currentTime);
|
logging.print(currentTime);
|
||||||
Serial.print(" SerialDataLink-Receiver - NewData :");
|
logging.print(" SerialDataLink-Receiver - NewData :");
|
||||||
Serial.print(reads);
|
logging.print(reads);
|
||||||
Serial.print(" Errors : ");
|
logging.print(" Errors : ");
|
||||||
Serial.println(errors);
|
logging.println(errors);
|
||||||
reads = 0;
|
reads = 0;
|
||||||
errors = 0;
|
errors = 0;
|
||||||
|
|
||||||
// --- printUsefullData();
|
// --- printUsefullData();
|
||||||
//Serial.print("SOC = ");
|
//logging.print("SOC = ");
|
||||||
//Serial.println(SOC);
|
//logging.println(SOC);
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
update_values_serial_link();
|
update_values_serial_link();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -179,43 +179,43 @@ void manageSerialLinkReceiver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_values_serial_link() {
|
void update_values_serial_link() {
|
||||||
Serial.println("Values from battery: ");
|
logging.println("Values from battery: ");
|
||||||
Serial.print("SOC: ");
|
logging.print("SOC: ");
|
||||||
Serial.print(datalayer.battery.status.real_soc);
|
logging.print(datalayer.battery.status.real_soc);
|
||||||
Serial.print(" SOH: ");
|
logging.print(" SOH: ");
|
||||||
Serial.print(datalayer.battery.status.soh_pptt);
|
logging.print(datalayer.battery.status.soh_pptt);
|
||||||
Serial.print(" Voltage: ");
|
logging.print(" Voltage: ");
|
||||||
Serial.print(datalayer.battery.status.voltage_dV);
|
logging.print(datalayer.battery.status.voltage_dV);
|
||||||
Serial.print(" Current: ");
|
logging.print(" Current: ");
|
||||||
Serial.print(datalayer.battery.status.current_dA);
|
logging.print(datalayer.battery.status.current_dA);
|
||||||
Serial.print(" Capacity: ");
|
logging.print(" Capacity: ");
|
||||||
Serial.print(datalayer.battery.info.total_capacity_Wh);
|
logging.print(datalayer.battery.info.total_capacity_Wh);
|
||||||
Serial.print(" Remain cap: ");
|
logging.print(" Remain cap: ");
|
||||||
Serial.print(datalayer.battery.status.remaining_capacity_Wh);
|
logging.print(datalayer.battery.status.remaining_capacity_Wh);
|
||||||
Serial.print(" Max discharge W: ");
|
logging.print(" Max discharge W: ");
|
||||||
Serial.print(datalayer.battery.status.max_discharge_power_W);
|
logging.print(datalayer.battery.status.max_discharge_power_W);
|
||||||
Serial.print(" Max charge W: ");
|
logging.print(" Max charge W: ");
|
||||||
Serial.print(datalayer.battery.status.max_charge_power_W);
|
logging.print(datalayer.battery.status.max_charge_power_W);
|
||||||
Serial.print(" BMS status: ");
|
logging.print(" BMS status: ");
|
||||||
Serial.print(datalayer.battery.status.bms_status);
|
logging.print(datalayer.battery.status.bms_status);
|
||||||
Serial.print(" Power: ");
|
logging.print(" Power: ");
|
||||||
Serial.print(datalayer.battery.status.active_power_W);
|
logging.print(datalayer.battery.status.active_power_W);
|
||||||
Serial.print(" Temp min: ");
|
logging.print(" Temp min: ");
|
||||||
Serial.print(datalayer.battery.status.temperature_min_dC);
|
logging.print(datalayer.battery.status.temperature_min_dC);
|
||||||
Serial.print(" Temp max: ");
|
logging.print(" Temp max: ");
|
||||||
Serial.print(datalayer.battery.status.temperature_max_dC);
|
logging.print(datalayer.battery.status.temperature_max_dC);
|
||||||
Serial.print(" Cell max: ");
|
logging.print(" Cell max: ");
|
||||||
Serial.print(datalayer.battery.status.cell_max_voltage_mV);
|
logging.print(datalayer.battery.status.cell_max_voltage_mV);
|
||||||
Serial.print(" Cell min: ");
|
logging.print(" Cell min: ");
|
||||||
Serial.print(datalayer.battery.status.cell_min_voltage_mV);
|
logging.print(datalayer.battery.status.cell_min_voltage_mV);
|
||||||
Serial.print(" LFP : ");
|
logging.print(" LFP : ");
|
||||||
Serial.print(datalayer.battery.info.chemistry);
|
logging.print(datalayer.battery.info.chemistry);
|
||||||
Serial.print(" Battery Allows Contactor Closing: ");
|
logging.print(" Battery Allows Contactor Closing: ");
|
||||||
Serial.print(datalayer.system.status.battery_allows_contactor_closing);
|
logging.print(datalayer.system.status.battery_allows_contactor_closing);
|
||||||
Serial.print(" Inverter Allows Contactor Closing: ");
|
logging.print(" Inverter Allows Contactor Closing: ");
|
||||||
Serial.print(datalayer.system.status.inverter_allows_contactor_closing);
|
logging.print(datalayer.system.status.inverter_allows_contactor_closing);
|
||||||
|
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_battery(void) {
|
void setup_battery(void) {
|
||||||
|
|
|
@ -1080,69 +1080,69 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
datalayer_extended.tesla.HVP_shuntBarTempStatus = HVP_shuntBarTempStatus;
|
datalayer_extended.tesla.HVP_shuntBarTempStatus = HVP_shuntBarTempStatus;
|
||||||
datalayer_extended.tesla.HVP_shuntAsicTempStatus = HVP_shuntAsicTempStatus;
|
datalayer_extended.tesla.HVP_shuntAsicTempStatus = HVP_shuntAsicTempStatus;
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
|
|
||||||
printFaultCodesIfActive();
|
printFaultCodesIfActive();
|
||||||
|
|
||||||
Serial.print("STATUS: Contactor: ");
|
logging.print("STATUS: Contactor: ");
|
||||||
Serial.print(contactorText[battery_contactor]); //Display what state the contactor is in
|
logging.print(contactorText[battery_contactor]); //Display what state the contactor is in
|
||||||
Serial.print(", HVIL: ");
|
logging.print(", HVIL: ");
|
||||||
Serial.print(hvilStatusState[battery_hvil_status]);
|
logging.print(hvilStatusState[battery_hvil_status]);
|
||||||
Serial.print(", NegativeState: ");
|
logging.print(", NegativeState: ");
|
||||||
Serial.print(contactorState[battery_packContNegativeState]);
|
logging.print(contactorState[battery_packContNegativeState]);
|
||||||
Serial.print(", PositiveState: ");
|
logging.print(", PositiveState: ");
|
||||||
Serial.print(contactorState[battery_packContPositiveState]);
|
logging.print(contactorState[battery_packContPositiveState]);
|
||||||
Serial.print(", setState: ");
|
logging.print(", setState: ");
|
||||||
Serial.print(contactorState[battery_packContactorSetState]);
|
logging.print(contactorState[battery_packContactorSetState]);
|
||||||
Serial.print(", close allowed: ");
|
logging.print(", close allowed: ");
|
||||||
Serial.print(battery_packCtrsClosingAllowed);
|
logging.print(battery_packCtrsClosingAllowed);
|
||||||
Serial.print(", Pyrotest: ");
|
logging.print(", Pyrotest: ");
|
||||||
Serial.println(battery_pyroTestInProgress);
|
logging.println(battery_pyroTestInProgress);
|
||||||
|
|
||||||
Serial.print("Battery values: ");
|
logging.print("Battery values: ");
|
||||||
Serial.print("Real SOC: ");
|
logging.print("Real SOC: ");
|
||||||
Serial.print(battery_soc_ui / 10.0, 1);
|
logging.print(battery_soc_ui / 10.0, 1);
|
||||||
print_int_with_units(", Battery voltage: ", battery_volts, "V");
|
print_int_with_units(", Battery voltage: ", battery_volts, "V");
|
||||||
print_int_with_units(", Battery HV current: ", (battery_amps * 0.1), "A");
|
print_int_with_units(", Battery HV current: ", (battery_amps * 0.1), "A");
|
||||||
Serial.print(", Fully charged?: ");
|
logging.print(", Fully charged?: ");
|
||||||
if (battery_full_charge_complete)
|
if (battery_full_charge_complete)
|
||||||
Serial.print("YES, ");
|
logging.print("YES, ");
|
||||||
else
|
else
|
||||||
Serial.print("NO, ");
|
logging.print("NO, ");
|
||||||
if (datalayer.battery.info.chemistry == battery_chemistry_enum::LFP) {
|
if (datalayer.battery.info.chemistry == battery_chemistry_enum::LFP) {
|
||||||
Serial.print("LFP chemistry detected!");
|
logging.print("LFP chemistry detected!");
|
||||||
}
|
}
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
Serial.print("Cellstats, Max: ");
|
logging.print("Cellstats, Max: ");
|
||||||
Serial.print(battery_cell_max_v);
|
logging.print(battery_cell_max_v);
|
||||||
Serial.print("mV (cell ");
|
logging.print("mV (cell ");
|
||||||
Serial.print(battery_max_vno);
|
logging.print(battery_max_vno);
|
||||||
Serial.print("), Min: ");
|
logging.print("), Min: ");
|
||||||
Serial.print(battery_cell_min_v);
|
logging.print(battery_cell_min_v);
|
||||||
Serial.print("mV (cell ");
|
logging.print("mV (cell ");
|
||||||
Serial.print(battery_min_vno);
|
logging.print(battery_min_vno);
|
||||||
Serial.print("), Imbalance: ");
|
logging.print("), Imbalance: ");
|
||||||
Serial.print(battery_cell_deviation_mV);
|
logging.print(battery_cell_deviation_mV);
|
||||||
Serial.println("mV.");
|
logging.println("mV.");
|
||||||
|
|
||||||
print_int_with_units("High Voltage Output Pins: ", battery_dcdcHvBusVolt, "V");
|
print_int_with_units("High Voltage Output Pins: ", battery_dcdcHvBusVolt, "V");
|
||||||
Serial.print(", ");
|
logging.print(", ");
|
||||||
print_int_with_units("Low Voltage: ", battery_dcdcLvBusVolt, "V");
|
print_int_with_units("Low Voltage: ", battery_dcdcLvBusVolt, "V");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
print_int_with_units("DC/DC 12V current: ", battery_dcdcLvOutputCurrent, "A");
|
print_int_with_units("DC/DC 12V current: ", battery_dcdcLvOutputCurrent, "A");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
|
|
||||||
Serial.println("Values passed to the inverter: ");
|
logging.println("Values passed to the inverter: ");
|
||||||
print_SOC(" SOC: ", datalayer.battery.status.reported_soc);
|
print_SOC(" SOC: ", datalayer.battery.status.reported_soc);
|
||||||
print_int_with_units(" Max discharge power: ", datalayer.battery.status.max_discharge_power_W, "W");
|
print_int_with_units(" Max discharge power: ", datalayer.battery.status.max_discharge_power_W, "W");
|
||||||
Serial.print(", ");
|
logging.print(", ");
|
||||||
print_int_with_units(" Max charge power: ", datalayer.battery.status.max_charge_power_W, "W");
|
print_int_with_units(" Max charge power: ", datalayer.battery.status.max_charge_power_W, "W");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
print_int_with_units(" Max temperature: ", ((int16_t)datalayer.battery.status.temperature_min_dC * 0.1), "°C");
|
print_int_with_units(" Max temperature: ", ((int16_t)datalayer.battery.status.temperature_min_dC * 0.1), "°C");
|
||||||
Serial.print(", ");
|
logging.print(", ");
|
||||||
print_int_with_units(" Min temperature: ", ((int16_t)datalayer.battery.status.temperature_max_dC * 0.1), "°C");
|
print_int_with_units(" Min temperature: ", ((int16_t)datalayer.battery.status.temperature_max_dC * 0.1), "°C");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
#endif //DEBUG_VIA_USB
|
#endif //DEBUG_LOG
|
||||||
}
|
}
|
||||||
|
|
||||||
void receive_can_battery(CAN_frame rx_frame) {
|
void receive_can_battery(CAN_frame rx_frame) {
|
||||||
|
@ -2514,69 +2514,69 @@ void update_values_battery2() { //This function maps all the values fetched via
|
||||||
}
|
}
|
||||||
#endif // TESLA_MODEL_3Y_BATTERY
|
#endif // TESLA_MODEL_3Y_BATTERY
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
|
|
||||||
printFaultCodesIfActive_battery2();
|
printFaultCodesIfActive_battery2();
|
||||||
|
|
||||||
Serial.print("STATUS: Contactor: ");
|
logging.print("STATUS: Contactor: ");
|
||||||
Serial.print(contactorText[battery2_contactor]); //Display what state the contactor is in
|
logging.print(contactorText[battery2_contactor]); //Display what state the contactor is in
|
||||||
Serial.print(", HVIL: ");
|
logging.print(", HVIL: ");
|
||||||
Serial.print(hvilStatusState[battery2_hvil_status]);
|
logging.print(hvilStatusState[battery2_hvil_status]);
|
||||||
Serial.print(", NegativeState: ");
|
logging.print(", NegativeState: ");
|
||||||
Serial.print(contactorState[battery2_packContNegativeState]);
|
logging.print(contactorState[battery2_packContNegativeState]);
|
||||||
Serial.print(", PositiveState: ");
|
logging.print(", PositiveState: ");
|
||||||
Serial.print(contactorState[battery2_packContPositiveState]);
|
logging.print(contactorState[battery2_packContPositiveState]);
|
||||||
Serial.print(", setState: ");
|
logging.print(", setState: ");
|
||||||
Serial.print(contactorState[battery2_packContactorSetState]);
|
logging.print(contactorState[battery2_packContactorSetState]);
|
||||||
Serial.print(", close allowed: ");
|
logging.print(", close allowed: ");
|
||||||
Serial.print(battery2_packCtrsClosingAllowed);
|
logging.print(battery2_packCtrsClosingAllowed);
|
||||||
Serial.print(", Pyrotest: ");
|
logging.print(", Pyrotest: ");
|
||||||
Serial.println(battery2_pyroTestInProgress);
|
logging.println(battery2_pyroTestInProgress);
|
||||||
|
|
||||||
Serial.print("Battery2 values: ");
|
logging.print("Battery2 values: ");
|
||||||
Serial.print("Real SOC: ");
|
logging.print("Real SOC: ");
|
||||||
Serial.print(battery2_soc_ui / 10.0, 1);
|
logging.print(battery2_soc_ui / 10.0, 1);
|
||||||
print_int_with_units(", Battery2 voltage: ", battery2_volts, "V");
|
print_int_with_units(", Battery2 voltage: ", battery2_volts, "V");
|
||||||
print_int_with_units(", Battery2 HV current: ", (battery2_amps * 0.1), "A");
|
print_int_with_units(", Battery2 HV current: ", (battery2_amps * 0.1), "A");
|
||||||
Serial.print(", Fully charged?: ");
|
logging.print(", Fully charged?: ");
|
||||||
if (battery2_full_charge_complete)
|
if (battery2_full_charge_complete)
|
||||||
Serial.print("YES, ");
|
logging.print("YES, ");
|
||||||
else
|
else
|
||||||
Serial.print("NO, ");
|
logging.print("NO, ");
|
||||||
if (datalayer.battery2.info.chemistry == battery_chemistry_enum::LFP) {
|
if (datalayer.battery2.info.chemistry == battery_chemistry_enum::LFP) {
|
||||||
Serial.print("LFP chemistry detected!");
|
logging.print("LFP chemistry detected!");
|
||||||
}
|
}
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
Serial.print("Cellstats, Max: ");
|
logging.print("Cellstats, Max: ");
|
||||||
Serial.print(battery2_cell_max_v);
|
logging.print(battery2_cell_max_v);
|
||||||
Serial.print("mV (cell ");
|
logging.print("mV (cell ");
|
||||||
Serial.print(battery2_max_vno);
|
logging.print(battery2_max_vno);
|
||||||
Serial.print("), Min: ");
|
logging.print("), Min: ");
|
||||||
Serial.print(battery2_cell_min_v);
|
logging.print(battery2_cell_min_v);
|
||||||
Serial.print("mV (cell ");
|
logging.print("mV (cell ");
|
||||||
Serial.print(battery2_min_vno);
|
logging.print(battery2_min_vno);
|
||||||
Serial.print("), Imbalance: ");
|
logging.print("), Imbalance: ");
|
||||||
Serial.print(battery2_cell_deviation_mV);
|
logging.print(battery2_cell_deviation_mV);
|
||||||
Serial.println("mV.");
|
logging.println("mV.");
|
||||||
|
|
||||||
print_int_with_units("High Voltage Output Pins: ", battery2_dcdcHvBusVolt, "V");
|
print_int_with_units("High Voltage Output Pins: ", battery2_dcdcHvBusVolt, "V");
|
||||||
Serial.print(", ");
|
logging.print(", ");
|
||||||
print_int_with_units("Low Voltage: ", battery2_dcdcLvBusVolt, "V");
|
print_int_with_units("Low Voltage: ", battery2_dcdcLvBusVolt, "V");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
print_int_with_units("DC/DC 12V current: ", battery2_dcdcLvOutputCurrent, "A");
|
print_int_with_units("DC/DC 12V current: ", battery2_dcdcLvOutputCurrent, "A");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
|
|
||||||
Serial.println("Values passed to the inverter: ");
|
logging.println("Values passed to the inverter: ");
|
||||||
print_SOC(" SOC: ", datalayer.battery2.status.reported_soc);
|
print_SOC(" SOC: ", datalayer.battery2.status.reported_soc);
|
||||||
print_int_with_units(" Max discharge power: ", datalayer.battery2.status.max_discharge_power_W, "W");
|
print_int_with_units(" Max discharge power: ", datalayer.battery2.status.max_discharge_power_W, "W");
|
||||||
Serial.print(", ");
|
logging.print(", ");
|
||||||
print_int_with_units(" Max charge power: ", datalayer.battery2.status.max_charge_power_W, "W");
|
print_int_with_units(" Max charge power: ", datalayer.battery2.status.max_charge_power_W, "W");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
print_int_with_units(" Max temperature: ", ((int16_t)datalayer.battery2.status.temperature_min_dC * 0.1), "°C");
|
print_int_with_units(" Max temperature: ", ((int16_t)datalayer.battery2.status.temperature_min_dC * 0.1), "°C");
|
||||||
Serial.print(", ");
|
logging.print(", ");
|
||||||
print_int_with_units(" Min temperature: ", ((int16_t)datalayer.battery2.status.temperature_max_dC * 0.1), "°C");
|
print_int_with_units(" Min temperature: ", ((int16_t)datalayer.battery2.status.temperature_max_dC * 0.1), "°C");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //DOUBLE_BATTERY
|
#endif //DOUBLE_BATTERY
|
||||||
|
@ -2688,32 +2688,32 @@ the first, for a few cycles, then stop all messages which causes the contactor
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_int_with_units(char* header, int value, char* units) {
|
void print_int_with_units(char* header, int value, char* units) {
|
||||||
Serial.print(header);
|
logging.print(header);
|
||||||
Serial.print(value);
|
logging.print(value);
|
||||||
Serial.print(units);
|
logging.print(units);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_SOC(char* header, int SOC) {
|
void print_SOC(char* header, int SOC) {
|
||||||
Serial.print(header);
|
logging.print(header);
|
||||||
Serial.print(SOC / 100);
|
logging.print(SOC / 100);
|
||||||
Serial.print(".");
|
logging.print(".");
|
||||||
int hundredth = SOC % 100;
|
int hundredth = SOC % 100;
|
||||||
if (hundredth < 10)
|
if (hundredth < 10)
|
||||||
Serial.print(0);
|
logging.print(0);
|
||||||
Serial.print(hundredth);
|
logging.print(hundredth);
|
||||||
Serial.println("%");
|
logging.println("%");
|
||||||
}
|
}
|
||||||
|
|
||||||
void printFaultCodesIfActive() {
|
void printFaultCodesIfActive() {
|
||||||
if (battery_packCtrsClosingAllowed == 0) {
|
if (battery_packCtrsClosingAllowed == 0) {
|
||||||
Serial.println(
|
logging.println(
|
||||||
"ERROR: Check high voltage connectors and interlock circuit! Closing contactor not allowed! Values: ");
|
"ERROR: Check high voltage connectors and interlock circuit! Closing contactor not allowed! Values: ");
|
||||||
}
|
}
|
||||||
if (battery_pyroTestInProgress == 1) {
|
if (battery_pyroTestInProgress == 1) {
|
||||||
Serial.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!");
|
logging.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!");
|
||||||
}
|
}
|
||||||
if (datalayer.system.status.inverter_allows_contactor_closing == false) {
|
if (datalayer.system.status.inverter_allows_contactor_closing == false) {
|
||||||
Serial.println(
|
logging.println(
|
||||||
"ERROR: Solar inverter does not allow for contactor closing. Check communication connection to the inverter "
|
"ERROR: Solar inverter does not allow for contactor closing. Check communication connection to the inverter "
|
||||||
"OR "
|
"OR "
|
||||||
"disable the inverter protocol to proceed with contactor closing");
|
"disable the inverter protocol to proceed with contactor closing");
|
||||||
|
@ -2875,14 +2875,14 @@ void printFaultCodesIfActive() {
|
||||||
#ifdef DOUBLE_BATTERY //need to update battery2
|
#ifdef DOUBLE_BATTERY //need to update battery2
|
||||||
void printFaultCodesIfActive_battery2() {
|
void printFaultCodesIfActive_battery2() {
|
||||||
if (battery2_packCtrsClosingAllowed == 0) {
|
if (battery2_packCtrsClosingAllowed == 0) {
|
||||||
Serial.println(
|
logging.println(
|
||||||
"ERROR: Check high voltage connectors and interlock circuit! Closing contactor not allowed! Values: ");
|
"ERROR: Check high voltage connectors and interlock circuit! Closing contactor not allowed! Values: ");
|
||||||
}
|
}
|
||||||
if (battery2_pyroTestInProgress == 1) {
|
if (battery2_pyroTestInProgress == 1) {
|
||||||
Serial.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!");
|
logging.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!");
|
||||||
}
|
}
|
||||||
if (datalayer.system.status.inverter_allows_contactor_closing == false) {
|
if (datalayer.system.status.inverter_allows_contactor_closing == false) {
|
||||||
Serial.println(
|
logging.println(
|
||||||
"ERROR: Solar inverter does not allow for contactor closing. Check communication connection to the inverter "
|
"ERROR: Solar inverter does not allow for contactor closing. Check communication connection to the inverter "
|
||||||
"OR "
|
"OR "
|
||||||
"disable the inverter protocol to proceed with contactor closing");
|
"disable the inverter protocol to proceed with contactor closing");
|
||||||
|
@ -3045,7 +3045,7 @@ void printFaultCodesIfActive_battery2() {
|
||||||
|
|
||||||
void printDebugIfActive(uint8_t symbol, const char* message) {
|
void printDebugIfActive(uint8_t symbol, const char* message) {
|
||||||
if (symbol == 1) {
|
if (symbol == 1) {
|
||||||
Serial.println(message);
|
logging.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ CAN_frame TEST = {.FD = false,
|
||||||
.data = {0x10, 0x64, 0x00, 0xB0, 0x00, 0x1E, 0x00, 0x8F}};
|
.data = {0x10, 0x64, 0x00, 0xB0, 0x00, 0x1E, 0x00, 0x8F}};
|
||||||
|
|
||||||
void print_units(char* header, int value, char* units) {
|
void print_units(char* header, int value, char* units) {
|
||||||
Serial.print(header);
|
logging.print(header);
|
||||||
Serial.print(value);
|
logging.print(value);
|
||||||
Serial.print(units);
|
logging.print(units);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_values_battery() { /* This function puts fake values onto the parameters sent towards the inverter */
|
void update_values_battery() { /* This function puts fake values onto the parameters sent towards the inverter */
|
||||||
|
@ -54,8 +54,8 @@ void update_values_battery() { /* This function puts fake values onto the parame
|
||||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
|
||||||
/*Finally print out values to serial if configured to do so*/
|
/*Finally print out values to serial if configured to do so*/
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("FAKE Values going to inverter");
|
logging.println("FAKE Values going to inverter");
|
||||||
print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% ");
|
print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% ");
|
||||||
print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% ");
|
print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% ");
|
||||||
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
|
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
|
||||||
|
@ -65,7 +65,7 @@ void update_values_battery() { /* This function puts fake values onto the parame
|
||||||
print_units(", Min temp: ", (datalayer.battery.status.temperature_min_dC * 0.1), "°C ");
|
print_units(", Min temp: ", (datalayer.battery.status.temperature_min_dC * 0.1), "°C ");
|
||||||
print_units(", Max cell voltage: ", datalayer.battery.status.cell_max_voltage_mV, "mV ");
|
print_units(", Max cell voltage: ", datalayer.battery.status.cell_max_voltage_mV, "mV ");
|
||||||
print_units(", Min cell voltage: ", datalayer.battery.status.cell_min_voltage_mV, "mV ");
|
print_units(", Min cell voltage: ", datalayer.battery.status.cell_min_voltage_mV, "mV ");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,8 +107,8 @@ void update_values_battery2() { // Handle the values coming in from battery #2
|
||||||
datalayer.battery2.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
datalayer.battery2.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
|
||||||
/*Finally print out values to serial if configured to do so*/
|
/*Finally print out values to serial if configured to do so*/
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("FAKE Values battery 2 going to inverter");
|
logging.println("FAKE Values battery 2 going to inverter");
|
||||||
print_units("SOH 2 %: ", (datalayer.battery2.status.soh_pptt * 0.01), "% ");
|
print_units("SOH 2 %: ", (datalayer.battery2.status.soh_pptt * 0.01), "% ");
|
||||||
print_units(", SOC 2 %: ", (datalayer.battery2.status.reported_soc * 0.01), "% ");
|
print_units(", SOC 2 %: ", (datalayer.battery2.status.reported_soc * 0.01), "% ");
|
||||||
print_units(", Voltage 2: ", (datalayer.battery2.status.voltage_dV * 0.1), "V ");
|
print_units(", Voltage 2: ", (datalayer.battery2.status.voltage_dV * 0.1), "V ");
|
||||||
|
@ -118,7 +118,7 @@ void update_values_battery2() { // Handle the values coming in from battery #2
|
||||||
print_units(", Min temp 2: ", (datalayer.battery2.status.temperature_min_dC * 0.1), "°C ");
|
print_units(", Min temp 2: ", (datalayer.battery2.status.temperature_min_dC * 0.1), "°C ");
|
||||||
print_units(", Max cell voltage 2: ", datalayer.battery2.status.cell_max_voltage_mV, "mV ");
|
print_units(", Max cell voltage 2: ", datalayer.battery2.status.cell_max_voltage_mV, "mV ");
|
||||||
print_units(", Min cell voltage 2: ", datalayer.battery2.status.cell_min_voltage_mV, "mV ");
|
print_units(", Min cell voltage 2: ", datalayer.battery2.status.cell_min_voltage_mV, "mV ");
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,49 +94,49 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
datalayer.battery.status.cell_voltages_mV[i] = cell_voltages[i];
|
datalayer.battery.status.cell_voltages_mV[i] = cell_voltages[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.print("BMS reported SOC%: ");
|
logging.print("BMS reported SOC%: ");
|
||||||
Serial.println(SOC_BMS);
|
logging.println(SOC_BMS);
|
||||||
Serial.print("Calculated SOC%: ");
|
logging.print("Calculated SOC%: ");
|
||||||
Serial.println(SOC_CALC);
|
logging.println(SOC_CALC);
|
||||||
Serial.print("Rescaled SOC%: ");
|
logging.print("Rescaled SOC%: ");
|
||||||
Serial.println(datalayer.battery.status.reported_soc / 100);
|
logging.println(datalayer.battery.status.reported_soc / 100);
|
||||||
Serial.print("Battery current: ");
|
logging.print("Battery current: ");
|
||||||
Serial.println(BATT_I);
|
logging.println(BATT_I);
|
||||||
Serial.print("Battery voltage: ");
|
logging.print("Battery voltage: ");
|
||||||
Serial.println(BATT_U);
|
logging.println(BATT_U);
|
||||||
Serial.print("Battery maximum voltage limit: ");
|
logging.print("Battery maximum voltage limit: ");
|
||||||
Serial.println(MAX_U);
|
logging.println(MAX_U);
|
||||||
Serial.print("Battery minimum voltage limit: ");
|
logging.print("Battery minimum voltage limit: ");
|
||||||
Serial.println(MIN_U);
|
logging.println(MIN_U);
|
||||||
Serial.print("Remaining Energy: ");
|
logging.print("Remaining Energy: ");
|
||||||
Serial.println(remaining_capacity);
|
logging.println(remaining_capacity);
|
||||||
Serial.print("Discharge limit: ");
|
logging.print("Discharge limit: ");
|
||||||
Serial.println(HvBattPwrLimDchaSoft);
|
logging.println(HvBattPwrLimDchaSoft);
|
||||||
Serial.print("Battery Error Indication: ");
|
logging.print("Battery Error Indication: ");
|
||||||
Serial.println(BATT_ERR_INDICATION);
|
logging.println(BATT_ERR_INDICATION);
|
||||||
Serial.print("Maximum battery temperature: ");
|
logging.print("Maximum battery temperature: ");
|
||||||
Serial.println(BATT_T_MAX / 10);
|
logging.println(BATT_T_MAX / 10);
|
||||||
Serial.print("Minimum battery temperature: ");
|
logging.print("Minimum battery temperature: ");
|
||||||
Serial.println(BATT_T_MIN / 10);
|
logging.println(BATT_T_MIN / 10);
|
||||||
Serial.print("Average battery temperature: ");
|
logging.print("Average battery temperature: ");
|
||||||
Serial.println(BATT_T_AVG / 10);
|
logging.println(BATT_T_AVG / 10);
|
||||||
Serial.print("BMS Highest cell voltage: ");
|
logging.print("BMS Highest cell voltage: ");
|
||||||
Serial.println(CELL_U_MAX * 10);
|
logging.println(CELL_U_MAX * 10);
|
||||||
Serial.print("BMS Lowest cell voltage: ");
|
logging.print("BMS Lowest cell voltage: ");
|
||||||
Serial.println(CELL_U_MIN * 10);
|
logging.println(CELL_U_MIN * 10);
|
||||||
Serial.print("BMS Highest cell nr: ");
|
logging.print("BMS Highest cell nr: ");
|
||||||
Serial.println(CELL_ID_U_MAX);
|
logging.println(CELL_ID_U_MAX);
|
||||||
Serial.print("Highest cell voltage: ");
|
logging.print("Highest cell voltage: ");
|
||||||
Serial.println(min_max_voltage[1]);
|
logging.println(min_max_voltage[1]);
|
||||||
Serial.print("Lowest cell voltage: ");
|
logging.print("Lowest cell voltage: ");
|
||||||
Serial.println(min_max_voltage[0]);
|
logging.println(min_max_voltage[0]);
|
||||||
Serial.print("Cell voltage,");
|
logging.print("Cell voltage,");
|
||||||
while (cnt < 108) {
|
while (cnt < 108) {
|
||||||
Serial.print(cell_voltages[cnt++]);
|
logging.print(cell_voltages[cnt++]);
|
||||||
Serial.print(",");
|
logging.print(",");
|
||||||
}
|
}
|
||||||
Serial.println(";");
|
logging.println(";");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,8 +148,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
BATT_I = (0 - ((((rx_frame.data.u8[6] & 0x7F) * 256.0 + rx_frame.data.u8[7]) * 0.1) - 1638));
|
BATT_I = (0 - ((((rx_frame.data.u8[6] & 0x7F) * 256.0 + rx_frame.data.u8[7]) * 0.1) - 1638));
|
||||||
else {
|
else {
|
||||||
BATT_I = 0;
|
BATT_I = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("BATT_I not valid");
|
logging.println("BATT_I not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,22 +157,22 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
MAX_U = (((rx_frame.data.u8[2] & 0x07) * 256.0 + rx_frame.data.u8[3]) * 0.25);
|
MAX_U = (((rx_frame.data.u8[2] & 0x07) * 256.0 + rx_frame.data.u8[3]) * 0.25);
|
||||||
else {
|
else {
|
||||||
//MAX_U = 0;
|
//MAX_U = 0;
|
||||||
//Serial.println("MAX_U not valid"); // Value toggles between true/false from BMS
|
//logging.println("MAX_U not valid"); // Value toggles between true/false from BMS
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rx_frame.data.u8[4] & 0x08) == 0x08)
|
if ((rx_frame.data.u8[4] & 0x08) == 0x08)
|
||||||
MIN_U = (((rx_frame.data.u8[4] & 0x07) * 256.0 + rx_frame.data.u8[5]) * 0.25);
|
MIN_U = (((rx_frame.data.u8[4] & 0x07) * 256.0 + rx_frame.data.u8[5]) * 0.25);
|
||||||
else {
|
else {
|
||||||
//MIN_U = 0;
|
//MIN_U = 0;
|
||||||
//Serial.println("MIN_U not valid"); // Value toggles between true/false from BMS
|
//logging.println("MIN_U not valid"); // Value toggles between true/false from BMS
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rx_frame.data.u8[0] & 0x08) == 0x08)
|
if ((rx_frame.data.u8[0] & 0x08) == 0x08)
|
||||||
BATT_U = (((rx_frame.data.u8[0] & 0x07) * 256.0 + rx_frame.data.u8[1]) * 0.25);
|
BATT_U = (((rx_frame.data.u8[0] & 0x07) * 256.0 + rx_frame.data.u8[1]) * 0.25);
|
||||||
else {
|
else {
|
||||||
BATT_U = 0;
|
BATT_U = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("BATT_U not valid");
|
logging.println("BATT_U not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -189,8 +189,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
BATT_ERR_INDICATION = ((rx_frame.data.u8[0] & 0x40) >> 6);
|
BATT_ERR_INDICATION = ((rx_frame.data.u8[0] & 0x40) >> 6);
|
||||||
else {
|
else {
|
||||||
BATT_ERR_INDICATION = 0;
|
BATT_ERR_INDICATION = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("BATT_ERR_INDICATION not valid");
|
logging.println("BATT_ERR_INDICATION not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if ((rx_frame.data.u8[0] & 0x20) == 0x20) {
|
if ((rx_frame.data.u8[0] & 0x20) == 0x20) {
|
||||||
|
@ -201,8 +201,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
BATT_T_MAX = 0;
|
BATT_T_MAX = 0;
|
||||||
BATT_T_MIN = 0;
|
BATT_T_MIN = 0;
|
||||||
BATT_T_AVG = 0;
|
BATT_T_AVG = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("BATT_T not valid");
|
logging.println("BATT_T not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -211,8 +211,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
HvBattPwrLimDchaSoft = (((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[6]) >> 2);
|
HvBattPwrLimDchaSoft = (((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[6]) >> 2);
|
||||||
} else {
|
} else {
|
||||||
HvBattPwrLimDchaSoft = 0;
|
HvBattPwrLimDchaSoft = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("HvBattPwrLimDchaSoft not valid");
|
logging.println("HvBattPwrLimDchaSoft not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -221,8 +221,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
SOC_BMS = ((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[7]);
|
SOC_BMS = ((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[7]);
|
||||||
} else {
|
} else {
|
||||||
SOC_BMS = 0;
|
SOC_BMS = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("SOC_BMS not valid");
|
logging.println("SOC_BMS not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,8 +230,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
CELL_U_MAX = ((rx_frame.data.u8[2] & 0x01) * 256 + rx_frame.data.u8[3]);
|
CELL_U_MAX = ((rx_frame.data.u8[2] & 0x01) * 256 + rx_frame.data.u8[3]);
|
||||||
else {
|
else {
|
||||||
CELL_U_MAX = 0;
|
CELL_U_MAX = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("CELL_U_MAX not valid");
|
logging.println("CELL_U_MAX not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,8 +239,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
CELL_U_MIN = ((rx_frame.data.u8[0] & 0x01) * 256.0 + rx_frame.data.u8[1]);
|
CELL_U_MIN = ((rx_frame.data.u8[0] & 0x01) * 256.0 + rx_frame.data.u8[1]);
|
||||||
else {
|
else {
|
||||||
CELL_U_MIN = 0;
|
CELL_U_MIN = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("CELL_U_MIN not valid");
|
logging.println("CELL_U_MIN not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,8 +248,8 @@ void receive_can_battery(CAN_frame rx_frame) {
|
||||||
CELL_ID_U_MAX = ((rx_frame.data.u8[4] & 0x01) * 256.0 + rx_frame.data.u8[5]);
|
CELL_ID_U_MAX = ((rx_frame.data.u8[4] & 0x01) * 256.0 + rx_frame.data.u8[5]);
|
||||||
else {
|
else {
|
||||||
CELL_ID_U_MAX = 0;
|
CELL_ID_U_MAX = 0;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("CELL_ID_U_MAX not valid");
|
logging.println("CELL_ID_U_MAX not valid");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -101,8 +101,8 @@ void receive_can_charger(CAN_frame rx_frame) {
|
||||||
case 0x308:
|
case 0x308:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.printf("CAN Rcv unknown frame MsgID=%x\n", rx_frame.MsgID);
|
logging.printf("CAN Rcv unknown frame MsgID=%x\n", rx_frame.MsgID);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -177,15 +177,15 @@ void send_can_charger() {
|
||||||
transmit_can(&charger_set_targets, can_config.charger);
|
transmit_can(&charger_set_targets, can_config.charger);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
/* Serial echo every 5s of charger stats */
|
/* Serial echo every 5s of charger stats */
|
||||||
if (currentMillis - previousMillis5000ms >= INTERVAL_5_S) {
|
if (currentMillis - previousMillis5000ms >= INTERVAL_5_S) {
|
||||||
previousMillis5000ms = currentMillis;
|
previousMillis5000ms = currentMillis;
|
||||||
Serial.printf("Charger AC in IAC=%fA VAC=%fV\n", charger_stat_ACcur, charger_stat_ACvol);
|
logging.printf("Charger AC in IAC=%fA VAC=%fV\n", charger_stat_ACcur, charger_stat_ACvol);
|
||||||
Serial.printf("Charger HV out IDC=%fA VDC=%fV\n", charger_stat_HVcur, charger_stat_HVvol);
|
logging.printf("Charger HV out IDC=%fA VDC=%fV\n", charger_stat_HVcur, charger_stat_HVvol);
|
||||||
Serial.printf("Charger LV out IDC=%fA VDC=%fV\n", charger_stat_LVcur, charger_stat_LVvol);
|
logging.printf("Charger LV out IDC=%fA VDC=%fV\n", charger_stat_LVcur, charger_stat_LVvol);
|
||||||
Serial.printf("Charger mode=%s\n", (charger_mode > MODE_DISABLED) ? "Enabled" : "Disabled");
|
logging.printf("Charger mode=%s\n", (charger_mode > MODE_DISABLED) ? "Enabled" : "Disabled");
|
||||||
Serial.printf("Charger HVset=%uV,%uA finishCurrent=%uA\n", setpoint_HV_VDC, setpoint_HV_IDC, setpoint_HV_IDC_END);
|
logging.printf("Charger HVset=%uV,%uA finishCurrent=%uA\n", setpoint_HV_VDC, setpoint_HV_IDC, setpoint_HV_IDC_END);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,31 +35,31 @@ void init_CAN() {
|
||||||
ESP32Can.CANInit();
|
ESP32Can.CANInit();
|
||||||
|
|
||||||
#ifdef CAN_ADDON
|
#ifdef CAN_ADDON
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Dual CAN Bus (ESP32+MCP2515) selected");
|
logging.println("Dual CAN Bus (ESP32+MCP2515) selected");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
gBuffer.initWithSize(25);
|
gBuffer.initWithSize(25);
|
||||||
SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI);
|
SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI);
|
||||||
ACAN2515Settings settings(QUARTZ_FREQUENCY, 500UL * 1000UL); // CAN bit rate 500 kb/s
|
ACAN2515Settings settings(QUARTZ_FREQUENCY, 500UL * 1000UL); // CAN bit rate 500 kb/s
|
||||||
settings.mRequestedMode = ACAN2515Settings::NormalMode;
|
settings.mRequestedMode = ACAN2515Settings::NormalMode;
|
||||||
const uint16_t errorCodeMCP = can.begin(settings, [] { can.isr(); });
|
const uint16_t errorCodeMCP = can.begin(settings, [] { can.isr(); });
|
||||||
if (errorCodeMCP == 0) {
|
if (errorCodeMCP == 0) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Can ok");
|
logging.println("Can ok");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.print("Error Can: 0x");
|
logging.print("Error Can: 0x");
|
||||||
Serial.println(errorCodeMCP, HEX);
|
logging.println(errorCodeMCP, HEX);
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
set_event(EVENT_CANMCP_INIT_FAILURE, (uint8_t)errorCodeMCP);
|
set_event(EVENT_CANMCP_INIT_FAILURE, (uint8_t)errorCodeMCP);
|
||||||
}
|
}
|
||||||
#endif // CAN_ADDON
|
#endif // CAN_ADDON
|
||||||
|
|
||||||
#ifdef CANFD_ADDON
|
#ifdef CANFD_ADDON
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("CAN FD add-on (ESP32+MCP2517) selected");
|
logging.println("CAN FD add-on (ESP32+MCP2517) selected");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
SPI.begin(MCP2517_SCK, MCP2517_SDO, MCP2517_SDI);
|
SPI.begin(MCP2517_SCK, MCP2517_SDO, MCP2517_SDI);
|
||||||
ACAN2517FDSettings settings(CANFD_ADDON_CRYSTAL_FREQUENCY_MHZ, 500 * 1000,
|
ACAN2517FDSettings settings(CANFD_ADDON_CRYSTAL_FREQUENCY_MHZ, 500 * 1000,
|
||||||
DataBitRateFactor::x4); // Arbitration bit rate: 500 kbit/s, data bit rate: 2 Mbit/s
|
DataBitRateFactor::x4); // Arbitration bit rate: 500 kbit/s, data bit rate: 2 Mbit/s
|
||||||
|
@ -71,29 +71,29 @@ void init_CAN() {
|
||||||
const uint32_t errorCode = canfd.begin(settings, [] { canfd.isr(); });
|
const uint32_t errorCode = canfd.begin(settings, [] { canfd.isr(); });
|
||||||
canfd.poll();
|
canfd.poll();
|
||||||
if (errorCode == 0) {
|
if (errorCode == 0) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.print("Bit Rate prescaler: ");
|
logging.print("Bit Rate prescaler: ");
|
||||||
Serial.println(settings.mBitRatePrescaler);
|
logging.println(settings.mBitRatePrescaler);
|
||||||
Serial.print("Arbitration Phase segment 1: ");
|
logging.print("Arbitration Phase segment 1: ");
|
||||||
Serial.println(settings.mArbitrationPhaseSegment1);
|
logging.print(settings.mArbitrationPhaseSegment1);
|
||||||
Serial.print("Arbitration Phase segment 2: ");
|
logging.print(" segment 2: ");
|
||||||
Serial.println(settings.mArbitrationPhaseSegment2);
|
logging.print(settings.mArbitrationPhaseSegment2);
|
||||||
Serial.print("Arbitration SJW:");
|
logging.print(" SJW: ");
|
||||||
Serial.println(settings.mArbitrationSJW);
|
logging.println(settings.mArbitrationSJW);
|
||||||
Serial.print("Actual Arbitration Bit Rate: ");
|
logging.print("Actual Arbitration Bit Rate: ");
|
||||||
Serial.print(settings.actualArbitrationBitRate());
|
logging.print(settings.actualArbitrationBitRate());
|
||||||
Serial.println(" bit/s");
|
logging.print(" bit/s");
|
||||||
Serial.print("Exact Arbitration Bit Rate ? ");
|
logging.print(" (Exact:");
|
||||||
Serial.println(settings.exactArbitrationBitRate() ? "yes" : "no");
|
logging.println(settings.exactArbitrationBitRate() ? "yes)" : "no)");
|
||||||
Serial.print("Arbitration Sample point: ");
|
logging.print("Arbitration Sample point: ");
|
||||||
Serial.print(settings.arbitrationSamplePointFromBitStart());
|
logging.print(settings.arbitrationSamplePointFromBitStart());
|
||||||
Serial.println("%");
|
logging.println("%");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.print("CAN-FD Configuration error 0x");
|
logging.print("CAN-FD Configuration error 0x");
|
||||||
Serial.println(errorCode, HEX);
|
logging.println(errorCode, HEX);
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
set_event(EVENT_CANFD_INIT_FAILURE, (uint8_t)errorCode);
|
set_event(EVENT_CANFD_INIT_FAILURE, (uint8_t)errorCode);
|
||||||
}
|
}
|
||||||
#endif // CANFD_ADDON
|
#endif // CANFD_ADDON
|
||||||
|
@ -153,6 +153,8 @@ void transmit_can(CAN_frame* tx_frame, int interface) {
|
||||||
send_ok = canfd.tryToSend(MCP2518Frame);
|
send_ok = canfd.tryToSend(MCP2518Frame);
|
||||||
if (!send_ok) {
|
if (!send_ok) {
|
||||||
set_event(EVENT_CANFD_BUFFER_FULL, interface);
|
set_event(EVENT_CANFD_BUFFER_FULL, interface);
|
||||||
|
} else {
|
||||||
|
clear_event(EVENT_CANFD_BUFFER_FULL);
|
||||||
}
|
}
|
||||||
#else // Interface not compiled, and settings try to use it
|
#else // Interface not compiled, and settings try to use it
|
||||||
set_event(EVENT_INTERFACE_MISSING, interface);
|
set_event(EVENT_INTERFACE_MISSING, interface);
|
||||||
|
|
|
@ -3,6 +3,42 @@
|
||||||
|
|
||||||
#include "../include.h"
|
#include "../include.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/** uint16_t */
|
||||||
|
/** PID polling parameters */
|
||||||
|
uint16_t battery_5V_ref = 0;
|
||||||
|
int16_t battery_module_temp_1 = 0;
|
||||||
|
int16_t battery_module_temp_2 = 0;
|
||||||
|
int16_t battery_module_temp_3 = 0;
|
||||||
|
int16_t battery_module_temp_4 = 0;
|
||||||
|
int16_t battery_module_temp_5 = 0;
|
||||||
|
int16_t battery_module_temp_6 = 0;
|
||||||
|
uint16_t battery_cell_average_voltage = 0;
|
||||||
|
uint16_t battery_cell_average_voltage_2 = 0;
|
||||||
|
uint16_t battery_terminal_voltage = 0;
|
||||||
|
uint16_t battery_ignition_power_mode = 0;
|
||||||
|
int16_t battery_current_7E7 = 0;
|
||||||
|
uint16_t battery_capacity_my17_18 = 0;
|
||||||
|
uint16_t battery_capacity_my19plus = 0;
|
||||||
|
uint16_t battery_SOC_display = 0;
|
||||||
|
uint16_t battery_SOC_raw_highprec = 0;
|
||||||
|
uint16_t battery_max_temperature = 0;
|
||||||
|
uint16_t battery_min_temperature = 0;
|
||||||
|
uint16_t battery_max_cell_voltage = 0;
|
||||||
|
uint16_t battery_min_cell_voltage = 0;
|
||||||
|
uint16_t battery_lowest_cell = 0;
|
||||||
|
uint16_t battery_highest_cell = 0;
|
||||||
|
uint16_t battery_internal_resistance = 0;
|
||||||
|
uint16_t battery_voltage_polled = 0;
|
||||||
|
uint16_t battery_vehicle_isolation = 0;
|
||||||
|
uint16_t battery_isolation_kohm = 0;
|
||||||
|
uint16_t battery_HV_locked = 0;
|
||||||
|
uint16_t battery_crash_event = 0;
|
||||||
|
uint16_t battery_HVIL = 0;
|
||||||
|
uint16_t battery_HVIL_status = 0;
|
||||||
|
int16_t battery_current_7E4 = 0;
|
||||||
|
} DATALAYER_INFO_BOLTAMPERA;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** uint16_t */
|
/** uint16_t */
|
||||||
/** Terminal 30 - 12V SME Supply Voltage */
|
/** Terminal 30 - 12V SME Supply Voltage */
|
||||||
|
@ -535,6 +571,7 @@ typedef struct {
|
||||||
|
|
||||||
class DataLayerExtended {
|
class DataLayerExtended {
|
||||||
public:
|
public:
|
||||||
|
DATALAYER_INFO_BOLTAMPERA boltampera;
|
||||||
DATALAYER_INFO_BMWIX bmwix;
|
DATALAYER_INFO_BMWIX bmwix;
|
||||||
DATALAYER_INFO_BMWI3 bmwi3;
|
DATALAYER_INFO_BMWI3 bmwi3;
|
||||||
DATALAYER_INFO_BYDATTO3 bydAtto3;
|
DATALAYER_INFO_BYDATTO3 bydAtto3;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include "../../../USER_SECRETS.h"
|
||||||
#include "../../../USER_SETTINGS.h"
|
#include "../../../USER_SETTINGS.h"
|
||||||
#include "../../battery/BATTERIES.h"
|
#include "../../battery/BATTERIES.h"
|
||||||
#include "../../datalayer/datalayer.h"
|
#include "../../datalayer/datalayer.h"
|
||||||
|
@ -194,9 +195,9 @@ static void publish_common_info(void) {
|
||||||
#endif // DOUBLE_BATTERY
|
#endif // DOUBLE_BATTERY
|
||||||
serializeJson(doc, mqtt_msg);
|
serializeJson(doc, mqtt_msg);
|
||||||
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
|
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Common info MQTT msg could not be sent");
|
logging.println("Common info MQTT msg could not be sent");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
}
|
}
|
||||||
doc.clear();
|
doc.clear();
|
||||||
#ifdef HA_AUTODISCOVERY
|
#ifdef HA_AUTODISCOVERY
|
||||||
|
@ -292,9 +293,9 @@ static void publish_cell_voltages(void) {
|
||||||
serializeJson(doc, mqtt_msg, sizeof(mqtt_msg));
|
serializeJson(doc, mqtt_msg, sizeof(mqtt_msg));
|
||||||
|
|
||||||
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
|
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Cell voltage MQTT msg could not be sent");
|
logging.println("Cell voltage MQTT msg could not be sent");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
}
|
}
|
||||||
doc.clear();
|
doc.clear();
|
||||||
}
|
}
|
||||||
|
@ -312,9 +313,9 @@ static void publish_cell_voltages(void) {
|
||||||
serializeJson(doc, mqtt_msg, sizeof(mqtt_msg));
|
serializeJson(doc, mqtt_msg, sizeof(mqtt_msg));
|
||||||
|
|
||||||
if (!mqtt_publish(state_topic_2.c_str(), mqtt_msg, false)) {
|
if (!mqtt_publish(state_topic_2.c_str(), mqtt_msg, false)) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Cell voltage MQTT msg could not be sent");
|
logging.println("Cell voltage MQTT msg could not be sent");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
}
|
}
|
||||||
doc.clear();
|
doc.clear();
|
||||||
}
|
}
|
||||||
|
@ -384,9 +385,9 @@ void publish_events() {
|
||||||
|
|
||||||
serializeJson(doc, mqtt_msg);
|
serializeJson(doc, mqtt_msg);
|
||||||
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
|
if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Common info MQTT msg could not be sent");
|
logging.println("Common info MQTT msg could not be sent");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
} else {
|
} else {
|
||||||
set_event_MQTTpublished(event_handle);
|
set_event_MQTTpublished(event_handle);
|
||||||
}
|
}
|
||||||
|
@ -402,9 +403,9 @@ void publish_events() {
|
||||||
/* If we lose the connection, get it back */
|
/* If we lose the connection, get it back */
|
||||||
static bool reconnect() {
|
static bool reconnect() {
|
||||||
// attempt one reconnection
|
// attempt one reconnection
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.print("Attempting MQTT connection... ");
|
logging.print("Attempting MQTT connection... ");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
char clientId[64]; // Adjust the size as needed
|
char clientId[64]; // Adjust the size as needed
|
||||||
snprintf(clientId, sizeof(clientId), "BatteryEmulatorClient-%s", WiFi.getHostname());
|
snprintf(clientId, sizeof(clientId), "BatteryEmulatorClient-%s", WiFi.getHostname());
|
||||||
// Attempt to connect
|
// Attempt to connect
|
||||||
|
@ -413,19 +414,19 @@ static bool reconnect() {
|
||||||
clear_event(EVENT_MQTT_DISCONNECT);
|
clear_event(EVENT_MQTT_DISCONNECT);
|
||||||
set_event(EVENT_MQTT_CONNECT, 0);
|
set_event(EVENT_MQTT_CONNECT, 0);
|
||||||
reconnectAttempts = 0; // Reset attempts on successful connection
|
reconnectAttempts = 0; // Reset attempts on successful connection
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("connected");
|
logging.println("connected");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
clear_event(EVENT_MQTT_CONNECT);
|
clear_event(EVENT_MQTT_CONNECT);
|
||||||
} else {
|
} else {
|
||||||
if (connected_once)
|
if (connected_once)
|
||||||
set_event(EVENT_MQTT_DISCONNECT, 0);
|
set_event(EVENT_MQTT_DISCONNECT, 0);
|
||||||
reconnectAttempts++; // Count failed attempts
|
reconnectAttempts++; // Count failed attempts
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.print("failed, rc=");
|
logging.print("failed, rc=");
|
||||||
Serial.print(client.state());
|
logging.print(client.state());
|
||||||
Serial.println(" try again in 5 seconds");
|
logging.println(" try again in 5 seconds");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
// Wait 5 seconds before retrying
|
// Wait 5 seconds before retrying
|
||||||
}
|
}
|
||||||
return client.connected();
|
return client.connected();
|
||||||
|
@ -449,9 +450,9 @@ void init_mqtt(void) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
client.setServer(MQTT_SERVER, MQTT_PORT);
|
client.setServer(MQTT_SERVER, MQTT_PORT);
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("MQTT initialized");
|
logging.println("MQTT initialized");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
|
|
||||||
client.setKeepAlive(30); // Increase keepalive to manage network latency better. default is 15
|
client.setKeepAlive(30); // Increase keepalive to manage network latency better. default is 15
|
||||||
|
|
||||||
|
@ -478,8 +479,8 @@ void mqtt_loop(void) {
|
||||||
if (reconnect()) {
|
if (reconnect()) {
|
||||||
lastReconnectAttempt = 0;
|
lastReconnectAttempt = 0;
|
||||||
} else if (reconnectAttempts >= maxReconnectAttempts) {
|
} else if (reconnectAttempts >= maxReconnectAttempts) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Too many failed reconnect attempts, restarting client.");
|
logging.println("Too many failed reconnect attempts, restarting client.");
|
||||||
#endif
|
#endif
|
||||||
client.disconnect(); // Force close the MQTT client connection
|
client.disconnect(); // Force close the MQTT client connection
|
||||||
reconnectAttempts = 0; // Reset attempts to avoid infinite loop
|
reconnectAttempts = 0; // Reset attempts to avoid infinite loop
|
||||||
|
|
|
@ -118,15 +118,15 @@ void init_events(void) {
|
||||||
|
|
||||||
// Push changes to eeprom
|
// Push changes to eeprom
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("EEPROM wasn't ready");
|
logging.println("EEPROM wasn't ready");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
events.event_log_head_index = EEPROM.readUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS);
|
events.event_log_head_index = EEPROM.readUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS);
|
||||||
events.event_log_tail_index = EEPROM.readUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS);
|
events.event_log_tail_index = EEPROM.readUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS);
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("EEPROM was initialized for event logging");
|
logging.println("EEPROM was initialized for event logging");
|
||||||
Serial.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
|
logging.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
|
||||||
#endif
|
#endif
|
||||||
print_event_log();
|
print_event_log();
|
||||||
}
|
}
|
||||||
|
@ -471,6 +471,10 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
|
||||||
if (events.entries[event].log) {
|
if (events.entries[event].log) {
|
||||||
log_event(event, events.entries[event].millisrolloverCount, events.entries[event].timestamp, data);
|
log_event(event, events.entries[event].millisrolloverCount, events.entries[event].timestamp, data);
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_LOG
|
||||||
|
logging.print("Event: ");
|
||||||
|
logging.println(get_event_message_string(event));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should set the event, update event info
|
// We should set the event, update event info
|
||||||
|
@ -484,10 +488,6 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
|
||||||
events.level = max(events.level, events.entries[event].level);
|
events.level = max(events.level, events.entries[event].level);
|
||||||
|
|
||||||
update_bms_status();
|
update_bms_status();
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
|
||||||
Serial.println(get_event_message_string(event));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_bms_status(void) {
|
static void update_bms_status(void) {
|
||||||
|
@ -561,8 +561,8 @@ static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint3
|
||||||
// Store the new indices
|
// Store the new indices
|
||||||
EEPROM.writeUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS, events.event_log_head_index);
|
EEPROM.writeUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS, events.event_log_head_index);
|
||||||
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, events.event_log_tail_index);
|
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, events.event_log_tail_index);
|
||||||
//Serial.println("Wrote event " + String(event) + " to " + String(entry_address));
|
//logging.println("Wrote event " + String(event) + " to " + String(entry_address));
|
||||||
//Serial.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
|
//logging.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
|
||||||
|
|
||||||
// We don't need the exact number, it's just for deciding to store or not
|
// We don't need the exact number, it's just for deciding to store or not
|
||||||
events.nof_logged_events += (events.nof_logged_events < 255) ? 1 : 0;
|
events.nof_logged_events += (events.nof_logged_events < 255) ? 1 : 0;
|
||||||
|
@ -571,8 +571,8 @@ static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint3
|
||||||
static void print_event_log(void) {
|
static void print_event_log(void) {
|
||||||
// If the head actually points to the tail, the log is probably blank
|
// If the head actually points to the tail, the log is probably blank
|
||||||
if (events.event_log_head_index == events.event_log_tail_index) {
|
if (events.event_log_head_index == events.event_log_tail_index) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("No events in log");
|
logging.println("No events in log");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -588,9 +588,9 @@ static void print_event_log(void) {
|
||||||
// The entry is a blank that has been left behind somehow
|
// The entry is a blank that has been left behind somehow
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) +
|
logging.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) +
|
||||||
", time: " + String(entry.timestamp));
|
", time: " + String(entry.timestamp));
|
||||||
#endif
|
#endif
|
||||||
if (index == events.event_log_head_index) {
|
if (index == events.event_log_head_index) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -25,9 +25,9 @@ void run_sequence_on_target(void) {
|
||||||
case ETOT_INIT:
|
case ETOT_INIT:
|
||||||
timer.set_interval(10000);
|
timer.set_interval(10000);
|
||||||
events_test_state = ETOT_FIRST_WAIT;
|
events_test_state = ETOT_FIRST_WAIT;
|
||||||
Serial.println("Events test: initialized");
|
logging.println("Events test: initialized");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
break;
|
break;
|
||||||
case ETOT_FIRST_WAIT:
|
case ETOT_FIRST_WAIT:
|
||||||
if (timer.elapsed()) {
|
if (timer.elapsed()) {
|
||||||
|
@ -35,9 +35,9 @@ void run_sequence_on_target(void) {
|
||||||
events_test_state = ETOT_INFO;
|
events_test_state = ETOT_INFO;
|
||||||
set_event(EVENT_DUMMY_INFO, 123);
|
set_event(EVENT_DUMMY_INFO, 123);
|
||||||
set_event(EVENT_DUMMY_INFO, 234); // 234 should show, occurrence 1
|
set_event(EVENT_DUMMY_INFO, 234); // 234 should show, occurrence 1
|
||||||
Serial.println("Events test: info event set, data: 234");
|
logging.println("Events test: info event set, data: 234");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_INFO:
|
case ETOT_INFO:
|
||||||
|
@ -45,9 +45,9 @@ void run_sequence_on_target(void) {
|
||||||
timer.set_interval(8000);
|
timer.set_interval(8000);
|
||||||
clear_event(EVENT_DUMMY_INFO);
|
clear_event(EVENT_DUMMY_INFO);
|
||||||
events_test_state = ETOT_INFO_CLEAR;
|
events_test_state = ETOT_INFO_CLEAR;
|
||||||
Serial.println("Events test : info event cleared");
|
logging.println("Events test : info event cleared");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_INFO_CLEAR:
|
case ETOT_INFO_CLEAR:
|
||||||
|
@ -56,9 +56,9 @@ void run_sequence_on_target(void) {
|
||||||
events_test_state = ETOT_DEBUG;
|
events_test_state = ETOT_DEBUG;
|
||||||
set_event(EVENT_DUMMY_DEBUG, 111);
|
set_event(EVENT_DUMMY_DEBUG, 111);
|
||||||
set_event(EVENT_DUMMY_DEBUG, 222); // 222 should show, occurrence 1
|
set_event(EVENT_DUMMY_DEBUG, 222); // 222 should show, occurrence 1
|
||||||
Serial.println("Events test : debug event set, data: 222");
|
logging.println("Events test : debug event set, data: 222");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_DEBUG:
|
case ETOT_DEBUG:
|
||||||
|
@ -66,9 +66,9 @@ void run_sequence_on_target(void) {
|
||||||
timer.set_interval(8000);
|
timer.set_interval(8000);
|
||||||
clear_event(EVENT_DUMMY_DEBUG);
|
clear_event(EVENT_DUMMY_DEBUG);
|
||||||
events_test_state = ETOT_DEBUG_CLEAR;
|
events_test_state = ETOT_DEBUG_CLEAR;
|
||||||
Serial.println("Events test : info event cleared");
|
logging.println("Events test : info event cleared");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_DEBUG_CLEAR:
|
case ETOT_DEBUG_CLEAR:
|
||||||
|
@ -77,9 +77,9 @@ void run_sequence_on_target(void) {
|
||||||
events_test_state = ETOT_WARNING;
|
events_test_state = ETOT_WARNING;
|
||||||
set_event(EVENT_DUMMY_WARNING, 234);
|
set_event(EVENT_DUMMY_WARNING, 234);
|
||||||
set_event(EVENT_DUMMY_WARNING, 121); // 121 should show, occurrence 1
|
set_event(EVENT_DUMMY_WARNING, 121); // 121 should show, occurrence 1
|
||||||
Serial.println("Events test : warning event set, data: 121");
|
logging.println("Events test : warning event set, data: 121");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_WARNING:
|
case ETOT_WARNING:
|
||||||
|
@ -87,9 +87,9 @@ void run_sequence_on_target(void) {
|
||||||
timer.set_interval(8000);
|
timer.set_interval(8000);
|
||||||
clear_event(EVENT_DUMMY_WARNING);
|
clear_event(EVENT_DUMMY_WARNING);
|
||||||
events_test_state = ETOT_WARNING_CLEAR;
|
events_test_state = ETOT_WARNING_CLEAR;
|
||||||
Serial.println("Events test : warning event cleared");
|
logging.println("Events test : warning event cleared");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_WARNING_CLEAR:
|
case ETOT_WARNING_CLEAR:
|
||||||
|
@ -98,9 +98,9 @@ void run_sequence_on_target(void) {
|
||||||
events_test_state = ETOT_ERROR;
|
events_test_state = ETOT_ERROR;
|
||||||
set_event(EVENT_DUMMY_ERROR, 221);
|
set_event(EVENT_DUMMY_ERROR, 221);
|
||||||
set_event(EVENT_DUMMY_ERROR, 133); // 133 should show, occurrence 1
|
set_event(EVENT_DUMMY_ERROR, 133); // 133 should show, occurrence 1
|
||||||
Serial.println("Events test : error event set, data: 133");
|
logging.println("Events test : error event set, data: 133");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_ERROR:
|
case ETOT_ERROR:
|
||||||
|
@ -108,9 +108,9 @@ void run_sequence_on_target(void) {
|
||||||
timer.set_interval(8000);
|
timer.set_interval(8000);
|
||||||
clear_event(EVENT_DUMMY_ERROR);
|
clear_event(EVENT_DUMMY_ERROR);
|
||||||
events_test_state = ETOT_ERROR_CLEAR;
|
events_test_state = ETOT_ERROR_CLEAR;
|
||||||
Serial.println("Events test : error event cleared");
|
logging.println("Events test : error event cleared");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_ERROR_CLEAR:
|
case ETOT_ERROR_CLEAR:
|
||||||
|
@ -119,9 +119,9 @@ void run_sequence_on_target(void) {
|
||||||
events_test_state = ETOT_ERROR_LATCHED;
|
events_test_state = ETOT_ERROR_LATCHED;
|
||||||
set_event_latched(EVENT_DUMMY_ERROR, 221);
|
set_event_latched(EVENT_DUMMY_ERROR, 221);
|
||||||
set_event_latched(EVENT_DUMMY_ERROR, 133); // 133 should show, occurrence 1
|
set_event_latched(EVENT_DUMMY_ERROR, 133); // 133 should show, occurrence 1
|
||||||
Serial.println("Events test : latched error event set, data: 133");
|
logging.println("Events test : latched error event set, data: 133");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_ERROR_LATCHED:
|
case ETOT_ERROR_LATCHED:
|
||||||
|
@ -129,9 +129,9 @@ void run_sequence_on_target(void) {
|
||||||
timer.set_interval(8000);
|
timer.set_interval(8000);
|
||||||
clear_event(EVENT_DUMMY_ERROR);
|
clear_event(EVENT_DUMMY_ERROR);
|
||||||
events_test_state = ETOT_DONE;
|
events_test_state = ETOT_DONE;
|
||||||
Serial.println("Events test : latched error event cleared?");
|
logging.println("Events test : latched error event cleared?");
|
||||||
Serial.print("datalayer.battery.status.bms_status: ");
|
logging.print("datalayer.battery.status.bms_status: ");
|
||||||
Serial.println(datalayer.battery.status.bms_status);
|
logging.println(datalayer.battery.status.bms_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ETOT_DONE:
|
case ETOT_DONE:
|
||||||
|
|
86
Software/src/devboard/utils/logging.cpp
Normal file
86
Software/src/devboard/utils/logging.cpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#include "logging.h"
|
||||||
|
#include "../../datalayer/datalayer.h"
|
||||||
|
|
||||||
|
size_t Logging::write(const uint8_t* buffer, size_t size) {
|
||||||
|
#ifdef DEBUG_LOG
|
||||||
|
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
|
||||||
|
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
|
||||||
|
unsigned long currentTime = millis();
|
||||||
|
#ifdef DEBUG_VIA_USB
|
||||||
|
size_t n = 0;
|
||||||
|
while (size--) {
|
||||||
|
if (Serial.write(*buffer++))
|
||||||
|
n++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG_VIA_WEB
|
||||||
|
if (datalayer.system.info.can_logging_active) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (offset + size + 13 > sizeof(datalayer.system.info.logged_can_messages)) {
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
if (buffer[0] != '\r' && buffer[0] != '\n' &&
|
||||||
|
(offset == 0 || message_string[offset - 1] == '\r' || message_string[offset - 1] == '\n')) {
|
||||||
|
offset += snprintf(message_string + offset, message_string_size - offset - 1, "%8lu.%03lu ", currentTime / 1000,
|
||||||
|
currentTime % 1000);
|
||||||
|
}
|
||||||
|
memcpy(message_string + offset, buffer, size);
|
||||||
|
datalayer.system.info.logged_can_messages_offset = offset + size; // Update offset in buffer
|
||||||
|
return size;
|
||||||
|
#endif // DEBUG_VIA_WEB
|
||||||
|
#endif // DEBUG_LOG
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logging::printf(const char* fmt, ...) {
|
||||||
|
#ifdef DEBUG_LOG
|
||||||
|
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
|
||||||
|
size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages);
|
||||||
|
#ifdef DEBUG_VIA_USB
|
||||||
|
static char buf[128];
|
||||||
|
message_string = buf;
|
||||||
|
offset = 0;
|
||||||
|
message_string_size = sizeof(buf);
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG_VIA_WEB
|
||||||
|
if (datalayer.system.info.can_logging_active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
message_string = datalayer.system.info.logged_can_messages;
|
||||||
|
offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer
|
||||||
|
message_string_size = sizeof(datalayer.system.info.logged_can_messages);
|
||||||
|
#endif
|
||||||
|
if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) {
|
||||||
|
// Not enough space, reset and start from the beginning
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
unsigned long currentTime = millis();
|
||||||
|
// Add timestamp
|
||||||
|
offset += snprintf(message_string + offset, message_string_size - offset - 1, "%8lu.%03lu ", currentTime / 1000,
|
||||||
|
currentTime % 1000);
|
||||||
|
|
||||||
|
va_list(args);
|
||||||
|
va_start(args, fmt);
|
||||||
|
offset += vsnprintf(message_string + offset, message_string_size - offset - 1, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (datalayer.system.info.can_logging_active) {
|
||||||
|
size_t size = offset;
|
||||||
|
size_t n = 0;
|
||||||
|
while (size--) {
|
||||||
|
if (Serial.write(*message_string++))
|
||||||
|
n++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer
|
||||||
|
}
|
||||||
|
#endif // DEBUG_LOG
|
||||||
|
}
|
16
Software/src/devboard/utils/logging.h
Normal file
16
Software/src/devboard/utils/logging.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef __LOGGING_H__
|
||||||
|
#define __LOGGING_H__
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "Print.h"
|
||||||
|
|
||||||
|
class Logging : public Print {
|
||||||
|
public:
|
||||||
|
virtual size_t write(const uint8_t* buffer, size_t size);
|
||||||
|
virtual size_t write(uint8_t) { return 0; }
|
||||||
|
void printf(const char* fmt, ...);
|
||||||
|
Logging() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Logging logging;
|
||||||
|
#endif // __LOGGING_H__
|
|
@ -20,6 +20,44 @@ String advanced_battery_processor(const String& var) {
|
||||||
// Start a new block with a specific background color
|
// Start a new block with a specific background color
|
||||||
content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px;border-radius: 50px'>";
|
content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px;border-radius: 50px'>";
|
||||||
|
|
||||||
|
#ifdef BOLT_AMPERA_BATTERY
|
||||||
|
content += "<h4>5V Reference: " + String(datalayer_extended.boltampera.battery_5V_ref) + "</h4>";
|
||||||
|
content += "<h4>Module 1 temp: " + String(datalayer_extended.boltampera.battery_module_temp_1) + "</h4>";
|
||||||
|
content += "<h4>Module 2 temp: " + String(datalayer_extended.boltampera.battery_module_temp_2) + "</h4>";
|
||||||
|
content += "<h4>Module 3 temp: " + String(datalayer_extended.boltampera.battery_module_temp_3) + "</h4>";
|
||||||
|
content += "<h4>Module 4 temp: " + String(datalayer_extended.boltampera.battery_module_temp_4) + "</h4>";
|
||||||
|
content += "<h4>Module 5 temp: " + String(datalayer_extended.boltampera.battery_module_temp_5) + "</h4>";
|
||||||
|
content += "<h4>Module 6 temp: " + String(datalayer_extended.boltampera.battery_module_temp_6) + "</h4>";
|
||||||
|
content +=
|
||||||
|
"<h4>Cell average voltage: " + String(datalayer_extended.boltampera.battery_cell_average_voltage) + "</h4>";
|
||||||
|
content +=
|
||||||
|
"<h4>Cell average voltage 2: " + String(datalayer_extended.boltampera.battery_cell_average_voltage_2) + "</h4>";
|
||||||
|
content += "<h4>Terminal voltage: " + String(datalayer_extended.boltampera.battery_terminal_voltage) + "</h4>";
|
||||||
|
content +=
|
||||||
|
"<h4>Ignition power mode: " + String(datalayer_extended.boltampera.battery_ignition_power_mode) + "</h4>";
|
||||||
|
content += "<h4>Battery current (7E7): " + String(datalayer_extended.boltampera.battery_current_7E7) + "</h4>";
|
||||||
|
content += "<h4>Capacity MY17-18: " + String(datalayer_extended.boltampera.battery_capacity_my17_18) + "</h4>";
|
||||||
|
content += "<h4>Capacity MY19+: " + String(datalayer_extended.boltampera.battery_capacity_my19plus) + "</h4>";
|
||||||
|
content += "<h4>SOC Display: " + String(datalayer_extended.boltampera.battery_SOC_display) + "</h4>";
|
||||||
|
content += "<h4>SOC Raw highprec: " + String(datalayer_extended.boltampera.battery_SOC_raw_highprec) + "</h4>";
|
||||||
|
content += "<h4>Max temp: " + String(datalayer_extended.boltampera.battery_max_temperature) + "</h4>";
|
||||||
|
content += "<h4>Min temp: " + String(datalayer_extended.boltampera.battery_min_temperature) + "</h4>";
|
||||||
|
content += "<h4>Cell max mV: " + String(datalayer_extended.boltampera.battery_max_cell_voltage) + "</h4>";
|
||||||
|
content += "<h4>Cell min mV: " + String(datalayer_extended.boltampera.battery_min_cell_voltage) + "</h4>";
|
||||||
|
content += "<h4>Lowest cell: " + String(datalayer_extended.boltampera.battery_lowest_cell) + "</h4>";
|
||||||
|
content += "<h4>Highest cell: " + String(datalayer_extended.boltampera.battery_highest_cell) + "</h4>";
|
||||||
|
content +=
|
||||||
|
"<h4>Internal resistance: " + String(datalayer_extended.boltampera.battery_internal_resistance) + "</h4>";
|
||||||
|
content += "<h4>Voltage: " + String(datalayer_extended.boltampera.battery_voltage_polled) + "</h4>";
|
||||||
|
content += "<h4>Isolation Ohm: " + String(datalayer_extended.boltampera.battery_vehicle_isolation) + "</h4>";
|
||||||
|
content += "<h4>Isolation kOhm: " + String(datalayer_extended.boltampera.battery_isolation_kohm) + "</h4>";
|
||||||
|
content += "<h4>HV locked: " + String(datalayer_extended.boltampera.battery_HV_locked) + "</h4>";
|
||||||
|
content += "<h4>Crash event: " + String(datalayer_extended.boltampera.battery_crash_event) + "</h4>";
|
||||||
|
content += "<h4>HVIL: " + String(datalayer_extended.boltampera.battery_HVIL) + "</h4>";
|
||||||
|
content += "<h4>HVIL status: " + String(datalayer_extended.boltampera.battery_HVIL_status) + "</h4>";
|
||||||
|
content += "<h4>Current (7E4): " + String(datalayer_extended.boltampera.battery_current_7E4) + "</h4>";
|
||||||
|
#endif //BOLT_AMPERA_BATTERY
|
||||||
|
|
||||||
#ifdef BMW_IX_BATTERY
|
#ifdef BMW_IX_BATTERY
|
||||||
content +=
|
content +=
|
||||||
"<h4>Battery Voltage after Contactor: " + String(datalayer_extended.bmwix.battery_voltage_after_contactor) +
|
"<h4>Battery Voltage after Contactor: " + String(datalayer_extended.bmwix.battery_voltage_after_contactor) +
|
||||||
|
@ -983,9 +1021,10 @@ String advanced_battery_processor(const String& var) {
|
||||||
content += "<h4>soc max: " + String(datalayer_extended.zoePH2.battery_soc_max) + "</h4>";
|
content += "<h4>soc max: " + String(datalayer_extended.zoePH2.battery_soc_max) + "</h4>";
|
||||||
#endif //RENAULT_ZOE_GEN2_BATTERY
|
#endif //RENAULT_ZOE_GEN2_BATTERY
|
||||||
|
|
||||||
#if !defined(TESLA_BATTERY) && !defined(NISSAN_LEAF_BATTERY) && !defined(BMW_I3_BATTERY) && \
|
#if !defined(BMW_IX_BATTERY) && !defined(BOLT_AMPERA_BATTERY) && !defined(TESLA_BATTERY) && \
|
||||||
!defined(BYD_ATTO_3_BATTERY) && !defined(RENAULT_ZOE_GEN2_BATTERY) && !defined(CELLPOWER_BMS) && \
|
!defined(NISSAN_LEAF_BATTERY) && !defined(BMW_I3_BATTERY) && !defined(BYD_ATTO_3_BATTERY) && \
|
||||||
!defined(MEB_BATTERY) //Only the listed types have extra info
|
!defined(RENAULT_ZOE_GEN2_BATTERY) && !defined(CELLPOWER_BMS) && \
|
||||||
|
!defined(MEB_BATTERY) // Only the listed types have extra info
|
||||||
content += "No extra information available for this battery type";
|
content += "No extra information available for this battery type";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
String can_logger_processor(const String& var) {
|
String can_logger_processor(const String& var) {
|
||||||
if (var == "X") {
|
if (var == "X") {
|
||||||
|
if (!datalayer.system.info.can_logging_active) {
|
||||||
|
datalayer.system.info.logged_can_messages_offset = 0;
|
||||||
|
datalayer.system.info.logged_can_messages[0] = '\0';
|
||||||
|
}
|
||||||
datalayer.system.info.can_logging_active =
|
datalayer.system.info.can_logging_active =
|
||||||
true; // Signal to main loop that we should log messages. Disabled by default for performance reasons
|
true; // Signal to main loop that we should log messages. Disabled by default for performance reasons
|
||||||
String content = "";
|
String content = "";
|
||||||
|
@ -19,7 +23,7 @@ String can_logger_processor(const String& var) {
|
||||||
"monospace; }";
|
"monospace; }";
|
||||||
content += "</style>";
|
content += "</style>";
|
||||||
content += "<button onclick='refreshPage()'>Refresh data</button> ";
|
content += "<button onclick='refreshPage()'>Refresh data</button> ";
|
||||||
content += "<button onclick='exportLogs()'>Export to .txt</button> ";
|
content += "<button onclick='exportLog()'>Export to .txt</button> ";
|
||||||
content += "<button onclick='stopLoggingAndGoToMainPage()'>Back to main page</button>";
|
content += "<button onclick='stopLoggingAndGoToMainPage()'>Back to main page</button>";
|
||||||
|
|
||||||
// Start a new block for the CAN messages
|
// Start a new block for the CAN messages
|
||||||
|
@ -47,9 +51,9 @@ String can_logger_processor(const String& var) {
|
||||||
// Add JavaScript for navigation
|
// Add JavaScript for navigation
|
||||||
content += "<script>";
|
content += "<script>";
|
||||||
content += "function refreshPage(){ location.reload(true); }";
|
content += "function refreshPage(){ location.reload(true); }";
|
||||||
content += "function exportLogs() { window.location.href = '/export_logs'; }";
|
content += "function exportLog() { window.location.href = '/export_can_log'; }";
|
||||||
content += "function stopLoggingAndGoToMainPage() {";
|
content += "function stopLoggingAndGoToMainPage() {";
|
||||||
content += " fetch('/stop_logging').then(() => window.location.href = '/');";
|
content += " fetch('/stop_can_logging').then(() => window.location.href = '/');";
|
||||||
content += "}";
|
content += "}";
|
||||||
content += "</script>";
|
content += "</script>";
|
||||||
return content;
|
return content;
|
||||||
|
|
36
Software/src/devboard/webserver/debug_logging_html.cpp
Normal file
36
Software/src/devboard/webserver/debug_logging_html.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#include "debug_logging_html.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "../../datalayer/datalayer.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG_VIA_WEB
|
||||||
|
String debug_logger_processor(const String& var) {
|
||||||
|
String content = "";
|
||||||
|
// Page format
|
||||||
|
content += "<style>";
|
||||||
|
content += "body { background-color: black; color: white; font-family: Arial, sans-serif; }";
|
||||||
|
content +=
|
||||||
|
"button { background-color: #505E67; color: white; border: none; padding: 10px 20px; margin-bottom: 20px; "
|
||||||
|
"cursor: pointer; border-radius: 10px; }";
|
||||||
|
content += "button:hover { background-color: #3A4A52; }";
|
||||||
|
content +=
|
||||||
|
".can-message { background-color: #404E57; margin-bottom: 5px; padding: 10px; border-radius: 5px; font-family: "
|
||||||
|
"monospace; }";
|
||||||
|
content += "</style>";
|
||||||
|
content += "<button onclick='refreshPage()'>Refresh data</button> ";
|
||||||
|
content += "<button onclick='exportLog()'>Export to .txt</button> ";
|
||||||
|
content += "<button onclick='goToMainPage()'>Back to main page</button>";
|
||||||
|
|
||||||
|
// Start a new block for the debug log messages
|
||||||
|
content += "<PRE style='text-align: left'>";
|
||||||
|
content += String(datalayer.system.info.logged_can_messages);
|
||||||
|
content += "</PRE>";
|
||||||
|
|
||||||
|
// Add JavaScript for navigation
|
||||||
|
content += "<script>";
|
||||||
|
content += "function refreshPage(){ location.reload(true); }";
|
||||||
|
content += "function exportLog() { window.location.href = '/export_log'; }";
|
||||||
|
content += "function goToMainPage() { window.location.href = '/'; }";
|
||||||
|
content += "</script>";
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
#endif // DEBUG_VIA_WEB
|
16
Software/src/devboard/webserver/debug_logging_html.h
Normal file
16
Software/src/devboard/webserver/debug_logging_html.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef DEBUGLOGGER_H
|
||||||
|
#define DEBUGLOGGER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces placeholder with content section in web page
|
||||||
|
*
|
||||||
|
* @param[in] var
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
String debug_logger_processor(const String& var);
|
||||||
|
|
||||||
|
#endif
|
|
@ -39,11 +39,11 @@ String events_processor(const String& var) {
|
||||||
for (const auto& event : order_events) {
|
for (const auto& event : order_events) {
|
||||||
EVENTS_ENUM_TYPE event_handle = event.event_handle;
|
EVENTS_ENUM_TYPE event_handle = event.event_handle;
|
||||||
event_pointer = event.event_pointer;
|
event_pointer = event.event_pointer;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Event: " + String(get_event_enum_string(event_handle)) +
|
logging.println("Showing Event: " + String(get_event_enum_string(event_handle)) +
|
||||||
" count: " + String(event_pointer->occurences) + " seconds: " + String(event_pointer->timestamp) +
|
" count: " + String(event_pointer->occurences) + " seconds: " + String(event_pointer->timestamp) +
|
||||||
" data: " + String(event_pointer->data) +
|
" data: " + String(event_pointer->data) +
|
||||||
" level: " + String(get_event_level_string(event_handle)));
|
" level: " + String(get_event_level_string(event_handle)));
|
||||||
#endif
|
#endif
|
||||||
content.concat("<div class='event'>");
|
content.concat("<div class='event'>");
|
||||||
content.concat("<div>" + String(get_event_enum_string(event_handle)) + "</div>");
|
content.concat("<div>" + String(get_event_enum_string(event_handle)) + "</div>");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "webserver.h"
|
#include "webserver.h"
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include "../../../USER_SECRETS.h"
|
||||||
#include "../../datalayer/datalayer.h"
|
#include "../../datalayer/datalayer.h"
|
||||||
#include "../../datalayer/datalayer_extended.h"
|
#include "../../datalayer/datalayer_extended.h"
|
||||||
#include "../../lib/bblanchon-ArduinoJson/ArduinoJson.h"
|
#include "../../lib/bblanchon-ArduinoJson/ArduinoJson.h"
|
||||||
|
@ -17,6 +18,7 @@ unsigned long ota_progress_millis = 0;
|
||||||
#include "advanced_battery_html.h"
|
#include "advanced_battery_html.h"
|
||||||
#include "can_logging_html.h"
|
#include "can_logging_html.h"
|
||||||
#include "cellmonitor_html.h"
|
#include "cellmonitor_html.h"
|
||||||
|
#include "debug_logging_html.h"
|
||||||
#include "events_html.h"
|
#include "events_html.h"
|
||||||
#include "index_html.cpp"
|
#include "index_html.cpp"
|
||||||
#include "settings_html.h"
|
#include "settings_html.h"
|
||||||
|
@ -63,14 +65,21 @@ void init_webserver() {
|
||||||
request->send_P(200, "text/html", index_html, can_logger_processor);
|
request->send_P(200, "text/html", index_html, can_logger_processor);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Define the handler to stop logging
|
#ifdef DEBUG_VIA_WEB
|
||||||
server.on("/stop_logging", HTTP_GET, [](AsyncWebServerRequest* request) {
|
// Route for going to debug logging web page
|
||||||
|
server.on("/log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
request->send_P(200, "text/html", index_html, debug_logger_processor);
|
||||||
|
});
|
||||||
|
#endif // DEBUG_VIA_WEB
|
||||||
|
|
||||||
|
// Define the handler to stop can logging
|
||||||
|
server.on("/stop_can_logging", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
datalayer.system.info.can_logging_active = false;
|
datalayer.system.info.can_logging_active = false;
|
||||||
request->send_P(200, "text/plain", "Logging stopped");
|
request->send_P(200, "text/plain", "Logging stopped");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Define the handler to export logs
|
// Define the handler to export can log
|
||||||
server.on("/export_logs", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/export_can_log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
String logs = String(datalayer.system.info.logged_can_messages);
|
String logs = String(datalayer.system.info.logged_can_messages);
|
||||||
if (logs.length() == 0) {
|
if (logs.length() == 0) {
|
||||||
logs = "No logs available.";
|
logs = "No logs available.";
|
||||||
|
@ -96,6 +105,33 @@ void init_webserver() {
|
||||||
request->send(response);
|
request->send(response);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Define the handler to export debug log
|
||||||
|
server.on("/export_log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
String logs = String(datalayer.system.info.logged_can_messages);
|
||||||
|
if (logs.length() == 0) {
|
||||||
|
logs = "No logs available.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current time
|
||||||
|
time_t now = time(nullptr);
|
||||||
|
struct tm timeinfo;
|
||||||
|
localtime_r(&now, &timeinfo);
|
||||||
|
|
||||||
|
// Ensure time retrieval was successful
|
||||||
|
char filename[32];
|
||||||
|
if (strftime(filename, sizeof(filename), "log_%H-%M-%S.txt", &timeinfo)) {
|
||||||
|
// Valid filename created
|
||||||
|
} else {
|
||||||
|
// Fallback filename if automatic timestamping failed
|
||||||
|
strcpy(filename, "battery_emulator_log.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use request->send with dynamic headers
|
||||||
|
AsyncWebServerResponse* response = request->beginResponse(200, "text/plain", logs);
|
||||||
|
response->addHeader("Content-Disposition", String("attachment; filename=\"") + String(filename) + "\"");
|
||||||
|
request->send(response);
|
||||||
|
});
|
||||||
|
|
||||||
// Route for going to cellmonitor web page
|
// Route for going to cellmonitor web page
|
||||||
server.on("/cellmonitor", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/cellmonitor", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
|
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
|
||||||
|
@ -535,14 +571,15 @@ String processor(const String& var) {
|
||||||
content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px;border-radius: 50px'>";
|
content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px;border-radius: 50px'>";
|
||||||
|
|
||||||
// Show version number
|
// Show version number
|
||||||
content += "<h4>Software: " + String(version_number) + "</h4>";
|
content += "<h4>Software: " + String(version_number);
|
||||||
// Show hardware used:
|
// Show hardware used:
|
||||||
#ifdef HW_LILYGO
|
#ifdef HW_LILYGO
|
||||||
content += "<h4>Hardware: LilyGo T-CAN485</h4>";
|
content += " Hardware: LilyGo T-CAN485";
|
||||||
#endif // HW_LILYGO
|
#endif // HW_LILYGO
|
||||||
#ifdef HW_STARK
|
#ifdef HW_STARK
|
||||||
content += "<h4>Hardware: Stark CMR Module</h4>";
|
content += " Hardware: Stark CMR Module";
|
||||||
#endif // HW_STARK
|
#endif // HW_STARK
|
||||||
|
content += "</h4>";
|
||||||
content += "<h4>Uptime: " + uptime_formatter::getUptime() + "</h4>";
|
content += "<h4>Uptime: " + uptime_formatter::getUptime() + "</h4>";
|
||||||
#ifdef FUNCTION_TIME_MEASUREMENT
|
#ifdef FUNCTION_TIME_MEASUREMENT
|
||||||
// Load information
|
// Load information
|
||||||
|
@ -566,11 +603,14 @@ String processor(const String& var) {
|
||||||
|
|
||||||
wl_status_t status = WiFi.status();
|
wl_status_t status = WiFi.status();
|
||||||
// Display ssid of network connected to and, if connected to the WiFi, its own IP
|
// Display ssid of network connected to and, if connected to the WiFi, its own IP
|
||||||
content += "<h4>SSID: " + String(ssid.c_str()) + "</h4>";
|
content += "<h4>SSID: " + String(ssid.c_str());
|
||||||
|
if (status == WL_CONNECTED) {
|
||||||
|
// Get and display the signal strength (RSSI) and channel
|
||||||
|
content += " RSSI:" + String(WiFi.RSSI()) + " dBm Ch: " + String(WiFi.channel());
|
||||||
|
}
|
||||||
|
content += "</h4>";
|
||||||
if (status == WL_CONNECTED) {
|
if (status == WL_CONNECTED) {
|
||||||
content += "<h4>IP: " + WiFi.localIP().toString() + "</h4>";
|
content += "<h4>IP: " + WiFi.localIP().toString() + "</h4>";
|
||||||
// Get and display the signal strength (RSSI) and channel
|
|
||||||
content += "<h4>Signal strength: " + String(WiFi.RSSI()) + " dBm, at channel " + String(WiFi.channel()) + "</h4>";
|
|
||||||
} else {
|
} else {
|
||||||
content += "<h4>Wifi state: " + getConnectResultString(status) + "</h4>";
|
content += "<h4>Wifi state: " + getConnectResultString(status) + "</h4>";
|
||||||
}
|
}
|
||||||
|
@ -692,13 +732,30 @@ String processor(const String& var) {
|
||||||
}
|
}
|
||||||
content += "<h4>Temperature max: " + String(tempMaxFloat, 1) + " C</h4>";
|
content += "<h4>Temperature max: " + String(tempMaxFloat, 1) + " C</h4>";
|
||||||
content += "<h4>Temperature min: " + String(tempMinFloat, 1) + " C</h4>";
|
content += "<h4>Temperature min: " + String(tempMinFloat, 1) + " C</h4>";
|
||||||
if (datalayer.battery.status.bms_status == ACTIVE) {
|
|
||||||
content += "<h4>System status: OK </h4>";
|
content += "<h4>System status: ";
|
||||||
} else if (datalayer.battery.status.bms_status == UPDATING) {
|
switch (datalayer.battery.status.bms_status) {
|
||||||
content += "<h4>System status: UPDATING </h4>";
|
case ACTIVE:
|
||||||
} else {
|
content += String("OK");
|
||||||
content += "<h4>System status: FAULT </h4>";
|
break;
|
||||||
|
case UPDATING:
|
||||||
|
content += String("UPDATING");
|
||||||
|
break;
|
||||||
|
case FAULT:
|
||||||
|
content += String("FAULT");
|
||||||
|
break;
|
||||||
|
case INACTIVE:
|
||||||
|
content += String("INACTIVE");
|
||||||
|
break;
|
||||||
|
case STANDBY:
|
||||||
|
content += String("STANDBY");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
content += String("??");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
content += "</h4>";
|
||||||
|
|
||||||
if (datalayer.battery.status.current_dA == 0) {
|
if (datalayer.battery.status.current_dA == 0) {
|
||||||
content += "<h4>Battery idle</h4>";
|
content += "<h4>Battery idle</h4>";
|
||||||
} else if (datalayer.battery.status.current_dA < 0) {
|
} else if (datalayer.battery.status.current_dA < 0) {
|
||||||
|
@ -977,6 +1034,9 @@ String processor(const String& var) {
|
||||||
content += "<button onclick='Settings()'>Change Settings</button> ";
|
content += "<button onclick='Settings()'>Change Settings</button> ";
|
||||||
content += "<button onclick='Advanced()'>More Battery Info</button> ";
|
content += "<button onclick='Advanced()'>More Battery Info</button> ";
|
||||||
content += "<button onclick='CANlog()'>CAN logger</button> ";
|
content += "<button onclick='CANlog()'>CAN logger</button> ";
|
||||||
|
#ifdef DEBUG_VIA_WEB
|
||||||
|
content += "<button onclick='Log()'>Log</button> ";
|
||||||
|
#endif // DEBUG_VIA_WEB
|
||||||
content += "<button onclick='Cellmon()'>Cellmonitor</button> ";
|
content += "<button onclick='Cellmon()'>Cellmonitor</button> ";
|
||||||
content += "<button onclick='Events()'>Events</button> ";
|
content += "<button onclick='Events()'>Events</button> ";
|
||||||
content += "<button onclick='askReboot()'>Reboot Emulator</button>";
|
content += "<button onclick='askReboot()'>Reboot Emulator</button>";
|
||||||
|
@ -1002,6 +1062,7 @@ String processor(const String& var) {
|
||||||
content += "function Settings() { window.location.href = '/settings'; }";
|
content += "function Settings() { window.location.href = '/settings'; }";
|
||||||
content += "function Advanced() { window.location.href = '/advanced'; }";
|
content += "function Advanced() { window.location.href = '/advanced'; }";
|
||||||
content += "function CANlog() { window.location.href = '/canlog'; }";
|
content += "function CANlog() { window.location.href = '/canlog'; }";
|
||||||
|
content += "function Log() { window.location.href = '/log'; }";
|
||||||
content += "function Events() { window.location.href = '/events'; }";
|
content += "function Events() { window.location.href = '/events'; }";
|
||||||
content +=
|
content +=
|
||||||
"function askReboot() { if (window.confirm('Are you sure you want to reboot the emulator? NOTE: If "
|
"function askReboot() { if (window.confirm('Are you sure you want to reboot the emulator? NOTE: If "
|
||||||
|
@ -1062,9 +1123,9 @@ void onOTAProgress(size_t current, size_t final) {
|
||||||
// Log every 1 second
|
// Log every 1 second
|
||||||
if (millis() - ota_progress_millis > 1000) {
|
if (millis() - ota_progress_millis > 1000) {
|
||||||
ota_progress_millis = millis();
|
ota_progress_millis = millis();
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
|
logging.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
// Reset the "watchdog"
|
// Reset the "watchdog"
|
||||||
ota_timeout_timer.reset();
|
ota_timeout_timer.reset();
|
||||||
}
|
}
|
||||||
|
@ -1081,13 +1142,13 @@ void onOTAEnd(bool success) {
|
||||||
// Max Charge/Discharge = 0; CAN = stop; contactors = open
|
// Max Charge/Discharge = 0; CAN = stop; contactors = open
|
||||||
setBatteryPause(true, true, true, false);
|
setBatteryPause(true, true, true, false);
|
||||||
// a reboot will be done by the OTA library. no need to do anything here
|
// a reboot will be done by the OTA library. no need to do anything here
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("OTA update finished successfully!");
|
logging.println("OTA update finished successfully!");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("There was an error during OTA update!");
|
logging.println("There was an error during OTA update!");
|
||||||
#endif // DEBUG_VIA_USB
|
#endif // DEBUG_LOG
|
||||||
//try to Resume the battery pause and CAN communication
|
//try to Resume the battery pause and CAN communication
|
||||||
setBatteryPause(false, false);
|
setBatteryPause(false, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,28 +72,28 @@ void wifi_monitor() {
|
||||||
// Increase the current check interval if it's not at the maximum
|
// Increase the current check interval if it's not at the maximum
|
||||||
if (current_check_interval + STEP_WIFI_CHECK_INTERVAL <= MAX_STEP_WIFI_CHECK_INTERVAL)
|
if (current_check_interval + STEP_WIFI_CHECK_INTERVAL <= MAX_STEP_WIFI_CHECK_INTERVAL)
|
||||||
current_check_interval += STEP_WIFI_CHECK_INTERVAL;
|
current_check_interval += STEP_WIFI_CHECK_INTERVAL;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Wi-Fi not connected, attempting to reconnect...");
|
logging.println("Wi-Fi not connected, attempting to reconnect...");
|
||||||
#endif
|
#endif
|
||||||
// Try WiFi.reconnect() if it was successfully connected at least once
|
// Try WiFi.reconnect() if it was successfully connected at least once
|
||||||
if (hasConnectedBefore) {
|
if (hasConnectedBefore) {
|
||||||
lastReconnectAttempt = millis(); // Reset reconnection attempt timer
|
lastReconnectAttempt = millis(); // Reset reconnection attempt timer
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Wi-Fi reconnect attempt...");
|
logging.println("Wi-Fi reconnect attempt...");
|
||||||
#endif
|
#endif
|
||||||
if (WiFi.reconnect()) {
|
if (WiFi.reconnect()) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Wi-Fi reconnect attempt sucess...");
|
logging.println("Wi-Fi reconnect attempt sucess...");
|
||||||
#endif
|
#endif
|
||||||
reconnectAttempts = 0; // Reset the attempt counter on successful reconnect
|
reconnectAttempts = 0; // Reset the attempt counter on successful reconnect
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Wi-Fi reconnect attempt error...");
|
logging.println("Wi-Fi reconnect attempt error...");
|
||||||
#endif
|
#endif
|
||||||
reconnectAttempts++;
|
reconnectAttempts++;
|
||||||
if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Failed to reconnect multiple times, forcing a full connection attempt...");
|
logging.println("Failed to reconnect multiple times, forcing a full connection attempt...");
|
||||||
#endif
|
#endif
|
||||||
FullReconnectToWiFi();
|
FullReconnectToWiFi();
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,8 @@ void wifi_monitor() {
|
||||||
} else {
|
} else {
|
||||||
// If no previous connection, force a full connection attempt
|
// If no previous connection, force a full connection attempt
|
||||||
if (currentMillis - lastReconnectAttempt > current_full_reconnect_interval) {
|
if (currentMillis - lastReconnectAttempt > current_full_reconnect_interval) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("No previous OK connection, force a full connection attempt...");
|
logging.println("No previous OK connection, force a full connection attempt...");
|
||||||
#endif
|
#endif
|
||||||
FullReconnectToWiFi();
|
FullReconnectToWiFi();
|
||||||
}
|
}
|
||||||
|
@ -127,13 +127,13 @@ static void FullReconnectToWiFi() {
|
||||||
static void connectToWiFi() {
|
static void connectToWiFi() {
|
||||||
if (WiFi.status() != WL_CONNECTED) {
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
lastReconnectAttempt = millis(); // Reset the reconnect attempt timer
|
lastReconnectAttempt = millis(); // Reset the reconnect attempt timer
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Connecting to Wi-Fi...");
|
logging.println("Connecting to Wi-Fi...");
|
||||||
#endif
|
#endif
|
||||||
WiFi.begin(ssid.c_str(), password.c_str(), wifi_channel);
|
WiFi.begin(ssid.c_str(), password.c_str(), wifi_channel);
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Wi-Fi already connected.");
|
logging.println("Wi-Fi already connected.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,10 +143,11 @@ static void onWifiConnect(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||||
clear_event(EVENT_WIFI_DISCONNECT);
|
clear_event(EVENT_WIFI_DISCONNECT);
|
||||||
set_event(EVENT_WIFI_CONNECT, 0);
|
set_event(EVENT_WIFI_CONNECT, 0);
|
||||||
connected_once = true;
|
connected_once = true;
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Wi-Fi connected.");
|
logging.print("Wi-Fi connected. RSSI: ");
|
||||||
Serial.print("IP address: ");
|
logging.print(-WiFi.RSSI());
|
||||||
Serial.println(WiFi.localIP());
|
logging.print(" dBm, IP address: ");
|
||||||
|
logging.println(WiFi.localIP().toString());
|
||||||
#endif
|
#endif
|
||||||
hasConnectedBefore = true; // Mark as successfully connected at least once
|
hasConnectedBefore = true; // Mark as successfully connected at least once
|
||||||
reconnectAttempts = 0; // Reset the attempt counter
|
reconnectAttempts = 0; // Reset the attempt counter
|
||||||
|
@ -159,10 +160,10 @@ static void onWifiConnect(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||||
static void onWifiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
static void onWifiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||||
//clear disconnects events if we got a IP
|
//clear disconnects events if we got a IP
|
||||||
clear_event(EVENT_WIFI_DISCONNECT);
|
clear_event(EVENT_WIFI_DISCONNECT);
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Wi-Fi Got IP.");
|
logging.print("Wi-Fi Got IP. ");
|
||||||
Serial.print("IP address: ");
|
logging.print("IP address: ");
|
||||||
Serial.println(WiFi.localIP());
|
logging.println(WiFi.localIP().toString());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +171,8 @@ static void onWifiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||||
static void onWifiDisconnect(WiFiEvent_t event, WiFiEventInfo_t info) {
|
static void onWifiDisconnect(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||||
if (connected_once)
|
if (connected_once)
|
||||||
set_event(EVENT_WIFI_DISCONNECT, 0);
|
set_event(EVENT_WIFI_DISCONNECT, 0);
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Wi-Fi disconnected.");
|
logging.println("Wi-Fi disconnected.");
|
||||||
#endif
|
#endif
|
||||||
//we dont do anything here, the reconnect will be handled by the monitor
|
//we dont do anything here, the reconnect will be handled by the monitor
|
||||||
//too many events received when the connection is lost
|
//too many events received when the connection is lost
|
||||||
|
@ -188,8 +189,8 @@ void init_mDNS() {
|
||||||
|
|
||||||
// Initialize mDNS .local resolution
|
// Initialize mDNS .local resolution
|
||||||
if (!MDNS.begin(mdnsHost)) {
|
if (!MDNS.begin(mdnsHost)) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Error setting up MDNS responder!");
|
logging.println("Error setting up MDNS responder!");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// Advertise via bonjour the service so we can auto discover these battery emulators on the local network.
|
// Advertise via bonjour the service so we can auto discover these battery emulators on the local network.
|
||||||
|
@ -200,16 +201,16 @@ void init_mDNS() {
|
||||||
|
|
||||||
#ifdef WIFIAP
|
#ifdef WIFIAP
|
||||||
void init_WiFi_AP() {
|
void init_WiFi_AP() {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Creating Access Point: " + String(ssidAP));
|
logging.println("Creating Access Point: " + String(ssidAP));
|
||||||
Serial.println("With password: " + String(passwordAP));
|
logging.println("With password: " + String(passwordAP));
|
||||||
#endif
|
#endif
|
||||||
WiFi.softAP(ssidAP, passwordAP);
|
WiFi.softAP(ssidAP, passwordAP);
|
||||||
IPAddress IP = WiFi.softAPIP();
|
IPAddress IP = WiFi.softAPIP();
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Access Point created.");
|
logging.println("Access Point created.");
|
||||||
Serial.print("IP address: ");
|
logging.print("IP address: ");
|
||||||
Serial.println(IP);
|
logging.println(IP);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif // WIFIAP
|
#endif // WIFIAP
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "devboard/hal/hal.h"
|
#include "devboard/hal/hal.h"
|
||||||
#include "devboard/safety/safety.h"
|
#include "devboard/safety/safety.h"
|
||||||
|
#include "devboard/utils/logging.h"
|
||||||
#include "devboard/utils/time_meas.h"
|
#include "devboard/utils/time_meas.h"
|
||||||
#include "devboard/utils/types.h"
|
#include "devboard/utils/types.h"
|
||||||
|
|
||||||
|
|
|
@ -153,13 +153,13 @@ void update_values_can_inverter() { //This function maps all the values fetched
|
||||||
BYD_210.data.u8[2] = (datalayer.battery.status.temperature_min_dC >> 8);
|
BYD_210.data.u8[2] = (datalayer.battery.status.temperature_min_dC >> 8);
|
||||||
BYD_210.data.u8[3] = (datalayer.battery.status.temperature_min_dC & 0x00FF);
|
BYD_210.data.u8[3] = (datalayer.battery.status.temperature_min_dC & 0x00FF);
|
||||||
|
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
if (inverter_name[0] != 0) {
|
if (inverter_name[0] != 0) {
|
||||||
Serial.print("Detected inverter: ");
|
logging.print("Detected inverter: ");
|
||||||
for (uint8_t i = 0; i < 7; i++) {
|
for (uint8_t i = 0; i < 7; i++) {
|
||||||
Serial.print((char)inverter_name[i]);
|
logging.print((char)inverter_name[i]);
|
||||||
}
|
}
|
||||||
Serial.println();
|
logging.println();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,8 +595,8 @@ void send_can_inverter() { // This function loops as fast as possible
|
||||||
// Send a subset of messages per iteration to avoid overloading the CAN bus / transmit buffer
|
// Send a subset of messages per iteration to avoid overloading the CAN bus / transmit buffer
|
||||||
switch (can_message_cellvolt_index) {
|
switch (can_message_cellvolt_index) {
|
||||||
case 0:
|
case 0:
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Sending large batch");
|
logging.println("Sending large batch");
|
||||||
#endif
|
#endif
|
||||||
transmit_can(&FOXESS_0C1D, can_config.inverter);
|
transmit_can(&FOXESS_0C1D, can_config.inverter);
|
||||||
transmit_can(&FOXESS_0C21, can_config.inverter);
|
transmit_can(&FOXESS_0C21, can_config.inverter);
|
||||||
|
@ -655,8 +655,8 @@ void send_can_inverter() { // This function loops as fast as possible
|
||||||
transmit_can(&FOXESS_0D49, can_config.inverter);
|
transmit_can(&FOXESS_0D49, can_config.inverter);
|
||||||
transmit_can(&FOXESS_0D51, can_config.inverter);
|
transmit_can(&FOXESS_0D51, can_config.inverter);
|
||||||
transmit_can(&FOXESS_0D59, can_config.inverter);
|
transmit_can(&FOXESS_0D59, can_config.inverter);
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Sending completed");
|
logging.println("Sending completed");
|
||||||
#endif
|
#endif
|
||||||
send_cellvoltages = false;
|
send_cellvoltages = false;
|
||||||
break;
|
break;
|
||||||
|
@ -679,14 +679,14 @@ void receive_can_inverter(CAN_frame rx_frame) {
|
||||||
if (rx_frame.data.u8[0] == 0x03) { //0x1871 [0x03, 0x06, 0x17, 0x05, 0x09, 0x09, 0x28, 0x22]
|
if (rx_frame.data.u8[0] == 0x03) { //0x1871 [0x03, 0x06, 0x17, 0x05, 0x09, 0x09, 0x28, 0x22]
|
||||||
//This message is sent by the inverter every '6' seconds (0.5s after the pack serial numbers)
|
//This message is sent by the inverter every '6' seconds (0.5s after the pack serial numbers)
|
||||||
//and contains a timestamp in bytes 2-7 i.e. <YY>,<MM>,<DD>,<HH>,<mm>,<ss>
|
//and contains a timestamp in bytes 2-7 i.e. <YY>,<MM>,<DD>,<HH>,<mm>,<ss>
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Inverter sends current time and date");
|
logging.println("Inverter sends current time and date");
|
||||||
#endif
|
#endif
|
||||||
} else if (rx_frame.data.u8[0] == 0x01) {
|
} else if (rx_frame.data.u8[0] == 0x01) {
|
||||||
if (rx_frame.data.u8[4] == 0x00) {
|
if (rx_frame.data.u8[4] == 0x00) {
|
||||||
// Inverter wants to know bms info (every 1s)
|
// Inverter wants to know bms info (every 1s)
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Inverter requests 1s BMS info, we reply");
|
logging.println("Inverter requests 1s BMS info, we reply");
|
||||||
#endif
|
#endif
|
||||||
transmit_can(&FOXESS_1872, can_config.inverter);
|
transmit_can(&FOXESS_1872, can_config.inverter);
|
||||||
transmit_can(&FOXESS_1873, can_config.inverter);
|
transmit_can(&FOXESS_1873, can_config.inverter);
|
||||||
|
@ -698,8 +698,8 @@ void receive_can_inverter(CAN_frame rx_frame) {
|
||||||
transmit_can(&FOXESS_1879, can_config.inverter);
|
transmit_can(&FOXESS_1879, can_config.inverter);
|
||||||
} else if (rx_frame.data.u8[4] == 0x01) { // b4 0x01 , 0x1871 [0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
|
} else if (rx_frame.data.u8[4] == 0x01) { // b4 0x01 , 0x1871 [0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
|
||||||
//Inverter wants to know all individual cellvoltages (occurs 6 seconds after valid BMS reply)
|
//Inverter wants to know all individual cellvoltages (occurs 6 seconds after valid BMS reply)
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Inverter requests individual battery pack status, we reply");
|
logging.println("Inverter requests individual battery pack status, we reply");
|
||||||
#endif
|
#endif
|
||||||
transmit_can(&FOXESS_0C05, can_config.inverter); //TODO, should we limit this incase NUMBER_OF_PACKS =! 8?
|
transmit_can(&FOXESS_0C05, can_config.inverter); //TODO, should we limit this incase NUMBER_OF_PACKS =! 8?
|
||||||
transmit_can(&FOXESS_0C06, can_config.inverter);
|
transmit_can(&FOXESS_0C06, can_config.inverter);
|
||||||
|
@ -711,19 +711,19 @@ void receive_can_inverter(CAN_frame rx_frame) {
|
||||||
transmit_can(&FOXESS_0C0C, can_config.inverter);
|
transmit_can(&FOXESS_0C0C, can_config.inverter);
|
||||||
} else if (rx_frame.data.u8[4] == 0x04) { // b4 0x01 , 0x1871 [0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
|
} else if (rx_frame.data.u8[4] == 0x04) { // b4 0x01 , 0x1871 [0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
|
||||||
//Inverter wants to know all individual cellvoltages (occurs 6 seconds after valid BMS reply)
|
//Inverter wants to know all individual cellvoltages (occurs 6 seconds after valid BMS reply)
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Inverter requests cellvoltages and temps, we reply");
|
logging.println("Inverter requests cellvoltages and temps, we reply");
|
||||||
#endif
|
#endif
|
||||||
send_cellvoltages = true;
|
send_cellvoltages = true;
|
||||||
}
|
}
|
||||||
} else if (rx_frame.data.u8[0] == 0x02) { //0x1871 [0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
|
} else if (rx_frame.data.u8[0] == 0x02) { //0x1871 [0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00]
|
||||||
// Ack message
|
// Ack message
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Inverter acks, no reply needed");
|
logging.println("Inverter acks, no reply needed");
|
||||||
#endif
|
#endif
|
||||||
} else if (rx_frame.data.u8[0] == 0x05) { //0x1871 [0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
|
} else if (rx_frame.data.u8[0] == 0x05) { //0x1871 [0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Inverter wants to know serial numbers, we reply");
|
logging.println("Inverter wants to know serial numbers, we reply");
|
||||||
#endif
|
#endif
|
||||||
for (uint8_t i = 0; i < (NUMBER_OF_PACKS + 1); i++) {
|
for (uint8_t i = 0; i < (NUMBER_OF_PACKS + 1); i++) {
|
||||||
FOXESS_1881.data.u8[0] = (uint8_t)i;
|
FOXESS_1881.data.u8[0] = (uint8_t)i;
|
||||||
|
|
|
@ -119,15 +119,15 @@ void float2frameMSB(byte* arr, float value, byte framepointer) {
|
||||||
|
|
||||||
void send_kostal(byte* arr, int alen) {
|
void send_kostal(byte* arr, int alen) {
|
||||||
#ifdef DEBUG_KOSTAL_RS485_DATA
|
#ifdef DEBUG_KOSTAL_RS485_DATA
|
||||||
Serial.print("TX: ");
|
logging.print("TX: ");
|
||||||
for (int i = 0; i < alen; i++) {
|
for (int i = 0; i < alen; i++) {
|
||||||
if (arr[i] < 0x10) {
|
if (arr[i] < 0x10) {
|
||||||
Serial.print("0");
|
logging.print("0");
|
||||||
}
|
}
|
||||||
Serial.print(arr[i], HEX);
|
logging.print(arr[i], HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
}
|
}
|
||||||
Serial.println("\n");
|
logging.println("\n");
|
||||||
#endif
|
#endif
|
||||||
Serial2.write(arr, alen);
|
Serial2.write(arr, alen);
|
||||||
}
|
}
|
||||||
|
@ -274,12 +274,12 @@ void receive_RS485() // Runs as fast as possible to handle the serial stream
|
||||||
if (RS485_RXFRAME[rx_index - 1] == 0x00) {
|
if (RS485_RXFRAME[rx_index - 1] == 0x00) {
|
||||||
if ((rx_index == 10) && (RS485_RXFRAME[0] == 0x09) && register_content_ok) {
|
if ((rx_index == 10) && (RS485_RXFRAME[0] == 0x09) && register_content_ok) {
|
||||||
#ifdef DEBUG_KOSTAL_RS485_DATA
|
#ifdef DEBUG_KOSTAL_RS485_DATA
|
||||||
Serial.print("RX: ");
|
logging.print("RX: ");
|
||||||
for (uint8_t i = 0; i < 10; i++) {
|
for (uint8_t i = 0; i < 10; i++) {
|
||||||
Serial.print(RS485_RXFRAME[i], HEX);
|
logging.print(RS485_RXFRAME[i], HEX);
|
||||||
Serial.print(" ");
|
logging.print(" ");
|
||||||
}
|
}
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
#endif
|
#endif
|
||||||
rx_index = 0;
|
rx_index = 0;
|
||||||
if (check_kostal_frame_crc()) {
|
if (check_kostal_frame_crc()) {
|
||||||
|
|
|
@ -60,8 +60,8 @@ void manageSerialLinkTransmitter() {
|
||||||
}
|
}
|
||||||
bool sendError = dataLinkTransmit.checkTransmissionError(true);
|
bool sendError = dataLinkTransmit.checkTransmissionError(true);
|
||||||
if (sendError) {
|
if (sendError) {
|
||||||
Serial.print(currentTime);
|
logging.print(currentTime);
|
||||||
Serial.println(" - ERROR: Serial Data Link - SEND Error");
|
logging.println(" - ERROR: Serial Data Link - SEND Error");
|
||||||
lasterror = true;
|
lasterror = true;
|
||||||
transmitGoodSince = currentTime;
|
transmitGoodSince = currentTime;
|
||||||
}
|
}
|
||||||
|
@ -82,17 +82,17 @@ void manageSerialLinkTransmitter() {
|
||||||
|
|
||||||
if (lasterror && (ackReceived > 0)) {
|
if (lasterror && (ackReceived > 0)) {
|
||||||
lasterror = false;
|
lasterror = false;
|
||||||
Serial.print(currentTime);
|
logging.print(currentTime);
|
||||||
Serial.println(" - RECOVERY: Serial Data Link - Send GOOD");
|
logging.println(" - RECOVERY: Serial Data Link - Send GOOD");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--- reporting every 60 seconds that transmission is good
|
//--- reporting every 60 seconds that transmission is good
|
||||||
if (currentTime - transmitGoodSince > INTERVAL_60_S) {
|
if (currentTime - transmitGoodSince > INTERVAL_60_S) {
|
||||||
transmitGoodSince = currentTime;
|
transmitGoodSince = currentTime;
|
||||||
Serial.print(currentTime);
|
logging.print(currentTime);
|
||||||
Serial.println(" - Transmit Good");
|
logging.println(" - Transmit Good");
|
||||||
// printUsefullData();
|
// printUsefullData();
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
void printSendingValues();
|
void printSendingValues();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -100,13 +100,13 @@ void manageSerialLinkTransmitter() {
|
||||||
//--- report that Errors been ocurring for > 60 seconds
|
//--- report that Errors been ocurring for > 60 seconds
|
||||||
if (currentTime - lastGood > INTERVAL_60_S) {
|
if (currentTime - lastGood > INTERVAL_60_S) {
|
||||||
lastGood = currentTime;
|
lastGood = currentTime;
|
||||||
Serial.print(currentTime);
|
logging.print(currentTime);
|
||||||
Serial.println(" - Transmit Failed : 60 seconds");
|
logging.println(" - Transmit Failed : 60 seconds");
|
||||||
// print the max_ data
|
// print the max_ data
|
||||||
Serial.println("SerialDataLink : bms_status=4");
|
logging.println("SerialDataLink : bms_status=4");
|
||||||
Serial.println("SerialDataLink : LEDcolor = RED");
|
logging.println("SerialDataLink : LEDcolor = RED");
|
||||||
Serial.println("SerialDataLink : max_target_discharge_power = 0");
|
logging.println("SerialDataLink : max_target_discharge_power = 0");
|
||||||
Serial.println("SerialDataLink : max_target_charge_power = 0");
|
logging.println("SerialDataLink : max_target_charge_power = 0");
|
||||||
|
|
||||||
datalayer.battery.status.max_discharge_power_W = 0;
|
datalayer.battery.status.max_discharge_power_W = 0;
|
||||||
datalayer.battery.status.max_charge_power_W = 0;
|
datalayer.battery.status.max_charge_power_W = 0;
|
||||||
|
@ -117,8 +117,8 @@ void manageSerialLinkTransmitter() {
|
||||||
// lastMessageReceived from CAN bus (Battery)
|
// lastMessageReceived from CAN bus (Battery)
|
||||||
if (currentTime - lastMessageReceived > (5 * 60000) ) // 5 minutes
|
if (currentTime - lastMessageReceived > (5 * 60000) ) // 5 minutes
|
||||||
{
|
{
|
||||||
Serial.print(millis());
|
logging.print(millis());
|
||||||
Serial.println(" - Data Stale : 5 minutes");
|
logging.println(" - Data Stale : 5 minutes");
|
||||||
// throw error
|
// throw error
|
||||||
|
|
||||||
// stop transmitting until fresh
|
// stop transmitting until fresh
|
||||||
|
@ -154,42 +154,42 @@ void manageSerialLinkTransmitter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void printSendingValues() {
|
void printSendingValues() {
|
||||||
Serial.println("Values from battery: ");
|
logging.println("Values from battery: ");
|
||||||
Serial.print("SOC: ");
|
logging.print("SOC: ");
|
||||||
Serial.print(datalayer.battery.status.real_soc);
|
logging.print(datalayer.battery.status.real_soc);
|
||||||
Serial.print(" SOH: ");
|
logging.print(" SOH: ");
|
||||||
Serial.print(datalayer.battery.status.soh_pptt);
|
logging.print(datalayer.battery.status.soh_pptt);
|
||||||
Serial.print(" Voltage: ");
|
logging.print(" Voltage: ");
|
||||||
Serial.print(datalayer.battery.status.voltage_dV);
|
logging.print(datalayer.battery.status.voltage_dV);
|
||||||
Serial.print(" Current: ");
|
logging.print(" Current: ");
|
||||||
Serial.print(datalayer.battery.status.current_dA);
|
logging.print(datalayer.battery.status.current_dA);
|
||||||
Serial.print(" Capacity: ");
|
logging.print(" Capacity: ");
|
||||||
Serial.print(datalayer.battery.info.total_capacity_Wh);
|
logging.print(datalayer.battery.info.total_capacity_Wh);
|
||||||
Serial.print(" Remain cap: ");
|
logging.print(" Remain cap: ");
|
||||||
Serial.print(datalayer.battery.status.remaining_capacity_Wh);
|
logging.print(datalayer.battery.status.remaining_capacity_Wh);
|
||||||
Serial.print(" Max discharge W: ");
|
logging.print(" Max discharge W: ");
|
||||||
Serial.print(datalayer.battery.status.max_discharge_power_W);
|
logging.print(datalayer.battery.status.max_discharge_power_W);
|
||||||
Serial.print(" Max charge W: ");
|
logging.print(" Max charge W: ");
|
||||||
Serial.print(datalayer.battery.status.max_charge_power_W);
|
logging.print(datalayer.battery.status.max_charge_power_W);
|
||||||
Serial.print(" BMS status: ");
|
logging.print(" BMS status: ");
|
||||||
Serial.print(datalayer.battery.status.bms_status);
|
logging.print(datalayer.battery.status.bms_status);
|
||||||
Serial.print(" Power: ");
|
logging.print(" Power: ");
|
||||||
Serial.print(datalayer.battery.status.active_power_W);
|
logging.print(datalayer.battery.status.active_power_W);
|
||||||
Serial.print(" Temp min: ");
|
logging.print(" Temp min: ");
|
||||||
Serial.print(datalayer.battery.status.temperature_min_dC);
|
logging.print(datalayer.battery.status.temperature_min_dC);
|
||||||
Serial.print(" Temp max: ");
|
logging.print(" Temp max: ");
|
||||||
Serial.print(datalayer.battery.status.temperature_max_dC);
|
logging.print(datalayer.battery.status.temperature_max_dC);
|
||||||
Serial.print(" Cell max: ");
|
logging.print(" Cell max: ");
|
||||||
Serial.print(datalayer.battery.status.cell_max_voltage_mV);
|
logging.print(datalayer.battery.status.cell_max_voltage_mV);
|
||||||
Serial.print(" Cell min: ");
|
logging.print(" Cell min: ");
|
||||||
Serial.print(datalayer.battery.status.cell_min_voltage_mV);
|
logging.print(datalayer.battery.status.cell_min_voltage_mV);
|
||||||
Serial.print(" LFP : ");
|
logging.print(" LFP : ");
|
||||||
Serial.print(datalayer.battery.info.chemistry);
|
logging.print(datalayer.battery.info.chemistry);
|
||||||
Serial.print(" Battery Allows Contactor Closing: ");
|
logging.print(" Battery Allows Contactor Closing: ");
|
||||||
Serial.print(datalayer.system.status.battery_allows_contactor_closing);
|
logging.print(datalayer.system.status.battery_allows_contactor_closing);
|
||||||
Serial.print(" Inverter Allows Contactor Closing: ");
|
logging.print(" Inverter Allows Contactor Closing: ");
|
||||||
Serial.print(datalayer.system.status.inverter_allows_contactor_closing);
|
logging.print(datalayer.system.status.inverter_allows_contactor_closing);
|
||||||
|
|
||||||
Serial.println("");
|
logging.println("");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -207,8 +207,8 @@ void receive_can_inverter(CAN_frame rx_frame) {
|
||||||
LastFrameTime = millis();
|
LastFrameTime = millis();
|
||||||
switch (STATE) {
|
switch (STATE) {
|
||||||
case (BATTERY_ANNOUNCE):
|
case (BATTERY_ANNOUNCE):
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Solax Battery State: Announce");
|
logging.println("Solax Battery State: Announce");
|
||||||
#endif
|
#endif
|
||||||
datalayer.system.status.inverter_allows_contactor_closing = false;
|
datalayer.system.status.inverter_allows_contactor_closing = false;
|
||||||
SOLAX_1875.data.u8[4] = (0x00); // Inform Inverter: Contactor 0=off, 1=on.
|
SOLAX_1875.data.u8[4] = (0x00); // Inform Inverter: Contactor 0=off, 1=on.
|
||||||
|
@ -239,8 +239,8 @@ void receive_can_inverter(CAN_frame rx_frame) {
|
||||||
transmit_can(&SOLAX_1878, can_config.inverter);
|
transmit_can(&SOLAX_1878, can_config.inverter);
|
||||||
transmit_can(&SOLAX_1801, can_config.inverter); // Announce that the battery will be connected
|
transmit_can(&SOLAX_1801, can_config.inverter); // Announce that the battery will be connected
|
||||||
STATE = CONTACTOR_CLOSED; // Jump to Contactor Closed State
|
STATE = CONTACTOR_CLOSED; // Jump to Contactor Closed State
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("Solax Battery State: Contactor Closed");
|
logging.println("Solax Battery State: Contactor Closed");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -267,13 +267,13 @@ void receive_can_inverter(CAN_frame rx_frame) {
|
||||||
if (rx_frame.ID == 0x1871 && rx_frame.data.u64 == __builtin_bswap64(0x0500010000000000)) {
|
if (rx_frame.ID == 0x1871 && rx_frame.data.u64 == __builtin_bswap64(0x0500010000000000)) {
|
||||||
transmit_can(&SOLAX_1881, can_config.inverter);
|
transmit_can(&SOLAX_1881, can_config.inverter);
|
||||||
transmit_can(&SOLAX_1882, can_config.inverter);
|
transmit_can(&SOLAX_1882, can_config.inverter);
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("1871 05-frame received from inverter");
|
logging.println("1871 05-frame received from inverter");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (rx_frame.ID == 0x1871 && rx_frame.data.u8[0] == (0x03)) {
|
if (rx_frame.ID == 0x1871 && rx_frame.data.u8[0] == (0x03)) {
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_LOG
|
||||||
Serial.println("1871 03-frame received from inverter");
|
logging.println("1871 03-frame received from inverter");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue