From 01207458bf54d17cc60c7f38261203065841e99c Mon Sep 17 00:00:00 2001 From: songyueli Date: Fri, 12 Dec 2025 23:58:28 -0500 Subject: [PATCH 01/30] initialize new max114x adc --- include/ACU_Constants.h | 38 ++++++++++- include/ACU_InterfaceTasks.h | 4 ++ lib/interfaces/include/MAX114XInterface.h | 52 +++++++++++++++ lib/interfaces/include/MAX114XInterface.tpp | 74 +++++++++++++++++++++ src/ACU_InterfaceTasks.cpp | 48 ++++++++++++- src/main.cpp | 31 +++++---- 6 files changed, 231 insertions(+), 16 deletions(-) create mode 100644 lib/interfaces/include/MAX114XInterface.h create mode 100644 lib/interfaces/include/MAX114XInterface.tpp diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index a54b3b8..6567b31 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -31,6 +31,38 @@ namespace ACUInterfaces { const size_t ANALOG_READ_RESOLUTION = 12; const size_t SERIAL_BAUDRATE = 115200; + constexpr int ADC0_CS = 10; + constexpr int ADC0_MOSI = 11; + constexpr int ADC0_MISO = 12; + constexpr int ADC0_CLK = 13; + constexpr int ADC0_SPEED = 2000000; // 1 MHz + /* Channels on ADC */ + constexpr int ISO_PACK_N_CHANNEL = 0; + constexpr int ISO_PACK_P_CHANNEL = 1; + constexpr int PACK_VOLTAGE_SENSE_CHANNEL = 2; + constexpr int SHUNT_CURRENT_OUT_CHANNEL = 3; + constexpr int SHUNT_CURRENT_P_CHANNEL = 4; + constexpr int SHUNT_CURRENT_N_CHANNEL = 5; + constexpr int TS_OUT_FILTERED_CHANNEL = 6; + constexpr int PACK_OUT_FILTERED_CHANNEL = 7; + /* SCALE/OFFSETS on ADC */ + const float ISO_PACK_N_SCALE = 1; + const float ISO_PACK_P_SCALE = 1; + const float PACK_VOLTAGE_SENSE_SCALE = 1; + const float SHUNT_CURRENT_OUT_SCALE = 1; + const float SHUNT_CURRENT_P_SCALE = 1; + const float SHUNT_CURRENT_N_SCALE = 1; + const float TS_OUT_FILTERED_SCALE = 1; + const float PACK_OUT_FILTERED_SCALE = 1; + const float ISO_PACK_N_OFFSET = 0; + const float ISO_PACK_P_OFFSET = 0; + const float PACK_VOLTAGE_SENSE_OFFSET = 0; + const float SHUNT_CURRENT_OUT_OFFSET = 0; + const float SHUNT_CURRENT_P_OFFSET = 0; + const float SHUNT_CURRENT_N_OFFSET = 0; + const float TS_OUT_FILTERED_OFFSET = 0; + const float PACK_OUT_FILTERED_OFFSET = 0; + constexpr const size_t TEENSY_OK_PIN = 3; // > Needs to stay HIGH while wd_kick_pin flips to keep BMS_OK high constexpr const size_t WD_KICK_PIN = 4; // > Needs to flip at 100 Hz to keep BMS_OK high constexpr const size_t N_LATCH_EN_PIN = 6; // > Input to Safety Light, true when teensy is not in FAULT state @@ -58,7 +90,8 @@ namespace ACUConstants constexpr size_t NUM_CHIPS = 12; constexpr size_t NUM_CELL_TEMPS = 48; constexpr size_t NUM_CHIP_SELECTS = 2; - + constexpr size_t NUM_MAX1148_CHANNELS = 8; + const float VALID_SHDN_OUT_MIN_VOLTAGE_THRESHOLD = 12.0F; const uint32_t MIN_ALLOWED_INVALID_SHDN_OUT_MS = 10; // 10 ms -- requies 100 Hz samp freq. @@ -82,6 +115,9 @@ namespace ACUConstants constexpr uint32_t ALL_DATA_ETHERNET_PRIORITY = 5; constexpr uint32_t CORE_DATA_ETHERNET_PERIOD_US = 20000UL; // 20 000 us = 50 Hz constexpr uint32_t CORE_DATA_ETHERNET_PRIORITY = 4; + + constexpr uint32_t SAMPLE_ADC_PRIORITY = 20; + constexpr uint32_t SAMPLE_ADC_PERIOD_US = 100000UL; // 100 000 us = 10 Hz constexpr uint32_t CCU_SEND_PERIOD_US = 100000UL; // 100 000 us = 10 Hz constexpr uint32_t CCU_SEND_PRIORITY = 11; diff --git a/include/ACU_InterfaceTasks.h b/include/ACU_InterfaceTasks.h index 671b820..f110533 100644 --- a/include/ACU_InterfaceTasks.h +++ b/include/ACU_InterfaceTasks.h @@ -15,6 +15,7 @@ #include "ADCInterface.h" #include "FaultLatchManager.h" #include "SystemTimeInterface.h" +#include "MAX114XInterface.h" /* For Debugging */ #include "ACUStateMachine.h" @@ -24,6 +25,7 @@ using chip_type = LTC6811_Type_e; using BMSDriverInstance_t = BMSDriverInstance; using BMSFaultDataManagerInstance_t = BMSFaultDataManagerInstance; +using MAX1148ADCInstance_t = MAX114XInterfaceInstance; /** * Init Functions - to be called in setup */ @@ -54,6 +56,8 @@ ::HT_TASK::TaskResponse enqueue_ACU_ok_CAN_data(const unsigned long& sysMicros, ::HT_TASK::TaskResponse sample_CAN_data(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo); +::HT_TASK::TaskResponse sample_adc(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo); + ::HT_TASK::TaskResponse idle_sample_interfaces(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo); ::HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK::TaskInfo &taskInfo); diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h new file mode 100644 index 0000000..a5a3492 --- /dev/null +++ b/lib/interfaces/include/MAX114XInterface.h @@ -0,0 +1,52 @@ +#ifndef MAX1148INTERFACE +#define MAX1148INTERFACE + +#include +#include "AnalogSensorsInterface.h" + +// Definitions +const int MAX114X_ADC_DEFAULT_SPI_SDI = 12; +const int MAX114X_ADC_DEFAULT_SPI_SDO = 11; +const int MAX114X_ADC_DEFAULT_SPI_CLK = 13; +const int MAX114X_ADC_DEFAULT_SPI_SPEED = 2000000; + +/** + * The MCP_ADC is a concrete subclass of the AnalogMultiSensor parent class. This allows + * for SPI communication with the MCP_ADC, which can be a 4-channel or 8-channel sensor. + * IMPORTANT - must call SPI.begin() once and only once before instantiating any MCP_ADC object!! + */ +template +class MAX114XInterface : public AnalogMultiSensor +{ +private: + const int _spiPinCS; + const int _spiPinSDI; + const int _spiPinSDO; + const int _spiPinCLK; + const int _spiSpeed; + + /** + * Samples the MCP_ADC over SPI. Samples all eight channels and, in accordance with the AnalogMultiSensor's function + * contract, stores the raw sampled values into each AnalogChannel's lastSample instance variable. + */ + void _sample() override; + +public: + /* Constructors */ + MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX1148X_ADC_NUM_CHANNELS], const float offsets[MAX1148X_ADC_NUM_CHANNELS]); + + /* Functions */ + + /** + * Calls sample() and convert(). After calling tick(), this MCP_ADC's data can be accessed using the get() command. + */ + void tick() override; + +}; + +template +using MAX114XInterfaceInstance = etl::singleton>; + +#include "MAX114XInterface.tpp" + +#endif /* __MCP_ADC_H__ */ \ No newline at end of file diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp new file mode 100644 index 0000000..e5bc0cf --- /dev/null +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -0,0 +1,74 @@ +#include "MAX114XInterface.h" +#include + +template +MAX114XInterface::MAX114XInterface(const int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX1148X_ADC_NUM_CHANNELS], const float offsets[MAX1148X_ADC_NUM_CHANNELS]) +: _spiPinCS(spiPinCS) +, _spiPinSDI(spiPinSDI) +, _spiPinSDO(spiPinSDO) +, _spiPinCLK(spiPinCLK) +, _spiSpeed(spiSpeed) +{ + for (int i = 0; i < MAX1148X_ADC_NUM_CHANNELS; i++) + { + MAX114XInterface::_channels[i] = AnalogChannel(); + this->setChannelScaleAndOffset(i, scales[i], offsets[i]); + } + pinMode(_spiPinCS, OUTPUT); + digitalWrite(_spiPinCS, HIGH); +} + +template +void MAX114XInterface::tick() +{ + _sample(); + this->_convert(); +} + +template +void MAX114XInterface::_sample() +{ + // uint16_t command = ( + // (0b1 << 15) | // start bit + // (0b1 << 14) // single ended mode + // ); + byte command, b0, b1, b2; + + // initialize SPI bus. REQUIRED: call SPI.begin() before this + SPI.beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); + + for (int channelIndex = 0; channelIndex < MAX1148X_ADC_NUM_CHANNELS; channelIndex++) + { + digitalWrite(_spiPinCS, LOW); + + // UPDATE CODE BELOW + + command = ((0x01 << 7) | // start bit + ((channelIndex & 0x07) << 4) | // channel number + (0x01 << 3) | // single or differential + (0x01 << 2) | // unipolar or !bipolar + (0x01 << 1) | // external clock mode + (0x01 << 0)); // + b0 = SPI.transfer(command); + b1 = SPI.transfer(0x00); + b2 = SPI.transfer(0x00); + + Serial.print("b0: "); + Serial.println(b0, HEX); + Serial.print("b1: "); + Serial.println(b1, HEX); + Serial.print("b2: "); + Serial.println(b2, HEX); + + // uint16_t value = SPI.transfer16(command | channelIndex << 11); + uint16_t value = (b0 & 0x01) << 11 | (b1 & 0xFF) << 3 | (b2 & 0xE0) >> 5; + MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); + + // UPDATE CODE ABOVE + + digitalWrite(_spiPinCS, HIGH); + delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns + } + + SPI.endTransaction(); +} \ No newline at end of file diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 432527c..f62a029 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -76,7 +76,39 @@ void initialize_all_interfaces() /* Ethernet Interface */ ACUEthernetInterfaceInstance::create(); ACUEthernetInterfaceInstance::instance().init_ethernet_device(); - + + std::array adc0_scales = { + ACUInterfaces::ISO_PACK_N_SCALE, + ACUInterfaces::ISO_PACK_P_SCALE, + ACUInterfaces::PACK_VOLTAGE_SENSE_SCALE, + ACUInterfaces::SHUNT_CURRENT_OUT_SCALE, + ACUInterfaces::SHUNT_CURRENT_P_SCALE, + ACUInterfaces::SHUNT_CURRENT_N_SCALE, + ACUInterfaces::TS_OUT_FILTERED_SCALE, + ACUInterfaces::PACK_OUT_FILTERED_SCALE, + }; + + std::array adc0_offsets = { + ACUInterfaces::ISO_PACK_N_OFFSET, + ACUInterfaces::ISO_PACK_P_OFFSET, + ACUInterfaces::PACK_VOLTAGE_SENSE_OFFSET, + ACUInterfaces::SHUNT_CURRENT_OUT_OFFSET, + ACUInterfaces::SHUNT_CURRENT_P_OFFSET, + ACUInterfaces::SHUNT_CURRENT_N_OFFSET, + ACUInterfaces::TS_OUT_FILTERED_OFFSET, + ACUInterfaces::PACK_OUT_FILTERED_OFFSET, + }; + + /* ADC Interface */ + MAX1148ADCInstance_t::create( + ACUInterfaces::ADC0_CS, + ACUInterfaces::ADC0_MISO, + ACUInterfaces::ADC0_MOSI, + ACUInterfaces::ADC0_CLK, + ACUInterfaces::ADC0_SPEED, + adc0_scales.data(), + adc0_offsets.data() + ); /* CCU Interface */ CCUInterfaceInstance::create(sys_time::hal_millis()); @@ -133,6 +165,20 @@ HT_TASK::TaskResponse write_cell_balancing_config(const unsigned long &sysMicros return HT_TASK::TaskResponse::YIELD; } +HT_TASK::TaskResponse sample_adc(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo) +{ + MAX1148ADCInstance_t::instance().tick(); + + Serial.print("ADC0: "); + auto data = MAX1148ADCInstance_t::instance().get(); + for (size_t i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { + Serial.print(data.conversions[i].conversion); + Serial.print(" "); + } + + return HT_TASK::TaskResponse::YIELD; +} + HT_TASK::TaskResponse handle_send_ACU_core_ethernet_data(const unsigned long &sysMicros, const HT_TASK::TaskInfo &taskInfo) { auto data = make_acu_all_data(); diff --git a/src/main.cpp b/src/main.cpp index 48754f8..f297c3a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ ::HT_TASK::Task enqueue_ACU_OK_CAN_task(HT_TASK::DUMMY_FUNCTION, enqueue_ACU_ok_ ::HT_TASK::Task sample_CAN_task(HT_TASK::DUMMY_FUNCTION, sample_CAN_data, ACUConstants::RECV_CAN_PRIORITY, ACUConstants::RECV_CAN_PERIOD_US); ::HT_TASK::Task idle_sample_task(HT_TASK::DUMMY_FUNCTION, idle_sample_interfaces, ACUConstants::IDLE_SAMPLE_PRIORITY, ACUConstants::IDLE_SAMPLE_PERIOD_US); ::HT_TASK::Task debug_prints_task(HT_TASK::DUMMY_FUNCTION, debug_print, ACUConstants::DEBUG_PRINT_PRIORITY, ACUConstants::DEBUG_PRINT_PERIOD_US); +::HT_TASK::Task sample_adc_task(HT_TASK::DUMMY_FUNCTION, sample_adc, ACUConstants::SAMPLE_ADC_PRIORITY, ACUConstants::SAMPLE_ADC_PERIOD_US); FlexCAN_t ACUCANInterfaceImpl::CCU_CAN; FlexCAN_t ACUCANInterfaceImpl::EM_CAN; @@ -47,25 +48,27 @@ void setup() initialize_all_systems(); scheduler.setTimingFunction(micros); - scheduler.schedule(tick_state_machine_task); - scheduler.schedule(kick_watchdog_task); - scheduler.schedule(sample_bms_data_task); - scheduler.schedule(eval_accumulator_task); - scheduler.schedule(write_cell_balancing_config_task); + // scheduler.schedule(tick_state_machine_task); + // scheduler.schedule(kick_watchdog_task); + // scheduler.schedule(sample_bms_data_task); + // scheduler.schedule(eval_accumulator_task); + // scheduler.schedule(write_cell_balancing_config_task); - scheduler.schedule(send_all_data_ethernet_task); - scheduler.schedule(send_core_data_ethernet_task); // waiting on update on drivebrain + // scheduler.schedule(send_all_data_ethernet_task); + // scheduler.schedule(send_core_data_ethernet_task); // waiting on update on drivebrain - scheduler.schedule(send_CAN_task); - scheduler.schedule(enqueue_CCU_core_CAN_task); - scheduler.schedule(enqueue_CCU_all_voltages_CAN_task); - scheduler.schedule(enqueue_CCU_all_temps_CAN_task); - scheduler.schedule(enqueue_ACU_OK_CAN_task); + // scheduler.schedule(send_CAN_task); + // scheduler.schedule(enqueue_CCU_core_CAN_task); + // scheduler.schedule(enqueue_CCU_all_voltages_CAN_task); + // scheduler.schedule(enqueue_CCU_all_temps_CAN_task); + // scheduler.schedule(enqueue_ACU_OK_CAN_task); - scheduler.schedule(sample_CAN_task); - scheduler.schedule(idle_sample_task); + // scheduler.schedule(sample_CAN_task); + // scheduler.schedule(idle_sample_task); //scheduler.schedule(debug_prints_task); + + scheduler.schedule(sample_adc_task); handle_CAN_setup(ACUCANInterfaceImpl::CCU_CAN, ACUConstants::Veh_CAN_baudrate, &ACUCANInterfaceImpl::on_ccu_can_receive); handle_CAN_setup(ACUCANInterfaceImpl::EM_CAN, ACUConstants::EM_CAN_baudrate, &ACUCANInterfaceImpl::on_em_can_receive); From 9f35d8e5fd2e17db6c1082dc1d175fb1562d2c75 Mon Sep 17 00:00:00 2001 From: songyueli Date: Mon, 12 Jan 2026 19:42:13 -0500 Subject: [PATCH 02/30] added channel mapping and corrected value bit manipulation --- lib/interfaces/include/MAX114XInterface.h | 2 ++ lib/interfaces/include/MAX114XInterface.tpp | 20 +++++++++++--------- src/ACU_InterfaceTasks.cpp | 2 ++ src/main.cpp | 1 + 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index a5a3492..704f215 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -24,6 +24,8 @@ class MAX114XInterface : public AnalogMultiSensor const int _spiPinSDO; const int _spiPinCLK; const int _spiSpeed; + + std::array _single_end_channel_to_select_map; /** * Samples the MCP_ADC over SPI. Samples all eight channels and, in accordance with the AnalogMultiSensor's function diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index e5bc0cf..9f6ecc2 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -16,6 +16,8 @@ MAX114XInterface::MAX114XInterface(const int spiPinCS } pinMode(_spiPinCS, OUTPUT); digitalWrite(_spiPinCS, HIGH); + + _single_end_channel_to_select_map = {0, 4, 1, 5, 2, 6, 3, 7}; } template @@ -42,26 +44,26 @@ void MAX114XInterface::_sample() digitalWrite(_spiPinCS, LOW); // UPDATE CODE BELOW - + command = ((0x01 << 7) | // start bit - ((channelIndex & 0x07) << 4) | // channel number + ((_single_end_channel_to_select_map[channelIndex] & 0x07) << 4) | // channel number (0x01 << 3) | // single or differential (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode - (0x01 << 0)); // + (0x01 << 1)); // b0 = SPI.transfer(command); b1 = SPI.transfer(0x00); b2 = SPI.transfer(0x00); - Serial.print("b0: "); - Serial.println(b0, HEX); Serial.print("b1: "); - Serial.println(b1, HEX); - Serial.print("b2: "); - Serial.println(b2, HEX); + Serial.print(b1, HEX); + Serial.print(" b2: "); + Serial.print(b2, HEX); // uint16_t value = SPI.transfer16(command | channelIndex << 11); - uint16_t value = (b0 & 0x01) << 11 | (b1 & 0xFF) << 3 | (b2 & 0xE0) >> 5; + uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); + Serial.print(" value: "); + Serial.println(value); MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); // UPDATE CODE ABOVE diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index f62a029..b5e92cf 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -138,6 +138,8 @@ void initialize_all_interfaces() /* CAN Interfaces Construct */ CANInterfacesInstance::create(CCUInterfaceInstance::instance(), EMInterfaceInstance::instance()); + + Serial.println("All interfaces initialized."); } HT_TASK::TaskResponse run_kick_watchdog(const unsigned long &sysMicros, const HT_TASK::TaskInfo &taskInfo) diff --git a/src/main.cpp b/src/main.cpp index f297c3a..aab7456 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ FlexCAN_t ACUCANInterfaceImpl::EM_CAN; void setup() { + Serial.println("Initializing all systems..."); /* Interface and System initialization */ initialize_all_interfaces(); // must init first initialize_all_systems(); From 59617d121c114d70a2e82d7be4002713a27b6b24 Mon Sep 17 00:00:00 2001 From: William Schotte Date: Wed, 14 Jan 2026 21:15:36 -0500 Subject: [PATCH 03/30] Updated MAX114X Interface --- lib/interfaces/include/MAX114XInterface.h | 33 +++++--- lib/interfaces/include/MAX114XInterface.tpp | 89 +++++++++++++++------ src/ACU_InterfaceTasks.cpp | 5 +- 3 files changed, 91 insertions(+), 36 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index 704f215..b65655e 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -10,32 +10,47 @@ const int MAX114X_ADC_DEFAULT_SPI_SDO = 11; const int MAX114X_ADC_DEFAULT_SPI_CLK = 13; const int MAX114X_ADC_DEFAULT_SPI_SPEED = 2000000; +enum class CHANNEL_TYPE_e{ + SINGLE, + DIFFERENTIAL, + INV_DIFFERENTIAL, +}; + + /** - * The MCP_ADC is a concrete subclass of the AnalogMultiSensor parent class. This allows - * for SPI communication with the MCP_ADC, which can be a 4-channel or 8-channel sensor. + * The MAX114X_ADC is a concrete subclass of the AnalogMultiSensor parent class. This allows + * for SPI communication with any version of the MAX114X_ADC, which can be a 4-channel or 8-channel sensor. * IMPORTANT - must call SPI.begin() once and only once before instantiating any MCP_ADC object!! */ -template -class MAX114XInterface : public AnalogMultiSensor +template +class MAX114XInterface : public AnalogMultiSensor { private: + // const int _max114xVersion; + + const std::array _channelTypes; + const int _spiPinCS; const int _spiPinSDI; const int _spiPinSDO; const int _spiPinCLK; const int _spiSpeed; - std::array _single_end_channel_to_select_map; + std::array _single_end_channel_to_select_map; + std::array _differential_end_channel_to_select_map; + std::array _inv_differential_end_channel_to_select_map; /** * Samples the MCP_ADC over SPI. Samples all eight channels and, in accordance with the AnalogMultiSensor's function * contract, stores the raw sampled values into each AnalogChannel's lastSample instance variable. */ void _sample() override; + + int _getSel(CHANNEL_TYPE_e channelType, int& channelId); public: /* Constructors */ - MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX1148X_ADC_NUM_CHANNELS], const float offsets[MAX1148X_ADC_NUM_CHANNELS]); + MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes, const int max114xVersion); /* Functions */ @@ -46,9 +61,9 @@ class MAX114XInterface : public AnalogMultiSensor }; -template -using MAX114XInterfaceInstance = etl::singleton>; +template +using MAX114XInterfaceInstance = etl::singleton>; #include "MAX114XInterface.tpp" -#endif /* __MCP_ADC_H__ */ \ No newline at end of file +#endif /* __MCP_ADC_H__ */ diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 9f6ecc2..d08ab5d 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -1,34 +1,59 @@ +/* Code was based off of this data sheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX1146-MAX1149.pdf +Page 14: Control byte format +Page 15: channel codes +*/ + #include "MAX114XInterface.h" #include -template -MAX114XInterface::MAX114XInterface(const int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX1148X_ADC_NUM_CHANNELS], const float offsets[MAX1148X_ADC_NUM_CHANNELS]) -: _spiPinCS(spiPinCS) -, _spiPinSDI(spiPinSDI) -, _spiPinSDO(spiPinSDO) -, _spiPinCLK(spiPinCLK) -, _spiSpeed(spiSpeed) +template +MAX114XInterface::MAX114XInterface( + const int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, + const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], + const std::array& channelTypes, + const int max114xVersion) + + : _spiPinCS(spiPinCS) + , _spiPinSDI(spiPinSDI) + , _spiPinSDO(spiPinSDO) + , _spiPinCLK(spiPinCLK) + , _spiSpeed(spiSpeed) + , _channelTypes(channelTypes) { - for (int i = 0; i < MAX1148X_ADC_NUM_CHANNELS; i++) + for (int i = 0; i < MAX114X_ADC_NUM_CHANNELS; i++) { - MAX114XInterface::_channels[i] = AnalogChannel(); - this->setChannelScaleAndOffset(i, scales[i], offsets[i]); + MAX114XInterface::_channels[i] = AnalogChannel(); + this->setChannelScaleAndOffset(i, scales[i], offsets[i]); } + pinMode(_spiPinCS, OUTPUT); digitalWrite(_spiPinCS, HIGH); - - _single_end_channel_to_select_map = {0, 4, 1, 5, 2, 6, 3, 7}; + + switch (max114xVersion) { + case 6: + case 7: + _single_end_channel_to_select_map = {0, 4, 1, 5}; + break; + case 8: + case 9: + _single_end_channel_to_select_map = {0, 4, 1, 5, 2, 6, 3, 7}; + break; + default: + // THROW ERROR + break; + } + } -template -void MAX114XInterface::tick() +template +void MAX114XInterface::tick() { _sample(); this->_convert(); } -template -void MAX114XInterface::_sample() +template +void MAX114XInterface::_sample() { // uint16_t command = ( // (0b1 << 15) | // start bit @@ -39,18 +64,19 @@ void MAX114XInterface::_sample() // initialize SPI bus. REQUIRED: call SPI.begin() before this SPI.beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); - for (int channelIndex = 0; channelIndex < MAX1148X_ADC_NUM_CHANNELS; channelIndex++) + for (int channelIndex = 0; channelIndex < MAX114X_ADC_NUM_CHANNELS; channelIndex++) { digitalWrite(_spiPinCS, LOW); + CHANNEL_TYPE_e channelType = _channelTypes[channelIndex / 2]; // UPDATE CODE BELOW - command = ((0x01 << 7) | // start bit - ((_single_end_channel_to_select_map[channelIndex] & 0x07) << 4) | // channel number - (0x01 << 3) | // single or differential - (0x01 << 2) | // unipolar or !bipolar - (0x01 << 1) | // external clock mode - (0x01 << 1)); // + command = ((0x01 << 7) | // start bit + ((_getSel(channelType, channelIndex) & 0x07) << 4) | // channel number + ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single or differential + (0x01 << 2) | // unipolar or !bipolar + (0x01 << 1) | // external clock mode + (0x01 << 1)); // b0 = SPI.transfer(command); b1 = SPI.transfer(0x00); b2 = SPI.transfer(0x00); @@ -64,7 +90,7 @@ void MAX114XInterface::_sample() uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); Serial.print(" value: "); Serial.println(value); - MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); + MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); // UPDATE CODE ABOVE @@ -73,4 +99,17 @@ void MAX114XInterface::_sample() } SPI.endTransaction(); -} \ No newline at end of file +} + +template +int MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int& channelId) +{ + switch (channelType) { + case CHANNEL_TYPE_e::SINGLE: + return _single_end_channel_to_select_map[channelId]; + case CHANNEL_TYPE_e::DIFFERENTIAL: + return channelId++ / 2; + case CHANNEL_TYPE_e::INV_DIFFERENTIAL: + return (channelId++ / 2) + 4; + } +} diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index b5e92cf..3e3b40a 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -107,7 +107,8 @@ void initialize_all_interfaces() ACUInterfaces::ADC0_CLK, ACUInterfaces::ADC0_SPEED, adc0_scales.data(), - adc0_offsets.data() + adc0_offsets.data(), + ); /* CCU Interface */ @@ -433,4 +434,4 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: // Serial.println(); return HT_TASK::TaskResponse::YIELD; -} \ No newline at end of file +} From e67203020ae83d83eb759d768935eda36dfb0549 Mon Sep 17 00:00:00 2001 From: William Schotte Date: Wed, 14 Jan 2026 21:35:59 -0500 Subject: [PATCH 04/30] Finished first version of updated MAX114X interface --- include/ACU_Constants.h | 4 +++- lib/interfaces/include/MAX114XInterface.h | 6 ++++-- lib/interfaces/include/MAX114XInterface.tpp | 4 +++- src/ACU_InterfaceTasks.cpp | 11 ++++++++++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index 6567b31..8ed13cd 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -36,6 +36,8 @@ namespace ACUInterfaces { constexpr int ADC0_MISO = 12; constexpr int ADC0_CLK = 13; constexpr int ADC0_SPEED = 2000000; // 1 MHz + /* ADC Versions*/ + constexpr int MAX1148_VERSION = 8; /* Channels on ADC */ constexpr int ISO_PACK_N_CHANNEL = 0; constexpr int ISO_PACK_P_CHANNEL = 1; @@ -144,4 +146,4 @@ namespace ACUConstants const uint32_t EM_CAN_baudrate = 500000; } -#endif \ No newline at end of file +#endif diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index b65655e..25fedac 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -10,13 +10,15 @@ const int MAX114X_ADC_DEFAULT_SPI_SDO = 11; const int MAX114X_ADC_DEFAULT_SPI_CLK = 13; const int MAX114X_ADC_DEFAULT_SPI_SPEED = 2000000; +/** + * Enum representing the different channel configurations in MAX114X ADCs (SINGLE, DIFFERENTIAL, or INV_DIFFERENTIAL) + */ enum class CHANNEL_TYPE_e{ SINGLE, DIFFERENTIAL, INV_DIFFERENTIAL, }; - /** * The MAX114X_ADC is a concrete subclass of the AnalogMultiSensor parent class. This allows * for SPI communication with any version of the MAX114X_ADC, which can be a 4-channel or 8-channel sensor. @@ -50,7 +52,7 @@ class MAX114XInterface : public AnalogMultiSensor public: /* Constructors */ - MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes, const int max114xVersion); + MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const CHANNEL_TYPE_e channelTypes[MAX114X_ADC_NUM_CHANNELS], const int max114xVersion); /* Functions */ diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index d08ab5d..f483922 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -5,12 +5,14 @@ Page 15: channel codes #include "MAX114XInterface.h" #include +#include template MAX114XInterface::MAX114XInterface( const int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], - const std::array& channelTypes, + // const std::array& channelTypes, + const CHANNEL_TYPE_e channelTypes[MAX114X_ADC_NUM_CHANNELS], const int max114xVersion) : _spiPinCS(spiPinCS) diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 3e3b40a..43ce331 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -99,6 +99,14 @@ void initialize_all_interfaces() ACUInterfaces::PACK_OUT_FILTERED_OFFSET, }; + // Consider saving this array as a constant in ACUConstants + std::array adc0_channels = { + CHANNEL_TYPE_e::INV_DIFFERENTIAL, + CHANNEL_TYPE_e::SINGLE, + CHANNEL_TYPE_e::DIFFERENTIAL, + CHANNEL_TYPE_e::SINGLE + }; + /* ADC Interface */ MAX1148ADCInstance_t::create( ACUInterfaces::ADC0_CS, @@ -108,7 +116,8 @@ void initialize_all_interfaces() ACUInterfaces::ADC0_SPEED, adc0_scales.data(), adc0_offsets.data(), - + adc0_channels.data(), + ACUInterfaces::MAX1148_VERSION // Save this value as a constant in ACUConstants ); /* CCU Interface */ From e18f7cc572d870772add7a148d09dbf869ba46c5 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Wed, 14 Jan 2026 22:10:44 -0500 Subject: [PATCH 05/30] Fixed build issues in MAX114X Interface constructor and added comments --- lib/interfaces/include/MAX114XInterface.h | 4 ++-- lib/interfaces/include/MAX114XInterface.tpp | 12 +++++++++--- src/ACU_InterfaceTasks.cpp | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index 25fedac..c468c12 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -30,7 +30,7 @@ class MAX114XInterface : public AnalogMultiSensor private: // const int _max114xVersion; - const std::array _channelTypes; + const std::array _channelTypes; const int _spiPinCS; const int _spiPinSDI; @@ -52,7 +52,7 @@ class MAX114XInterface : public AnalogMultiSensor public: /* Constructors */ - MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const CHANNEL_TYPE_e channelTypes[MAX114X_ADC_NUM_CHANNELS], const int max114xVersion); + MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes, const int max114xVersion); /* Functions */ diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index f483922..84e6562 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -11,8 +11,8 @@ template MAX114XInterface::MAX114XInterface( const int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], - // const std::array& channelTypes, - const CHANNEL_TYPE_e channelTypes[MAX114X_ADC_NUM_CHANNELS], + const std::array& channelTypes, + // const CHANNEL_TYPE_e channelTypes[MAX114X_ADC_NUM_CHANNELS / 2], const int max114xVersion) : _spiPinCS(spiPinCS) @@ -31,6 +31,7 @@ MAX114XInterface::MAX114XInterface( pinMode(_spiPinCS, OUTPUT); digitalWrite(_spiPinCS, HIGH); + // Page 15 switch (max114xVersion) { case 6: case 7: @@ -41,7 +42,7 @@ MAX114XInterface::MAX114XInterface( _single_end_channel_to_select_map = {0, 4, 1, 5, 2, 6, 3, 7}; break; default: - // THROW ERROR + static_assert(false, "Invalid version number"); break; } @@ -108,10 +109,15 @@ int MAX114XInterface::_getSel(CHANNEL_TYPE_e channelTy { switch (channelType) { case CHANNEL_TYPE_e::SINGLE: + // The channel selection bits for single mode follows this array return _single_end_channel_to_select_map[channelId]; case CHANNEL_TYPE_e::DIFFERENTIAL: + // The channel selection bits for differential mode is the channel number halved and then truncated + // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair return channelId++ / 2; case CHANNEL_TYPE_e::INV_DIFFERENTIAL: + // The channel selection bits for inversed differential mode is the channel number halved, truncated, and plus 4 + // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair return (channelId++ / 2) + 4; } } diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 43ce331..9be2adf 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -100,7 +100,7 @@ void initialize_all_interfaces() }; // Consider saving this array as a constant in ACUConstants - std::array adc0_channels = { + std::array adc0_channels = { CHANNEL_TYPE_e::INV_DIFFERENTIAL, CHANNEL_TYPE_e::SINGLE, CHANNEL_TYPE_e::DIFFERENTIAL, @@ -116,7 +116,7 @@ void initialize_all_interfaces() ACUInterfaces::ADC0_SPEED, adc0_scales.data(), adc0_offsets.data(), - adc0_channels.data(), + adc0_channels, ACUInterfaces::MAX1148_VERSION // Save this value as a constant in ACUConstants ); From 4b81d7214042add23c3d985b9b3984edd9abd256 Mon Sep 17 00:00:00 2001 From: William Schotte Date: Wed, 14 Jan 2026 22:24:17 -0500 Subject: [PATCH 06/30] fixed header guards --- lib/interfaces/include/MAX114XInterface.h | 10 ++++++---- lib/interfaces/include/MAX114XInterface.tpp | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index c468c12..5684f58 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -1,9 +1,10 @@ -#ifndef MAX1148INTERFACE -#define MAX1148INTERFACE +#ifndef MAX114XINTERFACE_H +#define MAX114XINTERFACE_H -#include #include "AnalogSensorsInterface.h" +#include + // Definitions const int MAX114X_ADC_DEFAULT_SPI_SDI = 12; const int MAX114X_ADC_DEFAULT_SPI_SDO = 11; @@ -12,6 +13,7 @@ const int MAX114X_ADC_DEFAULT_SPI_SPEED = 2000000; /** * Enum representing the different channel configurations in MAX114X ADCs (SINGLE, DIFFERENTIAL, or INV_DIFFERENTIAL) + * @param */ enum class CHANNEL_TYPE_e{ SINGLE, @@ -68,4 +70,4 @@ using MAX114XInterfaceInstance = etl::singleton #include From a52518d1d32d8b9006bb52e031d397dce68af326 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Wed, 14 Jan 2026 23:10:00 -0500 Subject: [PATCH 07/30] Co-authored-by: William Schotte Co-authored-by: Ryan2551 --- include/ACU_InterfaceTasks.h | 4 +- lib/interfaces/include/MAX114XInterface.h | 28 ++++---- lib/interfaces/include/MAX114XInterface.tpp | 76 ++++++++++++--------- src/ACU_InterfaceTasks.cpp | 3 +- 4 files changed, 64 insertions(+), 47 deletions(-) diff --git a/include/ACU_InterfaceTasks.h b/include/ACU_InterfaceTasks.h index f110533..6db6007 100644 --- a/include/ACU_InterfaceTasks.h +++ b/include/ACU_InterfaceTasks.h @@ -25,9 +25,9 @@ using chip_type = LTC6811_Type_e; using BMSDriverInstance_t = BMSDriverInstance; using BMSFaultDataManagerInstance_t = BMSFaultDataManagerInstance; -using MAX1148ADCInstance_t = MAX114XInterfaceInstance; +using MAX1148ADCInstance_t = MAX114XInterfaceInstance; /** - * Init Functions - to be called in setup + * Init Functions - to be called in setup@ */ void initialize_all_interfaces(); diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index c468c12..1c99337 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -11,25 +11,25 @@ const int MAX114X_ADC_DEFAULT_SPI_CLK = 13; const int MAX114X_ADC_DEFAULT_SPI_SPEED = 2000000; /** - * Enum representing the different channel configurations in MAX114X ADCs (SINGLE, DIFFERENTIAL, or INV_DIFFERENTIAL) + * Enum representing the different channel configurations in MAX114X ADCs */ enum class CHANNEL_TYPE_e{ - SINGLE, - DIFFERENTIAL, - INV_DIFFERENTIAL, + SINGLE, ///< single channel + DIFFERENTIAL, ///< +- differential pair + INV_DIFFERENTIAL, ///< -+ differential pair }; /** * The MAX114X_ADC is a concrete subclass of the AnalogMultiSensor parent class. This allows * for SPI communication with any version of the MAX114X_ADC, which can be a 4-channel or 8-channel sensor. * IMPORTANT - must call SPI.begin() once and only once before instantiating any MCP_ADC object!! + * @param MAX114X_ADC_NUM_CHANNELS number of channels for the ADC + * @param MAX114xVersion 6, 7, 8, or 9, corresponding to the MAX1146, MAX1147, MAX1148, and MAX1149 ADCs */ -template +template class MAX114XInterface : public AnalogMultiSensor { private: - // const int _max114xVersion; - const std::array _channelTypes; const int _spiPinCS; @@ -39,8 +39,6 @@ class MAX114XInterface : public AnalogMultiSensor const int _spiSpeed; std::array _single_end_channel_to_select_map; - std::array _differential_end_channel_to_select_map; - std::array _inv_differential_end_channel_to_select_map; /** * Samples the MCP_ADC over SPI. Samples all eight channels and, in accordance with the AnalogMultiSensor's function @@ -48,11 +46,17 @@ class MAX114XInterface : public AnalogMultiSensor */ void _sample() override; + /** + * Returns the channel selection bits for a channel based on its type and ID. Also increments the channelId for the sample() function when channel is part of a pair. + * @param channelType CHANNEL_TYPE_e of the channel + * @param channelId the channel number + * @return channel selection bits + */ int _getSel(CHANNEL_TYPE_e channelType, int& channelId); public: /* Constructors */ - MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes, const int max114xVersion); + MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes); /* Functions */ @@ -63,8 +67,8 @@ class MAX114XInterface : public AnalogMultiSensor }; -template -using MAX114XInterfaceInstance = etl::singleton>; +template +using MAX114XInterfaceInstance = etl::singleton>; #include "MAX114XInterface.tpp" diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 84e6562..a104589 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -1,19 +1,19 @@ -/* Code was based off of this data sheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX1146-MAX1149.pdf -Page 14: Control byte format -Page 15: channel codes -*/ +/** + * Code was based off of this data sheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX1146-MAX1149.pdf + * Page 14: Control byte format + * Page 15: channel codes + */ + #include "MAX114XInterface.h" #include #include -template -MAX114XInterface::MAX114XInterface( +template +MAX114XInterface::MAX114XInterface( const int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], - const std::array& channelTypes, - // const CHANNEL_TYPE_e channelTypes[MAX114X_ADC_NUM_CHANNELS / 2], - const int max114xVersion) + const std::array& channelTypes) : _spiPinCS(spiPinCS) , _spiPinSDI(spiPinSDI) @@ -24,39 +24,45 @@ MAX114XInterface::MAX114XInterface( { for (int i = 0; i < MAX114X_ADC_NUM_CHANNELS; i++) { - MAX114XInterface::_channels[i] = AnalogChannel(); + MAX114XInterface::_channels[i] = AnalogChannel(); this->setChannelScaleAndOffset(i, scales[i], offsets[i]); } pinMode(_spiPinCS, OUTPUT); digitalWrite(_spiPinCS, HIGH); - // Page 15 - switch (max114xVersion) { - case 6: - case 7: - _single_end_channel_to_select_map = {0, 4, 1, 5}; - break; - case 8: - case 9: - _single_end_channel_to_select_map = {0, 4, 1, 5, 2, 6, 3, 7}; - break; - default: - static_assert(false, "Invalid version number"); - break; + // Returns a compile time error if an incorrect version is given to the interface's template + static_assert( + (MAX114xVersion == 6 || MAX114xVersion == 7 || + MAX114xVersion == 8 || MAX114xVersion == 9), + "Invalid MAX114X version number" + ); + + // Page 15 of datasheet + switch (MAX114xVersion) { + case 6: + case 7: + _single_end_channel_to_select_map = {0, 4, 1, 5}; + break; + case 8: + case 9: + _single_end_channel_to_select_map = {0, 4, 1, 5, 2, 6, 3, 7}; + break; + default: + break; } } -template -void MAX114XInterface::tick() +template +void MAX114XInterface::tick() { _sample(); this->_convert(); } -template -void MAX114XInterface::_sample() +template +void MAX114XInterface::_sample() { // uint16_t command = ( // (0b1 << 15) | // start bit @@ -84,6 +90,7 @@ void MAX114XInterface::_sample() b1 = SPI.transfer(0x00); b2 = SPI.transfer(0x00); + // MOVE DEBUGGING TO TASKS Serial.print("b1: "); Serial.print(b1, HEX); Serial.print(" b2: "); @@ -91,9 +98,11 @@ void MAX114XInterface::_sample() // uint16_t value = SPI.transfer16(command | channelIndex << 11); uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); - Serial.print(" value: "); + Serial.print(" value: "); Serial.println(value); - MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); + // REMOVE ABOVE + + MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); // UPDATE CODE ABOVE @@ -104,18 +113,23 @@ void MAX114XInterface::_sample() SPI.endTransaction(); } -template -int MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int& channelId) +template +int MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int& channelId) { switch (channelType) { case CHANNEL_TYPE_e::SINGLE: + // The channel selection bits for single mode follows this array return _single_end_channel_to_select_map[channelId]; + case CHANNEL_TYPE_e::DIFFERENTIAL: + // The channel selection bits for differential mode is the channel number halved and then truncated // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair return channelId++ / 2; + case CHANNEL_TYPE_e::INV_DIFFERENTIAL: + // The channel selection bits for inversed differential mode is the channel number halved, truncated, and plus 4 // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair return (channelId++ / 2) + 4; diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 9be2adf..317b35f 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -116,8 +116,7 @@ void initialize_all_interfaces() ACUInterfaces::ADC0_SPEED, adc0_scales.data(), adc0_offsets.data(), - adc0_channels, - ACUInterfaces::MAX1148_VERSION // Save this value as a constant in ACUConstants + adc0_channels ); /* CCU Interface */ From 141614c38bce109600792d63bc23f908ab4d38ce Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Wed, 14 Jan 2026 23:47:55 -0500 Subject: [PATCH 08/30] Fixing naming bug --- include/ACU_Constants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index 8ed13cd..4610e3b 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -37,7 +37,7 @@ namespace ACUInterfaces { constexpr int ADC0_CLK = 13; constexpr int ADC0_SPEED = 2000000; // 1 MHz /* ADC Versions*/ - constexpr int MAX1148_VERSION = 8; + constexpr int MAX114X_VERSION = 8; /* Channels on ADC */ constexpr int ISO_PACK_N_CHANNEL = 0; constexpr int ISO_PACK_P_CHANNEL = 1; From 6057b5c21834756061d94ae36ae8dabe8980b2db Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Thu, 15 Jan 2026 12:56:07 -0500 Subject: [PATCH 09/30] Added and removed some comments --- lib/interfaces/include/MAX114XInterface.h | 10 ++++++++ src/main.cpp | 28 +++++++++++------------ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index 9686817..9619590 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -31,6 +31,12 @@ template class MAX114XInterface : public AnalogMultiSensor { private: + /** + * Channel configuration is defined per channel pair (two physical channels). + * This array stores the channel type for each pair of channels in the ADC. + * Each pair may be configured as SINGLE, DIFFERENTIAL, or INV_DIFFERENTIAL as defined in the enclosed enum. + * SINGLE indicates both channels in the pair are single-ended inputs and operate separately. + */ const std::array _channelTypes; const int _spiPinCS; @@ -39,6 +45,10 @@ class MAX114XInterface : public AnalogMultiSensor const int _spiPinCLK; const int _spiSpeed; + /** + * The select bits for single-ended channels are all over the place and do not follow a logical mapping. + * This array stores the specific single-ended select-bit mapping for each channel as defined in the datasheet. + */ std::array _single_end_channel_to_select_map; /** diff --git a/src/main.cpp b/src/main.cpp index aab7456..7c11f26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -49,23 +49,23 @@ void setup() initialize_all_systems(); scheduler.setTimingFunction(micros); - // scheduler.schedule(tick_state_machine_task); - // scheduler.schedule(kick_watchdog_task); - // scheduler.schedule(sample_bms_data_task); - // scheduler.schedule(eval_accumulator_task); - // scheduler.schedule(write_cell_balancing_config_task); + scheduler.schedule(tick_state_machine_task); + scheduler.schedule(kick_watchdog_task); + scheduler.schedule(sample_bms_data_task); + scheduler.schedule(eval_accumulator_task); + scheduler.schedule(write_cell_balancing_config_task); - // scheduler.schedule(send_all_data_ethernet_task); - // scheduler.schedule(send_core_data_ethernet_task); // waiting on update on drivebrain + scheduler.schedule(send_all_data_ethernet_task); + scheduler.schedule(send_core_data_ethernet_task); // waiting on update on drivebrain - // scheduler.schedule(send_CAN_task); - // scheduler.schedule(enqueue_CCU_core_CAN_task); - // scheduler.schedule(enqueue_CCU_all_voltages_CAN_task); - // scheduler.schedule(enqueue_CCU_all_temps_CAN_task); - // scheduler.schedule(enqueue_ACU_OK_CAN_task); + scheduler.schedule(send_CAN_task); + scheduler.schedule(enqueue_CCU_core_CAN_task); + scheduler.schedule(enqueue_CCU_all_voltages_CAN_task); + scheduler.schedule(enqueue_CCU_all_temps_CAN_task); + scheduler.schedule(enqueue_ACU_OK_CAN_task); - // scheduler.schedule(sample_CAN_task); - // scheduler.schedule(idle_sample_task); + scheduler.schedule(sample_CAN_task); + scheduler.schedule(idle_sample_task); //scheduler.schedule(debug_prints_task); From 0ae0cd1f79f427780fe687836842574d1abbd2f9 Mon Sep 17 00:00:00 2001 From: William Schotte Date: Thu, 15 Jan 2026 19:35:44 -0500 Subject: [PATCH 10/30] added additional comments --- lib/interfaces/include/MAX114XInterface.h | 6 +++++- lib/interfaces/include/MAX114XInterface.tpp | 17 ++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index 9619590..9eafc52 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -58,7 +58,7 @@ class MAX114XInterface : public AnalogMultiSensor void _sample() override; /** - * Returns the channel selection bits for a channel based on its type and ID. Also increments the channelId for the sample() function when channel is part of a pair. + * Returns the channel selection bits for a channel based on its type and ID. Also increments the channelId/loop index for the sample() function when channel is part of a differential pair. * @param channelType CHANNEL_TYPE_e of the channel * @param channelId the channel number * @return channel selection bits @@ -67,6 +67,10 @@ class MAX114XInterface : public AnalogMultiSensor public: /* Constructors */ + /** + * Constructs a MAX114X ADC interface of the specified ADC model, number of channels, and channel types. + * @param channelTypes Constructs an array of channel types (Single, Differential, Inverse Differential) that is half the length of the ADC's channels. This is because each element of the array corresponds to a pair of channels. + */ MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes); /* Functions */ diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 8129079..3161629 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -22,7 +22,8 @@ MAX114XInterface::MAX114XInterface( , _spiPinCLK(spiPinCLK) , _spiSpeed(spiSpeed) , _channelTypes(channelTypes) -{ +{ + /* Constructs an AnalogChannel object for each channel of the ADC and sets scales and offsets*/ for (int i = 0; i < MAX114X_ADC_NUM_CHANNELS; i++) { MAX114XInterface::_channels[i] = AnalogChannel(); @@ -40,6 +41,7 @@ MAX114XInterface::MAX114XInterface( ); // Page 15 of datasheet + /* Assigns single mode selection codes to an array depending on version*/ switch (MAX114xVersion) { case 6: case 7: @@ -78,18 +80,19 @@ void MAX114XInterface::_sample() { digitalWrite(_spiPinCS, LOW); + /* Creates variable corresponding to the current channels channelType (Single, Differential, Inverse Differential) using the array input by the user. The index is divided by 2 since there is one channelType enum corresponding to each pair of channels */ CHANNEL_TYPE_e channelType = _channelTypes[channelIndex / 2]; - // UPDATE CODE BELOW + /* Page 14 of datasheet */ command = ((0x01 << 7) | // start bit ((_getSel(channelType, channelIndex) & 0x07) << 4) | // channel number - ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single or differential + ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode - (0x01 << 1)); // + (0x01 << 1)); // CHECK THIS b0 = SPI.transfer(command); - b1 = SPI.transfer(0x00); - b2 = SPI.transfer(0x00); + b1 = SPI.transfer(0x00); // dummy bytes to clock out data from the ADC + b2 = SPI.transfer(0x00); // ^ // MOVE DEBUGGING TO TASKS Serial.print("b1: "); @@ -124,7 +127,7 @@ int MAX114XInterface::_getSel(CHANNEL_ return _single_end_channel_to_select_map[channelId]; case CHANNEL_TYPE_e::DIFFERENTIAL: - + // The channel selection bits for differential mode is the channel number halved and then truncated // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair return channelId++ / 2; From f8b6fd01c4d3c885f000cebde19d24753b1acbcb Mon Sep 17 00:00:00 2001 From: William Schotte Date: Fri, 16 Jan 2026 17:55:39 -0500 Subject: [PATCH 11/30] improved some comments --- lib/interfaces/include/MAX114XInterface.tpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 3161629..bf308c3 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -89,12 +89,13 @@ void MAX114XInterface::_sample() ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode - (0x01 << 1)); // CHECK THIS + (0x01 << 1)); // ^ b0 = SPI.transfer(command); b1 = SPI.transfer(0x00); // dummy bytes to clock out data from the ADC b2 = SPI.transfer(0x00); // ^ // MOVE DEBUGGING TO TASKS + Serial.print("") Serial.print("b1: "); Serial.print(b1, HEX); Serial.print(" b2: "); @@ -108,8 +109,6 @@ void MAX114XInterface::_sample() MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); - // UPDATE CODE ABOVE - digitalWrite(_spiPinCS, HIGH); delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns } @@ -134,7 +133,7 @@ int MAX114XInterface::_getSel(CHANNEL_ case CHANNEL_TYPE_e::INV_DIFFERENTIAL: - // The channel selection bits for inversed differential mode is the channel number halved, truncated, and plus 4 + // The channel selection bits for inverse differential mode is the channel number halved, truncated, and plus 4 (SEL codes 1-4 are differential and 5-8 are inverse differential) // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair return (channelId++ / 2) + 4; } From 462c235545637b88a025438dde18cb16adfde3bd Mon Sep 17 00:00:00 2001 From: William Schotte Date: Fri, 16 Jan 2026 19:10:56 -0500 Subject: [PATCH 12/30] Improved print statements and verified code worked on ADC --- lib/interfaces/include/MAX114XInterface.tpp | 33 ++++++++++++++++++--- src/ACU_InterfaceTasks.cpp | 8 ++++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index bf308c3..7c68398 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -89,14 +89,38 @@ void MAX114XInterface::_sample() ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode - (0x01 << 1)); // ^ + (0x01)); // ^ b0 = SPI.transfer(command); b1 = SPI.transfer(0x00); // dummy bytes to clock out data from the ADC b2 = SPI.transfer(0x00); // ^ - // MOVE DEBUGGING TO TASKS - Serial.print("") - Serial.print("b1: "); + // MOVE TO DEBUG PRINT + Serial.print("\n"); + if (channelType == CHANNEL_TYPE_e::SINGLE) + { + Serial.print("Single Channel: "); + Serial.print(channelIndex); + } + else + { + if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { + Serial.print("Differential"); + } + else + { + Serial.print("Inverse Differential"); + } + Serial.print(" Channels: "); + Serial.print(channelIndex - 1); + Serial.print(" & "); + Serial.print(channelIndex); + } + + Serial.print(" b0/command: "); + Serial.print(command, BIN); + + + Serial.print(" b1: "); Serial.print(b1, HEX); Serial.print(" b2: "); Serial.print(b2, HEX); @@ -107,6 +131,7 @@ void MAX114XInterface::_sample() Serial.println(value); // REMOVE ABOVE + /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the higher of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 2 holds the return value. */ MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); digitalWrite(_spiPinCS, HIGH); diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 00ad8b4..0caafc7 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -106,6 +106,12 @@ void initialize_all_interfaces() CHANNEL_TYPE_e::DIFFERENTIAL, CHANNEL_TYPE_e::SINGLE }; + // std::array adc0_channels = { + // CHANNEL_TYPE_e::SINGLE, + // CHANNEL_TYPE_e::SINGLE, + // CHANNEL_TYPE_e::SINGLE, + // CHANNEL_TYPE_e::SINGLE + // }; /* ADC Interface */ MAX1148ADCInstance_t::create( @@ -190,7 +196,7 @@ HT_TASK::TaskResponse sample_adc(const unsigned long& sysMicros, const HT_TASK:: Serial.print(data.conversions[i].conversion); Serial.print(" "); } - + Serial.print("\n------------------------------------------------------------------"); return HT_TASK::TaskResponse::YIELD; } From 25b2fa65ff49588a5c25960e33cbc566f85b765d Mon Sep 17 00:00:00 2001 From: akemiyu <43460886+akemiyu@users.noreply.github.com> Date: Sun, 18 Jan 2026 10:05:31 -0500 Subject: [PATCH 13/30] Shifted print statements from Interface to InterfaceTasks --- lib/interfaces/include/MAX114XInterface.h | 4 ++ lib/interfaces/include/MAX114XInterface.tpp | 69 ++++++++++++--------- src/ACU_InterfaceTasks.cpp | 8 +++ 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index 9eafc52..f9a6d6c 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -80,6 +80,10 @@ class MAX114XInterface : public AnalogMultiSensor */ void tick() override; + /** + * Gets 14 bit value of a channel for a sample + */ + uint16_t getLastSample(int index) const; }; template diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 7c68398..ca46934 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -95,40 +95,40 @@ void MAX114XInterface::_sample() b2 = SPI.transfer(0x00); // ^ // MOVE TO DEBUG PRINT - Serial.print("\n"); - if (channelType == CHANNEL_TYPE_e::SINGLE) - { - Serial.print("Single Channel: "); - Serial.print(channelIndex); - } - else - { - if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { - Serial.print("Differential"); - } - else - { - Serial.print("Inverse Differential"); - } - Serial.print(" Channels: "); - Serial.print(channelIndex - 1); - Serial.print(" & "); - Serial.print(channelIndex); - } - - Serial.print(" b0/command: "); - Serial.print(command, BIN); - - - Serial.print(" b1: "); - Serial.print(b1, HEX); - Serial.print(" b2: "); - Serial.print(b2, HEX); + // Serial.print("\n"); + // if (channelType == CHANNEL_TYPE_e::SINGLE) + // { + // Serial.print("Single Channel: "); + // Serial.print(channelIndex); + // } + // else + // { + // if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { + // Serial.print("Differential"); + // } + // else + // { + // Serial.print("Inverse Differential"); + // } + // Serial.print(" Channels: "); + // Serial.print(channelIndex - 1); + // Serial.print(" & "); + // Serial.print(channelIndex); + // } + + // Serial.print(" b0/command: "); + // Serial.print(command, BIN); + + + // Serial.print(" b1: "); + // Serial.print(b1, HEX); + // Serial.print(" b2: "); + // Serial.print(b2, HEX); // uint16_t value = SPI.transfer16(command | channelIndex << 11); uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); - Serial.print(" value: "); - Serial.println(value); + // Serial.print(" value: "); + // Serial.println(value); // REMOVE ABOVE /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the higher of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 2 holds the return value. */ @@ -141,6 +141,13 @@ void MAX114XInterface::_sample() SPI.endTransaction(); } +template +uint16_t MAX114XInterface::getLastSample(int index) const +{ + return this->_channels[index].lastSample; +} + + template int MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int& channelId) { diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 0caafc7..e740c39 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -457,5 +457,13 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: // } // Serial.println(); + for (int i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { + Serial.print("CH"); + Serial.print(i); + Serial.print(": "); + Serial.print(MAX1148ADCInstance_t::instance().getLastSample(i)); + Serial.print(" "); + } + return HT_TASK::TaskResponse::YIELD; } From 8af3f9f7217f6bfcc18d49aa77b26754566806ca Mon Sep 17 00:00:00 2001 From: William Schotte Date: Sun, 18 Jan 2026 16:46:46 -0500 Subject: [PATCH 14/30] modified debug print --- src/ACU_InterfaceTasks.cpp | 5 ++--- src/main.cpp | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index e740c39..6c04818 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -99,7 +99,7 @@ void initialize_all_interfaces() ACUInterfaces::PACK_OUT_FILTERED_OFFSET, }; - // Consider saving this array as a constant in ACUConstants + // Each channel type corresponds to a pair of channels (0&1, 2&3, etc.) So length is channels / 2 std::array adc0_channels = { CHANNEL_TYPE_e::INV_DIFFERENTIAL, CHANNEL_TYPE_e::SINGLE, @@ -190,13 +190,11 @@ HT_TASK::TaskResponse sample_adc(const unsigned long& sysMicros, const HT_TASK:: { MAX1148ADCInstance_t::instance().tick(); - Serial.print("ADC0: "); auto data = MAX1148ADCInstance_t::instance().get(); for (size_t i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { Serial.print(data.conversions[i].conversion); Serial.print(" "); } - Serial.print("\n------------------------------------------------------------------"); return HT_TASK::TaskResponse::YIELD; } @@ -457,6 +455,7 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: // } // Serial.println(); + Serial.println("MAX114X Interface Output: "); for (int i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { Serial.print("CH"); Serial.print(i); diff --git a/src/main.cpp b/src/main.cpp index 7c11f26..040d5d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,7 +67,7 @@ void setup() scheduler.schedule(sample_CAN_task); scheduler.schedule(idle_sample_task); - //scheduler.schedule(debug_prints_task); + // scheduler.schedule(debug_prints_task); scheduler.schedule(sample_adc_task); @@ -78,4 +78,4 @@ void setup() void loop() { scheduler.run(); -} \ No newline at end of file +} From ffef987b4569562c348dd6dba768eb1c558fb718 Mon Sep 17 00:00:00 2001 From: William Schotte Date: Sun, 18 Jan 2026 16:56:19 -0500 Subject: [PATCH 15/30] reformatted debug print for MAX114X --- src/ACU_InterfaceTasks.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 6c04818..3037d0e 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -191,10 +191,10 @@ HT_TASK::TaskResponse sample_adc(const unsigned long& sysMicros, const HT_TASK:: MAX1148ADCInstance_t::instance().tick(); auto data = MAX1148ADCInstance_t::instance().get(); - for (size_t i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { - Serial.print(data.conversions[i].conversion); - Serial.print(" "); - } + // for (size_t i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { + // Serial.print(data.conversions[i].conversion); + // Serial.print(" "); + // } return HT_TASK::TaskResponse::YIELD; } @@ -455,7 +455,7 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: // } // Serial.println(); - Serial.println("MAX114X Interface Output: "); + Serial.println("\nMAX114X Output: "); for (int i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { Serial.print("CH"); Serial.print(i); @@ -463,6 +463,7 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: Serial.print(MAX1148ADCInstance_t::instance().getLastSample(i)); Serial.print(" "); } + Serial.print('\n'); return HT_TASK::TaskResponse::YIELD; } From 10ab9c2c9bb0649be87d20584f6a0bd1af0bd062 Mon Sep 17 00:00:00 2001 From: William Schotte Date: Sun, 18 Jan 2026 17:50:55 -0500 Subject: [PATCH 16/30] fixed data getters (debug print on still) --- include/ACU_Constants.h | 1 + lib/interfaces/include/MAX114XInterface.h | 7 ++++++- lib/interfaces/include/MAX114XInterface.tpp | 9 +++++++-- src/ACU_InterfaceTasks.cpp | 8 +------- src/main.cpp | 2 +- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index 4610e3b..de2e265 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -47,6 +47,7 @@ namespace ACUInterfaces { constexpr int SHUNT_CURRENT_N_CHANNEL = 5; constexpr int TS_OUT_FILTERED_CHANNEL = 6; constexpr int PACK_OUT_FILTERED_CHANNEL = 7; + /* SCALE/OFFSETS on ADC */ const float ISO_PACK_N_SCALE = 1; const float ISO_PACK_P_SCALE = 1; diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index f9a6d6c..6f08423 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -83,7 +83,12 @@ class MAX114XInterface : public AnalogMultiSensor /** * Gets 14 bit value of a channel for a sample */ - uint16_t getLastSample(int index) const; + uint16_t getLastSampleRaw(int index) const; + + /** + * Gets 14 bit value of a channel for a sample + */ + float getLastSampleConverted(int index) const; }; template diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index ca46934..91ef816 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -142,11 +142,16 @@ void MAX114XInterface::_sample() } template -uint16_t MAX114XInterface::getLastSample(int index) const +uint16_t MAX114XInterface::getLastSampleRaw(int index) const { - return this->_channels[index].lastSample; + return static_cast(this->data.conversions[index].raw); } +template +float MAX114XInterface::getLastSampleConverted(int index) const +{ + return this->data.conversions[index].conversion; +} template int MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int& channelId) diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 3037d0e..35a448b 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -189,12 +189,6 @@ HT_TASK::TaskResponse write_cell_balancing_config(const unsigned long &sysMicros HT_TASK::TaskResponse sample_adc(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo) { MAX1148ADCInstance_t::instance().tick(); - - auto data = MAX1148ADCInstance_t::instance().get(); - // for (size_t i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { - // Serial.print(data.conversions[i].conversion); - // Serial.print(" "); - // } return HT_TASK::TaskResponse::YIELD; } @@ -460,7 +454,7 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: Serial.print("CH"); Serial.print(i); Serial.print(": "); - Serial.print(MAX1148ADCInstance_t::instance().getLastSample(i)); + Serial.print(MAX1148ADCInstance_t::instance().getLastSampleConverted(i)); Serial.print(" "); } Serial.print('\n'); diff --git a/src/main.cpp b/src/main.cpp index 040d5d8..d56c63d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,7 +67,7 @@ void setup() scheduler.schedule(sample_CAN_task); scheduler.schedule(idle_sample_task); - // scheduler.schedule(debug_prints_task); + scheduler.schedule(debug_prints_task); scheduler.schedule(sample_adc_task); From bea950b46ae7449d95bd7eb99b86efab3fb6a2ca Mon Sep 17 00:00:00 2001 From: William Schotte Date: Sun, 18 Jan 2026 18:52:58 -0500 Subject: [PATCH 17/30] added only sampling two channels per call and scaling (something is wrong) --- include/ACU_Constants.h | 8 +-- lib/interfaces/include/MAX114XInterface.h | 56 +++++++++++---------- lib/interfaces/include/MAX114XInterface.tpp | 42 +++++++++------- src/ACU_InterfaceTasks.cpp | 3 ++ 4 files changed, 60 insertions(+), 49 deletions(-) diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index de2e265..4fba193 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -52,15 +52,15 @@ namespace ACUInterfaces { const float ISO_PACK_N_SCALE = 1; const float ISO_PACK_P_SCALE = 1; const float PACK_VOLTAGE_SENSE_SCALE = 1; - const float SHUNT_CURRENT_OUT_SCALE = 1; - const float SHUNT_CURRENT_P_SCALE = 1; - const float SHUNT_CURRENT_N_SCALE = 1; + const float SHUNT_CURRENT_OUT_SCALE = 0.03125; + const float SHUNT_CURRENT_P_SCALE = 0.00025; + const float SHUNT_CURRENT_N_SCALE = 0.00025; const float TS_OUT_FILTERED_SCALE = 1; const float PACK_OUT_FILTERED_SCALE = 1; const float ISO_PACK_N_OFFSET = 0; const float ISO_PACK_P_OFFSET = 0; const float PACK_VOLTAGE_SENSE_OFFSET = 0; - const float SHUNT_CURRENT_OUT_OFFSET = 0; + const float SHUNT_CURRENT_OUT_OFFSET = -250; const float SHUNT_CURRENT_P_OFFSET = 0; const float SHUNT_CURRENT_N_OFFSET = 0; const float TS_OUT_FILTERED_OFFSET = 0; diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index 6f08423..1c1a1ae 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -30,6 +30,31 @@ enum class CHANNEL_TYPE_e{ template class MAX114XInterface : public AnalogMultiSensor { +public: + /* Constructors */ + /** + * Constructs a MAX114X ADC interface of the specified ADC model, number of channels, and channel types. + * @param channelTypes Constructs an array of channel types (Single, Differential, Inverse Differential) that is half the length of the ADC's channels. This is because each element of the array corresponds to a pair of channels. + */ + MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes); + + /* Functions */ + + /** + * Calls sample() and convert(). After calling tick(), this MCP_ADC's data can be accessed using the get() command. + */ + void tick() override; + + /** + * Gets raw 14 bit value of a channel for a sample + */ + uint16_t getLastSampleRaw(int index) const; + + /** + * Gets real value (current/voltage) of a channel for a sample + */ + float getLastSampleConverted(int index) const; + private: /** * Channel configuration is defined per channel pair (two physical channels). @@ -38,25 +63,26 @@ class MAX114XInterface : public AnalogMultiSensor * SINGLE indicates both channels in the pair are single-ended inputs and operate separately. */ const std::array _channelTypes; - + const int _spiPinCS; const int _spiPinSDI; const int _spiPinSDO; const int _spiPinCLK; const int _spiSpeed; + int _currentChannel; /** * The select bits for single-ended channels are all over the place and do not follow a logical mapping. * This array stores the specific single-ended select-bit mapping for each channel as defined in the datasheet. */ std::array _single_end_channel_to_select_map; - + /** * Samples the MCP_ADC over SPI. Samples all eight channels and, in accordance with the AnalogMultiSensor's function * contract, stores the raw sampled values into each AnalogChannel's lastSample instance variable. */ void _sample() override; - + /** * Returns the channel selection bits for a channel based on its type and ID. Also increments the channelId/loop index for the sample() function when channel is part of a differential pair. * @param channelType CHANNEL_TYPE_e of the channel @@ -65,30 +91,6 @@ class MAX114XInterface : public AnalogMultiSensor */ int _getSel(CHANNEL_TYPE_e channelType, int& channelId); -public: - /* Constructors */ - /** - * Constructs a MAX114X ADC interface of the specified ADC model, number of channels, and channel types. - * @param channelTypes Constructs an array of channel types (Single, Differential, Inverse Differential) that is half the length of the ADC's channels. This is because each element of the array corresponds to a pair of channels. - */ - MAX114XInterface(int spiPinCS, const int spiPinSDI, const int spiPinSDO, const int spiPinCLK, const int spiSpeed, const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes); - - /* Functions */ - - /** - * Calls sample() and convert(). After calling tick(), this MCP_ADC's data can be accessed using the get() command. - */ - void tick() override; - - /** - * Gets 14 bit value of a channel for a sample - */ - uint16_t getLastSampleRaw(int index) const; - - /** - * Gets 14 bit value of a channel for a sample - */ - float getLastSampleConverted(int index) const; }; template diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 91ef816..0398580 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -16,12 +16,13 @@ MAX114XInterface::MAX114XInterface( const float scales[MAX114X_ADC_NUM_CHANNELS], const float offsets[MAX114X_ADC_NUM_CHANNELS], const std::array& channelTypes) - : _spiPinCS(spiPinCS) + : _channelTypes(channelTypes) + , _spiPinCS(spiPinCS) , _spiPinSDI(spiPinSDI) , _spiPinSDO(spiPinSDO) , _spiPinCLK(spiPinCLK) , _spiSpeed(spiSpeed) - , _channelTypes(channelTypes) + , _currentChannel(0) { /* Constructs an AnalogChannel object for each channel of the ADC and sets scales and offsets*/ for (int i = 0; i < MAX114X_ADC_NUM_CHANNELS; i++) @@ -64,9 +65,22 @@ void MAX114XInterface::tick() this->_convert(); } +template +uint16_t MAX114XInterface::getLastSampleRaw(int index) const +{ + return static_cast(this->data.conversions[index].raw); +} + +template +float MAX114XInterface::getLastSampleConverted(int index) const +{ + return this->data.conversions[index].conversion; +} + template void MAX114XInterface::_sample() { + _currentChannel %= 8; // uint16_t command = ( // (0b1 << 15) | // start bit // (0b1 << 14) // single ended mode @@ -76,16 +90,18 @@ void MAX114XInterface::_sample() // initialize SPI bus. REQUIRED: call SPI.begin() before this SPI.beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); - for (int channelIndex = 0; channelIndex < MAX114X_ADC_NUM_CHANNELS; channelIndex++) + + int currentChannelPairEnd = _currentChannel + 2; + while (_currentChannel < currentChannelPairEnd) { digitalWrite(_spiPinCS, LOW); /* Creates variable corresponding to the current channels channelType (Single, Differential, Inverse Differential) using the array input by the user. The index is divided by 2 since there is one channelType enum corresponding to each pair of channels */ - CHANNEL_TYPE_e channelType = _channelTypes[channelIndex / 2]; + CHANNEL_TYPE_e channelType = _channelTypes[_currentChannel / 2]; /* Page 14 of datasheet */ command = ((0x01 << 7) | // start bit - ((_getSel(channelType, channelIndex) & 0x07) << 4) | // channel number + ((_getSel(channelType, _currentChannel) & 0x07) << 4) | // channel number ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode @@ -105,6 +121,7 @@ void MAX114XInterface::_sample() // { // if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { // Serial.print("Differential"); + // } // else // { @@ -132,27 +149,16 @@ void MAX114XInterface::_sample() // REMOVE ABOVE /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the higher of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 2 holds the return value. */ - MAX114XInterface::_channels[channelIndex].lastSample = (value & 0x3FFF); + MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); digitalWrite(_spiPinCS, HIGH); delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns + _currentChannel++; } SPI.endTransaction(); } -template -uint16_t MAX114XInterface::getLastSampleRaw(int index) const -{ - return static_cast(this->data.conversions[index].raw); -} - -template -float MAX114XInterface::getLastSampleConverted(int index) const -{ - return this->data.conversions[index].conversion; -} - template int MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int& channelId) { diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 35a448b..fba87f5 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -454,6 +454,9 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: Serial.print("CH"); Serial.print(i); Serial.print(": "); + Serial.print("Raw = "); + Serial.print(MAX1148ADCInstance_t::instance().getLastSampleRaw(i)); + Serial.print(" Converted = "); Serial.print(MAX1148ADCInstance_t::instance().getLastSampleConverted(i)); Serial.print(" "); } From bf98300f497b775f4302bec1ea5e3037e382b3c4 Mon Sep 17 00:00:00 2001 From: William Schotte Date: Sun, 18 Jan 2026 19:12:54 -0500 Subject: [PATCH 18/30] removed loops --- lib/interfaces/include/MAX114XInterface.tpp | 126 ++++++++++---------- src/main.cpp | 2 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 0398580..e8a7c12 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -80,82 +80,82 @@ float MAX114XInterface::getLastSampleC template void MAX114XInterface::_sample() { - _currentChannel %= 8; // uint16_t command = ( // (0b1 << 15) | // start bit // (0b1 << 14) // single ended mode // ); + if (_currentChannel == 8){ + _currentChannel = 0; + } + byte command, b0, b1, b2; // initialize SPI bus. REQUIRED: call SPI.begin() before this SPI.beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); - int currentChannelPairEnd = _currentChannel + 2; - while (_currentChannel < currentChannelPairEnd) + + digitalWrite(_spiPinCS, LOW); + + /* Creates variable corresponding to the current channels channelType (Single, Differential, Inverse Differential) using the array input by the user. The index is divided by 2 since there is one channelType enum corresponding to each pair of channels */ + CHANNEL_TYPE_e channelType = _channelTypes[_currentChannel / 2]; + + /* Page 14 of datasheet */ + command = ((0x01 << 7) | // start bit + ((_getSel(channelType, _currentChannel) & 0x07) << 4) | // channel number + ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) + (0x01 << 2) | // unipolar or !bipolar + (0x01 << 1) | // external clock mode + (0x01)); // ^ + b0 = SPI.transfer(command); + b1 = SPI.transfer(0x00); // dummy bytes to clock out data from the ADC + b2 = SPI.transfer(0x00); // ^ + + // MOVE TO DEBUG PRINT + Serial.print("\n"); + if (channelType == CHANNEL_TYPE_e::SINGLE) { - digitalWrite(_spiPinCS, LOW); - - /* Creates variable corresponding to the current channels channelType (Single, Differential, Inverse Differential) using the array input by the user. The index is divided by 2 since there is one channelType enum corresponding to each pair of channels */ - CHANNEL_TYPE_e channelType = _channelTypes[_currentChannel / 2]; - - /* Page 14 of datasheet */ - command = ((0x01 << 7) | // start bit - ((_getSel(channelType, _currentChannel) & 0x07) << 4) | // channel number - ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) - (0x01 << 2) | // unipolar or !bipolar - (0x01 << 1) | // external clock mode - (0x01)); // ^ - b0 = SPI.transfer(command); - b1 = SPI.transfer(0x00); // dummy bytes to clock out data from the ADC - b2 = SPI.transfer(0x00); // ^ - - // MOVE TO DEBUG PRINT - // Serial.print("\n"); - // if (channelType == CHANNEL_TYPE_e::SINGLE) - // { - // Serial.print("Single Channel: "); - // Serial.print(channelIndex); - // } - // else - // { - // if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { - // Serial.print("Differential"); - - // } - // else - // { - // Serial.print("Inverse Differential"); - // } - // Serial.print(" Channels: "); - // Serial.print(channelIndex - 1); - // Serial.print(" & "); - // Serial.print(channelIndex); - // } - - // Serial.print(" b0/command: "); - // Serial.print(command, BIN); - - - // Serial.print(" b1: "); - // Serial.print(b1, HEX); - // Serial.print(" b2: "); - // Serial.print(b2, HEX); - - // uint16_t value = SPI.transfer16(command | channelIndex << 11); - uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); - // Serial.print(" value: "); - // Serial.println(value); - // REMOVE ABOVE - - /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the higher of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 2 holds the return value. */ - MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); - - digitalWrite(_spiPinCS, HIGH); - delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns - _currentChannel++; + Serial.print("Single Channel: "); + Serial.print(_currentChannel); + } + else + { + if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { + Serial.print("Differential"); + + } + else + { + Serial.print("Inverse Differential"); + } + Serial.print(" Channels: "); + Serial.print(_currentChannel - 1); + Serial.print(" & "); + Serial.print(_currentChannel); } + + Serial.print(" b0/command: "); + Serial.print(command, BIN); + + + Serial.print(" b1: "); + Serial.print(b1, HEX); + Serial.print(" b2: "); + Serial.print(b2, HEX); + + // uint16_t value = SPI.transfer16(command | _currentChannel << 11); + uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); + Serial.print(" value: "); + Serial.println(value); + // REMOVE ABOVE + + /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the higher of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 2 holds the return value. */ + MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); + digitalWrite(_spiPinCS, HIGH); + delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns + _currentChannel++; + SPI.endTransaction(); } diff --git a/src/main.cpp b/src/main.cpp index d56c63d..040d5d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,7 +67,7 @@ void setup() scheduler.schedule(sample_CAN_task); scheduler.schedule(idle_sample_task); - scheduler.schedule(debug_prints_task); + // scheduler.schedule(debug_prints_task); scheduler.schedule(sample_adc_task); From 6ca600f802dd15191fd6b0cd6819249d555143c7 Mon Sep 17 00:00:00 2001 From: William Schotte Date: Sun, 18 Jan 2026 21:37:39 -0500 Subject: [PATCH 19/30] maybe fixed something but broke serial monitor --- lib/interfaces/include/BMSDriverGroup.tpp | 6 ++--- lib/interfaces/include/LTCSPIInterface.tpp | 18 ++++++------- lib/interfaces/include/MAX114XInterface.h | 2 +- lib/interfaces/include/MAX114XInterface.tpp | 28 +++++++++++++++------ src/ACU_InterfaceTasks.cpp | 2 ++ 5 files changed, 35 insertions(+), 21 deletions(-) diff --git a/lib/interfaces/include/BMSDriverGroup.tpp b/lib/interfaces/include/BMSDriverGroup.tpp index 97f4906..013620b 100644 --- a/lib/interfaces/include/BMSDriverGroup.tpp +++ b/lib/interfaces/include/BMSDriverGroup.tpp @@ -77,13 +77,13 @@ void BMSDriverGroup::_start_wakeup_proto if constexpr (chip_type == LTC6811_Type_e::LTC6811_1) { ltc_spi_interface::_write_and_delay_low(_chip_select[cs], 400); - SPI.transfer16(0); + SPI1.transfer16(0); ltc_spi_interface::_write_and_delay_high(_chip_select[cs], 400); } else { ltc_spi_interface::_write_and_delay_low(_chip_select[cs], 400); - SPI.transfer(0); + SPI1.transfer(0); ltc_spi_interface::_write_and_delay_high(_chip_select[cs], 400); // t_wake is 400 microseconds; wait that long to ensure device has turned on. } } @@ -783,4 +783,4 @@ size_t BMSDriverGroup::count_invalid_pac } } return invalid_count; -} \ No newline at end of file +} diff --git a/lib/interfaces/include/LTCSPIInterface.tpp b/lib/interfaces/include/LTCSPIInterface.tpp index 9569051..f19b7dd 100644 --- a/lib/interfaces/include/LTCSPIInterface.tpp +++ b/lib/interfaces/include/LTCSPIInterface.tpp @@ -5,7 +5,7 @@ template void _transfer_SPI_data(const std::array &data) { for (size_t i = 0; i < data_size; i++) { - SPI.transfer(data[i]); + SPI1.transfer(data[i]); } } @@ -14,7 +14,7 @@ std::array _receive_SPI_data() { std::array data_in; for (size_t i = 0; i < data_size; i++) { - data_in[i] = SPI.transfer(0); + data_in[i] = SPI1.transfer(0); } return data_in; @@ -32,7 +32,7 @@ void ltc_spi_interface::_write_and_delay_high(int cs, int delay_microSeconds) { template void ltc_spi_interface::write_registers_command(int cs, std::array cmd_and_pec, const std::array &data) { - SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3)); + SPI1.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3)); // Prompting SPI enable _write_and_delay_low(cs, 5); @@ -41,14 +41,14 @@ void ltc_spi_interface::write_registers_command(int cs, std::array c _transfer_SPI_data(data); _write_and_delay_high(cs, 5); - SPI.endTransaction(); + SPI1.endTransaction(); } template std::array ltc_spi_interface::read_registers_command(int cs, std::array cmd_and_pec) { std::array read_in; - SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3)); + SPI1.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3)); // Prompts SPI enable _write_and_delay_low(cs, 5); _transfer_SPI_data<4>(cmd_and_pec); @@ -56,19 +56,19 @@ std::array ltc_spi_interface::read_registers_command(int c read_in = _receive_SPI_data(); _write_and_delay_high(cs, 5); - SPI.endTransaction(); + SPI1.endTransaction(); return read_in; } void ltc_spi_interface::adc_conversion_command(int cs, std::array cmd_and_pec, size_t num_stacked_devices) { - SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3)); + SPI1.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3)); // Prompting SPI enable _write_and_delay_low(cs, 5); _transfer_SPI_data<4>(cmd_and_pec); for (size_t i = 0; i < num_stacked_devices; i++) { - SPI.transfer(0); + SPI1.transfer(0); } _write_and_delay_high(cs, 5); // End Messager - SPI.endTransaction(); + SPI1.endTransaction(); } diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index 1c1a1ae..eedb768 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -89,7 +89,7 @@ class MAX114XInterface : public AnalogMultiSensor * @param channelId the channel number * @return channel selection bits */ - int _getSel(CHANNEL_TYPE_e channelType, int& channelId); + uint8_t _getSel(CHANNEL_TYPE_e channelType, int channelId); }; diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index e8a7c12..a2b05ef 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -102,7 +102,8 @@ void MAX114XInterface::_sample() /* Page 14 of datasheet */ command = ((0x01 << 7) | // start bit - ((_getSel(channelType, _currentChannel) & 0x07) << 4) | // channel number + // ((_getSel(channelType, _currentChannel) & 0x07) << 4) | // channel number + ((_getSel(channelType, _currentChannel) & 0x07) << 4) | // channel number ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode @@ -129,9 +130,9 @@ void MAX114XInterface::_sample() Serial.print("Inverse Differential"); } Serial.print(" Channels: "); - Serial.print(_currentChannel - 1); - Serial.print(" & "); Serial.print(_currentChannel); + Serial.print(" & "); + Serial.print(_currentChannel + 1); } Serial.print(" b0/command: "); @@ -149,35 +150,46 @@ void MAX114XInterface::_sample() Serial.println(value); // REMOVE ABOVE - /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the higher of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 2 holds the return value. */ + + + /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the lower of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 1 holds the return value. */ MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); digitalWrite(_spiPinCS, HIGH); delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns + if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL || channelType == CHANNEL_TYPE_e::INV_DIFFERENTIAL){ + _currentChannel++; + } _currentChannel++; SPI.endTransaction(); } template -int MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int& channelId) +uint8_t MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int channelId) { switch (channelType) { case CHANNEL_TYPE_e::SINGLE: // The channel selection bits for single mode follows this array - return _single_end_channel_to_select_map[channelId]; + Serial.print("RETURNING SINGLE "); + Serial.print(static_cast(_single_end_channel_to_select_map[channelId])); + return static_cast(_single_end_channel_to_select_map[channelId]); case CHANNEL_TYPE_e::DIFFERENTIAL: // The channel selection bits for differential mode is the channel number halved and then truncated // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair - return channelId++ / 2; + Serial.print("RETURNING DIFF "); + Serial.print(static_cast(channelId / 2)); + return static_cast(channelId / 2); case CHANNEL_TYPE_e::INV_DIFFERENTIAL: // The channel selection bits for inverse differential mode is the channel number halved, truncated, and plus 4 (SEL codes 1-4 are differential and 5-8 are inverse differential) // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair - return (channelId++ / 2) + 4; + Serial.print("RETURNING INV "); + Serial.print(static_cast((channelId / 2) + 4)); + return static_cast((channelId / 2) + 4); } } diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index fba87f5..9a92da7 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -52,7 +52,9 @@ static ACUAllDataType_s make_acu_all_data() void initialize_all_interfaces() { SPI.begin(); + SPI1.begin(); SPI.setClockDivider(SPI_CLOCK_DIV8); // 16MHz (Arduino Clock Frequency) / 8 = 2MHz -> SPI Clock + SPI1.setClockDivider(SPI_CLOCK_DIV8); // 16MHz (Arduino Clock Frequency) / 8 = 2MHz -> SPI Clock Serial.begin(ACUInterfaces::SERIAL_BAUDRATE); analogReadResolution(ACUInterfaces::ANALOG_READ_RESOLUTION); /* Watchdog Interface */ From f239ebbed5224234b08be7c39dff54693d217809 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Mon, 19 Jan 2026 17:44:55 -0500 Subject: [PATCH 20/30] Fixing the differential problem Co-authored-by: William Schotte Co-authored-by: Ryan2551 Co-authored-by: akemiyu --- include/ACU_Constants.h | 14 +-- lib/interfaces/include/MAX114XInterface.tpp | 125 +++++++++++--------- src/ACU_InterfaceTasks.cpp | 4 +- src/main.cpp | 6 +- 4 files changed, 83 insertions(+), 66 deletions(-) diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index 4fba193..815f82d 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -69,13 +69,13 @@ namespace ACUInterfaces { constexpr const size_t TEENSY_OK_PIN = 3; // > Needs to stay HIGH while wd_kick_pin flips to keep BMS_OK high constexpr const size_t WD_KICK_PIN = 4; // > Needs to flip at 100 Hz to keep BMS_OK high constexpr const size_t N_LATCH_EN_PIN = 6; // > Input to Safety Light, true when teensy is not in FAULT state - constexpr const size_t TS_OUT_FILTERED_PIN = 17; - constexpr const size_t PACK_OUT_FILTERED_PIN = 18; - constexpr const size_t IMD_OK_PIN = 25; // < READ from IMD hardware, go to FAULT state if HIGH - constexpr const size_t PRECHARGE_PIN = 26; // READ from PRECHARGE - constexpr const size_t BSPD_CURRENT_PIN = 27; - constexpr const size_t SHDN_OUT_PIN = 38; // < READ from SHDN hardware, can leave FAULT state if goes to HIGH to signify car startup - constexpr const size_t SCALED_24V_PIN = 39; + constexpr const size_t TS_OUT_FILTERED_PIN = 25; + constexpr const size_t PACK_OUT_FILTERED_PIN = 24; + constexpr const size_t IMD_OK_PIN = 23; // < READ from IMD hardware, go to FAULT state if HIGH + constexpr const size_t PRECHARGE_PIN = 17; // READ from PRECHARGE + constexpr const size_t BSPD_CURRENT_PIN = 15; + constexpr const size_t SHDN_OUT_PIN = 16; // < READ from SHDN hardware, can leave FAULT state if goes to HIGH to signify car startup + constexpr const size_t SCALED_24V_PIN = 41; constexpr const float SHUTDOWN_CONV_FACTOR = 0.1155F; // voltage divider -> 4.7k / (4.7k + 36k) constexpr const float PRECHARGE_CONV_FACTOR = 0.6623F; // voltage divider -> 10k / (5.1k + 10k) diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index a2b05ef..cde1082 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -80,82 +80,104 @@ float MAX114XInterface::getLastSampleC template void MAX114XInterface::_sample() { - // uint16_t command = ( - // (0b1 << 15) | // start bit - // (0b1 << 14) // single ended mode - // ); - if (_currentChannel == 8){ + + if (_currentChannel == MAX114X_ADC_NUM_CHANNELS){ _currentChannel = 0; } byte command, b0, b1, b2; - // initialize SPI bus. REQUIRED: call SPI.begin() before this - SPI.beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); - - - digitalWrite(_spiPinCS, LOW); - /* Creates variable corresponding to the current channels channelType (Single, Differential, Inverse Differential) using the array input by the user. The index is divided by 2 since there is one channelType enum corresponding to each pair of channels */ CHANNEL_TYPE_e channelType = _channelTypes[_currentChannel / 2]; + uint8_t channelNum = 0; + + switch (channelType) { + case CHANNEL_TYPE_e::SINGLE: + + channelNum = (_single_end_channel_to_select_map[_currentChannel]); + break; + + case CHANNEL_TYPE_e::DIFFERENTIAL: + + channelNum = ((_currentChannel / 2) & 0x07); + channelNum = channelNum << 4; + break; + + case CHANNEL_TYPE_e::INV_DIFFERENTIAL: + + channelNum = (((_currentChannel / 2) + 4)); + break; + } + // const uint8_t channelConstNum = channelNum; + + command = 0; + + /* Page 14 of datasheet */ - command = ((0x01 << 7) | // start bit - // ((_getSel(channelType, _currentChannel) & 0x07) << 4) | // channel number - ((_getSel(channelType, _currentChannel) & 0x07) << 4) | // channel number - ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) + command = (0x01 << 7) | // start bit + ((channelNum) | // channel number + // ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) + (0x00 << 3) | // single(1) or differential(0) (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode (0x01)); // ^ + + + // initialize SPI bus. REQUIRED: call SPI.begin() before this + SPI.beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); + + digitalWrite(_spiPinCS, LOW); b0 = SPI.transfer(command); b1 = SPI.transfer(0x00); // dummy bytes to clock out data from the ADC b2 = SPI.transfer(0x00); // ^ // MOVE TO DEBUG PRINT - Serial.print("\n"); - if (channelType == CHANNEL_TYPE_e::SINGLE) - { - Serial.print("Single Channel: "); - Serial.print(_currentChannel); - } - else - { - if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { - Serial.print("Differential"); + // Serial.print("\n"); + // if (channelType == CHANNEL_TYPE_e::SINGLE) + // { + // Serial.print("Single Channel: "); + // Serial.print(_currentChannel); + // } + // else + // { + // if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { + // Serial.print("Differential"); - } - else - { - Serial.print("Inverse Differential"); - } - Serial.print(" Channels: "); - Serial.print(_currentChannel); - Serial.print(" & "); - Serial.print(_currentChannel + 1); - } - - Serial.print(" b0/command: "); - Serial.print(command, BIN); - - - Serial.print(" b1: "); - Serial.print(b1, HEX); - Serial.print(" b2: "); - Serial.print(b2, HEX); + // } + // else + // { + // Serial.print("Inverse Differential"); + // } + // Serial.print(" Channels: "); + // Serial.print(_currentChannel); + // Serial.print(" & "); + // Serial.print(_currentChannel + 1); + // } + + // Serial.print(" b0/command: "); + // Serial.print(command, BIN); + + + // Serial.print(" b1: "); + // Serial.print(b1, HEX); + // Serial.print(" b2: "); + // Serial.print(b2, HEX); // uint16_t value = SPI.transfer16(command | _currentChannel << 11); uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); - Serial.print(" value: "); - Serial.println(value); + // Serial.print(" value: "); + // Serial.println(value); // REMOVE ABOVE - + MAX114XInterface::_channels[_currentChannel].lastSample = 0; /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the lower of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 1 holds the return value. */ MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); digitalWrite(_spiPinCS, HIGH); + delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL || channelType == CHANNEL_TYPE_e::INV_DIFFERENTIAL){ _currentChannel++; @@ -165,31 +187,26 @@ void MAX114XInterface::_sample() SPI.endTransaction(); } -template +/*template uint8_t MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int channelId) { switch (channelType) { case CHANNEL_TYPE_e::SINGLE: // The channel selection bits for single mode follows this array - Serial.print("RETURNING SINGLE "); - Serial.print(static_cast(_single_end_channel_to_select_map[channelId])); return static_cast(_single_end_channel_to_select_map[channelId]); case CHANNEL_TYPE_e::DIFFERENTIAL: // The channel selection bits for differential mode is the channel number halved and then truncated // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair - Serial.print("RETURNING DIFF "); - Serial.print(static_cast(channelId / 2)); return static_cast(channelId / 2); case CHANNEL_TYPE_e::INV_DIFFERENTIAL: // The channel selection bits for inverse differential mode is the channel number halved, truncated, and plus 4 (SEL codes 1-4 are differential and 5-8 are inverse differential) // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair - Serial.print("RETURNING INV "); - Serial.print(static_cast((channelId / 2) + 4)); return static_cast((channelId / 2) + 4); } } +*/ diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 9a92da7..c3b4c5a 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -53,8 +53,8 @@ void initialize_all_interfaces() { SPI.begin(); SPI1.begin(); - SPI.setClockDivider(SPI_CLOCK_DIV8); // 16MHz (Arduino Clock Frequency) / 8 = 2MHz -> SPI Clock - SPI1.setClockDivider(SPI_CLOCK_DIV8); // 16MHz (Arduino Clock Frequency) / 8 = 2MHz -> SPI Clock + SPI.setClockDivider(SPI_CLOCK_DIV16); // 16MHz (Arduino Clock Frequency) / 8 = 2MHz -> SPI Clock + SPI1.setClockDivider(SPI_CLOCK_DIV16); // 16MHz (Arduino Clock Frequency) / 8 = 2MHz -> SPI Clock Serial.begin(ACUInterfaces::SERIAL_BAUDRATE); analogReadResolution(ACUInterfaces::ANALOG_READ_RESOLUTION); /* Watchdog Interface */ diff --git a/src/main.cpp b/src/main.cpp index 040d5d8..d5893d3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,9 +51,9 @@ void setup() scheduler.setTimingFunction(micros); scheduler.schedule(tick_state_machine_task); scheduler.schedule(kick_watchdog_task); - scheduler.schedule(sample_bms_data_task); + // scheduler.schedule(sample_bms_data_task); scheduler.schedule(eval_accumulator_task); - scheduler.schedule(write_cell_balancing_config_task); + // scheduler.schedule(write_cell_balancing_config_task); scheduler.schedule(send_all_data_ethernet_task); scheduler.schedule(send_core_data_ethernet_task); // waiting on update on drivebrain @@ -67,7 +67,7 @@ void setup() scheduler.schedule(sample_CAN_task); scheduler.schedule(idle_sample_task); - // scheduler.schedule(debug_prints_task); + scheduler.schedule(debug_prints_task); scheduler.schedule(sample_adc_task); From 2f983b3a5a075e2000ca30f363af8f837b3db0ca Mon Sep 17 00:00:00 2001 From: songyueli Date: Mon, 19 Jan 2026 21:13:29 -0500 Subject: [PATCH 21/30] Structural changes --- lib/interfaces/include/MAX114XInterface.tpp | 132 +++++++++----------- src/ACU_InterfaceTasks.cpp | 2 +- src/main.cpp | 2 +- 3 files changed, 58 insertions(+), 78 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index cde1082..7cc706a 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -36,8 +36,7 @@ MAX114XInterface::MAX114XInterface( // Returns a compile time error if an incorrect version is given to the interface's template static_assert( - (MAX114xVersion == 6 || MAX114xVersion == 7 || - MAX114xVersion == 8 || MAX114xVersion == 9), + (MAX114xVersion == 6 || MAX114xVersion == 7 || MAX114xVersion == 8 || MAX114xVersion == 9), "Invalid MAX114X version number" ); @@ -101,112 +100,93 @@ void MAX114XInterface::_sample() case CHANNEL_TYPE_e::DIFFERENTIAL: - channelNum = ((_currentChannel / 2) & 0x07); - channelNum = channelNum << 4; + channelNum = (_currentChannel / 2); break; case CHANNEL_TYPE_e::INV_DIFFERENTIAL: - channelNum = (((_currentChannel / 2) + 4)); + channelNum = ((_currentChannel / 2) + 4); break; - } - // const uint8_t channelConstNum = channelNum; - - command = 0; + } /* Page 14 of datasheet */ - command = (0x01 << 7) | // start bit - ((channelNum) | // channel number - // ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) - (0x00 << 3) | // single(1) or differential(0) + command = (0x01 << 7) | // start bit + ((channelNum & 0x7) << 4) | // channel number + ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode - (0x01)); // ^ + (0x01); // ^ // initialize SPI bus. REQUIRED: call SPI.begin() before this SPI.beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); digitalWrite(_spiPinCS, LOW); + + delayMicroseconds(1); // MAX114XInterface Tcs = 500ns + b0 = SPI.transfer(command); b1 = SPI.transfer(0x00); // dummy bytes to clock out data from the ADC b2 = SPI.transfer(0x00); // ^ - // MOVE TO DEBUG PRINT - // Serial.print("\n"); - // if (channelType == CHANNEL_TYPE_e::SINGLE) - // { - // Serial.print("Single Channel: "); - // Serial.print(_currentChannel); - // } - // else - // { - // if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { - // Serial.print("Differential"); - - // } - // else - // { - // Serial.print("Inverse Differential"); - // } - // Serial.print(" Channels: "); - // Serial.print(_currentChannel); - // Serial.print(" & "); - // Serial.print(_currentChannel + 1); - // } - - // Serial.print(" b0/command: "); - // Serial.print(command, BIN); - + digitalWrite(_spiPinCS, HIGH); - // Serial.print(" b1: "); - // Serial.print(b1, HEX); - // Serial.print(" b2: "); - // Serial.print(b2, HEX); + delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns + + SPI.endTransaction(); + + - // uint16_t value = SPI.transfer16(command | _currentChannel << 11); uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); - // Serial.print(" value: "); - // Serial.println(value); - // REMOVE ABOVE MAX114XInterface::_channels[_currentChannel].lastSample = 0; /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the lower of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 1 holds the return value. */ MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); - digitalWrite(_spiPinCS, HIGH); + + // MOVE TO DEBUG PRINT + Serial.print("\n"); + if (channelType == CHANNEL_TYPE_e::SINGLE) + { + Serial.print("Single Channel: "); + Serial.print(_currentChannel); + } + else + { + if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { + Serial.print("Differential"); + + } + else + { + Serial.print("Inverse Differential"); + } + Serial.print(" Channels: "); + Serial.print(_currentChannel); + Serial.print(" & "); + Serial.print(_currentChannel + 1); + } + + Serial.print(" b0/command: "); + Serial.print(command, BIN); + Serial.print(" HEX: "); + Serial.print(command, HEX); + + Serial.print(" b1: "); + Serial.print(b1, HEX); + Serial.print(" b2: "); + Serial.print(b2, HEX); + + Serial.print(" value: "); + Serial.println(value); + - delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL || channelType == CHANNEL_TYPE_e::INV_DIFFERENTIAL){ _currentChannel++; } _currentChannel++; - SPI.endTransaction(); -} - -/*template -uint8_t MAX114XInterface::_getSel(CHANNEL_TYPE_e channelType, int channelId) -{ - switch (channelType) { - case CHANNEL_TYPE_e::SINGLE: - - // The channel selection bits for single mode follows this array - return static_cast(_single_end_channel_to_select_map[channelId]); - - case CHANNEL_TYPE_e::DIFFERENTIAL: - - // The channel selection bits for differential mode is the channel number halved and then truncated - // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair - return static_cast(channelId / 2); - - case CHANNEL_TYPE_e::INV_DIFFERENTIAL: - - // The channel selection bits for inverse differential mode is the channel number halved, truncated, and plus 4 (SEL codes 1-4 are differential and 5-8 are inverse differential) - // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair - return static_cast((channelId / 2) + 4); - } -} -*/ + +} \ No newline at end of file diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index c3b4c5a..7dea185 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -106,7 +106,7 @@ void initialize_all_interfaces() CHANNEL_TYPE_e::INV_DIFFERENTIAL, CHANNEL_TYPE_e::SINGLE, CHANNEL_TYPE_e::DIFFERENTIAL, - CHANNEL_TYPE_e::SINGLE + CHANNEL_TYPE_e::DIFFERENTIAL }; // std::array adc0_channels = { // CHANNEL_TYPE_e::SINGLE, diff --git a/src/main.cpp b/src/main.cpp index d5893d3..0d24c53 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,7 +67,7 @@ void setup() scheduler.schedule(sample_CAN_task); scheduler.schedule(idle_sample_task); - scheduler.schedule(debug_prints_task); + // scheduler.schedule(debug_prints_task); scheduler.schedule(sample_adc_task); From 84201b47bb6ac3c741ccb386759f382a9c491969 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Mon, 19 Jan 2026 22:20:56 -0500 Subject: [PATCH 22/30] Cleaned up all the code and fixed all the printing Co-authored-by: akemiyu Co-authored-by: Ryan2551 --- lib/interfaces/include/MAX114XInterface.h | 5 ++ lib/interfaces/include/MAX114XInterface.tpp | 90 ++++++--------------- src/ACU_InterfaceTasks.cpp | 8 +- src/main.cpp | 4 +- 4 files changed, 39 insertions(+), 68 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index eedb768..1842c4d 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -54,6 +54,11 @@ class MAX114XInterface : public AnalogMultiSensor * Gets real value (current/voltage) of a channel for a sample */ float getLastSampleConverted(int index) const; + + /** + * Print debug statements + */ + void debugPrint(); private: /** diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 7cc706a..48a8db5 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -79,114 +79,76 @@ float MAX114XInterface::getLastSampleC template void MAX114XInterface::_sample() { + byte command, b0, b1, b2; + uint8_t selNum; - if (_currentChannel == MAX114X_ADC_NUM_CHANNELS){ + // Resets loop after last channel is reached + if (_currentChannel == MAX114X_ADC_NUM_CHANNELS) + { _currentChannel = 0; } - - byte command, b0, b1, b2; - - /* Creates variable corresponding to the current channels channelType (Single, Differential, Inverse Differential) using the array input by the user. The index is divided by 2 since there is one channelType enum corresponding to each pair of channels */ + /* Creates variable corresponding to the current channels channelType (Single, Differential, Inverse Differential) using the array input by the user. + * The index is divided by 2 since there is one channelType enum corresponding to each pair of channels + */ CHANNEL_TYPE_e channelType = _channelTypes[_currentChannel / 2]; - uint8_t channelNum = 0; - switch (channelType) { case CHANNEL_TYPE_e::SINGLE: - - channelNum = (_single_end_channel_to_select_map[_currentChannel]); + + // The channel selection bits for single mode follows this array + selNum = (_single_end_channel_to_select_map[_currentChannel]); break; case CHANNEL_TYPE_e::DIFFERENTIAL: - - channelNum = (_currentChannel / 2); + + // The channel selection bits for differential mode is the channel number halved and then truncated + // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair + selNum = (_currentChannel / 2); break; case CHANNEL_TYPE_e::INV_DIFFERENTIAL: - channelNum = ((_currentChannel / 2) + 4); + // The channel selection bits for inversed differential mode is the channel number halved, truncated, and plus 4 + // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair + selNum = ((_currentChannel / 2) + 4); break; } - - /* Page 14 of datasheet */ + /* Page 14 of datasheet + * Create command byte to send to ADC + */ + command = (0x01 << 7) | // start bit - ((channelNum & 0x7) << 4) | // channel number + ((selNum & 0x7) << 4) | // channel number ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) (0x01 << 2) | // unipolar or !bipolar (0x01 << 1) | // external clock mode (0x01); // ^ - // initialize SPI bus. REQUIRED: call SPI.begin() before this SPI.beginTransaction(SPISettings(_spiSpeed, MSBFIRST, SPI_MODE0)); digitalWrite(_spiPinCS, LOW); - delayMicroseconds(1); // MAX114XInterface Tcs = 500ns - b0 = SPI.transfer(command); b1 = SPI.transfer(0x00); // dummy bytes to clock out data from the ADC b2 = SPI.transfer(0x00); // ^ digitalWrite(_spiPinCS, HIGH); - - delayMicroseconds(1); // MAX114XInterface Tcsh = 500ns SPI.endTransaction(); - - uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); - - MAX114XInterface::_channels[_currentChannel].lastSample = 0; /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the lower of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 1 holds the return value. */ MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); - - // MOVE TO DEBUG PRINT - Serial.print("\n"); - if (channelType == CHANNEL_TYPE_e::SINGLE) + // Increments channel ID if the pair is differential or inverse differential + if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL || channelType == CHANNEL_TYPE_e::INV_DIFFERENTIAL) { - Serial.print("Single Channel: "); - Serial.print(_currentChannel); - } - else - { - if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL) { - Serial.print("Differential"); - - } - else - { - Serial.print("Inverse Differential"); - } - Serial.print(" Channels: "); - Serial.print(_currentChannel); - Serial.print(" & "); - Serial.print(_currentChannel + 1); - } - - Serial.print(" b0/command: "); - Serial.print(command, BIN); - Serial.print(" HEX: "); - Serial.print(command, HEX); - - Serial.print(" b1: "); - Serial.print(b1, HEX); - Serial.print(" b2: "); - Serial.print(b2, HEX); - - Serial.print(" value: "); - Serial.println(value); - - - if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL || channelType == CHANNEL_TYPE_e::INV_DIFFERENTIAL){ _currentChannel++; + MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); } _currentChannel++; - - } \ No newline at end of file diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index 7dea185..ee28a64 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -106,7 +106,7 @@ void initialize_all_interfaces() CHANNEL_TYPE_e::INV_DIFFERENTIAL, CHANNEL_TYPE_e::SINGLE, CHANNEL_TYPE_e::DIFFERENTIAL, - CHANNEL_TYPE_e::DIFFERENTIAL + CHANNEL_TYPE_e::SINGLE }; // std::array adc0_channels = { // CHANNEL_TYPE_e::SINGLE, @@ -460,7 +460,11 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: Serial.print(MAX1148ADCInstance_t::instance().getLastSampleRaw(i)); Serial.print(" Converted = "); Serial.print(MAX1148ADCInstance_t::instance().getLastSampleConverted(i)); - Serial.print(" "); + Serial.print('\n'); + // skip other half of differential pair + if (i == 0 || i == 4) { + i++; + } } Serial.print('\n'); diff --git a/src/main.cpp b/src/main.cpp index 0d24c53..c714af8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -53,7 +53,7 @@ void setup() scheduler.schedule(kick_watchdog_task); // scheduler.schedule(sample_bms_data_task); scheduler.schedule(eval_accumulator_task); - // scheduler.schedule(write_cell_balancing_config_task); + scheduler.schedule(write_cell_balancing_config_task); scheduler.schedule(send_all_data_ethernet_task); scheduler.schedule(send_core_data_ethernet_task); // waiting on update on drivebrain @@ -67,7 +67,7 @@ void setup() scheduler.schedule(sample_CAN_task); scheduler.schedule(idle_sample_task); - // scheduler.schedule(debug_prints_task); + scheduler.schedule(debug_prints_task); scheduler.schedule(sample_adc_task); From ff8de6584a84168cf30a07d00258115a4b92f2a5 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Mon, 19 Jan 2026 23:00:54 -0500 Subject: [PATCH 23/30] fin touches --- lib/interfaces/include/MAX114XInterface.h | 31 ++++----------------- lib/interfaces/include/MAX114XInterface.tpp | 12 ++++---- src/ACU_InterfaceTasks.cpp | 2 -- src/main.cpp | 7 ++--- 4 files changed, 14 insertions(+), 38 deletions(-) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index 1842c4d..edd3861 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -5,12 +5,6 @@ #include -// Definitions -const int MAX114X_ADC_DEFAULT_SPI_SDI = 12; -const int MAX114X_ADC_DEFAULT_SPI_SDO = 11; -const int MAX114X_ADC_DEFAULT_SPI_CLK = 13; -const int MAX114X_ADC_DEFAULT_SPI_SPEED = 2000000; - /** * Enum representing the different channel configurations in MAX114X ADCs (SINGLE, DIFFERENTIAL, or INV_DIFFERENTIAL) */ @@ -54,13 +48,15 @@ class MAX114XInterface : public AnalogMultiSensor * Gets real value (current/voltage) of a channel for a sample */ float getLastSampleConverted(int index) const; + +private: /** - * Print debug statements + * Samples the MCP_ADC over SPI. Samples all eight channels and, in accordance with the AnalogMultiSensor's function + * contract, stores the raw sampled values into each AnalogChannel's lastSample instance variable. */ - void debugPrint(); - -private: + void _sample() override; + /** * Channel configuration is defined per channel pair (two physical channels). * This array stores the channel type for each pair of channels in the ADC. @@ -81,21 +77,6 @@ class MAX114XInterface : public AnalogMultiSensor * This array stores the specific single-ended select-bit mapping for each channel as defined in the datasheet. */ std::array _single_end_channel_to_select_map; - - /** - * Samples the MCP_ADC over SPI. Samples all eight channels and, in accordance with the AnalogMultiSensor's function - * contract, stores the raw sampled values into each AnalogChannel's lastSample instance variable. - */ - void _sample() override; - - /** - * Returns the channel selection bits for a channel based on its type and ID. Also increments the channelId/loop index for the sample() function when channel is part of a differential pair. - * @param channelType CHANNEL_TYPE_e of the channel - * @param channelId the channel number - * @return channel selection bits - */ - uint8_t _getSel(CHANNEL_TYPE_e channelType, int channelId); - }; template diff --git a/lib/interfaces/include/MAX114XInterface.tpp b/lib/interfaces/include/MAX114XInterface.tpp index 48a8db5..146565f 100644 --- a/lib/interfaces/include/MAX114XInterface.tpp +++ b/lib/interfaces/include/MAX114XInterface.tpp @@ -4,9 +4,7 @@ * Page 15: channel codes */ - #include "MAX114XInterface.h" - #include #include @@ -109,16 +107,15 @@ void MAX114XInterface::_sample() case CHANNEL_TYPE_e::INV_DIFFERENTIAL: - // The channel selection bits for inversed differential mode is the channel number halved, truncated, and plus 4 + // The channel selection bits for inversed differential mode is the channel number halved, truncated, and with a 1 in the MSB // The channelId is post-incremented so the sample() function does not send the same command byte for the other channel in the differential pair - selNum = ((_currentChannel / 2) + 4); + selNum = ((_currentChannel / 2) | 0b100); break; } /* Page 14 of datasheet * Create command byte to send to ADC */ - command = (0x01 << 7) | // start bit ((selNum & 0x7) << 4) | // channel number ((channelType == CHANNEL_TYPE_e::SINGLE ? 0x01 : 0x00) << 3) | // single(1) or differential(0) @@ -139,16 +136,17 @@ void MAX114XInterface::_sample() SPI.endTransaction(); + // First two bits of b1 are filler uint16_t value = ((b1 & 0x3F) << 8) | (b2 & 0xFF); /* Stores return bytes (14 bit ADC conversion) in lastSample member of analog channel class corresponding to the channel. FOR DIFFERENTIAL: data for the pair is stored in the lower of the two channels. Ex: 1 & 2 are a differential pair, the object for channel 1 holds the return value. */ - MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); + MAX114XInterface::_channels[_currentChannel].lastSample = value; // Increments channel ID if the pair is differential or inverse differential if (channelType == CHANNEL_TYPE_e::DIFFERENTIAL || channelType == CHANNEL_TYPE_e::INV_DIFFERENTIAL) { _currentChannel++; - MAX114XInterface::_channels[_currentChannel].lastSample = (value & 0x3FFF); + MAX114XInterface::_channels[_currentChannel].lastSample = value; } _currentChannel++; } \ No newline at end of file diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index ee28a64..c897a56 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -155,8 +155,6 @@ void initialize_all_interfaces() /* CAN Interfaces Construct */ CANInterfacesInstance::create(CCUInterfaceInstance::instance(), EMInterfaceInstance::instance()); - - Serial.println("All interfaces initialized."); } HT_TASK::TaskResponse run_kick_watchdog(const unsigned long &sysMicros, const HT_TASK::TaskInfo &taskInfo) diff --git a/src/main.cpp b/src/main.cpp index c714af8..98979ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,7 +43,6 @@ FlexCAN_t ACUCANInterfaceImpl::EM_CAN; void setup() { - Serial.println("Initializing all systems..."); /* Interface and System initialization */ initialize_all_interfaces(); // must init first initialize_all_systems(); @@ -51,7 +50,7 @@ void setup() scheduler.setTimingFunction(micros); scheduler.schedule(tick_state_machine_task); scheduler.schedule(kick_watchdog_task); - // scheduler.schedule(sample_bms_data_task); + scheduler.schedule(sample_bms_data_task); scheduler.schedule(eval_accumulator_task); scheduler.schedule(write_cell_balancing_config_task); @@ -66,11 +65,11 @@ void setup() scheduler.schedule(sample_CAN_task); scheduler.schedule(idle_sample_task); - - scheduler.schedule(debug_prints_task); scheduler.schedule(sample_adc_task); + scheduler.schedule(debug_prints_task); + handle_CAN_setup(ACUCANInterfaceImpl::CCU_CAN, ACUConstants::Veh_CAN_baudrate, &ACUCANInterfaceImpl::on_ccu_can_receive); handle_CAN_setup(ACUCANInterfaceImpl::EM_CAN, ACUConstants::EM_CAN_baudrate, &ACUCANInterfaceImpl::on_em_can_receive); } From 8c0bc8267fca12bf8482364bf424abf54153f640 Mon Sep 17 00:00:00 2001 From: akemiyu <43460886+akemiyu@users.noreply.github.com> Date: Wed, 21 Jan 2026 23:00:43 -0500 Subject: [PATCH 24/30] Added rest of scales & offsets --- include/ACU_Constants.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index 815f82d..93990bd 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -49,14 +49,14 @@ namespace ACUInterfaces { constexpr int PACK_OUT_FILTERED_CHANNEL = 7; /* SCALE/OFFSETS on ADC */ - const float ISO_PACK_N_SCALE = 1; - const float ISO_PACK_P_SCALE = 1; - const float PACK_VOLTAGE_SENSE_SCALE = 1; + const float ISO_PACK_N_SCALE = 0.0656553030302; + const float ISO_PACK_P_SCALE = 0.0656553030302; + const float PACK_VOLTAGE_SENSE_SCALE = 0.0410345643939; const float SHUNT_CURRENT_OUT_SCALE = 0.03125; const float SHUNT_CURRENT_P_SCALE = 0.00025; const float SHUNT_CURRENT_N_SCALE = 0.00025; - const float TS_OUT_FILTERED_SCALE = 1; - const float PACK_OUT_FILTERED_SCALE = 1; + const float TS_OUT_FILTERED_SCALE = 0.0547254764211; + const float PACK_OUT_FILTERED_SCALE = 0.0547254764211; const float ISO_PACK_N_OFFSET = 0; const float ISO_PACK_P_OFFSET = 0; const float PACK_VOLTAGE_SENSE_OFFSET = 0; From c618050cd35de3e7323a1e7bda3eeffb2b9a5436 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Tue, 27 Jan 2026 19:19:50 -0500 Subject: [PATCH 25/30] Merge branch 'main' of https://github.com/hytech-racing/ACU into feat/max1148-adc-interface From 54ab30fea297564572396ee54c2b6ced4509f5d4 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Tue, 27 Jan 2026 22:18:25 -0500 Subject: [PATCH 26/30] brainrot --- lib/interfaces/include/ADCInterface.h | 54 +++++++++++++++++++++-- lib/interfaces/include/MAX114XInterface.h | 1 - lib/interfaces/src/ADCInterface.cpp | 17 +++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/lib/interfaces/include/ADCInterface.h b/lib/interfaces/include/ADCInterface.h index c9bc494..c3545a9 100644 --- a/lib/interfaces/include/ADCInterface.h +++ b/lib/interfaces/include/ADCInterface.h @@ -4,6 +4,7 @@ #include #include "SharedFirmwareTypes.h" #include "etl/singleton.h" +#include "MAX114XInterface.h" using pin = size_t; @@ -18,7 +19,7 @@ namespace adc_default_parameters } struct ADCPinout_s { - pin teensy_imd_ok_pin; + pin teensy_imd_ok_pin; pin teensy_precharge_pin; pin teensy_shdn_out_pin; pin teensy_ts_out_filtered_pin; @@ -50,12 +51,23 @@ struct ADCConfigs_s float teensy41_max_input_voltage; }; +struct ADCChannels_s +{ + int iso_pack_diff_channel; + int pack_voltage_sense_channel; + int shunt_current_out_single_channel; + int shunt_current_diff_channel; + // int ts_out_filtered_channel; + // int pack_out_filtered_channel; +}; + struct ADCInterfaceParams_s { ADCPinout_s pinout; ADCConversions_s conversions; ADCThresholds_s thresholds; ADCConfigs_s configs; + ADCChannels_s channels; float bit_resolution; }; @@ -65,6 +77,8 @@ class ADCInterface ADCInterface(ADCPinout_s pinout, ADCConversions_s conversions, float bit_resolution, + ADCChannels_s channels, + // MAX114XInterface& MAX114XInterfaceInstance, ADCThresholds_s thresholds = { .teensy41_min_digital_read_voltage_thresh = adc_default_parameters::TEENSY41_MIN_DIGITAL_READ_VOLTAGE_THRESH, .teensy41_max_digital_read_voltage_thresh = adc_default_parameters::TEENSY41_MAX_DIGITAL_READ_VOLTAGE_THRESH, @@ -87,7 +101,10 @@ class ADCInterface }(), thresholds, configs, - bit_resolution} {} + channels, + bit_resolution}, + // _max114x_instance(MAX114XInterfaceInstance) + {} /** * @pre constructor called and instance created @@ -144,7 +161,36 @@ class ADCInterface * @return shdn out voltage */ volt read_shdn_out_voltage(); - + + // constexpr int ISO_PACK_N_CHANNEL = 0; + // constexpr int ISO_PACK_P_CHANNEL = 1; + // constexpr int PACK_VOLTAGE_SENSE_CHANNEL = 2; + // constexpr int SHUNT_CURRENT_OUT_CHANNEL = 3; + // constexpr int SHUNT_CURRENT_P_CHANNEL = 4; + // constexpr int SHUNT_CURRENT_N_CHANNEL = 5; + // constexpr int TS_OUT_FILTERED_CHANNEL = 6; + // constexpr int PACK_OUT_FILTERED_CHANNEL = 7; + + /** + * @return ISO Pack Differential + */ + int read_iso_pack(); + + /** + * @return pack voltage sense + */ + int read_pack_voltage_sense(); + + /** + * @return shunt current single channel + */ + int read_shunt_current(); + + /** + * @return shunt current differential channels + */ + int read_differential_shunt_current(); + /** * @return ADC parameters */ @@ -157,6 +203,8 @@ class ADCInterface private: const ADCInterfaceParams_s _adc_parameters = {}; + // MAX114XInterface _max114x_instance; + /** * @brief true while within the IMD startup window (set in init()) diff --git a/lib/interfaces/include/MAX114XInterface.h b/lib/interfaces/include/MAX114XInterface.h index edd3861..7c9f3c8 100644 --- a/lib/interfaces/include/MAX114XInterface.h +++ b/lib/interfaces/include/MAX114XInterface.h @@ -2,7 +2,6 @@ #define MAX114XINTERFACE_H #include "AnalogSensorsInterface.h" - #include /** diff --git a/lib/interfaces/src/ADCInterface.cpp b/lib/interfaces/src/ADCInterface.cpp index 81450fe..a92a421 100644 --- a/lib/interfaces/src/ADCInterface.cpp +++ b/lib/interfaces/src/ADCInterface.cpp @@ -74,6 +74,23 @@ volt ADCInterface::read_global_lv_value() { return data; } +int ADCInterface::read_iso_pack() { + MAX1148ADCInstance_t + // MAX114XInterfaceInstance.getLastSampleConverted(_adc_parameters.channels.iso_pack_diff_channel); +} + +int ADCInterface::read_pack_voltage_sense() { + MAX114XInterfaceInstance.getLastSampleConverted(_adc_parameters.channels.pack_voltage_sense_channel); +} + +int ADCInterface::read_shunt_current() { + MAX114XInterfaceInstance<, >::instance().getLastSampleConverted(_adc_parameters.channels.shunt_current_out_single_channel); +} + +int ADCInterface::read_differential_shunt_current() { + MAX114XInterfaceInstance<, >::instance().getLastSampleConverted(_adc_parameters.channels.shunt_current_diff_channel); +} + const ADCInterfaceParams_s& ADCInterface::get_adc_params() const { return _adc_parameters; } From dca8e823efbf9a49898a418971e4d79d9b0eb25b Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Wed, 28 Jan 2026 00:17:32 -0500 Subject: [PATCH 27/30] Made MAX114XInterface fully contained in ADCInterface Co-authored-by: akemiyu Co-authored-by: Ryan2551 --- include/ACU_Constants.h | 4 +- include/ACU_InterfaceTasks.h | 2 +- lib/interfaces/include/ADCInterface.h | 134 +++++++++++++++++---- lib/interfaces/src/ADCInterface.cpp | 22 ++-- src/ACU_InterfaceTasks.cpp | 163 ++++++++++++++++---------- 5 files changed, 226 insertions(+), 99 deletions(-) diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index 93990bd..ade30f7 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -37,7 +37,7 @@ namespace ACUInterfaces { constexpr int ADC0_CLK = 13; constexpr int ADC0_SPEED = 2000000; // 1 MHz /* ADC Versions*/ - constexpr int MAX114X_VERSION = 8; + // constexpr int MAX114X_VERSION = 8; /* Channels on ADC */ constexpr int ISO_PACK_N_CHANNEL = 0; constexpr int ISO_PACK_P_CHANNEL = 1; @@ -93,7 +93,7 @@ namespace ACUConstants constexpr size_t NUM_CHIPS = 12; constexpr size_t NUM_CELL_TEMPS = 48; constexpr size_t NUM_CHIP_SELECTS = 2; - constexpr size_t NUM_MAX1148_CHANNELS = 8; + // constexpr size_t NUM_MAX1148_CHANNELS = 8; const float VALID_SHDN_OUT_MIN_VOLTAGE_THRESHOLD = 12.0F; const uint32_t MIN_ALLOWED_INVALID_SHDN_OUT_MS = 10; // 10 ms -- requies 100 Hz samp freq. diff --git a/include/ACU_InterfaceTasks.h b/include/ACU_InterfaceTasks.h index 6db6007..b403dff 100644 --- a/include/ACU_InterfaceTasks.h +++ b/include/ACU_InterfaceTasks.h @@ -25,7 +25,7 @@ using chip_type = LTC6811_Type_e; using BMSDriverInstance_t = BMSDriverInstance; using BMSFaultDataManagerInstance_t = BMSFaultDataManagerInstance; -using MAX1148ADCInstance_t = MAX114XInterfaceInstance; +// using MAX1148ADCInstance_t = MAX114XInterfaceInstance; /** * Init Functions - to be called in setup@ */ diff --git a/lib/interfaces/include/ADCInterface.h b/lib/interfaces/include/ADCInterface.h index c3545a9..a86839e 100644 --- a/lib/interfaces/include/ADCInterface.h +++ b/lib/interfaces/include/ADCInterface.h @@ -16,7 +16,11 @@ namespace adc_default_parameters constexpr const uint32_t IMD_STARTUP_TIME = 2000; constexpr const float TEENSY41_MAX_INPUT_VOLTAGE = 3.3F; -} + + constexpr int MAX114X_VERSION = 8; + constexpr size_t NUM_MAX1148_CHANNELS = 8; +}; + struct ADCPinout_s { pin teensy_imd_ok_pin; @@ -26,6 +30,13 @@ struct ADCPinout_s pin teensy_pack_out_filtered_pin; pin teensy_bspd_current_pin; pin teensy_scaled_24V_pin; + + // MAX114X + pin spiPinCS; + pin spiPinSDI; + pin spiPinSDO; + pin spiPinCLK; + }; struct ADCConversions_s @@ -49,16 +60,51 @@ struct ADCConfigs_s { uint32_t imd_startup_time; float teensy41_max_input_voltage; + int spiSpeed; }; struct ADCChannels_s { - int iso_pack_diff_channel; + int iso_pack_n_channel; + int iso_pack_p_channel; int pack_voltage_sense_channel; - int shunt_current_out_single_channel; - int shunt_current_diff_channel; - // int ts_out_filtered_channel; - // int pack_out_filtered_channel; + int shunt_current_out_channel; + int shunt_current_p_channel; + int shunt_current_n_channel; + int ts_out_filtered_channel; + int pack_out_filtered_channel; +}; + +struct ADCScales_s +{ + float iso_pack_n_scale; + float iso_pack_p_scale; + float pack_voltage_sense_scale; + float shunt_current_out_scale; + float shunt_current_p_scale; + float shunt_current_n_scale; + float ts_out_filtered_scale; + float pack_out_filtered_scale; +}; + +struct ADCOffsets_s +{ + float iso_pack_n_offset; + float iso_pack_p_offset; + float pack_voltage_sense_offset; + float shunt_current_out_offset; + float shunt_current_p_offset; + float shunt_current_n_offset; + float ts_out_filtered_offset; + float pack_out_filtered_offset; +}; + +struct MAX114XChannels_s +{ + CHANNEL_TYPE_e channelPair0; + CHANNEL_TYPE_e channelPair1; + CHANNEL_TYPE_e channelPair2; + CHANNEL_TYPE_e channelPair3; }; struct ADCInterfaceParams_s @@ -68,6 +114,10 @@ struct ADCInterfaceParams_s ADCThresholds_s thresholds; ADCConfigs_s configs; ADCChannels_s channels; + ADCScales_s scales; + ADCOffsets_s offsets; + MAX114XChannels_s pairs; + int spiSpeed; float bit_resolution; }; @@ -76,9 +126,12 @@ class ADCInterface public: ADCInterface(ADCPinout_s pinout, ADCConversions_s conversions, - float bit_resolution, ADCChannels_s channels, - // MAX114XInterface& MAX114XInterfaceInstance, + ADCScales_s scales, + ADCOffsets_s offsets, + MAX114XChannels_s pairs, + int spiSpeed, + float bit_resolution, ADCThresholds_s thresholds = { .teensy41_min_digital_read_voltage_thresh = adc_default_parameters::TEENSY41_MIN_DIGITAL_READ_VOLTAGE_THRESH, .teensy41_max_digital_read_voltage_thresh = adc_default_parameters::TEENSY41_MAX_DIGITAL_READ_VOLTAGE_THRESH, @@ -102,9 +155,45 @@ class ADCInterface thresholds, configs, channels, + scales, + offsets, + pairs, + spiSpeed, bit_resolution}, - // _max114x_instance(MAX114XInterfaceInstance) - {} + _max114x_instance( + _adc_parameters.pinout.spiPinCS, + _adc_parameters.pinout.spiPinSDO, + _adc_parameters.pinout.spiPinSDI, + _adc_parameters.pinout.spiPinCLK, + _adc_parameters.spiSpeed, + std::array { + _adc_parameters.scales.iso_pack_n_scale, + _adc_parameters.scales.iso_pack_p_scale, + _adc_parameters.scales.pack_voltage_sense_scale, + _adc_parameters.scales.shunt_current_out_scale, + _adc_parameters.scales.shunt_current_p_scale, + _adc_parameters.scales.shunt_current_n_scale, + _adc_parameters.scales.ts_out_filtered_scale, + _adc_parameters.scales.pack_out_filtered_scale, + }.data(), + std::array { + _adc_parameters.offsets.iso_pack_n_offset, + _adc_parameters.offsets.iso_pack_p_offset, + _adc_parameters.offsets.pack_voltage_sense_offset, + _adc_parameters.offsets.shunt_current_out_offset, + _adc_parameters.offsets.shunt_current_p_offset, + _adc_parameters.offsets.shunt_current_n_offset, + _adc_parameters.offsets.ts_out_filtered_offset, + _adc_parameters.offsets.pack_out_filtered_offset, + }.data(), + std::array { + _adc_parameters.pairs.channelPair0, + _adc_parameters.pairs.channelPair1, + _adc_parameters.pairs.channelPair2, + _adc_parameters.pairs.channelPair3 + } + ) + {} /** * @pre constructor called and instance created @@ -112,6 +201,11 @@ class ADCInterface */ void init(uint32_t init_millis); + /** + * Samples from MAX114X adc + */ + void tick(); + /** * @return the state of the IMD, HIGH = NO FAULT */ @@ -162,34 +256,25 @@ class ADCInterface */ volt read_shdn_out_voltage(); - // constexpr int ISO_PACK_N_CHANNEL = 0; - // constexpr int ISO_PACK_P_CHANNEL = 1; - // constexpr int PACK_VOLTAGE_SENSE_CHANNEL = 2; - // constexpr int SHUNT_CURRENT_OUT_CHANNEL = 3; - // constexpr int SHUNT_CURRENT_P_CHANNEL = 4; - // constexpr int SHUNT_CURRENT_N_CHANNEL = 5; - // constexpr int TS_OUT_FILTERED_CHANNEL = 6; - // constexpr int PACK_OUT_FILTERED_CHANNEL = 7; - /** * @return ISO Pack Differential */ - int read_iso_pack(); + float read_iso_pack(); /** * @return pack voltage sense */ - int read_pack_voltage_sense(); + float read_pack_voltage_sense(); /** * @return shunt current single channel */ - int read_shunt_current(); + float read_shunt_current(); /** * @return shunt current differential channels */ - int read_differential_shunt_current(); + float read_differential_shunt_current(); /** * @return ADC parameters @@ -203,8 +288,7 @@ class ADCInterface private: const ADCInterfaceParams_s _adc_parameters = {}; - // MAX114XInterface _max114x_instance; - + MAX114XInterface _max114x_instance; /** * @brief true while within the IMD startup window (set in init()) diff --git a/lib/interfaces/src/ADCInterface.cpp b/lib/interfaces/src/ADCInterface.cpp index a92a421..7c63574 100644 --- a/lib/interfaces/src/ADCInterface.cpp +++ b/lib/interfaces/src/ADCInterface.cpp @@ -14,6 +14,10 @@ void ADCInterface::init(uint32_t init_millis) { _in_imd_startup_period = true; } +void ADCInterface::tick() { + _max114x_instance.tick(); +} + bool ADCInterface::read_imd_ok(uint32_t curr_millis) { if (_in_imd_startup_period) { if ((curr_millis - _init_millis) >= _adc_parameters.configs.imd_startup_time) { // give 2 seconds for IMD to startup @@ -21,7 +25,6 @@ bool ADCInterface::read_imd_ok(uint32_t curr_millis) { } return true; } - // return static_cast(analogRead(_adc_parameters.pinout.teensy_imd_ok_pin)) * (_adc_parameters.configs.teensy41_max_input_voltage / _adc_parameters.bit_resolution) > _adc_parameters.thresholds.teensy41_min_digital_read_voltage_thresh; // idk if this would actually work, like if a LOW is a threshold or smth } @@ -74,21 +77,20 @@ volt ADCInterface::read_global_lv_value() { return data; } -int ADCInterface::read_iso_pack() { - MAX1148ADCInstance_t - // MAX114XInterfaceInstance.getLastSampleConverted(_adc_parameters.channels.iso_pack_diff_channel); +float ADCInterface::read_iso_pack() { + _max114x_instance.getLastSampleConverted(_adc_parameters.channels.iso_pack_n_channel); } -int ADCInterface::read_pack_voltage_sense() { - MAX114XInterfaceInstance.getLastSampleConverted(_adc_parameters.channels.pack_voltage_sense_channel); +float ADCInterface::read_pack_voltage_sense() { + _max114x_instance.getLastSampleConverted(_adc_parameters.channels.pack_voltage_sense_channel); } -int ADCInterface::read_shunt_current() { - MAX114XInterfaceInstance<, >::instance().getLastSampleConverted(_adc_parameters.channels.shunt_current_out_single_channel); +float ADCInterface::read_shunt_current() { + _max114x_instance.getLastSampleConverted(_adc_parameters.channels.shunt_current_out_channel); } -int ADCInterface::read_differential_shunt_current() { - MAX114XInterfaceInstance<, >::instance().getLastSampleConverted(_adc_parameters.channels.shunt_current_diff_channel); +float ADCInterface::read_differential_shunt_current() { + _max114x_instance.getLastSampleConverted(_adc_parameters.channels.shunt_current_p_channel); } const ADCInterfaceParams_s& ADCInterface::get_adc_params() const { diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index c897a56..d1ee104 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -79,53 +79,47 @@ void initialize_all_interfaces() ACUEthernetInterfaceInstance::create(); ACUEthernetInterfaceInstance::instance().init_ethernet_device(); - std::array adc0_scales = { - ACUInterfaces::ISO_PACK_N_SCALE, - ACUInterfaces::ISO_PACK_P_SCALE, - ACUInterfaces::PACK_VOLTAGE_SENSE_SCALE, - ACUInterfaces::SHUNT_CURRENT_OUT_SCALE, - ACUInterfaces::SHUNT_CURRENT_P_SCALE, - ACUInterfaces::SHUNT_CURRENT_N_SCALE, - ACUInterfaces::TS_OUT_FILTERED_SCALE, - ACUInterfaces::PACK_OUT_FILTERED_SCALE, - }; - - std::array adc0_offsets = { - ACUInterfaces::ISO_PACK_N_OFFSET, - ACUInterfaces::ISO_PACK_P_OFFSET, - ACUInterfaces::PACK_VOLTAGE_SENSE_OFFSET, - ACUInterfaces::SHUNT_CURRENT_OUT_OFFSET, - ACUInterfaces::SHUNT_CURRENT_P_OFFSET, - ACUInterfaces::SHUNT_CURRENT_N_OFFSET, - ACUInterfaces::TS_OUT_FILTERED_OFFSET, - ACUInterfaces::PACK_OUT_FILTERED_OFFSET, - }; - - // Each channel type corresponds to a pair of channels (0&1, 2&3, etc.) So length is channels / 2 - std::array adc0_channels = { - CHANNEL_TYPE_e::INV_DIFFERENTIAL, - CHANNEL_TYPE_e::SINGLE, - CHANNEL_TYPE_e::DIFFERENTIAL, - CHANNEL_TYPE_e::SINGLE - }; + // std::array adc0_scales = { + // ACUInterfaces::ISO_PACK_N_SCALE, + // ACUInterfaces::ISO_PACK_P_SCALE, + // ACUInterfaces::PACK_VOLTAGE_SENSE_SCALE, + // ACUInterfaces::SHUNT_CURRENT_OUT_SCALE, + // ACUInterfaces::SHUNT_CURRENT_P_SCALE, + // ACUInterfaces::SHUNT_CURRENT_N_SCALE, + // ACUInterfaces::TS_OUT_FILTERED_SCALE, + // ACUInterfaces::PACK_OUT_FILTERED_SCALE, + // }; + + // std::array adc0_offsets = { + // ACUInterfaces::ISO_PACK_N_OFFSET, + // ACUInterfaces::ISO_PACK_P_OFFSET, + // ACUInterfaces::PACK_VOLTAGE_SENSE_OFFSET, + // ACUInterfaces::SHUNT_CURRENT_OUT_OFFSET, + // ACUInterfaces::SHUNT_CURRENT_P_OFFSET, + // ACUInterfaces::SHUNT_CURRENT_N_OFFSET, + // ACUInterfaces::TS_OUT_FILTERED_OFFSET, + // ACUInterfaces::PACK_OUT_FILTERED_OFFSET, + // }; + + // // Each channel type corresponds to a pair of channels (0&1, 2&3, etc.) So length is channels / 2 // std::array adc0_channels = { + // CHANNEL_TYPE_e::INV_DIFFERENTIAL, // CHANNEL_TYPE_e::SINGLE, - // CHANNEL_TYPE_e::SINGLE, - // CHANNEL_TYPE_e::SINGLE, + // CHANNEL_TYPE_e::DIFFERENTIAL, // CHANNEL_TYPE_e::SINGLE // }; - /* ADC Interface */ - MAX1148ADCInstance_t::create( - ACUInterfaces::ADC0_CS, - ACUInterfaces::ADC0_MISO, - ACUInterfaces::ADC0_MOSI, - ACUInterfaces::ADC0_CLK, - ACUInterfaces::ADC0_SPEED, - adc0_scales.data(), - adc0_offsets.data(), - adc0_channels - ); + // /* ADC Interface */ + // MAX1148ADCInstance_t::create( + // ACUInterfaces::ADC0_CS, + // ACUInterfaces::ADC0_MISO, + // ACUInterfaces::ADC0_MOSI, + // ACUInterfaces::ADC0_CLK, + // ACUInterfaces::ADC0_SPEED, + // adc0_scales.data(), + // adc0_offsets.data(), + // adc0_channels + // ); /* CCU Interface */ CCUInterfaceInstance::create(sys_time::hal_millis()); @@ -150,8 +144,37 @@ void initialize_all_interfaces() ACUInterfaces::SHDN_OUT_CONV_FACTOR, ACUInterfaces::BSPD_CURRENT_CONV_FACTOR, ACUInterfaces::GLV_CONV_FACTOR}, - ACUInterfaces::BIT_RESOLUTION); - ADCInterfaceInstance::instance().init(sys_time::hal_millis()); + ADCChannels_s {ACUInterfaces::ISO_PACK_N_CHANNEL, + ACUInterfaces::ISO_PACK_P_CHANNEL, + ACUInterfaces::PACK_VOLTAGE_SENSE_CHANNEL, + ACUInterfaces::SHUNT_CURRENT_OUT_CHANNEL, + ACUInterfaces::SHUNT_CURRENT_P_CHANNEL, + ACUInterfaces::SHUNT_CURRENT_N_CHANNEL, + ACUInterfaces::TS_OUT_FILTERED_CHANNEL, + ACUInterfaces::PACK_OUT_FILTERED_CHANNEL}, + ADCScales_s {ACUInterfaces::ISO_PACK_N_SCALE, + ACUInterfaces::ISO_PACK_P_SCALE, + ACUInterfaces::PACK_VOLTAGE_SENSE_SCALE, + ACUInterfaces::SHUNT_CURRENT_OUT_SCALE, + ACUInterfaces::SHUNT_CURRENT_P_SCALE, + ACUInterfaces::SHUNT_CURRENT_N_SCALE, + ACUInterfaces::TS_OUT_FILTERED_SCALE, + ACUInterfaces::PACK_OUT_FILTERED_SCALE}, + ADCOffsets_s {ACUInterfaces::ISO_PACK_N_OFFSET, + ACUInterfaces::ISO_PACK_P_OFFSET, + ACUInterfaces::PACK_VOLTAGE_SENSE_OFFSET, + ACUInterfaces::SHUNT_CURRENT_OUT_OFFSET, + ACUInterfaces::SHUNT_CURRENT_P_OFFSET, + ACUInterfaces::SHUNT_CURRENT_N_OFFSET, + ACUInterfaces::TS_OUT_FILTERED_OFFSET, + ACUInterfaces::PACK_OUT_FILTERED_OFFSET}, + MAX114XChannels_s {CHANNEL_TYPE_e::INV_DIFFERENTIAL, + CHANNEL_TYPE_e::SINGLE, + CHANNEL_TYPE_e::DIFFERENTIAL, + CHANNEL_TYPE_e::SINGLE}, + ACUInterfaces::BIT_RESOLUTION, + ACUInterfaces::ADC0_SPEED + ); /* CAN Interfaces Construct */ CANInterfacesInstance::create(CCUInterfaceInstance::instance(), EMInterfaceInstance::instance()); @@ -188,7 +211,7 @@ HT_TASK::TaskResponse write_cell_balancing_config(const unsigned long &sysMicros HT_TASK::TaskResponse sample_adc(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo) { - MAX1148ADCInstance_t::instance().tick(); + ADCInterfaceInstance::instance().tick(); return HT_TASK::TaskResponse::YIELD; } @@ -449,22 +472,40 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: // } // Serial.println(); - Serial.println("\nMAX114X Output: "); - for (int i = 0; i < ACUConstants::NUM_MAX1148_CHANNELS; i++) { - Serial.print("CH"); - Serial.print(i); - Serial.print(": "); - Serial.print("Raw = "); - Serial.print(MAX1148ADCInstance_t::instance().getLastSampleRaw(i)); - Serial.print(" Converted = "); - Serial.print(MAX1148ADCInstance_t::instance().getLastSampleConverted(i)); - Serial.print('\n'); - // skip other half of differential pair - if (i == 0 || i == 4) { - i++; - } - } - Serial.print('\n'); + //read_iso_pack + //read_pack_voltage_sense + //read_shunt_current + //read_differential_ + // for (int i = 0; i < adc_default_parameters::NUM_MAX1148_CHANNELS; i++) { + // Serial.print("CH"); + // Serial.print(i); + // Serial.print(": "); + // Serial.print("Raw = "); + // Serial.print(ADCInterfaceInstance); + // Serial.print(" Converted = "); + // Serial.print(MAX1148ADCInstance_t::instance().getLastSampleConverted(i)); + // Serial.print('\n'); + // // skip other half of differential pair + // if (i == 0 || i == 4) { + // i++; + // } + // } + // Serial.print('\n'); + Serial.println("\nMAX114X Output:"); + Serial.print(" CH 0&1:"); + Serial.print(ADCInterfaceInstance::instance().read_iso_pack()); + Serial.print(" CH 2:"); + Serial.print(ADCInterfaceInstance::instance().read_pack_voltage_sense()); + Serial.print(" CH 3:"); + Serial.print(ADCInterfaceInstance::instance().read_shunt_current()); + Serial.print(" CH 4&5:"); + Serial.print(ADCInterfaceInstance::instance().read_differential_shunt_current()); + Serial.print(" CH 6:"); + Serial.print(ADCInterfaceInstance::instance().read_ts_out_filtered()); + Serial.print(" CH 7:"); + Serial.print(ADCInterfaceInstance::instance().read_pack_out_filtered()); + Serial.print('/n'); + return HT_TASK::TaskResponse::YIELD; } From 6c501958097544f6b94b44c5df45c2ed343403e2 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Thu, 29 Jan 2026 01:15:10 -0500 Subject: [PATCH 28/30] Fixed the fat error it works now thank goodness I can go home --- include/ACU_Constants.h | 2 -- lib/interfaces/include/ADCInterface.h | 2 +- lib/interfaces/src/ADCInterface.cpp | 8 ++++---- src/ACU_InterfaceTasks.cpp | 21 +++++++++++++-------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/ACU_Constants.h b/include/ACU_Constants.h index ade30f7..1ead7d7 100644 --- a/include/ACU_Constants.h +++ b/include/ACU_Constants.h @@ -37,7 +37,6 @@ namespace ACUInterfaces { constexpr int ADC0_CLK = 13; constexpr int ADC0_SPEED = 2000000; // 1 MHz /* ADC Versions*/ - // constexpr int MAX114X_VERSION = 8; /* Channels on ADC */ constexpr int ISO_PACK_N_CHANNEL = 0; constexpr int ISO_PACK_P_CHANNEL = 1; @@ -93,7 +92,6 @@ namespace ACUConstants constexpr size_t NUM_CHIPS = 12; constexpr size_t NUM_CELL_TEMPS = 48; constexpr size_t NUM_CHIP_SELECTS = 2; - // constexpr size_t NUM_MAX1148_CHANNELS = 8; const float VALID_SHDN_OUT_MIN_VOLTAGE_THRESHOLD = 12.0F; const uint32_t MIN_ALLOWED_INVALID_SHDN_OUT_MS = 10; // 10 ms -- requies 100 Hz samp freq. diff --git a/lib/interfaces/include/ADCInterface.h b/lib/interfaces/include/ADCInterface.h index a86839e..d441254 100644 --- a/lib/interfaces/include/ADCInterface.h +++ b/lib/interfaces/include/ADCInterface.h @@ -162,8 +162,8 @@ class ADCInterface bit_resolution}, _max114x_instance( _adc_parameters.pinout.spiPinCS, - _adc_parameters.pinout.spiPinSDO, _adc_parameters.pinout.spiPinSDI, + _adc_parameters.pinout.spiPinSDO, _adc_parameters.pinout.spiPinCLK, _adc_parameters.spiSpeed, std::array { diff --git a/lib/interfaces/src/ADCInterface.cpp b/lib/interfaces/src/ADCInterface.cpp index 7c63574..44f043a 100644 --- a/lib/interfaces/src/ADCInterface.cpp +++ b/lib/interfaces/src/ADCInterface.cpp @@ -78,19 +78,19 @@ volt ADCInterface::read_global_lv_value() { } float ADCInterface::read_iso_pack() { - _max114x_instance.getLastSampleConverted(_adc_parameters.channels.iso_pack_n_channel); + return _max114x_instance.getLastSampleConverted(_adc_parameters.channels.iso_pack_n_channel); } float ADCInterface::read_pack_voltage_sense() { - _max114x_instance.getLastSampleConverted(_adc_parameters.channels.pack_voltage_sense_channel); + return _max114x_instance.getLastSampleConverted(_adc_parameters.channels.pack_voltage_sense_channel); } float ADCInterface::read_shunt_current() { - _max114x_instance.getLastSampleConverted(_adc_parameters.channels.shunt_current_out_channel); + return _max114x_instance.getLastSampleConverted(_adc_parameters.channels.shunt_current_out_channel); } float ADCInterface::read_differential_shunt_current() { - _max114x_instance.getLastSampleConverted(_adc_parameters.channels.shunt_current_p_channel); + return _max114x_instance.getLastSampleConverted(_adc_parameters.channels.shunt_current_p_channel); } const ADCInterfaceParams_s& ADCInterface::get_adc_params() const { diff --git a/src/ACU_InterfaceTasks.cpp b/src/ACU_InterfaceTasks.cpp index d1ee104..2636348 100644 --- a/src/ACU_InterfaceTasks.cpp +++ b/src/ACU_InterfaceTasks.cpp @@ -137,7 +137,11 @@ void initialize_all_interfaces() ACUInterfaces::TS_OUT_FILTERED_PIN, ACUInterfaces::PACK_OUT_FILTERED_PIN, ACUInterfaces::BSPD_CURRENT_PIN, - ACUInterfaces::SCALED_24V_PIN}, + ACUInterfaces::SCALED_24V_PIN, + ACUInterfaces::ADC0_CS, + ACUInterfaces::ADC0_MOSI, + ACUInterfaces::ADC0_MISO, + ACUInterfaces::ADC0_CLK}, ADCConversions_s {ACUInterfaces::SHUTDOWN_CONV_FACTOR, ACUInterfaces::PRECHARGE_CONV_FACTOR, ACUInterfaces::PACK_AND_TS_OUT_CONV_FACTOR, @@ -172,9 +176,10 @@ void initialize_all_interfaces() CHANNEL_TYPE_e::SINGLE, CHANNEL_TYPE_e::DIFFERENTIAL, CHANNEL_TYPE_e::SINGLE}, - ACUInterfaces::BIT_RESOLUTION, - ACUInterfaces::ADC0_SPEED + ACUInterfaces::ADC0_SPEED, + ACUInterfaces::BIT_RESOLUTION ); + ADCInterfaceInstance::instance().init(sys_time::hal_millis()); /* CAN Interfaces Construct */ CANInterfacesInstance::create(CCUInterfaceInstance::instance(), EMInterfaceInstance::instance()); @@ -492,17 +497,17 @@ HT_TASK::TaskResponse debug_print(const unsigned long &sysMicros, const HT_TASK: // } // Serial.print('\n'); Serial.println("\nMAX114X Output:"); - Serial.print(" CH 0&1:"); + Serial.print(" CH 0&1: "); Serial.print(ADCInterfaceInstance::instance().read_iso_pack()); - Serial.print(" CH 2:"); + Serial.print(" CH 2: "); Serial.print(ADCInterfaceInstance::instance().read_pack_voltage_sense()); Serial.print(" CH 3:"); Serial.print(ADCInterfaceInstance::instance().read_shunt_current()); - Serial.print(" CH 4&5:"); + Serial.print(" CH 4&5: "); Serial.print(ADCInterfaceInstance::instance().read_differential_shunt_current()); - Serial.print(" CH 6:"); + Serial.print(" CH 6: "); Serial.print(ADCInterfaceInstance::instance().read_ts_out_filtered()); - Serial.print(" CH 7:"); + Serial.print(" CH 7: "); Serial.print(ADCInterfaceInstance::instance().read_pack_out_filtered()); Serial.print('/n'); From 49163af4526dbb13bafa48b18f5f9377233a9fd7 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Sun, 1 Feb 2026 21:46:20 -0500 Subject: [PATCH 29/30] Fixing ADC unit testing (not done) --- platformio.ini | 3 +- test/test_interfaces/test_adc_interface.h | 47 +++++++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index bb64b60..5a54e79 100644 --- a/platformio.ini +++ b/platformio.ini @@ -40,7 +40,8 @@ lib_deps = blemasle/MCP23017@^2.0.0 https://github.com/FabioBatSilva/ArduinoFake.git https://github.com/eranpeer/FakeIt.git - + https://github.com/hytech-racing/shared_firmware_interfaces.git#5baf17a0f6d83d0a9d571d6bf56f409d2c8ad98a + [env:teensy41] test_framework=googletest ; including only the current main file for compiling to keep old main still around for now while diff --git a/test/test_interfaces/test_adc_interface.h b/test/test_interfaces/test_adc_interface.h index 02040bd..9867399 100644 --- a/test/test_interfaces/test_adc_interface.h +++ b/test/test_interfaces/test_adc_interface.h @@ -3,6 +3,8 @@ #include #include "ADCInterface.h" #include "../../lib/interfaces/src/ADCInterface.cpp" +#include +#include using namespace fakeit; @@ -12,7 +14,11 @@ ADCPinout_s pinout = {ACUInterfaces::IMD_OK_PIN, ACUInterfaces::TS_OUT_FILTERED_PIN, ACUInterfaces::PACK_OUT_FILTERED_PIN, ACUInterfaces::BSPD_CURRENT_PIN, - ACUInterfaces::SCALED_24V_PIN}; + ACUInterfaces::SCALED_24V_PIN, + ACUInterfaces::ADC0_CS, + ACUInterfaces::ADC0_MOSI, + ACUInterfaces::ADC0_MISO, + ACUInterfaces::ADC0_CLK}; ADCConversions_s conversions = {ACUInterfaces::SHUTDOWN_CONV_FACTOR, ACUInterfaces::PRECHARGE_CONV_FACTOR, @@ -21,12 +27,45 @@ ADCConversions_s conversions = {ACUInterfaces::SHUTDOWN_CONV_FACTOR, ACUInterfaces::BSPD_CURRENT_CONV_FACTOR, ACUInterfaces::GLV_CONV_FACTOR}; +ADCChannels_s channels = {ACUInterfaces::ISO_PACK_N_CHANNEL, + ACUInterfaces::ISO_PACK_P_CHANNEL, + ACUInterfaces::PACK_VOLTAGE_SENSE_CHANNEL, + ACUInterfaces::SHUNT_CURRENT_OUT_CHANNEL, + ACUInterfaces::SHUNT_CURRENT_P_CHANNEL, + ACUInterfaces::SHUNT_CURRENT_N_CHANNEL, + ACUInterfaces::TS_OUT_FILTERED_CHANNEL, + ACUInterfaces::PACK_OUT_FILTERED_CHANNEL}; + +ADCScales_s scales = {ACUInterfaces::ISO_PACK_N_SCALE, + ACUInterfaces::ISO_PACK_P_SCALE, + ACUInterfaces::PACK_VOLTAGE_SENSE_SCALE, + ACUInterfaces::SHUNT_CURRENT_OUT_SCALE, + ACUInterfaces::SHUNT_CURRENT_P_SCALE, + ACUInterfaces::SHUNT_CURRENT_N_SCALE, + ACUInterfaces::TS_OUT_FILTERED_SCALE, + ACUInterfaces::PACK_OUT_FILTERED_SCALE}; + +ADCOffsets_s offsets = {ACUInterfaces::ISO_PACK_N_OFFSET, + ACUInterfaces::ISO_PACK_P_OFFSET, + ACUInterfaces::PACK_VOLTAGE_SENSE_OFFSET, + ACUInterfaces::SHUNT_CURRENT_OUT_OFFSET, + ACUInterfaces::SHUNT_CURRENT_P_OFFSET, + ACUInterfaces::SHUNT_CURRENT_N_OFFSET, + ACUInterfaces::TS_OUT_FILTERED_OFFSET, + ACUInterfaces::PACK_OUT_FILTERED_OFFSET}; + +MAX114XChannels_s pairs = {CHANNEL_TYPE_e::INV_DIFFERENTIAL, + CHANNEL_TYPE_e::SINGLE, + CHANNEL_TYPE_e::DIFFERENTIAL, + CHANNEL_TYPE_e::SINGLE}; + float bit_res = ACUInterfaces::BIT_RESOLUTION; +int spi_speed = ACUInterfaces::ADC0_SPEED; TEST (ADCInterfaceTesting, init) { When(Method(ArduinoFake(), pinMode)).AlwaysReturn(); - ADCInterfaceInstance::create(pinout, conversions, bit_res); + ADCInterfaceInstance::create(pinout, conversions, channels, scales, offsets, pairs, spi_speed, bit_res); ADCInterfaceInstance::instance().init(0); ASSERT_EQ(ADCInterfaceInstance::instance().is_in_imd_startup_period(), true); @@ -44,7 +83,7 @@ TEST (ADCInterfaceTesting, read_imd_ok) { When(Method(ArduinoFake(), pinMode)).AlwaysReturn(); When(Method(ArduinoFake(), analogRead)).AlwaysReturn(0); - ADCInterfaceInstance::create(pinout, conversions, bit_res); + ADCInterfaceInstance::create(pinout, conversions, channels, scales, offsets, pairs, spi_speed, bit_res); ADCInterfaceInstance::instance().init(0); ADCInterfaceInstance::instance().read_imd_ok(1000); @@ -63,7 +102,7 @@ TEST (ADCInterfaceTesting, read_functions) { When(Method(ArduinoFake(), pinMode)).AlwaysReturn(); When(Method(ArduinoFake(), analogRead)).AlwaysReturn(0); - ADCInterfaceInstance::create(pinout, conversions, bit_res); + ADCInterfaceInstance::create(pinout, conversions, channels, scales, offsets, pairs, spi_speed, bit_res); ADCInterfaceInstance::instance().init(3000); ADCInterfaceInstance::instance().read_shdn_voltage(); ADCInterfaceInstance::instance().read_shdn_out_voltage(); From 9b47092024515f17b7bcc4cc9b074cba87623b3b Mon Sep 17 00:00:00 2001 From: akemiyu <43460886+akemiyu@users.noreply.github.com> Date: Sun, 1 Feb 2026 22:50:36 -0500 Subject: [PATCH 30/30] Fixed dependency issues --- platformio.ini | 2 +- src/main_spi_test.cpp | 3 +-- test/test_interfaces/test_adc_interface.h | 6 ++++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index 5a54e79..b190d06 100644 --- a/platformio.ini +++ b/platformio.ini @@ -98,7 +98,7 @@ build_src_filter = - + + - + build_unflags = -std=gnu++11 build_flags = -std=c++17 diff --git a/src/main_spi_test.cpp b/src/main_spi_test.cpp index f1722a2..5947104 100644 --- a/src/main_spi_test.cpp +++ b/src/main_spi_test.cpp @@ -1,6 +1,5 @@ /* ACU Dependent */ #include "ACU_Constants.h" -#include "ACU_Globals.h" #include "SystemTimeInterface.h" #include "ACU_InterfaceTasks.h" #include "ACU_SystemTasks.h" @@ -40,7 +39,7 @@ const std::array addr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; // Instantiate BMS Driver Group (non-const so we can call non-const methods) BMSDriverGroup BMSGroup = BMSDriverGroup(cs, cs_per_chip, addr); -std::array chip_invalid_cmd_counts; +std::array::BMSFaultCountData_s, num_chips> chip_invalid_cmd_counts; // Tracking variables for optimized read testing struct ReadGroupStats { diff --git a/test/test_interfaces/test_adc_interface.h b/test/test_interfaces/test_adc_interface.h index 9867399..028187e 100644 --- a/test/test_interfaces/test_adc_interface.h +++ b/test/test_interfaces/test_adc_interface.h @@ -62,6 +62,12 @@ MAX114XChannels_s pairs = {CHANNEL_TYPE_e::INV_DIFFERENTIAL, float bit_res = ACUInterfaces::BIT_RESOLUTION; int spi_speed = ACUInterfaces::ADC0_SPEED; +template +void AnalogMultiSensor::_sample() {} + +template +void AnalogMultiSensor::tick() { _sample(); _convert(); } + TEST (ADCInterfaceTesting, init) { When(Method(ArduinoFake(), pinMode)).AlwaysReturn();