diff --git a/Software/Software.ino b/Software/Software.ino index 4f9a1078..16a1b66d 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -47,7 +47,6 @@ const char* version_number = "9.0.experimental"; volatile unsigned long currentMillis = 0; unsigned long previousMillis10ms = 0; unsigned long previousMillisUpdateVal = 0; -unsigned long lastMillisOverflowCheck = 0; #ifdef FUNCTION_TIME_MEASUREMENT // Task time measurement for debugging MyTimer core_task_timer_10s(INTERVAL_10_S); @@ -347,15 +346,6 @@ void init_serial() { #endif // DEBUG_VIA_USB } -void update_overflow(unsigned long currentMillis) { - // Check if millis overflowed - if (currentMillis < lastMillisOverflowCheck) { - // We have overflowed, increase rollover count - datalayer.system.status.millisrolloverCount++; - } - lastMillisOverflowCheck = currentMillis; -} - void check_interconnect_available() { if (datalayer.battery.status.voltage_dV == 0 || datalayer.battery2.status.voltage_dV == 0) { return; // Both voltage values need to be available to start check @@ -543,8 +533,6 @@ void update_calculated_values() { datalayer.battery.status.reported_remaining_capacity_Wh = datalayer.battery2.status.remaining_capacity_Wh; } } - - update_overflow(currentMillis); // Update millis rollover count } void check_reset_reason() { @@ -602,9 +590,3 @@ void check_reset_reason() { break; } } - -uint64_t get_timestamp(unsigned long currentMillis) { - update_overflow(currentMillis); - return (uint64_t)datalayer.system.status.millisrolloverCount * (uint64_t)std::numeric_limits::max() + - (uint64_t)currentMillis; -} diff --git a/Software/src/battery/BATTERIES.cpp b/Software/src/battery/BATTERIES.cpp index f327ed58..82d64787 100644 --- a/Software/src/battery/BATTERIES.cpp +++ b/Software/src/battery/BATTERIES.cpp @@ -94,6 +94,8 @@ const char* name_for_battery_type(BatteryType type) { return MebBattery::Name; case BatteryType::Mg5: return Mg5Battery::Name; + case BatteryType::MgHsPhev: + return MgHsPHEVBattery::Name; case BatteryType::NissanLeaf: return NissanLeafBattery::Name; case BatteryType::Pylon: @@ -189,6 +191,8 @@ Battery* create_battery(BatteryType type) { return new MebBattery(); case BatteryType::Mg5: return new Mg5Battery(); + case BatteryType::MgHsPhev: + return new MgHsPHEVBattery(); case BatteryType::NissanLeaf: return new NissanLeafBattery(); case BatteryType::Pylon: diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index c5ddf979..3016877d 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -811,6 +811,29 @@ void KiaEGmpBattery:: #endif } +// Getter implementations for HTML renderer +int KiaEGmpBattery::get_battery_12V() const { + return leadAcidBatteryVoltage; +} +int KiaEGmpBattery::get_waterleakageSensor() const { + return waterleakageSensor; +} +int KiaEGmpBattery::get_temperature_water_inlet() const { + return temperature_water_inlet; +} +int KiaEGmpBattery::get_powerRelayTemperature() const { + return powerRelayTemperature; +} +int KiaEGmpBattery::get_batteryManagementMode() const { + return batteryManagementMode; +} +int KiaEGmpBattery::get_BMS_ign() const { + return BMS_ign; +} +int KiaEGmpBattery::get_batRelay() const { + return batteryRelay; +} + void KiaEGmpBattery::handle_incoming_can_frame(CAN_frame rx_frame) { startedUp = true; switch (rx_frame.ID) { diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.h b/Software/src/battery/KIA-E-GMP-BATTERY.h index 06fc025c..bf1c769e 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.h +++ b/Software/src/battery/KIA-E-GMP-BATTERY.h @@ -1,6 +1,7 @@ #ifndef KIA_E_GMP_BATTERY_H #define KIA_E_GMP_BATTERY_H #include "CanBattery.h" +#include "KIA-E-GMP-HTML.h" #define ESTIMATE_SOC_FROM_CELLVOLTAGE @@ -10,13 +11,24 @@ class KiaEGmpBattery : public CanBattery { public: + KiaEGmpBattery() : renderer(*this) {} virtual void setup(void); virtual void handle_incoming_can_frame(CAN_frame rx_frame); virtual void update_values(); virtual void transmit_can(unsigned long currentMillis); static constexpr const char* Name = "Kia/Hyundai EGMP platform"; + BatteryHtmlRenderer& get_status_renderer() { return renderer; } + // Getter implementations for HTML renderer + int get_battery_12V() const; + int get_waterleakageSensor() const; + int get_temperature_water_inlet() const; + int get_powerRelayTemperature() const; + int get_batteryManagementMode() const; + int get_BMS_ign() const; + int get_batRelay() const; private: + KiaEGMPHtmlRenderer renderer; uint16_t estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps); void set_voltage_minmax_limits(); @@ -39,9 +51,9 @@ class KiaEGmpBattery : public CanBattery { uint16_t inverterVoltageFrameHigh = 0; uint16_t inverterVoltage = 0; - uint16_t soc_calculated = 0; - uint16_t SOC_BMS = 0; - uint16_t SOC_Display = 0; + uint16_t soc_calculated = 500; + uint16_t SOC_BMS = 500; + uint16_t SOC_Display = 500; uint16_t SOC_estimated_lowest = 0; uint16_t SOC_estimated_highest = 0; uint16_t batterySOH = 1000; @@ -50,24 +62,24 @@ class KiaEGmpBattery : public CanBattery { uint16_t batteryVoltage = 6700; int16_t leadAcidBatteryVoltage = 120; int16_t batteryAmps = 0; - int16_t temperatureMax = 0; - int16_t temperatureMin = 0; + int16_t temperatureMax = 20; + int16_t temperatureMin = 20; int16_t allowedDischargePower = 0; int16_t allowedChargePower = 0; int16_t poll_data_pid = 0; uint8_t CellVmaxNo = 0; uint8_t CellVminNo = 0; uint8_t batteryManagementMode = 0; - uint8_t BMS_ign = 0; + uint8_t BMS_ign = 0xff; uint8_t batteryRelay = 0; uint8_t waterleakageSensor = 164; bool startedUp = false; bool ok_start_polling_battery = false; uint8_t counter_200 = 0; uint8_t KIA_7E4_COUNTER = 0x01; - int8_t temperature_water_inlet = 0; - int8_t powerRelayTemperature = 0; - int8_t heatertemp = 0; + int8_t temperature_water_inlet = 20; + int8_t powerRelayTemperature = 10; + int8_t heatertemp = 20; bool set_voltage_limits = false; uint8_t ticks_200ms_counter = 0; uint8_t EGMP_1CF_counter = 0; diff --git a/Software/src/battery/KIA-E-GMP-HTML.cpp b/Software/src/battery/KIA-E-GMP-HTML.cpp new file mode 100644 index 00000000..67044dac --- /dev/null +++ b/Software/src/battery/KIA-E-GMP-HTML.cpp @@ -0,0 +1,15 @@ +#include "KIA-E-GMP-HTML.h" +#include "KIA-E-GMP-BATTERY.h" + +String KiaEGMPHtmlRenderer::get_status_html() { + String content; + content += "

