diff --git a/Code/diybmsCurrentShunt/MODBUS Registers.md b/Code/diybmsCurrentShunt/MODBUS Registers.md index c7f8fb2..cc3ec3e 100644 --- a/Code/diybmsCurrentShunt/MODBUS Registers.md +++ b/Code/diybmsCurrentShunt/MODBUS Registers.md @@ -20,10 +20,10 @@ All registers are read only, unless also specified in "Write Registers" later on |40010|Various status flags (see below) |40011|Power (4 byte double) |40012|Power -|40013|Shunt mV (4 byte double) -|40014|Shunt mV -|40015|CURRENT_LSB (4 byte double) -|40016|CURRENT_LSB +|40013|Daily milliamphour_out (4 byte unsigned long uint32_t) +|40014|Daily milliamphour_out (4 byte unsigned long uint32_t) +|40015|Daily milliamphour_in (4 byte unsigned long uint32_t) +|40016|Daily milliamphour_in |40017|shunt_resistance (4 byte double) |40018|shunt_resistance |40019|shunt_max_current (unsigned int16) @@ -71,9 +71,11 @@ All registers are read only, unless also specified in "Write Registers" later on |Register|Description|Example| |--------|-----------|-------| -|40005/40006|amphour_out|Set to zero to reset -|40007/40008|amphour_in|Set to zero to reset |40010|Watchdog timer trigger count (like error counter) (unsigned int16)| +|40013|Daily milliamphour_out/reset to zero +|40014|Daily milliamphour_out/reset to zero +|40015|Daily milliamphour_in/reset to zero +|40016|Daily milliamphour_in/reset to zero |40019|shunt_max_current (unsigned int16) |e.g. 150 |40020|shunt_millivolt (unsigned int16) |e.g. 50 |40021/40022|Battery Capacity (ah) (unsigned int16) diff --git a/Code/diybmsCurrentShunt/platformio.ini b/Code/diybmsCurrentShunt/platformio.ini index d88ebae..a24946b 100644 --- a/Code/diybmsCurrentShunt/platformio.ini +++ b/Code/diybmsCurrentShunt/platformio.ini @@ -34,7 +34,7 @@ board_build.f_cpu = 5000000L board_build.core = megatinycore board_build.extra_flags=-DARDUINO_attinyxy4 -DMILLIS_USE_TIMERD0 -DUARTBAUD5V upload_protocol = jtag2updi -upload_port = COM8 +;upload_port = COM8 board_hardware.updipin = updi diff --git a/Code/diybmsCurrentShunt/src/main.cpp b/Code/diybmsCurrentShunt/src/main.cpp index 4a45aae..339df16 100644 --- a/Code/diybmsCurrentShunt/src/main.cpp +++ b/Code/diybmsCurrentShunt/src/main.cpp @@ -104,6 +104,9 @@ const uint16_t loop_delay_ms = 2000; uint32_t milliamphour_out_lifetime = 0; uint32_t milliamphour_in_lifetime = 0; +uint32_t daily_milliamphour_out = 0; +uint32_t daily_milliamphour_in = 0; + uint32_t milliamphour_out = 0; uint32_t milliamphour_in = 0; @@ -535,8 +538,13 @@ void SetSOC(uint16_t value) // And we have consumed this much... milliamphour_out = (1.0 - ((float)value / 10000.0)) * milliamphour_in; + // Zero out readings using the offsets milliamphour_out_offset = milliamphour_out; milliamphour_in_offset = milliamphour_in; + + // Reset the daily counters + daily_milliamphour_in = 0; + daily_milliamphour_out = 0; } void SetINA228Registers() @@ -573,11 +581,15 @@ bool SetRegister(uint16_t address, uint16_t value) case 6: //|40022|Fully charged voltage (4 byte double) case 21: - //|40024|Tail current (Amps) (4 byte double) + //|40024|Tail current (Amps) (4 byte double) case 23: + // Temperature limit (signed int16) case 29: + // Bus Overvoltage (overvoltage protection) case 31: + // BusUnderVolt case 33: + // Shunt Over Voltage Limit (current limit) case 35: case 37: { @@ -649,6 +661,23 @@ bool SetRegister(uint16_t address, uint16_t value) SetINA228ConfigurationRegisters(); break; } + + // Allow reset of daily AH counters to ZERO + case 13: + case 14: + { + // Daily milliamphour_out (4 byte unsigned long uint32_t) + daily_milliamphour_out = 0; + break; + } + case 15: + case 16: + { + // Daily milliamphour_in (4 byte unsigned long uint32_t) + daily_milliamphour_in = 0; + break; + } + case 18: { registers.shunt_max_current = value; @@ -720,7 +749,6 @@ bool SetRegister(uint16_t address, uint16_t value) registers.R_BOVL = newvalue.dblvalue / 0.003125F; break; } - case 32: { // Bus under voltage @@ -728,7 +756,6 @@ bool SetRegister(uint16_t address, uint16_t value) registers.R_BUVL = newvalue.dblvalue / 0.003125F; break; } - case 34: { // Shunt Over Voltage Limit (current limit) @@ -1054,6 +1081,7 @@ void setup() // We apply a "guestimate" to SoC based on voltage - not really accurate, but somewhere to start // only applicable to 24V/48V (16S) setups. These voltages should be the unloaded (no current flowing) voltage. + // Assumption that its LIFEPO4 cells we are using double v = BusVoltage(); if (v > 20 && v < 30) @@ -1319,33 +1347,30 @@ uint16_t ReadHoldingRegister(uint16_t address) case 12: { - // Shunt mV - int32_t temp = ShuntVoltage() * 10000; - shuntv.word[0] = (uint16_t)(temp >> 16); - shuntv.word[1] = (uint16_t)(temp); - return shuntv.word[0]; + // milliamphour_out + return (uint16_t)(daily_milliamphour_out >> 16); break; } - case 13: { - // Shunt mV - return shuntv.word[1]; + // milliamphour_out (low 16 bits) + return (uint16_t)daily_milliamphour_out; break; } case 14: { - copy_current_lsb.dblvalue = registers.CURRENT_LSB; - return copy_current_lsb.word[0]; + // milliamphour_out + return (uint16_t)(daily_milliamphour_in >> 16); break; } - case 15: { - return copy_current_lsb.word[1]; + // milliamphour_out (low 16 bits) + return (uint16_t)daily_milliamphour_in; break; } + case 16: { copy_shunt_resistance.dblvalue = registers.RSHUNT; @@ -1412,7 +1437,6 @@ uint16_t ReadHoldingRegister(uint16_t address) { //|40027|State of charge % (unsigned int16) (scale x100 eg. 10000 = 100.00%, 8012 = 80.12%, 100 = 1.00%) return CalculateSOC(); - // return SOC; break; } case 27: @@ -1421,14 +1445,12 @@ uint16_t ReadHoldingRegister(uint16_t address) return i2c_readword(INA_REGISTER::SHUNT_CAL); break; } - case 28: { // temperature limit return (int16_t)TemperatureLimit(); break; } - case 29: { // Bus Overvoltage (overvoltage protection). @@ -1437,26 +1459,22 @@ uint16_t ReadHoldingRegister(uint16_t address) return BusOverVolt.word[0]; break; } - case 30: { return BusOverVolt.word[1]; break; } - case 31: { BusUnderVolt.dblvalue = (double)i2c_readword(INA_REGISTER::BUVL) * 0.003125F; return BusUnderVolt.word[0]; break; } - case 32: { return BusUnderVolt.word[1]; break; } - case 33: { // Shunt Over Voltage Limit (current limit) @@ -1473,7 +1491,6 @@ uint16_t ReadHoldingRegister(uint16_t address) return ShuntOverCurrentLimit.word[1]; break; } - case 35: { // Shunt UNDER Voltage Limit (under current limit) @@ -1713,8 +1730,10 @@ void loop() // Subtract remainder last_charge_coulombs = charge_coulombs - (difference - (integer_divide * 18)); // Chunks of 5mAh - milliamphour_out += integer_divide * 5; - milliamphour_out_lifetime += integer_divide * 5; + uint32_t a = integer_divide * 5; + milliamphour_out += a; + milliamphour_out_lifetime += a; + daily_milliamphour_out += a; } else { @@ -1724,8 +1743,10 @@ void loop() // Add on remainder last_charge_coulombs = charge_coulombs + (difference - (integer_divide * 18)); // chunks of 5mAh - milliamphour_in += integer_divide * 5; - milliamphour_in_lifetime += integer_divide * 5; + uint32_t a = integer_divide * 5; + milliamphour_in += a; + milliamphour_in_lifetime += a; + daily_milliamphour_in += a; } } } @@ -1758,8 +1779,6 @@ void loop() max_soc_reset_counter = soc_reset_counter; ResetChargeEnergyRegisters(); last_charge_coulombs = 0; - // milliamphour_in = 0; - // milliamphour_out = 0; soc_reset_counter = 0; SetSOC(10000); }