Replaced P102,P104 pads with high current part# 7460305
Added R107 (300k) and C104 (330pF) for better stability by lowering the gain
Update (All updates are already included in the github files, link at the end):
Updated R104, R105 to resistor value 470ohms for better reverse current protection threshold
Updated R101 to resistor value 16ohms for better stability
WHAT IS THIS?
What is an ideal diode? An ideal diode operates exactly as a traditional blocking diode that’s used to reverse current protection for a power path to protect the source from become the load and absorb power.
The only downside to using a diode is the power loss since most Shottky diodes, which is the a type of diode used primarily in power circuits, have a minimum voltage drop of 0.4V to allow current flow. This is an issue if you are trying to pass 50A through the diode which is a power loss of 10W which is a significant on design to eliminate that much heat from the diode.
The solution is to use is to use the ideal diode as a replacement for the Shottky diode. The ideal diode in summary is a linear op amp driving a mosfet with a low RDson internal resistance to turn on when current is flowing to the load and turn off when current tries to flow back to the source.
WHY DO WE NEED THIS?
Why is this circuit used and why is it needed?
The primary reason why I looked into this and designed this circuit was to have the ability to parallel multiple battery banks without having to worry if one of the banks ended up shorting out or having some fault that triggered the BMS system to turn off that particular bank.
This circuit is also known as an O-ring diode because it allows the use of multiple parallel sources to help drive the load and the load alone. If one source has an issue then it can be removed without having to turn off the system to do so and in the case of a battery bank, it keeps it from either being charged from the other batteries in parallel in case of an over voltage condition and it keeps it from discharging to other banks in case of an under voltage condition.
HOW DO WE CREATE THIS?
How is this circuit made? Below I’ve created a discrete ideal diode using an op amp for driving and a Mosfet as the diode switch.
Vinmax: 36V (This is limited by the mosfet and tvs diode, change those parts to increase input voltage range)
Imax: 30A ( This is dependent on the mosfet that is chosen, this rating is without a heatsink. I will perform test when I receive the actual boards as I used 2oz copper and should be able to handle more current without an issue. In theory this mosfet should be able to handle 400A with a proper heatsink)
Below I also simulated the circuit and you can see what both the sources share the current when they are equal in voltage. But when source “BAT01” drops in voltage, which simulates either a faster discharge on that parallel cell or the bms turned off the battery pack due to a fault event, source “BAT02” is now providing all the current to the load. You can see that BAT01 ideal diode is blocking the current from charging the battery which is known as reverse current.
WHERECAN I DOWNLOAD THIS?
I’ve uploaded all the files, which included sources files and gerber, on my github below:
Like my previous post about this project, this is a customizable arduino based 4S BMS system. This is now version 7 of hardware and version 21 of software.
The benefit of using this over other low cost solutions is that gives a lot more feedback about what exactly its doing and control over how its doing it. For example setting the limit for the over voltage protection and under voltage protection value.
Here is a couple pictures of my BMS in action on a 4S11P 18650 pack.
FEATURE SET AND SPECIFICATIONS
Now to the key features that makes this project different from the rest:
Adjustable voltage tolerance (maximum difference between cells)
Display individual voltage cell values on an oled i2C display and/or serial print monitor over UART (TX, RX, GND)
Set under-voltage protection value and over-voltage values for series MOSFET
Adjustable balance current with a swapping of drain resistor up to 1A safely
Serial commands for adjusting variables and feedback:
Under voltage protection value
Over voltage protection value
Cell voltage tolerance
Request calibration values
Request status of UVP and OVP event and reset if triggered
Enter calibration mode to re-calibrate if needed for ADC inputs
NOTE: Arduino BMS A7 hardware is supported only with the current arduino software
Now lets look into the hardware for this. There are 5 important sections in this board:
MCU: Arduino ATMEGA328P running at 8MHz with minicore bootloader
Reference 1.25V voltage for ADC
Voltage dividers for cell measurement into ADC
Series MOSFET Section
One of the most important sections in this project is the power section. Key features I was looking for was low Quiescent current because this will be battery operated.
Quiescent current is the amount of current needed to operate an IC.
The current power IC I’m using is a buck converter RT6208G. I chose a buck converter over an LDO because of efficiency, again trying to keep the current draw from the battery low. Key features of this converter is:
Low quiescent current: less than 500nA or 0.5mA
High input voltage: 36Vin max
Small and compact
Efficient: around 80-90%
One thing to mention is that the buck converter I chose is currently out of stock and will not be available until November. I’m currently working on choosing an alternative but any buck converter will work with this.
Anything here is that instead of stepping down to 3V3, I stepped down the voltage to 2V7. The image above is wrong and the FB resistor values are picked for an output voltage of 2V7 but it will function the same.
The reason for going with this voltage is because I was trying to minimize the current draw from the battery. I found that 2V7 is the minimum voltage I can use while still being able to use the I2C OLED screen.
MCU and REFERENCE VOLTAGE SECTION
The next section is the Arduino MCU and the external 1.25V reference.
Here you can see where the ADC pins are attached to the cell pins for measurements. And the digital pins for the control of the mosfets for the balance section. Its pretty straight forward here
On the bottom you can see the external 1.25V voltage reference. I’m sure there are different values I could have gone with but I figured that with a 1.25V I could try and increase resolution even after the voltage dividers. Without accounting for the voltage dividers for measuring the cells, we have a 1.22mV resolution. Not too bad but obviously it will increase with the voltage dividers.
VOLTAGE DIVIDER SECTION
The next section is the voltage divider section which is used to step down the cell voltages to within the voltage reference value, in our case 1.25V max.
My values calculated were based stepping down the voltage value to within 1.20V, that is when a cell is at 4.2V then the divider will be 1.20V. This gives some margin in case the cells get overcharged.
Here you can see the divider circuit. Since the measurements are single-ended measurements and not differential, then everything is reference to ground and there for the higher in cell measurements we go the bigger the voltage divider we need.
I used 100k as the base resistor as I tried to minimize current consumption. The measurement cycle will be slower due to the arduinos 14pF capacitor but thats ok because we sample about 100 measurements to offset this.
The last section is the balance section. Here the controllers turns off and on the mosfets corresponding to the cell its attached to. When the software determines that ex. cell 2 is higher than the lowest cell, then D1 is triggered and an 18 ohm resistor will start draining some current to let the rest of the cells catch up.
Looking at the bottom section of this circuit ( BAT0 / BAT1 ) you can see resistor value R424, this controls how much current is drained. At full charge of the cell 4.2V, you will see a current drain of 0.23A and then a minimum drain of 0.16A when the cell is at 3.0V.
Since the series mosfets are capable of 4.2A, you can theoretically lower the resistor value to drain more current but I do not suggest draining more than 1A at least with this board.
PROTECTION MOSFET SWITCH SECTION
This section was added for an extra layer of protection and is not needed for the bms balancing functionality to operate.
I’ve added a mosfet switch that utilizes the arduinos digital pin 9 and 10 to control power mosfets that are in series on the positive line of the battery.
Theoretically each mosfet can handle around 10A without a heatsink and about 40A per mosfet with a heatsink for a total of 120A total. But here you can add more in parallel for higher current or change the mosfet for a higher current capable one. The mosfets used here are P_Channel mosfets for high side switching.
Now to cover the software side of this board, here I will only cover the important sections in which you might want to adjust for your own purposes. Most of the variables you would want to change can be accessed and changed via serial monitor using an FTDI while only connecting the TX, RX, and GND pins.
Here I will list the important sections:
// Sampling number for analog read values.
// Will use this sample size to calculate a
// better estimation of the analog value
int samples = 100;
Here in the samples variable you can change the value for how many samples the adc takes before creating an averaging of the cells. If you want a smoother value you can increase but I would not go past 250 samples. Remember this will also effect the amount of time it takes to display voltage values.
// This is the max difference that the cells
// can achieve in respect to each other
float tol = 0.01; // 10mV max voltage difference
Here in the tol variable, it is used to as a reference for when the balancing of the cells should stop. The cells will balance until all cells are within 10mV of each other. This might not be exact because with the last 2 cells the register voltage different might be greater than 10mV due to a higher voltage divider but the measured voltage is around +/- 25mV of the actual cell voltage.
The most important part is the serial commands because this allows you to make changes without having to reflash the arduino.
Below we have a list of 6 serial commands that I will explain in details on how to enter the values into the serial monitor.
/* This is the table for entering into different modes and how to
* enter commands within serial console
* 1. Display ADC calibration values = 1001
* 2. Enter adc auto calibration = 1002
* 3. Adjust minimum and maximum = 1003
* voltage threshold for OVP
* and UVP
* 4. Used to set all digital outputs
* to low = 1004
* 5. Erase all EEPROM values = 1005
* 6. Reset series switch value = 1006
* 7. Display status for Reset, UVP
* OVP state condition = 1007
* 1.Example of displaying calibration values
* Serial window: mode
* Serial window: 1001
* 2.Example of entering into auto calibration mode
* Serial window: mode,vref1,vref2,vref3,vref4
* Serial window: 1002,4.00,8.00,12.00,16.00
* 3.Example of entering UVP and OVP values
* Serial window: mode,UVP,OVP
* Serial window: 1003,3.10,4.15
Lets look at the first command entry.
This will display the calibration values that is stored in EEPROM
This will enter calibration mode. Since there might be some offset from what the adc reads vs the actual value, I added a calibration mode that will add the offset to each adc value to try and get the values closer to the actual.
To enter calibration mode you will need to enter:
The vef1-4 values are the actual measurements of the battery cells
Enter 1004 first to turn off all balancing MOSFETS
Measure each cell value with a multimeter to get the actual value
Then enter calibration mode by entering 1002,3.54,3.76,3.20,3.56 as an example for vef values
This will adjust the values set for under voltage protection and over voltage protection. So if lets say 3.1V is set value for under-voltage protection then if any one of the cells drop below this value then the series FET will trigger if you have it attached.
This command is only valid if you use digital pin 9 and 10 for the series FET switch.
Used to set all balancing values to low so that no cell is draining current. This is usually used for testing purposes.
Enter 1004,1 for setting all values to low
Enter 1004,0 to go back to normal balancing operation
This is used to erase all eeprom values
If UVP or OVP is triggered then you will need to reset this fault condition
NOTE: If values are above or below the UVP and OVP values then resetting the 1006 command will not allow current to pass
CONCLUSION / FUTURE UPDATES
I’m very happy on how this project has progressed but its far from perfect and I will continue to optimize both the software and hardware to make it easier to integrate into a battery.
Future updates in my roadmap:
Optimize the Power MOSFET Switch circuit to handle higher currents
Possibly combine the mosfet control to one pin as using two might not be needed. UVP and OVP conditions open circuit the mosfet bidirectional switch
Add current sense capability for overcurrent protection.
My next big protection is creating a 7-8S BMS as well as a separate UVP, OVP, and Over-current protection board that will operate independently from the 8S BMS board but will still communicate via I2C to pass current data to the BMS board
If you have any questions or any suggestions or improvements please feel free to ask or comment.