83 #define DATALOG_ENABLED 1 84 #define DATALOG_DISABLED 0 168 bool DCCBITS[6] = {
false,
false,
false,
false,
false,
false};
184 Serial.begin(115200);
188 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC; current_ic++)
190 LTC6810_set_cfgr(current_ic, BMS_IC,
REFON,
ADCOPT,
GPIOBITS,
DCCBITS,
DCCBIT_0,
MCAL,
EN_DTMEN,
DIS_RED,
FDRF,
SCONV,
DCTOBITS,
UV,
OV);
203 if (Serial.available())
207 Serial.println(user_command);
219 uint32_t conv_time = 0;
458 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC;current_ic++)
477 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC;current_ic++)
504 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC;current_ic++)
531 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC;current_ic++)
547 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC;current_ic++)
604 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC;current_ic++)
606 LTC6810_set_cfgr(current_ic, BMS_IC,
REFON,
ADCOPT,
GPIOBITS,
DCCBITS,
DCCBIT_0,
MCAL,
EN_DTMEN,
DIS_RED,
FDRF,
SCONV,
DCTOBITS,
UV,
OV);
618 char str_error[]=
"Incorrect Option \n";
633 Serial.println(F(
"Transmit 'm' to quit"));
637 if (Serial.available() > 0)
704 Serial.println(F(
"Please enter LTC6810 Command"));
705 Serial.println(F(
"Write and Read Configuration: 1 |Loop Measurements: 12 |Set Discharge: 23"));
706 Serial.println(F(
"Read Configuration: 2 |Loop Measurements with Data Log output : 13 |Clear Discharge: 24"));
707 Serial.println(F(
"Start Cell Voltage Conversion: 3 |Clear all ADC Measurement Registers: 14 |Write and Read of PWM : 25"));
708 Serial.println(F(
"Read Cell Voltages: 4 |Run Mux Self Test: 15 |SPI Communication : 26"));
709 Serial.println(F(
"Start Aux Voltage Conversion: 5 |Run ADC Self Test: 16 |I2C Communication Write to Slave :27"));
710 Serial.println(F(
"Read Aux Voltages: 6 |Run Digital Redundancy Test: 17 |I2C Communication Read from Slave :28"));
711 Serial.println(F(
"Start Stat Voltage Conversion: 7 |Open Wire Test for single cell detection: 18 |Reverse ISOSPI : 29"));
712 Serial.println(F(
"Read Stat Voltages: 8 |Open Wire Test for multiple cell or two consecutive cells detection: 19|Read Serial ID : 30"));
713 Serial.println(F(
"Start Combined Cell Voltage and Cell 0, GPIO2 Conversion: 9|Open wire for Auxiliary Measurement: 20 |Enable MUTE : 31"));
714 Serial.println(F(
"Start Cell Voltage and Sum of cells: 10 |Print PEC Counter: 21 |Disable MUTE : 32"));
715 Serial.println(F(
"Read S Voltage Registers: 11 |Reset PEC Counter: 22 |Set or reset the gpio pins: 33 \n"));
716 Serial.println(F(
"Print 'm' for menu"));
717 Serial.println(F(
"Please enter command: \n"));
729 Serial.println(F(
"Written Configuration: "));
730 for (
int current_ic = 0; current_ic<
TOTAL_IC; current_ic++)
732 Serial.print(F(
"CFGA IC "));
733 Serial.print(current_ic+1,DEC);
734 for(
int i = 0;
i<6;
i++)
736 Serial.print(F(
", 0x"));
739 Serial.print(F(
", Calculated PEC: 0x"));
740 cfg_pec =
pec15_calc(6,&BMS_IC[current_ic].config.tx_data[0]);
742 Serial.print(F(
", 0x"));
744 Serial.println(
"\n");
755 Serial.println(F(
"Received Configuration "));
756 for (
int current_ic=0; current_ic<
TOTAL_IC; current_ic++)
758 Serial.print(F(
"CFGA IC "));
759 Serial.print(current_ic+1,DEC);
760 for(
int i = 0;
i < 6;
i++)
762 Serial.print(F(
", 0x"));
765 Serial.print(F(
", Received PEC: 0x"));
767 Serial.print(F(
", 0x"));
769 Serial.println(
"\n");
779 for (
int current_ic = 0 ; current_ic <
TOTAL_IC; current_ic++)
783 Serial.print(
" IC ");
784 Serial.print(current_ic+1,DEC);
788 Serial.print(
i+1,DEC);
790 Serial.print(BMS_IC[current_ic].cells.c_codes[
i]*0.0001,4);
797 Serial.print(
" Cells :");
800 Serial.print(BMS_IC[current_ic].cells.c_codes[
i]*0.0001,4);
805 Serial.println(
"\n");
814 for (
int current_ic =0 ; current_ic <
TOTAL_IC; current_ic++)
818 Serial.print(
" IC ");
819 Serial.print(current_ic+1,DEC);
820 Serial.print(F(
": S0_V :"));
821 Serial.print(BMS_IC[current_ic].aux.a_codes[0]*0.0001,4);
823 for (
int i = 1;
i < 5;
i++)
825 Serial.print(F(
" GPIO-"));
828 Serial.print(BMS_IC[current_ic].aux.a_codes[
i]*0.0001,4);
831 Serial.print(F(
" Vref2 :"));
832 Serial.print(BMS_IC[current_ic].aux.a_codes[5]*0.0001,4);
837 Serial.print(
"AUX :");
839 for (
int i=0;
i < 6;
i++)
841 Serial.print(BMS_IC[current_ic].aux.a_codes[
i]*0.0001,4);
846 Serial.println(
"\n");
856 for (
int current_ic =0 ; current_ic <
TOTAL_IC; current_ic++)
858 Serial.print(F(
" IC "));
859 Serial.print(current_ic+1,DEC);
860 Serial.print(F(
" SOC:"));
861 Serial.print(BMS_IC[current_ic].stat.stat_codes[0]*0.0001*10,4);
862 Serial.print(F(
", Itemp:"));
863 itmp = (double)((BMS_IC[current_ic].stat.stat_codes[1] * (0.0001 / 0.0075)) - 273);
864 Serial.print(itmp,4);
865 Serial.print(F(
", VregA:"));
866 Serial.print(BMS_IC[current_ic].stat.stat_codes[2]*0.0001,4);
867 Serial.print(F(
", VregD:"));
868 Serial.println(BMS_IC[current_ic].stat.stat_codes[3]*0.0001,4);
869 Serial.print(F(
" Flag bits: 0x"));
871 Serial.print(F(
",\t Flag bits and Mute bit:"));
872 Serial.print(F(
" 0x"));
874 Serial.print(F(
",\t Mux fail flag:"));
875 Serial.print(F(
" 0x"));
877 Serial.print(F(
",\t THSD:"));
878 Serial.print(F(
" 0x"));
880 Serial.println(
"\n");
890 for (
int current_ic =0 ; current_ic <
TOTAL_IC; current_ic++)
892 Serial.print(F(
" IC "));
893 Serial.print(current_ic+1,DEC);
894 Serial.print(F(
": SOC:"));
895 Serial.print(BMS_IC[current_ic].stat.stat_codes[0]*0.0001*10,4);
896 Serial.print(F(
","));
898 Serial.println(
"\n");
907 for (
int current_ic = 0 ; current_ic <
TOTAL_IC; current_ic++)
911 Serial.print(
" IC ");
912 Serial.print(current_ic+1,DEC);
915 for (
int i=6;
i<12;
i++)
920 Serial.print(BMS_IC[current_ic].cells.c_codes[
i]*0.0001,4);
928 Serial.print(
"S pin:, ");
929 for (
int i=6;
i<12;
i++)
931 Serial.print(BMS_IC[current_ic].cells.c_codes[
i]*0.0001,4);
936 Serial.println(
"\n");
948 Serial.print(
" IC ");
949 Serial.println(ic+1,DEC);
950 if (BMS_IC[ic].stat.mux_fail[0] != 0) error++;
952 if (error==0) Serial.println(F(
"Mux Test: PASS \n"));
953 else Serial.println(F(
"Mux Test: FAIL \n"));
965 Serial.println(
"Cell ");
969 Serial.println(
"Aux ");
973 Serial.println(
"Stat ");
975 Serial.print(error, DEC);
976 Serial.println(F(
" : errors detected in Digital Filter and Memory \n"));
987 Serial.println(
"Aux ");
991 Serial.println(
"Stat ");
994 Serial.print(error, DEC);
995 Serial.println(F(
" : errors detected in Measurement \n"));
1004 for (
int current_ic =0 ; current_ic <
TOTAL_IC; current_ic++)
1006 if (BMS_IC[current_ic].system_open_wire == 65535)
1008 Serial.print(
"No Opens Detected on IC ");
1009 Serial.print(current_ic+1, DEC);
1013 Serial.print(F(
"There is an open wire on IC "));
1014 Serial.print(current_ic + 1,DEC);
1015 Serial.print(F(
" Channel: "));
1016 Serial.println(BMS_IC[current_ic].system_open_wire);
1018 Serial.println(
"\n");
1028 for (
int current_ic=0; current_ic<
TOTAL_IC; current_ic++)
1031 Serial.print(BMS_IC[current_ic].crc_count.pec_count,DEC);
1032 Serial.print(F(
" : PEC Errors Detected on IC"));
1033 Serial.println(current_ic+1,DEC);
1035 Serial.println(
"\n");
1044 int8_t read_s_pin=0;
1046 Serial.print(F(
"Please enter the Spin number: "));
1048 Serial.println(read_s_pin);
1061 Serial.println(F(
"Written PWM Configuration: "));
1062 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC; current_ic++)
1064 Serial.print(F(
"IC "));
1065 Serial.print(current_ic+1,DEC);
1066 for(
int i = 0;
i < 6;
i++)
1068 Serial.print(F(
", 0x"));
1071 Serial.print(F(
", Calculated PEC: 0x"));
1072 pwm_pec =
pec15_calc(6,&BMS_IC[current_ic].pwm.tx_data[0]);
1074 Serial.print(F(
", 0x"));
1076 Serial.println(
"\n");
1087 Serial.println(F(
"Received pwm Configuration:"));
1088 for (uint8_t current_ic=0; current_ic<
TOTAL_IC; current_ic++)
1090 Serial.print(F(
"IC "));
1091 Serial.print(current_ic+1,DEC);
1092 for(
int i = 0;
i < 6;
i++)
1094 Serial.print(F(
", 0x"));
1097 Serial.print(F(
", Received PEC: 0x"));
1099 Serial.print(F(
", 0x"));
1101 Serial.println(
"\n");
1113 Serial.println(F(
"Written Data in COMM Register: "));
1114 for (
int current_ic = 0; current_ic<
TOTAL_IC; current_ic++)
1116 Serial.print(F(
" IC- "));
1117 Serial.print(current_ic+1,DEC);
1119 for(
int i = 0;
i < 6;
i++)
1121 Serial.print(F(
", 0x"));
1124 Serial.print(F(
", Calculated PEC: 0x"));
1125 comm_pec =
pec15_calc(6,&BMS_IC[current_ic].com.tx_data[0]);
1127 Serial.print(F(
", 0x"));
1129 Serial.println(
"\n");
1139 Serial.println(F(
"Received Data in COMM register:"));
1140 for (
int current_ic=0; current_ic<
TOTAL_IC; current_ic++)
1142 Serial.print(F(
" IC- "));
1143 Serial.print(current_ic+1,DEC);
1145 for(
int i = 0;
i < 6;
i++)
1147 Serial.print(F(
", 0x"));
1150 Serial.print(F(
", Received PEC: 0x"));
1152 Serial.print(F(
", 0x"));
1154 Serial.println(
"\n");
1166 Serial.println(F(
"Serial ID: "));
1167 for (uint8_t current_ic = 0; current_ic<
TOTAL_IC; current_ic++)
1169 Serial.print(F(
"IC "));
1170 Serial.print(current_ic+1,DEC);
1172 for(
int i = 0;
i < 6;
i++)
1174 Serial.print(F(
", 0x"));
1177 Serial.print(F(
", Calculated PEC: 0x"));
1178 sid_pec =
pec15_calc(6,&BMS_IC[current_ic].sid[0]);
1180 Serial.print(F(
", 0x"));
1182 Serial.println(
"\n");
1193 Serial.print(F(
"ISOSPI: "));
1197 Serial.print(F(
"Current ISOSPI Direction: "));
1198 Serial.println(BMS_IC[0].isospi_reverse);
1199 Serial.println(
"\n");
1208 for (
int current_ic = 0 ; current_ic <
TOTAL_IC; current_ic++)
1210 Serial.print(F(
" Mute bit in Status Register B: 0x"));
1212 Serial.println(
"\n");
1222 uint16_t m_factor=1000;
1224 Serial.print(F(
"Conversion completed in:"));
1225 Serial.print(((
float)conv_time/m_factor), 1);
1226 Serial.println(F(
"ms \n"));
1237 Serial.println(F(
"A PEC error was detected in the received data"));
1247 Serial.println(data);
1259 Serial.print((byte)data,HEX);
1262 Serial.print((byte)data,HEX);
1270 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' 1278 '0',
'x',
'0',
'0',
'\0' 1311 while (Serial.available() <= 0);
1312 return(Serial.read());
bool DCCBITS[6]
Discharge cell switch //Dcc 1,2,3,4,5,6.
static void print_open_wires(void)
const uint8_t MEASURE_AUX
This is to ENABLED or DISABLED reading the auxiliary registers in a continuous loop.
int16_t LTC6810_run_cell_adc_st(uint8_t adc_reg, uint8_t total_ic, cell_asic *ic, uint8_t md, bool adcopt)
Helper function that runs the ADC Self Tests.
static void print_conv_time(uint32_t conv_time)
uint8_t LTC6810_rdcv(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 cell voltage registers.
void LTC6810_set_cfgr(uint8_t nIC, cell_asic *ic, bool refon, bool adcopt, bool gpio[4], bool dcc[6], bool dcc_0, bool mcal, bool en_dtmen, bool dis_red, bool fdrf, bool sconv, bool dcto[4], uint16_t uv, uint16_t ov)
Helper function to set appropriate bits in CFGR register based on bit function.
unsigned char user_command
uint8_t tx_data[6]
Stores data to be transmitted.
const uint8_t TOTAL_IC
Number of ICs in the daisy chain.
#define CELL_CH_ALL
CH Dec Channels to convert 0000 All Cells 0011 Cell 1 and Cell 7 0102 Cell 2 and Cell 8 0113 Cell 3 ...
static void print_aux(uint8_t datalog_en)
static void print_selftest_errors(uint8_t adc_reg, int8_t error)
const uint8_t READ_CONFIG
This is to ENABLED or DISABLED reading the configuration registers in a continuous loop...
int8_t LTC6810_rdcomm(uint8_t total_ic, cell_asic *ic)
Reads comm registers of a LTC6810 in daisy chain.
LTC6810: 6-Channel Battery Stack Monitors.
static void print_sumofcells(void)
const uint16_t MEASUREMENT_LOOP_TIME
Loop Time in milliseconds(ms)
const uint8_t ADC_DCP
Discharge Permitted.
const uint8_t SEL_ALL_REG
Register Selection.
Header File for Linduino Libraries and Demo Code.
cell_asic BMS_IC[TOTAL_IC]
Global Battery Variable.
static int8_t select_s_pin(void)
#define AUX_CH_ALL
CHG Dec Channels to convert 000 0 All GPIOS and 2nd Ref 001 1 GPIO 1 010 2 GPIO 2 011 3 GPIO 3 100 4...
int8_t LTC6810_rdcfg(uint8_t total_ic, cell_asic *ic)
Reads configuration registers of a LTC6810 daisy chain.
static void print_rxcomm(void)
const uint8_t SEL_REG_B
Register Selection.
static void print_menu(void)
void spi_enable(uint8_t spi_clock_divider)
Setup the processor for hardware SPI communication.
static void print_cells(uint8_t datalog_en)
static uint16_t OV
Over voltage Comparison Voltage.
void LTC6810_clrstat()
Clears the LTC6810 Stat registers.
bool ADCOPT
ADC Mode option bit.
bool GPIOBITS[4]
GPIO Pin Control // Gpio 1,2,3,4.
int8_t LTC6810_rdpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Reads pwm registers of the LTC6810 in daisy chain.
static void print_stat(void)
void LTC6810_mute()
Mutes the LTC6810 discharge transistors.
static void print_wrconfig(void)
bool SCONV
Enable Cell Measurement Redundancy using S Pin.
bool EN_DTMEN
Enable Discharge timer monitor.
union LT_union_int32_4bytes data
void LTC6810_adcvsc(uint8_t MD, uint8_t DCP)
Starts cell voltage and SOC conversion.
char byte_to_hex_buffer[3]
static void measurement_loop(uint8_t datalog_en)
const uint16_t UV_THRESHOLD
Under voltage threshold ADC Code.
static void print_rxconfig(void)
static void print_pec_error_count(void)
static void reverse_isospi_direction(void)
const uint16_t OV_THRESHOLD
Over voltage threshold ADC Code.
bool DCTOBITS[4]
Discharge Time Out Value //Dcto 0,1,2,3 // Programed for 4 min.
void LTC6810_stcomm(uint8_t len)
Issues a stcomm command and clocks data out of the COMM register.
void LTC6810_adcv(uint8_t MD, uint8_t DCP, uint8_t CH)
Starts cell voltage conversion.
void LTC6810_clear_discharge(uint8_t total_ic, cell_asic *ic)
Clears all of the DCC bits in the configuration registers.
static uint16_t UV
Under voltage Comparison Voltage.
const uint8_t SEL_REG_A
Register Selection.
static void serial_print_text(char data[])
static void check_error(int error)
#define input(pin)
Return the state of pin "pin".
void LTC6810_clraux()
Clears the LTC6810 Auxiliary registers.
uint8_t cell_channels
Number of Cell channels.
void LTC6810_unmute()
Clears the LTC6810 Mute Discharge.
static void run_command(uint32_t cmd)
void LTC6810_reset_crc_count(uint8_t total_ic, cell_asic *ic)
Helper Function that resets the PEC error counters.
static void print_wrcomm(void)
/prints data which is written on COMM register onto the serial port
int8_t LTC6810_rdstat(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 stat registers.
void LTC6810_init_cfg(uint8_t total_ic, cell_asic *ic)
Helper Function to initialize the CFGR data structures.
const uint8_t MEASURE_CELL
This is to ENABLED or DISABLED measuring the cell voltages in a continuous loop.
uint8_t LTC6810_rds(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 S voltage registers.
bool REFON
Reference Powered Up Bit.
void LTC6810_clrcell()
Clears the LTC6810 cell voltage registers.
const uint8_t AUX_CH_TO_CONVERT
Channel Selection for ADC conversion.
uint16_t pec15_calc(uint8_t len, uint8_t *data)
static void check_mux_fail(void)
bool MCAL
Enable Multi-Calibration.
LT_SPI: Routines to communicate with ATmega328P's hardware SPI port.
const uint8_t MEASURE_STAT
This is to ENABLED or DISABLED reading the status registers in a continuous loop. ...
void LTC6810_wrcomm(uint8_t total_ic, cell_asic *ic)
Write the LTC6810 COMM register.
void LTC6810_run_gpio_openwire(uint8_t total_ic, cell_asic ic[])
void LTC6810_adax(uint8_t MD, uint8_t CHG)
Start a GPIO, cell 0 and Vref2 Conversion.
void LTC6810_adstat(uint8_t MD, uint8_t CHST)
Start a Status ADC Conversion.
const uint8_t WRITE_CONFIG
This is to ENABLED or DISABLED writing into to configuration registers in a continuous loop...
void LTC6810_adcvax(uint8_t MD, uint8_t DCP)
Starts cell voltage, Cell 0 and GPIO 1 conversion.
void quikeval_SPI_connect()
Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C...
void LTC6810_wrcfg(uint8_t total_ic, cell_asic *ic)
Write the LTC6810 configuration register.
int8_t LTC6810_rdaux(uint8_t reg, uint8_t total_ic, cell_asic *ic)
Reads and parses the LTC6810 auxiliary registers.
const uint8_t ADC_CONVERSION_MODE
ADC Mode.
const uint8_t STAT_CH_TO_CONVERT
Channel Selection for ADC conversion.
void LTC6810_diagn()
Starts the Mux Decoder diagnostic self test.
static void print_wrpwm(void)
static void print_sid(void)
uint8_t LTC6810_rdsid(uint8_t total_ic, cell_asic *ic)
Reads Serial ID registers group.
bool DCCBIT_0
Discharge cell switch //Dcc 0 // For discharging optional 7th cell.
int16_t LTC6810_run_adc_redundancy_st(uint8_t adc_mode, uint8_t adc_reg, uint8_t total_ic, cell_asic *ic)
Helper function that runs the ADC Digital Redundancy commands and checks output for errors...
const uint8_t ADC_OPT
ADC Mode option bit.
void LTC6810_run_openwire_single(uint8_t total_ic, cell_asic *ic)
Helper function that runs the data sheet open wire algorithm for single cell detection.
char hex_to_byte_buffer[5]
static void print_rxpwm(void)
const uint8_t PRINT_PEC
This is to ENABLED or DISABLED printing the PEC Error Count in a continuous loop. ...
bool FDRF
Force digital Redundancy Failure.
void LTC6810_init_reg_limits(uint8_t total_ic, cell_asic *ic)
Initialize the Register limits.
static void check_mute_bit(void)
static void serial_print_hex(uint8_t data)
static void print_svolt(uint8_t datalog_en)
const uint8_t CELL_CH_TO_CONVERT
Channel Selection for ADC conversion.
void LTC6810_run_openwire_multi(uint8_t total_ic, cell_asic *ic)
Runs the data sheet algorithm for open wire for multiple cell and two consecutive cells detection...
void LTC6810_wrpwm(uint8_t total_ic, uint8_t pwmReg, cell_asic *ic)
Writes to the LTC6810 PWM register of LTC6810.
uint32_t LTC6810_pollAdc()
This function will block operation until the ADC has finished it's conversion.
static void print_digital_redundancy_errors(uint8_t adc_reg, int8_t error)
bool DIS_RED
Disable Digital Redundancy Check.
void LTC6810_set_discharge(int Cell, uint8_t total_ic, cell_asic *ic)
Helper function to set discharge bit in CFG register.