Cells: " + String(datalayer.battery.info.number_of_cells) + "S

"; + content += "

12V voltage: " + String(batt.get_battery_12V() / 10.0, 1) + "

"; + content += "

Waterleakage: " + String(batt.get_waterleakageSensor()) + "

"; + content += "

Temperature, water inlet: " + String(batt.get_temperature_water_inlet()) + "

"; + content += "

Temperature, power relay: " + String(batt.get_powerRelayTemperature() * 2) + "

"; + content += "

Batterymanagement mode: " + String(batt.get_batteryManagementMode()) + "

"; + content += "

BMS ignition: " + String(batt.get_BMS_ign()) + "

"; + content += "

Battery relay: " + String(batt.get_batRelay()) + "

"; + return content; +} diff --git a/Software/src/battery/KIA-E-GMP-HTML.h b/Software/src/battery/KIA-E-GMP-HTML.h new file mode 100644 index 00000000..545cff0e --- /dev/null +++ b/Software/src/battery/KIA-E-GMP-HTML.h @@ -0,0 +1,18 @@ +#ifndef _KIA_E_GMP_HTML_H +#define _KIA_E_GMP_HTML_H + +#include "../datalayer/datalayer.h" +#include "../devboard/webserver/BatteryHtmlRenderer.h" + +class KiaEGmpBattery; + +class KiaEGMPHtmlRenderer : public BatteryHtmlRenderer { + private: + KiaEGmpBattery& batt; + + public: + KiaEGMPHtmlRenderer(KiaEGmpBattery& b) : batt(b) {} + String get_status_html(); +}; + +#endif diff --git a/Software/src/battery/MG-HS-PHEV-BATTERY.cpp b/Software/src/battery/MG-HS-PHEV-BATTERY.cpp index a9d6f881..e0e96e6d 100644 --- a/Software/src/battery/MG-HS-PHEV-BATTERY.cpp +++ b/Software/src/battery/MG-HS-PHEV-BATTERY.cpp @@ -1,4 +1,3 @@ -#ifdef MG_HS_PHEV_BATTERY_H #include "MG-HS-PHEV-BATTERY.h" #include "../communication/can/comm_can.h" #include "../communication/contactorcontrol/comm_contactorcontrol.h" @@ -381,5 +380,3 @@ void MgHsPHEVBattery::setup(void) { // Performs one time setup at startup datalayer.battery.info.total_capacity_Wh = BATTERY_WH_MAX; datalayer.battery.info.number_of_cells = 90; } - -#endif diff --git a/Software/src/datalayer/datalayer.h b/Software/src/datalayer/datalayer.h index 2598999d..769c5cd9 100644 --- a/Software/src/datalayer/datalayer.h +++ b/Software/src/datalayer/datalayer.h @@ -250,8 +250,6 @@ struct DATALAYER_SYSTEM_INFO_TYPE { }; struct DATALAYER_SYSTEM_STATUS_TYPE { - /** Millis rollover count. Increments every 49.7 days. Used for keeping track on events */ - uint8_t millisrolloverCount = 0; #ifdef FUNCTION_TIME_MEASUREMENT /** Core task measurement variable */ int64_t core_task_max_us = 0; diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index eb11271f..353d6802 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -398,8 +398,6 @@ EVENTS_LEVEL_TYPE get_event_level(void) { return events.level; } -uint64_t get_timestamp(unsigned long currentMillis); - /* Local functions */ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) { @@ -418,7 +416,7 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) { } // We should set the event, update event info - events.entries[event].timestamp = get_timestamp(millis()); + events.entries[event].timestamp = millis64(); events.entries[event].data = data; // Check if the event is latching events.entries[event].state = latched ? EVENT_STATE_ACTIVE_LATCHED : EVENT_STATE_ACTIVE; diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index 506e244b..2e88b491 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -3,6 +3,7 @@ #include #include +#include "millis64.h" #include "types.h" #define GENERATE_ENUM(ENUM) ENUM, diff --git a/Software/src/devboard/utils/millis64.cpp b/Software/src/devboard/utils/millis64.cpp new file mode 100644 index 00000000..7057b751 --- /dev/null +++ b/Software/src/devboard/utils/millis64.cpp @@ -0,0 +1,12 @@ +#include +#include "esp_timer.h" + +uint64_t ARDUINO_ISR_ATTR millis64() { + // ESP32's esp_timer_get_time() returns time in microseconds, we convert to + // milliseconds by dividing by 1000. + + // This is almost identical to the existing Arduino millis() function, except + // we return a 64-bit value which won't roll over for 600k years. + + return esp_timer_get_time() / 1000ULL; +} diff --git a/Software/src/devboard/utils/millis64.h b/Software/src/devboard/utils/millis64.h new file mode 100644 index 00000000..59e98686 --- /dev/null +++ b/Software/src/devboard/utils/millis64.h @@ -0,0 +1,11 @@ +#include + +/** + * @brief Return ESP32's high-resolution timer in milliseconds, as a 64 bit value. + * + * @param[in] void + * + * @return uint64_t Timestamp in milliseconds + * + */ +extern uint64_t millis64(void); diff --git a/Software/src/devboard/webserver/events_html.cpp b/Software/src/devboard/webserver/events_html.cpp index 3171aa27..737e8735 100644 --- a/Software/src/devboard/webserver/events_html.cpp +++ b/Software/src/devboard/webserver/events_html.cpp @@ -2,6 +2,7 @@ #include #include "../../datalayer/datalayer.h" #include "../../devboard/utils/logging.h" +#include "../../devboard/utils/millis64.h" const char EVENTS_HTML_START[] = R"=====(
Event Type
Severity
Last Event
Count
Data
Message
@@ -17,8 +18,6 @@ button:hover { background-color: #3A4A52; } )====="; -uint64_t get_timestamp(unsigned long currentMillis); - static std::vector order_events; String events_processor(const String& var) { @@ -40,7 +39,7 @@ String events_processor(const String& var) { } // Sort events by timestamp std::sort(order_events.begin(), order_events.end(), compareEventsByTimestampDesc); - uint64_t current_timestamp = get_timestamp(millis()); + uint64_t current_timestamp = millis64(); // Generate HTML and debug output for (const auto& event : order_events) { diff --git a/Software/src/lib/YiannisBourkelis-Uptime-Library/src/uptime.cpp b/Software/src/lib/YiannisBourkelis-Uptime-Library/src/uptime.cpp index 6b711651..20c59214 100644 --- a/Software/src/lib/YiannisBourkelis-Uptime-Library/src/uptime.cpp +++ b/Software/src/lib/YiannisBourkelis-Uptime-Library/src/uptime.cpp @@ -36,25 +36,16 @@ * https://github.com/YiannisBourkelis/ */ -#include //for millis() +#include "../../../devboard/utils/millis64.h" #include "uptime.h" //private variabes for converting milliseconds to total seconds,minutes,hours and days //after each call to millis() -unsigned long uptime::m_milliseconds; -unsigned long uptime::m_seconds; -unsigned long uptime::m_minutes; -unsigned long uptime::m_hours; -unsigned long uptime::m_days; - -//in case of millis() overflow, we store in these private variables -//the existing time passed until the moment of the overflow -//so that we can add them on the next call to compute the time passed -unsigned long uptime::m_last_milliseconds = 0; -unsigned long uptime::m_remaining_seconds = 0; -unsigned long uptime::m_remaining_minutes = 0; -unsigned long uptime::m_remaining_hours = 0; -unsigned long uptime::m_remaining_days = 0; +uint64_t uptime::m_milliseconds; +uint64_t uptime::m_seconds; +uint64_t uptime::m_minutes; +uint64_t uptime::m_hours; +uint64_t uptime::m_days; //private variables that in combination hold the actual time passed //Use the coresponding uptime::get_.... to read these private variables @@ -90,26 +81,13 @@ unsigned long uptime::getDays() //and store them in their static variables void uptime::calculateUptime() { - uptime::m_milliseconds = millis(); - - if (uptime::m_last_milliseconds > uptime::m_milliseconds){ - //in case of millis() overflow, store existing passed seconds,minutes,hours and days - uptime::m_remaining_seconds = uptime::m_mod_seconds; - uptime::m_remaining_minutes = uptime::m_mod_minutes; - uptime::m_remaining_hours = uptime::m_mod_hours; - uptime::m_remaining_days = uptime::m_days; - } - //store last millis(), so that we can detect on the next call - //if there is a millis() overflow ( millis() returns 0 ) - uptime::m_last_milliseconds = uptime::m_milliseconds; + uptime::m_milliseconds = millis64(); //convert passed millis to total seconds, minutes, hours and days. - //In case of overflow, the uptime::m_remaining_... variables contain the remaining time before the overflow. - //We add the remaining time, so that we can continue measuring the time passed from the last boot of the device. - uptime::m_seconds = (uptime::m_milliseconds / 1000) + uptime::m_remaining_seconds; - uptime::m_minutes = (uptime::m_seconds / 60) + uptime::m_remaining_minutes; - uptime::m_hours = (uptime::m_minutes / 60) + uptime::m_remaining_hours; - uptime::m_days = (uptime::m_hours / 24) + uptime::m_remaining_days; + uptime::m_seconds = (uptime::m_milliseconds / 1000); + uptime::m_minutes = (uptime::m_seconds / 60); + uptime::m_hours = (uptime::m_minutes / 60); + uptime::m_days = (uptime::m_hours / 24); //calculate the actual time passed, using modulus, in milliseconds, seconds and hours. //The days are calculated allready in the previous step. diff --git a/Software/src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h b/Software/src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h index fc00bbb7..ba16904f 100644 --- a/Software/src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h +++ b/Software/src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h @@ -53,21 +53,15 @@ class uptime static unsigned long getDays(); private: - static unsigned long m_milliseconds; - static unsigned long m_seconds; - static unsigned long m_minutes; - static unsigned long m_hours; - static unsigned long m_days; + static uint64_t m_milliseconds; + static uint64_t m_seconds; + static uint64_t m_minutes; + static uint64_t m_hours; + static uint64_t m_days; static unsigned long m_mod_milliseconds; static uint8_t m_mod_seconds; static uint8_t m_mod_minutes; static uint8_t m_mod_hours; - - static unsigned long m_last_milliseconds; - static unsigned long m_remaining_seconds; - static unsigned long m_remaining_minutes; - static unsigned long m_remaining_hours; - static unsigned long m_remaining_days; }; #endif diff --git a/test/emul/time.cpp b/test/emul/time.cpp index 7e97f46e..f8f1283c 100644 --- a/test/emul/time.cpp +++ b/test/emul/time.cpp @@ -7,3 +7,7 @@ unsigned long millis() { uint64_t get_timestamp(unsigned long millis) { return 0; } + +uint64_t millis64(void) { + return 0; +}